2001-01-25 10:37:55 +01:00
|
|
|
|
/* vi: set ts=2:
|
|
|
|
|
*
|
2001-04-16 16:34:19 +02:00
|
|
|
|
*
|
2004-12-03 20:08:00 +01:00
|
|
|
|
* Eressea PB(E)M host Copyright (C) 1998-2003
|
2001-01-25 10:37:55 +01:00
|
|
|
|
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
|
|
|
|
* Katja Zedel (katze@felidae.kn-bremen.de)
|
|
|
|
|
* Henning Peters (faroul@beyond.kn-bremen.de)
|
|
|
|
|
* Enno Rehling (enno@eressea-pbem.de)
|
|
|
|
|
* Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
|
|
|
|
|
*
|
|
|
|
|
* based on:
|
|
|
|
|
*
|
|
|
|
|
* Atlantis v1.0 13 September 1993 Copyright 1993 by Russell Wallace
|
|
|
|
|
* Atlantis v1.7 Copyright 1996 by Alex Schr<EFBFBD>der
|
|
|
|
|
*
|
|
|
|
|
* This program may not be used, modified or distributed without
|
|
|
|
|
* prior permission by the authors of Eressea.
|
|
|
|
|
* This program may not be sold or used commercially without prior written
|
|
|
|
|
* permission from the authors.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
2001-01-30 21:02:06 +01:00
|
|
|
|
#include <eressea.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include "laws.h"
|
|
|
|
|
|
2001-02-10 23:02:10 +01:00
|
|
|
|
#include <modules/gmcmd.h>
|
2001-04-26 19:41:06 +02:00
|
|
|
|
#include <modules/infocmd.h>
|
2004-02-21 23:25:00 +01:00
|
|
|
|
#ifdef WORMHOLE_MODULE
|
|
|
|
|
#include <modules/wormhole.h>
|
|
|
|
|
#endif
|
2001-01-30 21:02:06 +01:00
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
/* gamecode includes */
|
|
|
|
|
#include "economy.h"
|
|
|
|
|
#include "monster.h"
|
|
|
|
|
#include "randenc.h"
|
|
|
|
|
#include "study.h"
|
|
|
|
|
|
2001-01-30 21:02:06 +01:00
|
|
|
|
/* kernel includes */
|
2004-06-27 18:56:01 +02:00
|
|
|
|
#include <kernel/alchemy.h>
|
|
|
|
|
#include <kernel/alliance.h>
|
|
|
|
|
#include <kernel/battle.h>
|
|
|
|
|
#include <kernel/border.h>
|
|
|
|
|
#include <kernel/building.h>
|
2005-06-05 15:34:08 +02:00
|
|
|
|
#include <kernel/calendar.h>
|
2004-06-27 18:56:01 +02:00
|
|
|
|
#include <kernel/faction.h>
|
|
|
|
|
#include <kernel/group.h>
|
|
|
|
|
#include <kernel/item.h>
|
|
|
|
|
#include <kernel/karma.h>
|
|
|
|
|
#include <kernel/magic.h>
|
|
|
|
|
#include <kernel/message.h>
|
|
|
|
|
#include <kernel/movement.h>
|
|
|
|
|
#include <kernel/order.h>
|
|
|
|
|
#include <kernel/plane.h>
|
|
|
|
|
#include <kernel/pool.h>
|
|
|
|
|
#include <kernel/race.h>
|
|
|
|
|
#include <kernel/region.h>
|
|
|
|
|
#include <kernel/resources.h>
|
|
|
|
|
#include <kernel/save.h>
|
|
|
|
|
#include <kernel/ship.h>
|
|
|
|
|
#include <kernel/skill.h>
|
|
|
|
|
#include <kernel/spy.h>
|
2005-01-19 21:33:13 +01:00
|
|
|
|
#include <kernel/teleport.h>
|
2005-10-25 14:38:01 +02:00
|
|
|
|
#include <kernel/terrain.h>
|
|
|
|
|
#include <kernel/terrainid.h> /* for volcanoes in emigration (needs a flag) */
|
2004-06-27 18:56:01 +02:00
|
|
|
|
#include <kernel/unit.h>
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
/* attributes includes */
|
|
|
|
|
#include <attributes/racename.h>
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#include <attributes/raceprefix.h>
|
|
|
|
|
#include <attributes/synonym.h>
|
2006-01-13 20:43:33 +01:00
|
|
|
|
#include <attributes/variable.h>
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* util includes */
|
2005-02-12 03:18:13 +01:00
|
|
|
|
#include <util/base36.h>
|
2005-06-17 20:12:58 +02:00
|
|
|
|
#include <util/bsdstring.h>
|
2005-02-12 03:18:13 +01:00
|
|
|
|
#include <util/event.h>
|
|
|
|
|
#include <util/goodies.h>
|
|
|
|
|
#include <util/log.h>
|
|
|
|
|
#include <util/rand.h>
|
2006-02-19 23:43:56 +01:00
|
|
|
|
#include <util/rng.h>
|
2005-02-12 03:18:13 +01:00
|
|
|
|
#include <util/sql.h>
|
2001-05-20 23:47:56 +02:00
|
|
|
|
#include <util/message.h>
|
2006-02-19 23:43:56 +01:00
|
|
|
|
#include <util/rng.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-04-27 21:40:31 +02:00
|
|
|
|
#include <modules/xecmd.h>
|
|
|
|
|
|
2001-02-28 23:14:59 +01:00
|
|
|
|
#ifdef AT_OPTION
|
2001-02-28 19:25:25 +01:00
|
|
|
|
/* attributes includes */
|
|
|
|
|
#include <attributes/option.h>
|
2001-02-28 23:14:59 +01:00
|
|
|
|
#endif
|
2001-02-28 19:25:25 +01:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* libc includes */
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <assert.h>
|
2001-02-03 14:45:35 +01:00
|
|
|
|
#include <ctype.h>
|
2005-11-06 12:33:19 +01:00
|
|
|
|
#include <limits.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-04-14 14:11:45 +02:00
|
|
|
|
#include <attributes/otherfaction.h>
|
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
/* chance that a peasant dies of starvation: */
|
|
|
|
|
#define PEASANT_STARVATION_CHANCE 0.9F
|
|
|
|
|
/* Pferdevermehrung */
|
|
|
|
|
#define HORSEGROWTH 4
|
|
|
|
|
/* Wanderungschance pro Pferd */
|
|
|
|
|
#define HORSEMOVE 3
|
|
|
|
|
/* Vermehrungschance pro Baum */
|
|
|
|
|
#define FORESTGROWTH 10000 /* In Millionstel */
|
|
|
|
|
|
|
|
|
|
/** Ausbreitung und Vermehrung */
|
|
|
|
|
#define MAXDEMAND 25
|
|
|
|
|
#define DMRISE 0.1F /* weekly chance that demand goes up */
|
|
|
|
|
#define DMRISEHAFEN 0.2F /* weekly chance that demand goes up with harbor */
|
|
|
|
|
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* - external symbols ------------------------------------------ */
|
|
|
|
|
extern int dropouts[2];
|
|
|
|
|
extern int * age;
|
|
|
|
|
/* - exported global symbols ----------------------------------- */
|
|
|
|
|
boolean nobattle = false;
|
2003-09-21 12:09:08 +02:00
|
|
|
|
boolean nomonsters = false;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
static int
|
2003-09-21 09:40:16 +02:00
|
|
|
|
RemoveNMRNewbie(void) {
|
2004-04-10 12:43:46 +02:00
|
|
|
|
static int value = -1;
|
|
|
|
|
if (value<0) {
|
|
|
|
|
const char * str = get_param(global.parameters, "nmr.removenewbie");
|
|
|
|
|
value = str?atoi(str):0;
|
|
|
|
|
}
|
|
|
|
|
return value;
|
2003-07-29 11:48:03 +02:00
|
|
|
|
}
|
|
|
|
|
|
2002-01-13 11:42:56 +01:00
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
restart_race(unit *u, const race * rc)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-04-12 01:56:47 +02:00
|
|
|
|
faction * oldf = u->faction;
|
|
|
|
|
faction *f = addfaction(oldf->email, oldf->passw, rc, oldf->locale, oldf->subscription);
|
2003-12-14 11:02:29 +01:00
|
|
|
|
unit * nu = addplayer(u->region, f);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
order ** ordp = &u->orders;
|
2002-11-02 15:10:52 +01:00
|
|
|
|
f->subscription = u->faction->subscription;
|
2004-12-20 23:59:42 +01:00
|
|
|
|
f->age = u->faction->age;
|
2004-04-10 12:43:46 +02:00
|
|
|
|
fset(f, FFL_RESTART);
|
2004-07-10 19:16:15 +02:00
|
|
|
|
if (f->subscription) {
|
|
|
|
|
sql_print(("UPDATE subscriptions set faction='%s', race='%s' where id=%u;\n",
|
|
|
|
|
itoa36(f->no), dbrace(rc), f->subscription));
|
|
|
|
|
}
|
2004-04-10 12:43:46 +02:00
|
|
|
|
f->magiegebiet = u->faction->magiegebiet;
|
|
|
|
|
f->options = u->faction->options;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
free_orders(&nu->orders);
|
2004-04-10 12:43:46 +02:00
|
|
|
|
nu->orders = u->orders;
|
|
|
|
|
u->orders = NULL;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
while (*ordp) {
|
|
|
|
|
order * ord = *ordp;
|
2005-06-04 17:34:04 +02:00
|
|
|
|
if (get_keyword(ord) != K_RESTART) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
*ordp = ord->next;
|
|
|
|
|
ord->next = NULL;
|
|
|
|
|
if (u->thisorder == ord) set_order(&u->thisorder, NULL);
|
2005-04-30 19:07:46 +02:00
|
|
|
|
#ifdef LASTORDER
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (u->lastorder == ord) set_order(&u->lastorder, NULL);
|
2005-04-30 19:07:46 +02:00
|
|
|
|
#endif
|
2004-04-10 12:43:46 +02:00
|
|
|
|
} else {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
ordp = &ord->next;
|
2004-04-10 12:43:46 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
destroyfaction(u->faction);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
checkorders(void)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
faction *f;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Warne sp<73>te Spieler...");
|
|
|
|
|
for (f = factions; f; f = f->next)
|
|
|
|
|
if (f->no!=MONSTER_FACTION && turn - f->lastorders == NMRTimeout() - 1)
|
|
|
|
|
ADDMSG(&f->msgs, msg_message("turnreminder", ""));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2004-03-09 22:14:27 +01:00
|
|
|
|
static boolean
|
|
|
|
|
help_money(const unit * u)
|
|
|
|
|
{
|
|
|
|
|
if (u->race->ec_flags & GIVEITEM) return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
get_food(region *r)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
unit *u;
|
|
|
|
|
int peasantfood = rpeasants(r)*10;
|
2005-11-25 23:09:59 +01:00
|
|
|
|
faction * owner = region_owner(r);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* 1. Versorgung von eigenen Einheiten. Das vorhandene Silber
|
|
|
|
|
* wird zun<EFBFBD>chst so auf die Einheiten aufgeteilt, dass idealerweise
|
|
|
|
|
* jede Einheit genug Silber f<EFBFBD>r ihren Unterhalt hat. */
|
2001-03-04 19:41:27 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
int need = lifestyle(u);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* Erstmal zur<75>cksetzen */
|
|
|
|
|
freset(u, UFL_HUNGER);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-11-25 23:09:59 +01:00
|
|
|
|
/* if the region is owned, and the owner is nice, then we'll get
|
|
|
|
|
* food from the peasants */
|
|
|
|
|
if (owner!=NULL && (get_alliance(owner, u->faction) & HELP_MONEY)) {
|
|
|
|
|
int rm = rmoney(r);
|
|
|
|
|
int use = min(rm, need);
|
|
|
|
|
rsetmoney(r, rm-use);
|
|
|
|
|
need -= use;
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
need -= get_money(u);
|
|
|
|
|
if (need > 0) {
|
|
|
|
|
unit *v;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-03-09 22:14:27 +01:00
|
|
|
|
for (v = r->units; need && v; v = v->next) {
|
|
|
|
|
if (v->faction == u->faction && help_money(v)) {
|
|
|
|
|
int give = get_money(v) - lifestyle(v);
|
|
|
|
|
give = min(need, give);
|
|
|
|
|
if (give>0) {
|
|
|
|
|
change_money(v, -give);
|
|
|
|
|
change_money(u, give);
|
|
|
|
|
need -= give;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* 2. Versorgung durch Fremde. Das Silber alliierter Einheiten wird
|
|
|
|
|
* entsprechend verteilt. */
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
int need = lifestyle(u);
|
2004-03-09 22:14:27 +01:00
|
|
|
|
faction * f = u->faction;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
need -= max(0, get_money(u));
|
|
|
|
|
|
|
|
|
|
if (need > 0) {
|
|
|
|
|
unit *v;
|
|
|
|
|
|
|
|
|
|
for (v = r->units; need && v; v = v->next) {
|
|
|
|
|
if (v->faction != f && alliedunit(v, f, HELP_MONEY) && help_money(v)) {
|
|
|
|
|
int give = get_money(v) - lifestyle(v);
|
|
|
|
|
give = min(need, give);
|
|
|
|
|
|
|
|
|
|
if (give>0) {
|
|
|
|
|
change_money(v, -give);
|
|
|
|
|
change_money(u, give);
|
|
|
|
|
need -= give;
|
|
|
|
|
add_spende(v->faction, u->faction, give, r);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Die Einheit hat nicht genug Geld zusammengekratzt und
|
|
|
|
|
* nimmt Schaden: */
|
|
|
|
|
if (need) {
|
|
|
|
|
int lspp = lifestyle(u)/u->number;
|
|
|
|
|
if (lspp > 0) {
|
|
|
|
|
int number = (need+lspp-1)/lspp;
|
|
|
|
|
if (hunger(number, u)) fset(u, UFL_HUNGER);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 3. bestimmen, wie viele Bauern gefressen werden.
|
2004-02-29 09:59:15 +01:00
|
|
|
|
* bei fehlenden Bauern den D<EFBFBD>mon hungern lassen
|
|
|
|
|
*/
|
2004-12-03 20:08:00 +01:00
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->race == new_race[RC_DAEMON]) {
|
2004-08-21 03:55:56 +02:00
|
|
|
|
unit * donor = r->units;
|
2004-02-29 09:59:15 +01:00
|
|
|
|
int hungry = u->number;
|
|
|
|
|
|
2004-08-21 03:55:56 +02:00
|
|
|
|
while (donor!=NULL && hungry>0) {
|
2005-06-05 18:48:22 +02:00
|
|
|
|
/* always start with the first known unit that may have some blood */
|
2004-02-29 09:59:15 +01:00
|
|
|
|
static const struct potion_type * pt_blood;
|
2005-11-01 21:33:21 +01:00
|
|
|
|
if (pt_blood==NULL) {
|
|
|
|
|
const item_type * it_blood = it_find("peasantblood");
|
|
|
|
|
if (it_blood) pt_blood = it_blood->rtype->ptype;
|
|
|
|
|
}
|
|
|
|
|
if (pt_blood!=NULL) {
|
|
|
|
|
while (donor!=NULL) {
|
|
|
|
|
if (donor->race==new_race[RC_DAEMON]) {
|
|
|
|
|
if (get_effect(donor, pt_blood)) {
|
|
|
|
|
/* if he's in our faction, drain him: */
|
|
|
|
|
if (donor->faction==u->faction) break;
|
|
|
|
|
}
|
2004-02-29 09:59:15 +01:00
|
|
|
|
}
|
2005-11-01 21:33:21 +01:00
|
|
|
|
donor = donor->next;
|
|
|
|
|
}
|
|
|
|
|
if (donor != NULL) {
|
|
|
|
|
int blut = get_effect(donor, pt_blood);
|
|
|
|
|
blut = min(blut, hungry);
|
|
|
|
|
change_effect(donor, pt_blood, -blut);
|
|
|
|
|
hungry -= blut;
|
2004-02-29 09:59:15 +01:00
|
|
|
|
}
|
2004-02-29 11:00:26 +01:00
|
|
|
|
}
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
if (r->planep == NULL || !fval(r->planep, PFL_NOFEED)) {
|
|
|
|
|
if (peasantfood>=hungry) {
|
|
|
|
|
peasantfood -= hungry;
|
|
|
|
|
hungry = 0;
|
|
|
|
|
} else {
|
|
|
|
|
hungry -= peasantfood;
|
|
|
|
|
peasantfood = 0;
|
|
|
|
|
}
|
|
|
|
|
if (hungry > 0) {
|
2004-08-21 03:55:56 +02:00
|
|
|
|
/* nicht gef<65>tterte d<>monen hungern */
|
2004-09-25 12:26:30 +02:00
|
|
|
|
#ifdef PEASANT_HUNGRY_DAEMONS_HAVE_FULL_SKILLS
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* wdw special rule */
|
|
|
|
|
hunger(hungry, u);
|
2004-09-25 12:26:30 +02:00
|
|
|
|
#else
|
2004-08-21 03:55:56 +02:00
|
|
|
|
if (hunger(hungry, u)) fset(u, UFL_HUNGER);
|
2004-09-25 12:26:30 +02:00
|
|
|
|
#endif
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* used to be: hunger(hungry, u); */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rsetpeasants(r, peasantfood/10);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* 3. Von den <20>berlebenden das Geld abziehen: */
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
int need = min(get_money(u), lifestyle(u));
|
|
|
|
|
change_money(u, -need);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2005-05-07 00:30:19 +02:00
|
|
|
|
static void
|
|
|
|
|
age_unit(region * r, unit * u)
|
|
|
|
|
{
|
|
|
|
|
if (u->race == new_race[RC_SPELL]) {
|
|
|
|
|
if (--u->age <= 0) {
|
|
|
|
|
destroy_unit(u);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
++u->age;
|
|
|
|
|
if (u->race->age) {
|
|
|
|
|
u->race->age(u);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef ASTRAL_ITEM_RESTRICTIONS
|
2005-06-13 23:29:59 +02:00
|
|
|
|
if (u->region->planep==get_astralplane()) {
|
2005-05-07 00:30:19 +02:00
|
|
|
|
item ** itemp = &u->items;
|
|
|
|
|
while (*itemp) {
|
|
|
|
|
item * itm = *itemp;
|
2005-06-29 00:00:58 +02:00
|
|
|
|
if ((itm->type->flags & ITF_NOTLOST) == 0) {
|
2005-05-07 00:30:19 +02:00
|
|
|
|
if (itm->type->flags & (ITF_BIG|ITF_ANIMAL|ITF_CURSED)) {
|
2005-06-28 23:28:50 +02:00
|
|
|
|
ADDMSG(&u->faction->msgs, msg_message("itemcrumble", "unit region item amount",
|
|
|
|
|
u, u->region, itm->type->rtype, itm->number));
|
2005-05-07 00:30:19 +02:00
|
|
|
|
i_free(i_remove(itemp, itm));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
itemp=&itm->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static void
|
|
|
|
|
live(region * r)
|
|
|
|
|
{
|
2004-04-09 03:32:06 +02:00
|
|
|
|
unit **up = &r->units;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-04-09 03:32:06 +02:00
|
|
|
|
get_food(r);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-04-09 03:32:06 +02:00
|
|
|
|
while (*up) {
|
2004-03-09 22:14:27 +01:00
|
|
|
|
unit * u = *up;
|
2004-04-09 03:32:06 +02:00
|
|
|
|
/* IUW: age_unit() kann u l<>schen, u->next ist dann
|
|
|
|
|
* undefiniert, also m<EFBFBD>ssen wir hier schon das n<EFBFBD>chste
|
|
|
|
|
* Element bestimmen */
|
|
|
|
|
|
|
|
|
|
int effect = get_effect(u, oldpotiontype[P_FOOL]);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
if (effect > 0) { /* Trank "Dumpfbackenbrot" */
|
2004-04-09 03:32:06 +02:00
|
|
|
|
skill * sv = u->skills, * sb = NULL;
|
|
|
|
|
while (sv!=u->skills+u->skill_size) {
|
|
|
|
|
if (sb==NULL || skill_compare(sv, sb)>0) {
|
|
|
|
|
sb = sv;
|
|
|
|
|
}
|
|
|
|
|
++sv;
|
|
|
|
|
}
|
|
|
|
|
/* bestes Talent raussuchen */
|
|
|
|
|
if (sb!=NULL) {
|
|
|
|
|
int weeks = min(effect, u->number);
|
|
|
|
|
reduce_skill(u, sb, weeks);
|
|
|
|
|
ADDMSG(&u->faction->msgs, msg_message("dumbeffect",
|
|
|
|
|
"unit weeks skill", u, weeks, (skill_t)sb->id));
|
2004-12-03 20:08:00 +01:00
|
|
|
|
} /* sonst Gl<47>ck gehabt: wer nix wei<65>, kann nix vergessen... */
|
2004-03-09 22:14:27 +01:00
|
|
|
|
change_effect(u, oldpotiontype[P_FOOL], -effect);
|
2004-04-09 03:32:06 +02:00
|
|
|
|
}
|
2004-03-09 22:14:27 +01:00
|
|
|
|
age_unit(r, u);
|
|
|
|
|
if (*up==u) up=&u->next;
|
2004-04-09 03:32:06 +02:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* This procedure calculates the number of emigrating peasants for the given
|
|
|
|
|
* region r. There are two incentives for peasants to emigrate:
|
|
|
|
|
* 1) They prefer the less crowded areas.
|
|
|
|
|
* Example: mountains, 700 peasants (max 1000), 70% inhabited
|
|
|
|
|
* plain, 5000 peasants (max 10000), 50% inhabited
|
|
|
|
|
* 700*(PEASANTSWANDER_WEIGHT/100)*((70-50)/100) peasants wander
|
|
|
|
|
* from mountains to plain.
|
|
|
|
|
* Effect : peasents will leave densely populated regions.
|
|
|
|
|
* 2) Peasants prefer richer neighbour regions.
|
|
|
|
|
* Example: region A, 700 peasants, wealth $10500, $15 per head
|
|
|
|
|
* region B, 2500 peasants, wealth $25000, $10 per head
|
|
|
|
|
* Some peasants will emigrate from B to A because $15 > $10
|
|
|
|
|
* exactly: 2500*(PEASANTSGREED_WEIGHT1/100)*((15-10)/100)
|
|
|
|
|
* Not taken in consideration:
|
|
|
|
|
* - movement because of monsters.
|
|
|
|
|
* - movement because of wars
|
|
|
|
|
* - movement because of low loyalty relating to present parties.
|
|
|
|
|
*/
|
|
|
|
|
|
2002-02-24 20:29:21 +01:00
|
|
|
|
#if NEW_MIGRATION == 1
|
|
|
|
|
|
|
|
|
|
/* Arbeitsversion */
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static void
|
2002-02-24 20:29:21 +01:00
|
|
|
|
calculate_emigration(region *r)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
direction_t i;
|
|
|
|
|
int overpopulation = rpeasants(r) - maxworkingpeasants(r);
|
|
|
|
|
int weight[MAXDIRECTIONS], weightall;
|
|
|
|
|
|
|
|
|
|
/* Bauern wandern nur bei <20>berbev<65>lkerung, sonst gar nicht */
|
|
|
|
|
if(overpopulation <= 0) return;
|
|
|
|
|
|
|
|
|
|
weightall = 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i != MAXDIRECTIONS; i++) {
|
|
|
|
|
region *rc = rconnect(r,i);
|
|
|
|
|
int w;
|
|
|
|
|
|
2005-10-25 14:38:01 +02:00
|
|
|
|
if (rc == NULL || !fval(rc->terrain, LAND_REGION)) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
w = 0;
|
|
|
|
|
} else {
|
|
|
|
|
w = rpeasants(rc) - maxworkingpeasants(rc);
|
|
|
|
|
w = max(0,w);
|
2005-10-25 14:38:01 +02:00
|
|
|
|
if (rterrain(rc) == T_VOLCANO || rterrain(rc) == T_VOLCANO_SMOKING) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
w = w/10;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
weight[i] = w;
|
|
|
|
|
weightall += w;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (weightall !=0 ) for (i = 0; i != MAXDIRECTIONS; i++) {
|
2005-10-25 14:38:01 +02:00
|
|
|
|
region *rc = rconnect(r, i);
|
|
|
|
|
if (rc != NULL) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
int wandering_peasants = (overpopulation * weight[i])/weightall;
|
|
|
|
|
if (wandering_peasants > 0) {
|
|
|
|
|
r->land->newpeasants -= wandering_peasants;
|
|
|
|
|
rc->land->newpeasants += wandering_peasants;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-02-24 20:29:21 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else
|
2001-01-25 10:37:55 +01:00
|
|
|
|
void
|
|
|
|
|
calculate_emigration(region *r)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
direction_t i, j;
|
|
|
|
|
int maxpeasants_here;
|
|
|
|
|
int maxpeasants[MAXDIRECTIONS];
|
|
|
|
|
double wfactor, gfactor;
|
|
|
|
|
|
|
|
|
|
/* Vermeidung von DivByZero */
|
|
|
|
|
maxpeasants_here = max(maxworkingpeasants(r),1);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i != MAXDIRECTIONS; i++) {
|
|
|
|
|
region *c = rconnect(r, i);
|
|
|
|
|
if (c && rterrain(c) != T_OCEAN) {
|
|
|
|
|
maxpeasants[i] = maxworkingpeasants(c);
|
|
|
|
|
} else maxpeasants[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* calculate emigration for all directions independently */
|
|
|
|
|
|
|
|
|
|
for (i = 0; i != MAXDIRECTIONS; i++) {
|
2005-10-25 14:38:01 +02:00
|
|
|
|
region * rc = rconnect(r, i);
|
|
|
|
|
if (!rc) continue;
|
|
|
|
|
if (fval(r, RF_ORCIFIED)==fval(rc, RF_ORCIFIED)) {
|
|
|
|
|
if (fval(rc->terrain, LAND_REGION) && fval(r->terrain, LAND_REGION)) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
int wandering_peasants;
|
|
|
|
|
double vfactor;
|
|
|
|
|
|
|
|
|
|
/* First let's calculate the peasants who wander off to less inhabited
|
|
|
|
|
* regions. wfactor indicates the difference of population denity.
|
|
|
|
|
* Never let more than PEASANTSWANDER_WEIGHT per cent wander off in one
|
|
|
|
|
* direction. */
|
|
|
|
|
wfactor = ((double) rpeasants(r) / maxpeasants_here -
|
2005-10-25 14:38:01 +02:00
|
|
|
|
((double) rpeasants(rc) / maxpeasants[i]));
|
2004-12-03 20:08:00 +01:00
|
|
|
|
wfactor = max(wfactor, 0);
|
|
|
|
|
wfactor = min(wfactor, 1);
|
|
|
|
|
|
|
|
|
|
/* Now let's handle the greedy peasants. gfactor indicates the
|
|
|
|
|
* difference of per-head-wealth. Never let more than
|
|
|
|
|
* PEASANTSGREED_WEIGHT per cent wander off in one direction. */
|
2005-10-25 14:38:01 +02:00
|
|
|
|
gfactor = (((double) rmoney(rc) / max(rpeasants(rc), 1)) -
|
2004-12-03 20:08:00 +01:00
|
|
|
|
((double) rmoney(r) / max(rpeasants(r), 1))) / 500;
|
|
|
|
|
gfactor = max(gfactor, 0);
|
|
|
|
|
gfactor = min(gfactor, 1);
|
|
|
|
|
|
|
|
|
|
/* This calculates the influence of volcanos on peasant
|
|
|
|
|
* migration. */
|
|
|
|
|
|
2005-10-25 14:38:01 +02:00
|
|
|
|
if(rterrain(rc) == T_VOLCANO || rterrain(rc) == T_VOLCANO_SMOKING) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
vfactor = 0.10;
|
|
|
|
|
} else {
|
|
|
|
|
vfactor = 1.00;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(j=0; j != MAXDIRECTIONS; j++) {
|
2005-10-25 14:38:01 +02:00
|
|
|
|
region *rv = rconnect(rc, j);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
if(rv && (rterrain(rv) == T_VOLCANO || rterrain(rv) == T_VOLCANO_SMOKING)) {
|
|
|
|
|
vfactor *= 0.5;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wandering_peasants = (int) (rpeasants(r) * (gfactor+wfactor)
|
|
|
|
|
* vfactor * PEASANTSWANDER_WEIGHT / 100.0);
|
|
|
|
|
|
|
|
|
|
r->land->newpeasants -= wandering_peasants;
|
2005-10-25 14:38:01 +02:00
|
|
|
|
rc->land->newpeasants += wandering_peasants;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2002-02-24 20:29:21 +01:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-12-31 15:23:09 +01:00
|
|
|
|
/** Bauern vermehren sich */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
peasants(region * r)
|
|
|
|
|
{
|
2005-12-31 15:23:09 +01:00
|
|
|
|
int peasants = rpeasants(r);
|
|
|
|
|
int money = rmoney(r);
|
|
|
|
|
int maxp = production(r) * MAXPEASANTS_PER_AREA;
|
|
|
|
|
int n, satiated;
|
|
|
|
|
int dead = 0;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
|
|
|
|
|
/* Bis zu 1000 Bauern k<>nnen Zwillinge bekommen oder 1000 Bauern
|
|
|
|
|
* wollen nicht! */
|
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (peasants>0) {
|
|
|
|
|
int glueck = 0;
|
|
|
|
|
int births = (int)(0.5F + peasants * 0.0001F * PEASANTGROWTH);
|
|
|
|
|
attrib * a = a_find(r->attribs, &at_peasantluck);
|
2005-12-31 15:23:09 +01:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (a!=NULL) {
|
|
|
|
|
glueck = a->data.i * 1000;
|
2006-01-07 13:30:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
for (n = peasants; n; --n) {
|
|
|
|
|
int chances = 0;
|
|
|
|
|
|
|
|
|
|
if (glueck>0) {
|
|
|
|
|
--glueck;
|
|
|
|
|
chances += PEASANTLUCK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (chances--) {
|
|
|
|
|
if (rng_int() % 10000 < PEASANTGROWTH) {
|
|
|
|
|
/* Only raise with 75% chance if peasants have
|
|
|
|
|
* reached 90% of maxpopulation */
|
|
|
|
|
if (peasants/(float)maxp < 0.9 || chance(PEASANTFORCE)) {
|
|
|
|
|
++births;
|
|
|
|
|
}
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-02-19 23:43:56 +01:00
|
|
|
|
peasants += births;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Alle werden satt, oder halt soviele f<>r die es auch Geld gibt */
|
|
|
|
|
|
2005-11-25 23:09:59 +01:00
|
|
|
|
satiated = min(peasants, money / maintenance_cost(NULL));
|
|
|
|
|
rsetmoney(r, money - satiated * maintenance_cost(NULL));
|
2004-12-03 20:08:00 +01:00
|
|
|
|
|
|
|
|
|
/* Von denjenigen, die nicht satt geworden sind, verhungert der
|
|
|
|
|
* Gro<EFBFBD>teil. dead kann nie gr<EFBFBD><EFBFBD>er als rpeasants(r) - satiated werden,
|
|
|
|
|
* so dass rpeasants(r) >= 0 bleiben mu<EFBFBD>. */
|
|
|
|
|
|
|
|
|
|
/* Es verhungert maximal die unterern<72>hrten Bev<65>lkerung. */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
n = min(peasants - satiated, rpeasants(r));
|
|
|
|
|
dead += (int)(n * PEASANT_STARVATION_CHANCE);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
|
2005-12-31 15:23:09 +01:00
|
|
|
|
if (dead > 0) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
message * msg = add_message(&r->msgs, msg_message("phunger", "dead", dead));
|
|
|
|
|
msg_release(msg);
|
|
|
|
|
peasants -= dead;
|
|
|
|
|
}
|
2002-02-24 20:32:48 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
rsetpeasants(r, peasants);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
typedef struct migration {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
struct migration * next;
|
|
|
|
|
region * r;
|
|
|
|
|
int horses;
|
|
|
|
|
int trees;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} migration;
|
|
|
|
|
|
|
|
|
|
#define MSIZE 1023
|
|
|
|
|
migration * migrants[MSIZE];
|
|
|
|
|
migration * free_migrants;
|
|
|
|
|
|
|
|
|
|
static migration *
|
|
|
|
|
get_migrants(region * r)
|
|
|
|
|
{
|
2005-06-10 00:10:35 +02:00
|
|
|
|
int key = reg_hashkey(r);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
int index = key % MSIZE;
|
|
|
|
|
migration * m = migrants[index];
|
|
|
|
|
while (m && m->r != r)
|
|
|
|
|
m = m->next;
|
|
|
|
|
if (m == NULL) {
|
|
|
|
|
/* Es gibt noch keine Migration. Also eine erzeugen
|
|
|
|
|
*/
|
|
|
|
|
m = free_migrants;
|
|
|
|
|
if (!m) m = calloc(1, sizeof(migration));
|
|
|
|
|
else {
|
|
|
|
|
free_migrants = free_migrants->next;
|
|
|
|
|
m->horses = 0;
|
|
|
|
|
m->trees = 0;
|
|
|
|
|
}
|
|
|
|
|
m->r = r;
|
|
|
|
|
m->next = migrants[index];
|
|
|
|
|
migrants[index] = m;
|
|
|
|
|
}
|
|
|
|
|
return m;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
migrate(region * r)
|
|
|
|
|
{
|
2005-06-10 00:10:35 +02:00
|
|
|
|
int key = reg_hashkey(r);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
int index = key % MSIZE;
|
|
|
|
|
migration ** hp = &migrants[index];
|
|
|
|
|
fset(r, RF_MIGRATION);
|
|
|
|
|
while (*hp && (*hp)->r != r) hp = &(*hp)->next;
|
|
|
|
|
if (*hp) {
|
|
|
|
|
migration * m = *hp;
|
|
|
|
|
rsethorses(r, rhorses(r) + m->horses);
|
|
|
|
|
/* Was macht das denn hier?
|
|
|
|
|
* Baumwanderung wird in trees() gemacht.
|
|
|
|
|
* wer fragt das? Die Baumwanderung war abh<EFBFBD>ngig von der
|
|
|
|
|
* Auswertungsreihenfolge der regionen,
|
|
|
|
|
* das hatte ich ge<EFBFBD>ndert. jemand hat es wieder gel<EFBFBD>scht, toll.
|
|
|
|
|
* ich habe es wieder aktiviert, mu<EFBFBD> getestet werden.
|
|
|
|
|
*/
|
|
|
|
|
*hp = m->next;
|
|
|
|
|
m->next = free_migrants;
|
|
|
|
|
free_migrants = m;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
horses(region * r)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
int horses, maxhorses;
|
|
|
|
|
direction_t n;
|
|
|
|
|
|
|
|
|
|
/* Logistisches Wachstum, Optimum bei halbem Maximalbesatz. */
|
|
|
|
|
maxhorses = maxworkingpeasants(r)/10;
|
|
|
|
|
maxhorses = max(0, maxhorses);
|
|
|
|
|
horses = rhorses(r);
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (horses > 0) {
|
|
|
|
|
if (is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) {
|
|
|
|
|
rsethorses(r, (int)(horses*0.9F));
|
|
|
|
|
} else if (maxhorses) {
|
|
|
|
|
int i;
|
|
|
|
|
double growth = (RESOURCE_QUANTITY * HORSEGROWTH * 200 * (maxhorses-horses))/maxhorses;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (growth>0) {
|
|
|
|
|
if (a_find(r->attribs, &at_horseluck)) growth *= 2;
|
|
|
|
|
/* printf("Horses: <%d> %d -> ", growth, horses); */
|
|
|
|
|
i = (int)(0.5F + (horses * 0.0001F) * growth);
|
|
|
|
|
/* printf("%d\n", horses); */
|
|
|
|
|
rsethorses(r, horses + i);
|
|
|
|
|
}
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* Pferde wandern in Nachbarregionen.
|
|
|
|
|
* Falls die Nachbarregion noch berechnet
|
|
|
|
|
* werden mu<EFBFBD>, wird eine migration-Struktur gebildet,
|
|
|
|
|
* die dann erst in die Berechnung der Nachbarstruktur einflie<EFBFBD>t.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
for(n = 0; n != MAXDIRECTIONS; n++) {
|
|
|
|
|
region * r2 = rconnect(r, n);
|
2005-10-25 14:38:01 +02:00
|
|
|
|
if (r2 && fval(r2->terrain, WALK_INTO)) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
int pt = (rhorses(r) * HORSEMOVE)/100;
|
|
|
|
|
pt = (int)normalvariate(pt, pt/4.0);
|
|
|
|
|
pt = max(0, pt);
|
|
|
|
|
if (fval(r2, RF_MIGRATION))
|
|
|
|
|
rsethorses(r2, rhorses(r2) + pt);
|
|
|
|
|
else {
|
|
|
|
|
migration * nb;
|
|
|
|
|
/* haben wir die Migration schonmal benutzt?
|
|
|
|
|
* wenn nicht, m<EFBFBD>ssen wir sie suchen.
|
|
|
|
|
* Wandernde Pferde vermehren sich nicht.
|
|
|
|
|
*/
|
|
|
|
|
nb = get_migrants(r2);
|
|
|
|
|
nb->horses += pt;
|
|
|
|
|
}
|
|
|
|
|
/* Wandernde Pferde sollten auch abgezogen werden */
|
|
|
|
|
rsethorses(r, rhorses(r) - pt);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
assert(rhorses(r) >= 0);
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
count_race(const region *r, const race *rc)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
unit *u;
|
|
|
|
|
int c = 0;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
for(u = r->units; u; u=u->next)
|
|
|
|
|
if(u->race == rc) c += u->number;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
return c;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern attrib_type at_germs;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
trees(region * r, const int current_season, const int last_weeks_season)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
int growth, grownup_trees, i, seeds, sprout, seedchance;
|
|
|
|
|
direction_t d;
|
|
|
|
|
attrib *a;
|
|
|
|
|
|
|
|
|
|
if(current_season == SEASON_SUMMER || current_season == SEASON_AUTUMN) {
|
|
|
|
|
int elves = count_race(r,new_race[RC_ELF]);
|
|
|
|
|
|
|
|
|
|
a = a_find(r->attribs, &at_germs);
|
|
|
|
|
if(a && last_weeks_season == SEASON_SPRING) {
|
|
|
|
|
/* ungekeimte Samen bleiben erhalten, Spr<70><72>linge wachsen */
|
|
|
|
|
sprout = min(a->data.sa[1], rtrees(r, 1));
|
|
|
|
|
/* aus dem gesamt Spr<70><72>lingepool abziehen */
|
|
|
|
|
rsettrees(r, 1, rtrees(r, 1) - sprout);
|
|
|
|
|
/* zu den B<>umen hinzuf<75>gen */
|
|
|
|
|
rsettrees(r, 2, rtrees(r, 2) + sprout);
|
|
|
|
|
|
|
|
|
|
a_removeall(&r->attribs, &at_germs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) {
|
|
|
|
|
rsettrees(r, 1, (int)(rtrees(r, 1) * 0.9));
|
|
|
|
|
rsettrees(r, 2, (int)(rtrees(r, 2) * 0.9));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (production(r) <= 0) return;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
|
|
|
|
|
/* Grundchance 1.0% */
|
|
|
|
|
seedchance = (int)(FORESTGROWTH * RESOURCE_QUANTITY);
|
|
|
|
|
/* Jeder Elf in der Region erh<72>ht die Chance um 0.0008%. */
|
|
|
|
|
seedchance += (min(elves, (production(r)*MAXPEASANTS_PER_AREA)/8)) * 8;
|
|
|
|
|
grownup_trees = rtrees(r, 2);
|
|
|
|
|
seeds = 0;
|
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (grownup_trees>0) {
|
|
|
|
|
seeds += (int)(seedchance*0.000001F*grownup_trees);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
rsettrees(r, 0, rtrees(r, 0) + seeds);
|
|
|
|
|
|
|
|
|
|
/* B<>ume breiten sich in Nachbarregionen aus. */
|
|
|
|
|
|
|
|
|
|
/* Gesamtzahl der Samen:
|
|
|
|
|
* bis zu 6% (FORESTGROWTH*3) der B<EFBFBD>ume samen in die Nachbarregionen */
|
|
|
|
|
seeds = (rtrees(r, 2) * FORESTGROWTH * 3)/1000000;
|
|
|
|
|
for (d=0;d!=MAXDIRECTIONS;++d) {
|
|
|
|
|
region * r2 = rconnect(r, d);
|
2005-10-25 14:38:01 +02:00
|
|
|
|
if (r2 && fval(r2->terrain, LAND_REGION) && r2->terrain->size) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* Eine Landregion, wir versuchen Samen zu verteilen:
|
|
|
|
|
* Die Chance, das Samen ein St<EFBFBD>ck Boden finden, in dem sie
|
|
|
|
|
* keimen k<EFBFBD>nnen, h<EFBFBD>ngt von der Bewuchsdichte und der
|
|
|
|
|
* verf<EFBFBD>gbaren Fl<EFBFBD>che ab. In Gletschern gibt es weniger
|
|
|
|
|
* M<EFBFBD>glichkeiten als in Ebenen. */
|
|
|
|
|
sprout = 0;
|
2005-10-25 14:38:01 +02:00
|
|
|
|
seedchance = (1000 * maxworkingpeasants(r2)) / r2->terrain->size;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
for(i=0; i<seeds/MAXDIRECTIONS; i++) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if(rng_int()%10000 < seedchance) sprout++;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
rsettrees(r2, 0, rtrees(r2, 0) + sprout);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if(current_season == SEASON_SPRING) {
|
|
|
|
|
|
|
|
|
|
if(is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) return;
|
|
|
|
|
|
|
|
|
|
/* in at_germs merken uns die Zahl der Samen und Spr<70><72>linge, die
|
|
|
|
|
* dieses Jahr <EFBFBD>lter werden d<EFBFBD>rfen, damit nicht ein Same im selben
|
|
|
|
|
* Zyklus zum Baum werden kann */
|
|
|
|
|
a = a_find(r->attribs, &at_germs);
|
|
|
|
|
if(!a) {
|
|
|
|
|
a = a_add(&r->attribs, a_new(&at_germs));
|
|
|
|
|
a->data.sa[0] = (short)rtrees(r, 0);
|
|
|
|
|
a->data.sa[1] = (short)rtrees(r, 1);
|
|
|
|
|
}
|
|
|
|
|
/* wir haben 6 Wochen zum wachsen, jeder Same/Spro<72> hat 18% Chance
|
|
|
|
|
* zu wachsen, damit sollten nach 5-6 Wochen alle gewachsen sein */
|
|
|
|
|
growth = 1800;
|
|
|
|
|
|
|
|
|
|
/* Samenwachstum */
|
|
|
|
|
|
|
|
|
|
/* Raubbau abfangen, es d<>rfen nie mehr Samen wachsen, als aktuell
|
|
|
|
|
* in der Region sind */
|
|
|
|
|
seeds = min(a->data.sa[0], rtrees(r, 0));
|
|
|
|
|
sprout = 0;
|
|
|
|
|
|
|
|
|
|
for(i=0;i<seeds;i++) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if(rng_int()%10000 < growth) sprout++;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
/* aus dem Samenpool dieses Jahres abziehen */
|
|
|
|
|
a->data.sa[0] = (short)(seeds - sprout);
|
|
|
|
|
/* aus dem gesamt Samenpool abziehen */
|
|
|
|
|
rsettrees(r, 0, rtrees(r, 0) - sprout);
|
|
|
|
|
/* zu den Spr<70><72>linge hinzuf<75>gen */
|
|
|
|
|
rsettrees(r, 1, rtrees(r, 1) + sprout);
|
|
|
|
|
|
|
|
|
|
/* Baumwachstum */
|
|
|
|
|
|
|
|
|
|
/* hier gehen wir davon aus, das Jungb<67>ume nicht ohne weiteres aus
|
|
|
|
|
* der Region entfernt werden k<EFBFBD>nnen, da Jungb<EFBFBD>ume in der gleichen
|
|
|
|
|
* Runde nachwachsen, wir also nicht mehr zwischen diesj<EFBFBD>hrigen und
|
|
|
|
|
* 'alten' Jungb<EFBFBD>umen unterscheiden k<EFBFBD>nnten */
|
|
|
|
|
sprout = min(a->data.sa[1], rtrees(r, 1));
|
|
|
|
|
grownup_trees = 0;
|
|
|
|
|
|
|
|
|
|
for(i=0;i<sprout;i++) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if(rng_int()%10000 < growth) grownup_trees++;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
/* aus dem Spr<70><72>lingepool dieses Jahres abziehen */
|
|
|
|
|
a->data.sa[1] = (short)(sprout - grownup_trees);
|
|
|
|
|
/* aus dem gesamt Spr<70><72>lingepool abziehen */
|
|
|
|
|
rsettrees(r, 1, rtrees(r, 1) - grownup_trees);
|
|
|
|
|
/* zu den B<>umen hinzuf<75>gen */
|
|
|
|
|
rsettrees(r, 2, rtrees(r, 2) + grownup_trees);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Jetzt die Kr<4B>utervermehrung. Vermehrt wird logistisch:
|
|
|
|
|
*
|
|
|
|
|
* Jedes Kraut hat eine Wahrscheinlichkeit von (100-(vorhandene
|
|
|
|
|
* Kr<EFBFBD>uter))% sich zu vermehren. */
|
|
|
|
|
if(current_season == SEASON_SPRING || current_season == SEASON_SUMMER
|
|
|
|
|
|| current_season == SEASON_AUTUMN)
|
|
|
|
|
{
|
|
|
|
|
for(i = rherbs(r); i > 0; i--) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (rng_int()%100 < (100-rherbs(r))) rsetherbs(r, (short)(rherbs(r)+1));
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
demographics(void)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
region *r;
|
2005-06-05 15:34:08 +02:00
|
|
|
|
static int last_weeks_season = -1;
|
|
|
|
|
static int current_season = -1;
|
|
|
|
|
|
|
|
|
|
if (current_season<0) {
|
|
|
|
|
current_season = get_gamedate(turn, NULL)->season;
|
|
|
|
|
last_weeks_season = get_gamedate(turn-1, NULL)->season;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
for (r = regions; r; r = r->next) {
|
2005-10-25 14:38:01 +02:00
|
|
|
|
++r->age; /* also oceans. no idea why we didn't always do that */
|
2004-12-03 20:08:00 +01:00
|
|
|
|
live(r);
|
|
|
|
|
/* check_split_dragons(); */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-10-25 14:38:01 +02:00
|
|
|
|
if (!fval(r->terrain, SEA_REGION)) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* die Nachfrage nach Produkten steigt. */
|
|
|
|
|
struct demand * dmd;
|
|
|
|
|
if (r->land) for (dmd=r->land->demands;dmd;dmd=dmd->next) {
|
|
|
|
|
if (dmd->value>0 && dmd->value < MAXDEMAND) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
float rise = DMRISE;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
if (buildingtype_exists(r, bt_find("harbour"))) rise = DMRISEHAFEN;
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (rng_double()<rise) ++dmd->value;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Seuchen erst nachdem die Bauern sich vermehrt haben
|
|
|
|
|
* und gewandert sind */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
calculate_emigration(r);
|
|
|
|
|
peasants(r);
|
|
|
|
|
plagues(r, false);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
horses(r);
|
|
|
|
|
if(current_season != SEASON_WINTER) {
|
|
|
|
|
trees(r, current_season, last_weeks_season);
|
|
|
|
|
}
|
|
|
|
|
update_resources(r);
|
|
|
|
|
migrate(r);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while (free_migrants) {
|
|
|
|
|
migration * m = free_migrants->next;
|
|
|
|
|
free(free_migrants);
|
|
|
|
|
free_migrants = m;
|
|
|
|
|
};
|
|
|
|
|
putchar('\n');
|
|
|
|
|
|
|
|
|
|
remove_empty_units();
|
|
|
|
|
|
|
|
|
|
puts(" - Einwanderung...");
|
|
|
|
|
for (r = regions; r; r = r->next) {
|
2005-10-25 14:38:01 +02:00
|
|
|
|
if (fval(r->terrain, LAND_REGION)) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
int rp = rpeasants(r) + r->land->newpeasants;
|
|
|
|
|
rsetpeasants(r, max(0, rp));
|
|
|
|
|
/* Wenn keine Bauer da ist, soll auch kein Geld da sein */
|
|
|
|
|
/* Martin */
|
|
|
|
|
if (rpeasants(r) == 0)
|
|
|
|
|
rsetmoney(r, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
checkorders();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
modify(int i)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
int c;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
c = i * 2 / 3;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
if (c >= 1) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
return (c + rng_int() % c);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
} else {
|
|
|
|
|
return (i);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
inactivefaction(faction * f)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
FILE *inactiveFILE;
|
|
|
|
|
char zText[128];
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
sprintf(zText, "%s/%s", datapath(), "/inactive");
|
|
|
|
|
inactiveFILE = fopen(zText, "a");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
fprintf(inactiveFILE, "%s:%s:%d:%d\n",
|
|
|
|
|
factionid(f),
|
|
|
|
|
LOC(default_locale, rc_name(f->race, 1)),
|
|
|
|
|
modify(count_all(f)),
|
|
|
|
|
turn - f->lastorders);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
fclose(inactiveFILE);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2003-04-24 22:54:14 +02:00
|
|
|
|
static void
|
|
|
|
|
transfer_faction(faction *f, faction *f2)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
unit *u, *un;
|
|
|
|
|
|
|
|
|
|
for (u = f->units; u;) {
|
|
|
|
|
un = u->nextF;
|
|
|
|
|
if(!unit_has_cursed_item(u)
|
|
|
|
|
&& !has_skill(u, SK_MAGIC)
|
|
|
|
|
&& !has_skill(u, SK_ALCHEMY)) {
|
|
|
|
|
u_setfaction(u, f2);
|
|
|
|
|
}
|
|
|
|
|
u = un;
|
|
|
|
|
}
|
2003-04-24 22:54:14 +02:00
|
|
|
|
}
|
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
static int
|
2004-12-20 23:59:42 +01:00
|
|
|
|
restart_cmd(unit * u, struct order * ord)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token(); /* skip keyword */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-10-25 14:38:01 +02:00
|
|
|
|
if (!fval(u->region->terrain, LAND_REGION)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 242, MSG_EVENT);
|
|
|
|
|
} else {
|
|
|
|
|
const char * s_race = getstrtoken(), * s_pass;
|
|
|
|
|
const race * frace = findrace(s_race, u->faction->locale);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (!frace) {
|
|
|
|
|
frace = u->faction->race;
|
|
|
|
|
s_pass = s_race;
|
|
|
|
|
} else {
|
|
|
|
|
s_pass = getstrtoken();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (u->faction->age > 3 && fval(u->faction, FFL_RESTART)) {
|
|
|
|
|
cmistake(u, ord, 314, MSG_EVENT);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-14 23:26:02 +02:00
|
|
|
|
if (/* frace != u->faction->race && */ u->faction->age < 81) {
|
|
|
|
|
cmistake(u, ord, 241, MSG_EVENT);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (!playerrace(frace)) {
|
|
|
|
|
cmistake(u, ord, 243, MSG_EVENT);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!checkpasswd(u->faction, s_pass, false)) {
|
|
|
|
|
cmistake(u, ord, 86, MSG_EVENT);
|
|
|
|
|
log_warning(("NEUSTART mit falschem Passwort f<>r Partei %s: %s\n",
|
2004-09-05 15:48:00 +02:00
|
|
|
|
factionid(u->faction), s_pass));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
restart_race(u, frace);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-27 18:56:01 +02:00
|
|
|
|
static boolean
|
2004-06-27 20:56:03 +02:00
|
|
|
|
EnhancedQuit(void)
|
2004-06-27 18:56:01 +02:00
|
|
|
|
{
|
|
|
|
|
static int value = -1;
|
|
|
|
|
if (value<0) {
|
|
|
|
|
const char * str = get_param(global.parameters, "alliance.transferquit");
|
|
|
|
|
value = (str!=0 && strcmp(str, "true")==0);
|
|
|
|
|
}
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
static int
|
2006-01-13 20:43:33 +01:00
|
|
|
|
quit_cmd(unit * u, struct order * ord)
|
2004-06-21 18:45:27 +02:00
|
|
|
|
{
|
2006-01-13 20:43:33 +01:00
|
|
|
|
faction * f = u->faction;
|
2005-04-16 13:15:47 +02:00
|
|
|
|
const char * passwd;
|
2006-01-13 20:43:33 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token(); /* skip keyword */
|
2003-04-24 22:54:14 +02:00
|
|
|
|
|
2005-04-16 13:15:47 +02:00
|
|
|
|
passwd = getstrtoken();
|
2006-01-13 20:43:33 +01:00
|
|
|
|
if (checkpasswd(f, passwd, false)) {
|
2004-06-27 18:56:01 +02:00
|
|
|
|
if (EnhancedQuit()) {
|
2006-01-13 20:43:33 +01:00
|
|
|
|
const char * token = getstrtoken();
|
|
|
|
|
int f2_id = atoi36(token);
|
|
|
|
|
if (f2_id>0) {
|
2004-06-27 18:56:01 +02:00
|
|
|
|
faction *f2 = findfaction(f2_id);
|
|
|
|
|
|
|
|
|
|
if(f2 == NULL) {
|
|
|
|
|
cmistake(u, ord, 66, MSG_EVENT);
|
2006-01-13 20:43:33 +01:00
|
|
|
|
return 0;
|
2004-06-27 18:56:01 +02:00
|
|
|
|
} else if (!u->faction->alliance || u->faction->alliance != f2->alliance) {
|
|
|
|
|
cmistake(u, ord, 315, MSG_EVENT);
|
2006-01-13 20:43:33 +01:00
|
|
|
|
return 0;
|
2004-06-27 18:56:01 +02:00
|
|
|
|
} else if(!alliedfaction(NULL, f, f2, HELP_MONEY)) {
|
|
|
|
|
cmistake(u, ord, 316, MSG_EVENT);
|
2006-01-13 20:43:33 +01:00
|
|
|
|
return 0;
|
2004-06-27 18:56:01 +02:00
|
|
|
|
} else {
|
2006-01-13 20:43:33 +01:00
|
|
|
|
set_variable(&f->attribs, "quit", token);
|
2004-06-27 18:56:01 +02:00
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2006-01-13 20:43:33 +01:00
|
|
|
|
fset(f, FFL_QUIT);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
} else {
|
|
|
|
|
cmistake(u, ord, 86, MSG_EVENT);
|
|
|
|
|
log_warning(("STIRB mit falschem Passwort f<>r Partei %s: %s\n",
|
2006-01-13 20:43:33 +01:00
|
|
|
|
factionid(f), passwd));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2002-03-24 12:24:57 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static void
|
2006-01-13 20:43:33 +01:00
|
|
|
|
quit(void)
|
|
|
|
|
{
|
|
|
|
|
faction ** fptr = &factions;
|
|
|
|
|
while (*fptr) {
|
|
|
|
|
faction * f = *fptr;
|
|
|
|
|
if (f->flags & FFL_QUIT) {
|
|
|
|
|
if (EnhancedQuit()) {
|
|
|
|
|
const char * token = get_variable(f->attribs, "quit");
|
|
|
|
|
int f2_id = atoi36(token);
|
|
|
|
|
faction *f2 = findfaction(f2_id);
|
|
|
|
|
|
|
|
|
|
assert(f2_id>0);
|
|
|
|
|
assert(f2!=NULL);
|
|
|
|
|
transfer_faction(f, f2);
|
|
|
|
|
}
|
|
|
|
|
destroyfaction(f);
|
|
|
|
|
}
|
|
|
|
|
if (*fptr==f) fptr=&f->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
parse_restart(void)
|
2004-06-21 18:45:27 +02:00
|
|
|
|
{
|
|
|
|
|
region *r;
|
|
|
|
|
faction *f;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
/* Sterben erst nachdem man allen anderen gegeben hat - bzw. man kann
|
|
|
|
|
* alles machen, was nicht ein drei<EFBFBD>igt<EFBFBD>giger Befehl ist. */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
for (r = regions; r; r = r->next) {
|
|
|
|
|
unit * u, * un;
|
|
|
|
|
for (u = r->units; u;) {
|
|
|
|
|
order * ord;
|
2006-01-13 20:43:33 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
un = u->next;
|
2006-01-13 20:43:33 +01:00
|
|
|
|
for (ord = u->orders; ord!=NULL; ord = ord->next) {
|
|
|
|
|
if (get_keyword(ord) == K_RESTART) {
|
|
|
|
|
if (u->number > 0) {
|
|
|
|
|
if (restart_cmd(u, ord)!=0) {
|
|
|
|
|
break;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
2006-01-13 20:43:33 +01:00
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
u = un;
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
puts(" - beseitige Spieler, die sich zu lange nicht mehr gemeldet haben...");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
for (f = factions; f; f = f->next) {
|
|
|
|
|
if(fval(f, FFL_NOIDLEOUT)) f->lastorders = turn;
|
|
|
|
|
if (NMRTimeout()>0 && turn - f->lastorders >= NMRTimeout()) {
|
|
|
|
|
destroyfaction(f);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (fval(f, FFL_OVERRIDE)) {
|
|
|
|
|
free(f->override);
|
2006-02-19 23:43:56 +01:00
|
|
|
|
f->override = strdup(itoa36(rng_int()));
|
2005-07-26 12:17:43 +02:00
|
|
|
|
freset(f, FFL_OVERRIDE);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
if (turn!=f->lastorders) {
|
|
|
|
|
char info[256];
|
2004-12-03 20:08:00 +01:00
|
|
|
|
sprintf(info, "%d Einheiten, %d Personen, %d Silber",
|
2005-03-06 14:47:23 +01:00
|
|
|
|
f->no_units, f->num_total, f->money);
|
2004-07-10 19:16:15 +02:00
|
|
|
|
if (f->subscription) {
|
|
|
|
|
sql_print(("UPDATE subscriptions SET lastturn=%d, password='%s', info='%s' WHERE id=%u;\n",
|
|
|
|
|
f->lastorders, f->override, info, f->subscription));
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
} else {
|
2004-07-10 19:16:15 +02:00
|
|
|
|
if (f->subscription) {
|
2005-10-12 22:34:32 +02:00
|
|
|
|
sql_print(("UPDATE subscriptions SET status='ACTIVE', lastturn=%d, firstturn=greatest(firstturn,%d), password='%s' WHERE id=%u;\n",
|
2005-10-12 22:27:50 +02:00
|
|
|
|
f->lastorders, f->lastorders-f->age,
|
|
|
|
|
f->override, f->subscription));
|
2004-07-10 19:16:15 +02:00
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
2002-03-03 11:51:24 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (NMRTimeout()>0 && turn - f->lastorders >= (NMRTimeout() - 1)) {
|
|
|
|
|
inactivefaction(f);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
puts(" - beseitige Spieler, die sich nach der Anmeldung nicht "
|
|
|
|
|
"gemeldet haben...");
|
|
|
|
|
|
|
|
|
|
age = calloc(max(4,turn+1), sizeof(int));
|
|
|
|
|
for (f = factions; f; f = f->next) if (f->no != MONSTER_FACTION) {
|
|
|
|
|
if (RemoveNMRNewbie() && !fval(f, FFL_NOIDLEOUT)) {
|
|
|
|
|
if (f->age>=0 && f->age <= turn) ++age[f->age];
|
|
|
|
|
if (f->age == 2 || f->age == 3) {
|
|
|
|
|
if (f->lastorders == turn - 2) {
|
|
|
|
|
destroyfaction(f);
|
|
|
|
|
++dropouts[f->age-2];
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-06-27 18:56:01 +02:00
|
|
|
|
#ifndef ALLIANCEJOIN
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (f->alliance==NULL) {
|
|
|
|
|
/* destroyfaction(f); */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2002-09-02 22:36:12 +02:00
|
|
|
|
#endif
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
/* Clear away debris of destroyed factions */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
puts(" - beseitige leere Einheiten und leere Parteien...");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
remove_empty_units();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
/* Auskommentiert: Wenn factions gel<65>scht werden, zeigen
|
|
|
|
|
* Spendenpointer ins Leere. */
|
|
|
|
|
/* remove_empty_factions(); */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
/* HELFE partei [<ALLES | SILBER | GIB | KAEMPFE | WAHRNEHMUNG>] [NICHT] */
|
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static int
|
|
|
|
|
ally_cmd(unit * u, struct order * ord)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
ally * sf, ** sfp;
|
|
|
|
|
faction *f;
|
|
|
|
|
int keyword, not_kw;
|
|
|
|
|
const char *s;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
f = getfaction();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (f == 0 || f->no == 0) {
|
|
|
|
|
cmistake(u, ord, 66, MSG_EVENT);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (f == u->faction) return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
s = getstrtoken();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (!s[0])
|
|
|
|
|
keyword = P_ANY;
|
|
|
|
|
else
|
|
|
|
|
keyword = findparam(s, u->faction->locale);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
sfp = &u->faction->allies;
|
2005-06-12 19:57:14 +02:00
|
|
|
|
if (fval(u, UFL_GROUP)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
attrib * a = a_find(u->attribs, &at_group);
|
|
|
|
|
if (a) sfp = &((group*)a->data.v)->allies;
|
|
|
|
|
}
|
|
|
|
|
for (sf=*sfp; sf; sf = sf->next)
|
|
|
|
|
if (sf->faction == f)
|
2004-12-03 20:08:00 +01:00
|
|
|
|
break; /* Gleich die passende raussuchen, wenn vorhanden */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
not_kw = getparam(u->faction->locale); /* HELFE partei [modus] NICHT */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (!sf) {
|
|
|
|
|
if (keyword == P_NOT || not_kw == P_NOT) {
|
|
|
|
|
/* Wir helfen der Partei gar nicht... */
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
sf = calloc(1, sizeof(ally));
|
|
|
|
|
sf->faction = f;
|
|
|
|
|
sf->status = 0;
|
|
|
|
|
addlist(sfp, sf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
switch (keyword) {
|
|
|
|
|
case P_NOT:
|
|
|
|
|
sf->status = 0;
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case NOPARAM:
|
|
|
|
|
cmistake(u, ord, 137, MSG_EVENT);
|
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_ANY:
|
|
|
|
|
if (not_kw == P_NOT)
|
|
|
|
|
sf->status = 0;
|
|
|
|
|
else
|
|
|
|
|
sf->status = HELP_ALL;
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_TRAVEL:
|
|
|
|
|
if (not_kw == P_NOT)
|
|
|
|
|
sf->status = sf->status & (HELP_ALL - HELP_TRAVEL);
|
|
|
|
|
else
|
|
|
|
|
sf->status = sf->status | HELP_TRAVEL;
|
|
|
|
|
break;
|
2002-12-18 01:34:19 +01:00
|
|
|
|
|
|
|
|
|
case P_GIB:
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (not_kw == P_NOT)
|
|
|
|
|
sf->status = sf->status & (HELP_ALL - HELP_GIVE);
|
|
|
|
|
else
|
|
|
|
|
sf->status = sf->status | HELP_GIVE;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case P_SILVER:
|
|
|
|
|
if (not_kw == P_NOT)
|
|
|
|
|
sf->status = sf->status & (HELP_ALL - HELP_MONEY);
|
|
|
|
|
else
|
|
|
|
|
sf->status = sf->status | HELP_MONEY;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case P_KAEMPFE:
|
|
|
|
|
if (not_kw == P_NOT)
|
|
|
|
|
sf->status = sf->status & (HELP_ALL - HELP_FIGHT);
|
|
|
|
|
else
|
|
|
|
|
sf->status = sf->status | HELP_FIGHT;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case P_FACTIONSTEALTH:
|
|
|
|
|
if (not_kw == P_NOT)
|
|
|
|
|
sf->status = sf->status & (HELP_ALL - HELP_FSTEALTH);
|
|
|
|
|
else
|
|
|
|
|
sf->status = sf->status | HELP_FSTEALTH;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case P_GUARD:
|
|
|
|
|
if (not_kw == P_NOT)
|
|
|
|
|
sf->status = sf->status & (HELP_ALL - HELP_GUARD);
|
|
|
|
|
else
|
|
|
|
|
sf->status = sf->status | HELP_GUARD;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
if (sf->status == 0) { /* Alle HELPs geloescht */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
removelist(sfp, sf);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2004-09-12 11:51:36 +02:00
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
prefix_cmd(unit * u, struct order * ord)
|
|
|
|
|
{
|
|
|
|
|
attrib **ap;
|
|
|
|
|
int i;
|
|
|
|
|
const char *s;
|
|
|
|
|
|
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
|
|
|
|
|
if (!*s) {
|
2005-06-12 19:57:14 +02:00
|
|
|
|
attrib *a = NULL;
|
|
|
|
|
if (fval(u, UFL_GROUP)) {
|
|
|
|
|
a = a_find(u->attribs, &at_group);
|
|
|
|
|
}
|
2004-09-12 11:51:36 +02:00
|
|
|
|
if (a) {
|
2005-06-12 19:57:14 +02:00
|
|
|
|
group * g = (group*)a->data.v;
|
|
|
|
|
a_removeall(&g->attribs, &at_raceprefix);
|
2004-09-12 11:51:36 +02:00
|
|
|
|
} else {
|
|
|
|
|
a_removeall(&u->faction->attribs, &at_raceprefix);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(i=0; race_prefixes[i] != NULL; i++) {
|
|
|
|
|
const char * tag = mkname("prefix", race_prefixes[i]);
|
|
|
|
|
if (strncasecmp(s, LOC(u->faction->locale, tag), strlen(s)) == 0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (race_prefixes[i] == NULL) {
|
|
|
|
|
cmistake(u, ord, 299, MSG_EVENT);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ap = &u->faction->attribs;
|
2005-06-12 19:57:14 +02:00
|
|
|
|
if (fval(u, UFL_GROUP)) {
|
|
|
|
|
attrib * a = a_find(u->attribs, &at_group);
|
|
|
|
|
group * g = (group*)a->data.v;
|
|
|
|
|
if (a) ap = &g->attribs;
|
|
|
|
|
}
|
2004-09-12 11:51:36 +02:00
|
|
|
|
set_prefix(ap, race_prefixes[i]);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
synonym_cmd(unit * u, struct order * ord)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
const char *s;
|
|
|
|
|
|
|
|
|
|
attrib * a = a_find(u->faction->attribs, &at_synonym);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
if (a!=NULL) { /* Kann nur einmal gesetzt werden */
|
2004-09-12 11:51:36 +02:00
|
|
|
|
cmistake(u, ord, 302, MSG_EVENT);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
|
|
|
|
|
if (s==NULL) {
|
|
|
|
|
cmistake(u, ord, 301, MSG_EVENT);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i=0; race_synonyms[i].race != -1; i++) {
|
|
|
|
|
if (new_race[race_synonyms[i].race] == u->faction->race
|
|
|
|
|
&& strcasecmp(s, race_synonyms[i].synonyms[0]) == 0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (race_synonyms[i].race == -1) {
|
|
|
|
|
cmistake(u, ord, 300, MSG_EVENT);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
a = a_add(&u->faction->attribs, a_new(&at_synonym));
|
|
|
|
|
((frace_synonyms *)(a->data.v))->synonyms[0] =
|
|
|
|
|
strdup(race_synonyms[i].synonyms[0]);
|
|
|
|
|
((frace_synonyms *)(a->data.v))->synonyms[1] =
|
|
|
|
|
strdup(race_synonyms[i].synonyms[1]);
|
|
|
|
|
((frace_synonyms *)(a->data.v))->synonyms[2] =
|
|
|
|
|
strdup(race_synonyms[i].synonyms[2]);
|
|
|
|
|
((frace_synonyms *)(a->data.v))->synonyms[3] =
|
|
|
|
|
strdup(race_synonyms[i].synonyms[3]);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static int
|
|
|
|
|
display_cmd(unit * u, struct order * ord)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2005-04-23 11:47:03 +02:00
|
|
|
|
building * b = u->building;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
char **s = NULL;
|
|
|
|
|
region * r = u->region;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
switch (getparam(u->faction->locale)) {
|
|
|
|
|
case P_BUILDING:
|
|
|
|
|
case P_GEBAEUDE:
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (!b) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 145, MSG_PRODUCE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!fval(u, UFL_OWNER)) {
|
|
|
|
|
cmistake(u, ord, 5, MSG_PRODUCE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (b->type == bt_find("generic")) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 279, MSG_PRODUCE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (b->type == bt_find("monument") && b->display && b->display[0] != 0) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 29, MSG_PRODUCE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (b->type == bt_find("artsculpture") && b->display && b->display[0] != 0) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 29, MSG_PRODUCE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-04-23 11:47:03 +02:00
|
|
|
|
s = &b->display;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_SHIP:
|
|
|
|
|
if (!u->ship) {
|
|
|
|
|
cmistake(u, ord, 144, MSG_PRODUCE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!fval(u, UFL_OWNER)) {
|
|
|
|
|
cmistake(u, ord, 12, MSG_PRODUCE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
s = &u->ship->display;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case P_UNIT:
|
|
|
|
|
s = &u->display;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case P_PRIVAT:
|
|
|
|
|
{
|
|
|
|
|
const char *d = getstrtoken();
|
|
|
|
|
if(d == NULL || *d == 0) {
|
|
|
|
|
usetprivate(u, NULL);
|
|
|
|
|
} else {
|
|
|
|
|
usetprivate(u, d);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_REGION:
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (!b) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 145, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!fval(u, UFL_OWNER)) {
|
|
|
|
|
cmistake(u, ord, 148, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (b != largestbuilding(r,false)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 147, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
s = &r->display;
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
default:
|
|
|
|
|
cmistake(u, ord, 110, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-09-12 11:51:36 +02:00
|
|
|
|
if (s!=NULL) {
|
|
|
|
|
const char * s2 = getstrtoken();
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2004-09-12 11:51:36 +02:00
|
|
|
|
if (strlen(s2)>=DISPLAYSIZE) {
|
|
|
|
|
char * s3 = strdup(s2);
|
|
|
|
|
s3[DISPLAYSIZE] = 0;
|
|
|
|
|
set_string(s, s3);
|
|
|
|
|
free(s3);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
} else
|
2004-09-12 11:51:36 +02:00
|
|
|
|
set_string(s, s2);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2005-09-24 22:34:34 +02:00
|
|
|
|
static boolean
|
|
|
|
|
renamed_building(const building * b)
|
|
|
|
|
{
|
|
|
|
|
const struct locale * lang = locales;
|
|
|
|
|
for (;lang;lang=nextlocale(lang)) {
|
|
|
|
|
const char * bdname = LOC(lang, b->type->_name);
|
|
|
|
|
size_t bdlen = strlen(bdname);
|
|
|
|
|
if (strlen(b->name)>=bdlen && strncmp(b->name, bdname, bdlen)==0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static int
|
|
|
|
|
name_cmd(unit * u, struct order * ord)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2005-04-23 11:47:03 +02:00
|
|
|
|
building * b = u->building;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
region * r = u->region;
|
2004-09-12 11:51:36 +02:00
|
|
|
|
char **s = NULL;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
param_t p;
|
|
|
|
|
boolean foreign = false;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
p = getparam(u->faction->locale);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (p == P_FOREIGN) {
|
|
|
|
|
foreign = true;
|
|
|
|
|
p = getparam(u->faction->locale);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
switch (p) {
|
|
|
|
|
case P_BUILDING:
|
|
|
|
|
case P_GEBAEUDE:
|
|
|
|
|
if (foreign == true) {
|
|
|
|
|
building *b = getbuilding(r);
|
|
|
|
|
unit *uo;
|
|
|
|
|
|
|
|
|
|
if (!b) {
|
|
|
|
|
cmistake(u, ord, 6, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (b->type == bt_find("generic")) {
|
|
|
|
|
cmistake(u, ord, 278, MSG_EVENT);
|
|
|
|
|
break;
|
2004-07-12 23:10:16 +02:00
|
|
|
|
} else {
|
2005-09-24 22:34:34 +02:00
|
|
|
|
if (renamed_building(b)) {
|
2004-07-12 23:10:16 +02:00
|
|
|
|
cmistake(u, ord, 246, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
uo = buildingowner(r, b);
|
|
|
|
|
if (uo) {
|
|
|
|
|
if (cansee(uo->faction, r, u, 0)) {
|
2006-01-08 12:33:10 +01:00
|
|
|
|
ADDMSG(&uo->faction->msgs, msg_message("renamed_building_seen",
|
|
|
|
|
"building renamer region", b, u, r));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
} else {
|
2006-01-08 12:33:10 +01:00
|
|
|
|
ADDMSG(&uo->faction->msgs, msg_message("renamed_building_notseen",
|
|
|
|
|
"building region", b, r));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
s = &b->name;
|
|
|
|
|
} else {
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (!b) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 145, MSG_PRODUCE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!fval(u, UFL_OWNER)) {
|
|
|
|
|
cmistake(u, ord, 148, MSG_PRODUCE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (b->type == bt_find("generic")) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 278, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-08-20 20:04:09 +02:00
|
|
|
|
if (b->type == bt_find("monument")) {
|
2005-09-24 22:34:34 +02:00
|
|
|
|
if (renamed_building(b)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 29, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-08-20 20:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
if (b->type == bt_find("artsculpure")) {
|
|
|
|
|
cmistake(u, ord, 29, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
s = &b->name;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_FACTION:
|
|
|
|
|
if (foreign == true) {
|
|
|
|
|
faction *f;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
f = getfaction();
|
|
|
|
|
if (!f) {
|
|
|
|
|
cmistake(u, ord, 66, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (f->age < 10) {
|
|
|
|
|
cmistake(u, ord, 248, MSG_EVENT);
|
|
|
|
|
break;
|
2004-07-12 23:10:16 +02:00
|
|
|
|
} else {
|
|
|
|
|
const struct locale * lang = locales;
|
|
|
|
|
for (;lang;lang=nextlocale(lang)) {
|
|
|
|
|
const char * fdname = LOC(lang, "factiondefault");
|
|
|
|
|
size_t fdlen = strlen(fdname);
|
|
|
|
|
if (strlen(f->name)>=fdlen && strncmp(f->name, fdname, fdlen)==0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (lang==NULL) {
|
|
|
|
|
cmistake(u, ord, 247, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
if (cansee(f, r, u, 0)) {
|
2005-12-18 19:19:14 +01:00
|
|
|
|
ADDMSG(&f->msgs, msg_message("renamed_faction_seen", "unit region", u, r));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
} else {
|
2005-12-18 19:19:14 +01:00
|
|
|
|
ADDMSG(&f->msgs, msg_message("renamed_faction_notseen", "", r));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
s = &f->name;
|
|
|
|
|
} else {
|
|
|
|
|
s = &u->faction->name;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_SHIP:
|
|
|
|
|
if (foreign == true) {
|
|
|
|
|
ship *sh = getship(r);
|
|
|
|
|
unit *uo;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (!sh) {
|
|
|
|
|
cmistake(u, ord, 20, MSG_EVENT);
|
|
|
|
|
break;
|
2004-07-12 23:10:16 +02:00
|
|
|
|
} else {
|
|
|
|
|
const struct locale * lang = locales;
|
|
|
|
|
for (;lang;lang=nextlocale(lang)) {
|
|
|
|
|
const char * sdname = LOC(lang, sh->type->name[0]);
|
|
|
|
|
size_t sdlen = strlen(sdname);
|
|
|
|
|
if (strlen(sh->name)>=sdlen && strncmp(sh->name, sdname, sdlen)==0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sdname = LOC(lang, parameters[P_SHIP]);
|
|
|
|
|
sdlen = strlen(sdname);
|
|
|
|
|
if (strlen(sh->name)>=sdlen && strncmp(sh->name, sdname, sdlen)==0) {
|
|
|
|
|
break;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
2004-07-12 23:10:16 +02:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if (lang==NULL) {
|
|
|
|
|
cmistake(u, ord, 245, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
uo = shipowner(sh);
|
|
|
|
|
if (uo) {
|
|
|
|
|
if (cansee(uo->faction, r, u, 0)) {
|
2006-01-08 12:33:10 +01:00
|
|
|
|
ADDMSG(&uo->faction->msgs, msg_message("renamed_ship_seen",
|
|
|
|
|
"ship renamer region", sh, u, r));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
} else {
|
2006-01-08 12:33:10 +01:00
|
|
|
|
ADDMSG(&uo->faction->msgs, msg_message("renamed_ship_notseen",
|
|
|
|
|
"ship region", sh, r));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
s = &sh->name;
|
|
|
|
|
} else {
|
|
|
|
|
if (!u->ship) {
|
|
|
|
|
cmistake(u, ord, 144, MSG_PRODUCE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!fval(u, UFL_OWNER)) {
|
|
|
|
|
cmistake(u, ord, 12, MSG_PRODUCE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
s = &u->ship->name;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_UNIT:
|
|
|
|
|
if (foreign == true) {
|
|
|
|
|
unit *u2 = getunit(r, u->faction);
|
2004-07-12 23:10:16 +02:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (!u2 || !cansee(u->faction, r, u2, 0)) {
|
|
|
|
|
cmistake(u, ord, 63, MSG_EVENT);
|
|
|
|
|
break;
|
2004-07-12 23:10:16 +02:00
|
|
|
|
} else {
|
|
|
|
|
const char * udefault = LOC(u2->faction->locale, "unitdefault");
|
|
|
|
|
size_t udlen = strlen(udefault);
|
|
|
|
|
size_t unlen = strlen(u2->name);
|
|
|
|
|
if (unlen>=udlen && strncmp(u2->name, udefault, udlen)!=0) {
|
|
|
|
|
cmistake(u2, ord, 244, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
if (cansee(u2->faction, r, u, 0)) {
|
2006-01-08 12:33:10 +01:00
|
|
|
|
ADDMSG(&u2->faction->msgs, msg_message("renamed_seen",
|
|
|
|
|
"renamer renamed region", u, u2, r));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
} else {
|
2006-01-08 12:33:10 +01:00
|
|
|
|
ADDMSG(&u2->faction->msgs, msg_message("renamed_notseen",
|
|
|
|
|
"renamed region", u2, r));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
s = &u2->name;
|
|
|
|
|
} else {
|
|
|
|
|
s = &u->name;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_REGION:
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (!b) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 145, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!fval(u, UFL_OWNER)) {
|
|
|
|
|
cmistake(u, ord, 148, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (b != largestbuilding(r,false)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 147, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
s = &r->land->name;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case P_GROUP:
|
|
|
|
|
{
|
2005-06-12 19:57:14 +02:00
|
|
|
|
attrib * a = NULL;
|
|
|
|
|
if (fval(u, UFL_GROUP)) a = a_find(u->attribs, &at_group);
|
|
|
|
|
if (a) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
group * g = (group*)a->data.v;
|
2005-06-12 19:57:14 +02:00
|
|
|
|
s = &g->name;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
cmistake(u, ord, 109, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
cmistake(u, ord, 109, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-09-12 11:51:36 +02:00
|
|
|
|
if (s!=NULL) {
|
|
|
|
|
const char * s2 = getstrtoken();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-09-12 11:51:36 +02:00
|
|
|
|
if (!s2[0]) {
|
|
|
|
|
cmistake(u, ord, 84, MSG_EVENT);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-09-12 11:51:36 +02:00
|
|
|
|
if (strchr(s2, '(')!=NULL) {
|
|
|
|
|
cmistake(u, ord, 112, MSG_EVENT);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strlen(s2)>=NAMESIZE) {
|
|
|
|
|
char * s3 = strdup(s2);
|
|
|
|
|
s3[NAMESIZE] = 0;
|
|
|
|
|
set_string(s, s3);
|
|
|
|
|
free(s3);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
} else
|
2004-09-12 11:51:36 +02:00
|
|
|
|
set_string(s, s2);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
2004-09-12 11:51:36 +02:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
deliverMail(faction * f, region * r, unit * u, const char *s, unit * receiver)
|
|
|
|
|
{
|
2005-07-25 21:56:44 +02:00
|
|
|
|
if (!cansee(f, r, u, 0)) {
|
|
|
|
|
u = NULL;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
2005-07-25 21:56:44 +02:00
|
|
|
|
if (!receiver) { /* BOTSCHAFT an PARTEI */
|
|
|
|
|
ADDMSG(&f->msgs, msg_message("regionmessage", "region sender string", r, u, s));
|
|
|
|
|
} else { /* BOTSCHAFT an EINHEIT */
|
|
|
|
|
ADDMSG(&f->msgs, msg_message("unitmessage", "region unit sender string", r, receiver, u, s));
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2004-08-29 10:53:02 +02:00
|
|
|
|
static int
|
|
|
|
|
prepare_mail_cmd(unit * u, struct order * ord)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
const char *s;
|
|
|
|
|
int n;
|
|
|
|
|
|
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token(); /* skip the keyword */
|
|
|
|
|
s = getstrtoken();
|
2004-08-29 10:53:02 +02:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* Falls kein Parameter, ist das eine Einheitsnummer;
|
2004-08-29 10:53:02 +02:00
|
|
|
|
* das F<EFBFBD>llwort "AN" mu<EFBFBD> wegfallen, da g<EFBFBD>ltige Nummer! */
|
|
|
|
|
|
|
|
|
|
if (strcasecmp(s, "to") == 0) s = getstrtoken();
|
|
|
|
|
else if (strcasecmp(s, "an") == 0) s = getstrtoken();
|
2004-12-03 20:08:00 +01:00
|
|
|
|
|
|
|
|
|
switch (findparam(s, u->faction->locale)) {
|
|
|
|
|
case P_REGION:
|
|
|
|
|
break;
|
|
|
|
|
case P_FACTION:
|
|
|
|
|
break;
|
|
|
|
|
case P_UNIT:
|
2004-08-29 10:53:02 +02:00
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
region *r = u->region;
|
|
|
|
|
unit *u2;
|
|
|
|
|
boolean see = false;
|
|
|
|
|
|
|
|
|
|
n = getid();
|
|
|
|
|
|
|
|
|
|
for (u2=r->units; u2; u2=u2->next) {
|
|
|
|
|
if (u2->no == n && cansee(u->faction, r, u2, 0)) {
|
|
|
|
|
see = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (see == false) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
if (!s[0]) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
u2 = findunitr(r,n);
|
|
|
|
|
if(u2 && cansee(u->faction, r, u2, 0)) {
|
2005-06-10 00:10:35 +02:00
|
|
|
|
event_arg args[3];
|
|
|
|
|
args[0].data.v = (void*)s;
|
|
|
|
|
args[0].type = "string";
|
|
|
|
|
args[1].data.v = (void*)u;
|
|
|
|
|
args[1].type = "unit";
|
|
|
|
|
args[2].type = NULL;
|
|
|
|
|
handle_event(&u2->attribs, "message", args);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2004-08-29 10:53:02 +02:00
|
|
|
|
case P_BUILDING:
|
|
|
|
|
case P_GEBAEUDE:
|
2004-12-03 20:08:00 +01:00
|
|
|
|
break;
|
|
|
|
|
case P_SHIP:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2004-08-29 10:53:02 +02:00
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mailunit(region * r, unit * u, int n, struct order * ord, const char * s)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
unit * u2 = findunitr(r,n);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
if (u2 && cansee(u->faction, r, u2, 0)) {
|
|
|
|
|
deliverMail(u2->faction, r, u, s, u2);
|
|
|
|
|
/* now done in prepare_mail_cmd */
|
|
|
|
|
}
|
2004-08-08 13:02:42 +02:00
|
|
|
|
else {
|
|
|
|
|
/* Immer eine Meldung - sonst k<>nnte man so getarnte EHs enttarnen:
|
|
|
|
|
* keine Meldung -> EH hier. */
|
|
|
|
|
cmistake(u, ord, 63, MSG_MESSAGE);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mailfaction(unit * u, int n, struct order * ord, const char * s)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
faction *f;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
f = findfaction(n);
|
|
|
|
|
if (f && n>0)
|
|
|
|
|
deliverMail(f, u->region, u, s, NULL);
|
|
|
|
|
else
|
|
|
|
|
cmistake(u, ord, 66, MSG_MESSAGE);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static int
|
|
|
|
|
mail_cmd(unit * u, struct order * ord)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
region * r = u->region;
|
|
|
|
|
unit *u2;
|
|
|
|
|
const char *s;
|
|
|
|
|
int n;
|
|
|
|
|
|
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token(); /* skip the keyword */
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
|
|
|
|
|
/* Falls kein Parameter, ist das eine Einheitsnummer;
|
|
|
|
|
* das F<EFBFBD>llwort "AN" mu<EFBFBD> wegfallen, da g<EFBFBD>ltige Nummer! */
|
|
|
|
|
|
|
|
|
|
if (strcasecmp(s, "to") == 0) s = getstrtoken();
|
|
|
|
|
else if (strcasecmp(s, "an") == 0) s = getstrtoken();
|
|
|
|
|
|
|
|
|
|
switch (findparam(s, u->faction->locale)) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
case P_REGION:
|
2004-06-21 18:45:27 +02:00
|
|
|
|
/* k<>nnen alle Einheiten in der Region sehen */
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
if (!s[0]) {
|
|
|
|
|
cmistake(u, ord, 30, MSG_MESSAGE);
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(buf, "von %s: '%s'", unitname(u), s);
|
|
|
|
|
addmessage(r, 0, buf, MSG_MESSAGE, ML_IMPORTANT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_FACTION:
|
|
|
|
|
{
|
|
|
|
|
boolean see = false;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
n = getfactionid();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
for(u2=r->units; u2; u2=u2->next) {
|
|
|
|
|
if(u2->faction->no == n && seefaction(u->faction, r, u2, 0)) {
|
|
|
|
|
see = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if(see == false) {
|
|
|
|
|
cmistake(u, ord, 66, MSG_MESSAGE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
s = getstrtoken();
|
|
|
|
|
if (!s[0]) {
|
|
|
|
|
cmistake(u, ord, 30, MSG_MESSAGE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
mailfaction(u, n, ord, s);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_UNIT:
|
|
|
|
|
{
|
|
|
|
|
boolean see = false;
|
|
|
|
|
n = getid();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-08-08 13:02:42 +02:00
|
|
|
|
for (u2=r->units; u2; u2=u2->next) {
|
|
|
|
|
if (u2->no == n && cansee(u->faction, r, u2, 0)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
see = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-08-08 13:02:42 +02:00
|
|
|
|
if (see == false) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 63, MSG_MESSAGE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
s = getstrtoken();
|
|
|
|
|
if (!s[0]) {
|
|
|
|
|
cmistake(u, ord, 30, MSG_MESSAGE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
mailunit(r, u, n, ord, s);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_BUILDING:
|
|
|
|
|
case P_GEBAEUDE:
|
|
|
|
|
{
|
|
|
|
|
building *b = getbuilding(r);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if(!b) {
|
|
|
|
|
cmistake(u, ord, 6, MSG_MESSAGE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
s = getstrtoken();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (!s[0]) {
|
|
|
|
|
cmistake(u, ord, 30, MSG_MESSAGE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
for (u2 = r->units; u2; u2 = u2->next) freset(u2->faction, FL_DH);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
for(u2=r->units; u2; u2=u2->next) {
|
|
|
|
|
if(u2->building == b && !fval(u2->faction, FL_DH)
|
|
|
|
|
&& cansee(u->faction, r, u2, 0)) {
|
|
|
|
|
mailunit(r, u, u2->no, ord, s);
|
|
|
|
|
fset(u2->faction, FL_DH);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_SHIP:
|
|
|
|
|
{
|
|
|
|
|
ship *sh = getship(r);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if(!sh) {
|
|
|
|
|
cmistake(u, ord, 20, MSG_MESSAGE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
s = getstrtoken();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (!s[0]) {
|
|
|
|
|
cmistake(u, ord, 30, MSG_MESSAGE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
for (u2 = r->units; u2; u2 = u2->next) freset(u2->faction, FL_DH);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
for(u2=r->units; u2; u2=u2->next) {
|
|
|
|
|
if(u2->ship == sh && !fval(u2->faction, FL_DH)
|
|
|
|
|
&& cansee(u->faction, r, u2, 0)) {
|
|
|
|
|
mailunit(r, u, u2->no, ord, s);
|
|
|
|
|
fset(u2->faction, FL_DH);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
default:
|
|
|
|
|
cmistake(u, ord, 149, MSG_MESSAGE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
report_option(unit * u, const char * sec, struct order * ord)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
const messageclass * mc;
|
|
|
|
|
const char *s;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
mc = mc_find(sec);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
if (mc == NULL) {
|
|
|
|
|
cmistake(u, ord, 135, MSG_EVENT);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
s = getstrtoken();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
static int
|
2004-06-21 18:45:27 +02:00
|
|
|
|
banner_cmd(unit * u, struct order * ord)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
set_string(&u->faction->banner, getstrtoken());
|
2005-06-10 00:10:35 +02:00
|
|
|
|
add_message(&u->faction->msgs, msg_message("changebanner", "value",
|
|
|
|
|
u->faction->banner));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static int
|
|
|
|
|
email_cmd(unit * u, struct order * ord)
|
|
|
|
|
{
|
|
|
|
|
const char * s;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
s = getstrtoken();
|
2001-02-03 14:45:35 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (!s[0]) {
|
|
|
|
|
cmistake(u, ord, 85, MSG_EVENT);
|
|
|
|
|
} else {
|
2004-08-22 11:33:15 +02:00
|
|
|
|
faction * f = u->faction;
|
|
|
|
|
if (set_email(&f->email, s)!=0) {
|
2004-08-29 01:06:15 +02:00
|
|
|
|
log_error(("Invalid email address for faction %s: %s\n", itoa36(f->no), s));
|
2005-06-10 00:10:35 +02:00
|
|
|
|
ADDMSG(&f->msgs, msg_message("changemail_invalid", "value", s));
|
2004-08-22 11:33:15 +02:00
|
|
|
|
} else {
|
2005-06-10 00:10:35 +02:00
|
|
|
|
ADDMSG(&f->msgs, msg_message("changemail", "value", f->email));
|
2004-08-22 11:33:15 +02:00
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
password_cmd(unit * u, struct order * ord)
|
|
|
|
|
{
|
|
|
|
|
char pbuf[32];
|
|
|
|
|
int i;
|
|
|
|
|
const char * s;
|
|
|
|
|
|
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
|
|
|
|
|
if (!s || !*s) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
for(i=0; i<6; i++) pbuf[i] = (char)(97 + rng_int() % 26);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
pbuf[6] = 0;
|
|
|
|
|
} else {
|
|
|
|
|
boolean pwok = true;
|
|
|
|
|
char *c;
|
|
|
|
|
|
|
|
|
|
strncpy(pbuf, s, 31);
|
|
|
|
|
pbuf[31] = 0;
|
|
|
|
|
c = pbuf;
|
|
|
|
|
while(*c) {
|
|
|
|
|
if(!isalnum(*c)) pwok = false;
|
|
|
|
|
c++;
|
|
|
|
|
}
|
|
|
|
|
if (pwok == false) {
|
|
|
|
|
cmistake(u, ord, 283, MSG_EVENT);
|
2006-02-19 23:43:56 +01:00
|
|
|
|
for(i=0; i<6; i++) pbuf[i] = (char)(97 + rng_int() % 26);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
pbuf[6] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
set_string(&u->faction->passw, pbuf);
|
|
|
|
|
fset(u->faction, FFL_OVERRIDE);
|
|
|
|
|
ADDMSG(&u->faction->msgs, msg_message("changepasswd",
|
2005-06-10 00:10:35 +02:00
|
|
|
|
"value", u->faction->passw));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
report_cmd(unit * u, struct order * ord)
|
|
|
|
|
{
|
|
|
|
|
const char * s;
|
|
|
|
|
int i;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
|
|
|
|
|
i = atoi(s);
|
|
|
|
|
sprintf(buf, "%d", i);
|
|
|
|
|
if (!strcmp(buf, s)) {
|
|
|
|
|
/* int level;
|
|
|
|
|
level = geti();
|
|
|
|
|
not implemented yet. set individual levels for f->msglevels */
|
|
|
|
|
} else {
|
|
|
|
|
report_option(u, s, ord);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
send_cmd(unit * u, struct order * ord)
|
|
|
|
|
{
|
|
|
|
|
const char * s;
|
|
|
|
|
int option;
|
|
|
|
|
|
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
|
|
|
|
|
option = findoption(s, u->faction->locale);
|
2001-02-28 23:14:59 +01:00
|
|
|
|
#ifdef AT_OPTION
|
2004-06-21 18:45:27 +02:00
|
|
|
|
/* Sonderbehandlung Zeitungsoption */
|
|
|
|
|
if (option == O_NEWS) {
|
|
|
|
|
attrib *a = a_find(u->faction->attribs, &at_option_news);
|
|
|
|
|
if(a) a->data.i = 0;
|
|
|
|
|
|
|
|
|
|
while((s = getstrtoken())) {
|
|
|
|
|
if(findparam(s) == P_NOT) {
|
|
|
|
|
a_removeall(&u->faction->attribs, &at_option_news);
|
|
|
|
|
u->faction->options = u->faction->options & ~O_NEWS;
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
int sec = atoi(s);
|
|
|
|
|
if(sec != 0) {
|
|
|
|
|
if(!a) a_add(&u->faction->attribs, a_new(&at_option_news));
|
|
|
|
|
a->data.i = a->data.i & (1<<(sec-1));
|
|
|
|
|
u->faction->options = u->faction->options | O_NEWS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2001-02-28 23:14:59 +01:00
|
|
|
|
#endif
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (option == -1) {
|
|
|
|
|
cmistake(u, ord, 135, MSG_EVENT);
|
|
|
|
|
} else {
|
|
|
|
|
if (getparam(u->faction->locale) == P_NOT) {
|
|
|
|
|
if (option == O_COMPRESS || option == O_BZIP2) {
|
|
|
|
|
cmistake(u, ord, 305, MSG_EVENT);
|
|
|
|
|
} else {
|
|
|
|
|
u->faction->options = u->faction->options & ~((int)pow(2, option));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
u->faction->options = u->faction->options | ((int)pow(2, option));
|
|
|
|
|
if(option == O_COMPRESS) u->faction->options &= ~((int)pow(2, O_BZIP2));
|
|
|
|
|
if(option == O_BZIP2) u->faction->options &= ~((int)pow(2, O_COMPRESS));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static void
|
|
|
|
|
set_passw(void)
|
|
|
|
|
{
|
|
|
|
|
region *r;
|
|
|
|
|
puts(" - setze Passw<73>rter, Adressen und Format, Abstimmungen");
|
|
|
|
|
|
|
|
|
|
for (r = regions; r; r = r->next) {
|
|
|
|
|
unit *u;
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
struct order * ord;
|
|
|
|
|
for (ord = u->orders; ord; ord = ord->next) {
|
|
|
|
|
switch (get_keyword(ord)) {
|
|
|
|
|
case NOKEYWORD:
|
|
|
|
|
cmistake(u, ord, 22, MSG_EVENT);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case K_BANNER:
|
|
|
|
|
if (banner_cmd(u, ord)!=0) ord = NULL;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case K_EMAIL:
|
|
|
|
|
if (email_cmd(u, ord)!=0) ord = NULL;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case K_PASSWORD:
|
|
|
|
|
if (password_cmd(u, ord)!=0) ord = NULL;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case K_REPORT:
|
|
|
|
|
if (report_cmd(u, ord)!=0) ord = NULL;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case K_SEND:
|
|
|
|
|
if (send_cmd(u, ord)!=0) ord = NULL;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static boolean
|
2001-01-25 10:37:55 +01:00
|
|
|
|
display_item(faction *f, unit *u, const item_type * itype)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
const char *name;
|
2004-12-20 23:59:42 +01:00
|
|
|
|
const char *info;
|
|
|
|
|
const char *key;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-12-28 22:07:01 +01:00
|
|
|
|
if (u!=NULL) {
|
|
|
|
|
int i = i_get(u->items, itype);
|
|
|
|
|
if (i==0) {
|
|
|
|
|
if (u->region->land!=NULL) {
|
|
|
|
|
i = i_get(u->region->land->items, itype);
|
|
|
|
|
}
|
|
|
|
|
if (i==0) {
|
|
|
|
|
i = i_get(u->faction->items, itype);
|
|
|
|
|
if (i==0) return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-10-16 14:15:22 +02:00
|
|
|
|
|
|
|
|
|
name = resourcename(itype->rtype, 0);
|
2004-12-20 23:59:42 +01:00
|
|
|
|
key = mkname("iteminfo", name);
|
|
|
|
|
info = locale_string(f->locale, key);
|
|
|
|
|
|
2004-12-22 22:08:20 +01:00
|
|
|
|
if (info==key || strcmp(info, key)==0) {
|
2006-01-18 23:28:58 +01:00
|
|
|
|
info = locale_string(f->locale, mkname("iteminfo", "no_info"));
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
ADDMSG(&f->msgs, msg_message("displayitem", "weight item description",
|
2006-01-18 23:28:58 +01:00
|
|
|
|
itype->weight, itype->rtype, info));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
return true;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static boolean
|
2001-01-25 10:37:55 +01:00
|
|
|
|
display_potion(faction *f, unit *u, const potion_type * ptype)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
attrib *a;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
if (ptype==NULL) return false;
|
|
|
|
|
else {
|
|
|
|
|
int i = i_get(u->items, ptype->itype);
|
|
|
|
|
if (i==0 && 2*ptype->level > effskill(u,SK_ALCHEMY)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
a = a_find(f->attribs, &at_showitem);
|
|
|
|
|
while (a && a->data.v != ptype) a=a->next;
|
|
|
|
|
if (!a) {
|
|
|
|
|
a = a_add(&f->attribs, a_new(&at_showitem));
|
|
|
|
|
a->data.v = (void*) ptype->itype;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
return true;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static boolean
|
2001-12-10 01:13:39 +01:00
|
|
|
|
display_race(faction *f, unit *u, const race * rc)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2006-01-18 23:28:58 +01:00
|
|
|
|
const char *name, *info, *key;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
int a, at_count;
|
|
|
|
|
char buf2[2048];
|
2005-06-17 20:12:58 +02:00
|
|
|
|
char * bufp = buf;
|
|
|
|
|
size_t size = sizeof(buf), rsize;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
|
|
|
|
|
if (u && u->race != rc) return false;
|
|
|
|
|
name = rc_name(rc, 0);
|
|
|
|
|
|
2005-06-17 20:12:58 +02:00
|
|
|
|
rsize = slprintf(bufp, size, "%s: ", LOC(f->locale, name));
|
|
|
|
|
if (rsize>size) rsize = size-1;
|
|
|
|
|
size -= rsize;
|
|
|
|
|
bufp += rsize;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
|
2006-01-18 23:48:49 +01:00
|
|
|
|
key = mkname("raceinfo", rc->_name[0]);
|
2006-01-18 23:28:58 +01:00
|
|
|
|
info = locale_string(f->locale, key);
|
|
|
|
|
if (info==key || strcmp(info, key)==0) {
|
|
|
|
|
info = locale_string(f->locale, mkname("raceinfo", "no_info"));
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
2006-01-18 23:28:58 +01:00
|
|
|
|
rsize = strlcpy(bufp, info, size);
|
|
|
|
|
if (rsize>size) rsize = size-1;
|
|
|
|
|
size -= rsize;
|
|
|
|
|
bufp += rsize;
|
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* hp_p : Trefferpunkte */
|
2005-07-04 23:18:42 +02:00
|
|
|
|
sprintf(buf2, " %d Trefferpunkte", rc->hitpoints);
|
2005-06-17 20:12:58 +02:00
|
|
|
|
|
|
|
|
|
rsize = strlcpy(bufp, buf2, size);
|
|
|
|
|
if (rsize>size) rsize = size-1;
|
|
|
|
|
size -= rsize;
|
|
|
|
|
bufp += rsize;
|
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* b_armor : R<>stung */
|
|
|
|
|
if (rc->armor > 0){
|
|
|
|
|
sprintf(buf2, ", R<>stung: %d", rc->armor);
|
2005-07-04 23:18:42 +02:00
|
|
|
|
rsize = strlcpy(bufp, buf2, size);
|
2005-06-17 20:12:58 +02:00
|
|
|
|
if (rsize>size) rsize = size-1;
|
|
|
|
|
size -= rsize;
|
|
|
|
|
bufp += rsize;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
/* b_attacke : Angriff */
|
|
|
|
|
sprintf(buf2, ", Angriff: %d", (rc->at_default+rc->at_bonus));
|
2005-06-17 20:12:58 +02:00
|
|
|
|
rsize = strlcpy(bufp, buf2, size);
|
|
|
|
|
if (rsize>size) rsize = size-1;
|
|
|
|
|
size -= rsize;
|
|
|
|
|
bufp += rsize;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
|
|
|
|
|
/* b_defense : Verteidigung */
|
|
|
|
|
sprintf(buf2, ", Verteidigung: %d", (rc->df_default+rc->df_bonus));
|
2005-06-17 20:12:58 +02:00
|
|
|
|
rsize = strlcpy(bufp, buf2, size);
|
|
|
|
|
if (rsize>size) rsize = size-1;
|
|
|
|
|
size -= rsize;
|
|
|
|
|
bufp += rsize;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
|
2005-06-17 20:12:58 +02:00
|
|
|
|
if (size>1) {
|
|
|
|
|
strcpy(bufp++, ".");
|
|
|
|
|
--size;
|
|
|
|
|
}
|
2004-12-03 20:08:00 +01:00
|
|
|
|
|
|
|
|
|
/* b_damage : Schaden */
|
|
|
|
|
at_count=0;
|
|
|
|
|
for (a = 0; a < 6; a++) {
|
|
|
|
|
if (rc->attack[a].type != AT_NONE){
|
|
|
|
|
at_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (rc->battle_flags & BF_EQUIPMENT) {
|
2005-06-17 20:12:58 +02:00
|
|
|
|
rsize = strlcpy(bufp, " Kann Waffen benutzen.", size);
|
|
|
|
|
if (rsize>size) rsize = size-1;
|
|
|
|
|
size -= rsize;
|
|
|
|
|
bufp += rsize;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
if (rc->battle_flags & BF_RES_PIERCE) {
|
2005-06-17 20:12:58 +02:00
|
|
|
|
rsize = strlcpy(bufp, " Ist durch Stichwaffen, B<>gen und Armbr<62>ste schwer zu verwunden.", size);
|
|
|
|
|
if (rsize>size) rsize = size-1;
|
|
|
|
|
size -= rsize;
|
|
|
|
|
bufp += rsize;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
if (rc->battle_flags & BF_RES_CUT) {
|
2005-06-17 20:12:58 +02:00
|
|
|
|
rsize = strlcpy(bufp, " Ist durch Hiebwaffen schwer zu verwunden.", size);
|
|
|
|
|
if (rsize>size) rsize = size-1;
|
|
|
|
|
size -= rsize;
|
|
|
|
|
bufp += rsize;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
if (rc->battle_flags & BF_RES_BASH) {
|
2005-06-17 20:12:58 +02:00
|
|
|
|
rsize = strlcpy(bufp, " Ist durch Schlagwaffen und Katapulte schwer zu verwunden.", size);
|
|
|
|
|
if (rsize>size) rsize = size-1;
|
|
|
|
|
size -= rsize;
|
|
|
|
|
bufp += rsize;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sprintf(buf2, " Hat %d Angriff%s", at_count, (at_count>1)?"e":"");
|
2005-06-17 20:12:58 +02:00
|
|
|
|
rsize = strlcpy(bufp, buf2, size);
|
|
|
|
|
if (rsize>size) rsize = size-1;
|
|
|
|
|
size -= rsize;
|
|
|
|
|
bufp += rsize;
|
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
for (a = 0; a < 6; a++) {
|
|
|
|
|
if (rc->attack[a].type != AT_NONE){
|
2005-06-17 20:12:58 +02:00
|
|
|
|
if (size>2) {
|
|
|
|
|
if (a!=0) strcat(bufp, ", ");
|
|
|
|
|
else strcat(bufp, ": ");
|
|
|
|
|
size -= 2;
|
|
|
|
|
bufp += 2;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
switch(rc->attack[a].type) {
|
|
|
|
|
case AT_STANDARD:
|
|
|
|
|
sprintf(buf2, "ein Angriff mit der Waffe oder macht unbewaffnet %s Schaden", rc->def_damage);
|
|
|
|
|
break;
|
|
|
|
|
case AT_NATURAL:
|
|
|
|
|
sprintf(buf2, "ein Angriff mit Krallen, Z<>hnen oder Klauen, der %s Schaden macht", rc->attack[a].data.dice);
|
|
|
|
|
break;
|
|
|
|
|
case AT_SPELL:
|
|
|
|
|
case AT_COMBATSPELL:
|
|
|
|
|
case AT_DRAIN_ST:
|
|
|
|
|
case AT_DAZZLE:
|
|
|
|
|
sprintf(buf2, "ein magischer Angriff");
|
|
|
|
|
break;
|
|
|
|
|
case AT_STRUCTURAL:
|
|
|
|
|
sprintf(buf2, "ein Angriff, der %s Geb<65>udeschaden verursacht", rc->attack[a].data.dice);
|
|
|
|
|
}
|
2005-06-17 20:12:58 +02:00
|
|
|
|
rsize = strlcpy(bufp, buf2, size);
|
|
|
|
|
if (rsize>size) rsize = size-1;
|
|
|
|
|
size -= rsize;
|
|
|
|
|
bufp += rsize;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-06-17 20:12:58 +02:00
|
|
|
|
if (size>1) {
|
|
|
|
|
strcat(bufp++, ".");
|
|
|
|
|
--size;
|
|
|
|
|
}
|
2004-12-03 20:08:00 +01:00
|
|
|
|
|
|
|
|
|
addmessage(0, f, buf, MSG_EVENT, ML_IMPORTANT);
|
|
|
|
|
|
|
|
|
|
return true;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2004-04-11 00:02:52 +02:00
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
reshow(unit * u, struct order * ord, const char * s, param_t p)
|
2004-04-11 00:02:52 +02:00
|
|
|
|
{
|
|
|
|
|
int skill, c;
|
|
|
|
|
const potion_type * ptype;
|
|
|
|
|
const item_type * itype;
|
|
|
|
|
const spell * sp;
|
|
|
|
|
const race * rc;
|
|
|
|
|
|
|
|
|
|
switch (p) {
|
|
|
|
|
case P_ZAUBER:
|
|
|
|
|
a_removeall(&u->faction->attribs, &at_seenspell);
|
|
|
|
|
break;
|
|
|
|
|
case P_POTIONS:
|
|
|
|
|
skill = effskill(u, SK_ALCHEMY);
|
|
|
|
|
c = 0;
|
|
|
|
|
for (ptype = potiontypes; ptype!=NULL; ptype=ptype->next) {
|
|
|
|
|
if (ptype->level * 2 <= skill) {
|
|
|
|
|
c += display_potion(u->faction, u, ptype);
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (c == 0) cmistake(u, ord, 285, MSG_EVENT);
|
2004-04-11 00:02:52 +02:00
|
|
|
|
break;
|
|
|
|
|
case NOPARAM:
|
|
|
|
|
/* check if it's an item */
|
|
|
|
|
itype = finditemtype(s, u->faction->locale);
|
|
|
|
|
if (itype!=NULL) {
|
|
|
|
|
ptype = resource2potion(item2resource(itype));
|
|
|
|
|
if (ptype!=NULL) {
|
|
|
|
|
if (display_potion(u->faction, u, ptype)) break;
|
|
|
|
|
} else {
|
|
|
|
|
if (display_item(u->faction, u, itype)) break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* try for a spell */
|
2005-10-08 17:25:21 +02:00
|
|
|
|
sp = get_spellfromtoken(u, s, u->faction->locale);
|
2004-04-11 00:02:52 +02:00
|
|
|
|
if (sp!=NULL && has_spell(u, sp)) {
|
|
|
|
|
attrib *a = a_find(u->faction->attribs, &at_seenspell);
|
2006-02-25 01:12:48 +01:00
|
|
|
|
while (a!=NULL && a->type==&at_seenspell && a->data.v!=sp) a = a->next;
|
2004-04-11 00:02:52 +02:00
|
|
|
|
if (a!=NULL) a_remove(&u->faction->attribs, a);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
/* last, check if it's a race. */
|
|
|
|
|
rc = findrace(s, u->faction->locale);
|
|
|
|
|
if (rc != NULL) {
|
|
|
|
|
if (display_race(u->faction, u, rc)) break;
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 21, MSG_EVENT);
|
2004-04-11 00:02:52 +02:00
|
|
|
|
break;
|
|
|
|
|
default:
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 222, MSG_EVENT);
|
2004-04-11 00:02:52 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-03 17:34:26 +02:00
|
|
|
|
#ifdef HEROES
|
|
|
|
|
static int
|
2004-08-29 01:06:15 +02:00
|
|
|
|
promotion_cmd(unit * u, struct order * ord)
|
2004-08-03 17:34:26 +02:00
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
int money, people;
|
2004-08-03 17:34:26 +02:00
|
|
|
|
|
|
|
|
|
if (maxheroes(u->faction) < countheroes(u->faction)+u->number) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "heroes_maxed", "max count",
|
2004-08-03 17:34:26 +02:00
|
|
|
|
maxheroes(u->faction), countheroes(u->faction)));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (!playerrace(u->race)) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "heroes_race", "race",
|
2004-08-03 17:34:26 +02:00
|
|
|
|
u->race));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
people = count_all(u->faction) * u->number;
|
2006-02-19 23:43:56 +01:00
|
|
|
|
money = get_pooled(u, i_silver->rtype, GET_ALL, people);
|
2004-08-03 17:34:26 +02:00
|
|
|
|
|
|
|
|
|
if (people>money) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "heroes_cost", "cost have",
|
2004-08-03 17:34:26 +02:00
|
|
|
|
people, money));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2005-10-30 16:42:15 +01:00
|
|
|
|
use_pooled(u, i_silver->rtype, GET_ALL, people);
|
2004-08-03 17:34:26 +02:00
|
|
|
|
fset(u, UFL_HERO);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
ADDMSG(&u->faction->msgs, msg_message("hero_promotion", "unit cost",
|
2004-08-29 01:06:15 +02:00
|
|
|
|
u, people));
|
2004-08-03 17:34:26 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static int
|
|
|
|
|
group_cmd(unit * u, struct order * ord)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
const char * s;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
s = getstrtoken();
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
join_group(u, s);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static int
|
|
|
|
|
origin_cmd(unit * u, struct order * ord)
|
|
|
|
|
{
|
2005-06-10 00:10:35 +02:00
|
|
|
|
short px, py;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
2002-04-12 14:46:16 +02:00
|
|
|
|
|
2005-06-10 00:10:35 +02:00
|
|
|
|
px = (short)atoi(getstrtoken());
|
|
|
|
|
py = (short)atoi(getstrtoken());
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
set_ursprung(u->faction, getplaneid(u->region), px, py);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static int
|
2004-09-04 12:16:21 +02:00
|
|
|
|
guard_off_cmd(unit * u, struct order * ord)
|
2004-06-21 18:45:27 +02:00
|
|
|
|
{
|
2004-09-08 19:28:45 +02:00
|
|
|
|
assert(get_keyword(ord)==K_GUARD);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
|
2004-09-04 12:16:21 +02:00
|
|
|
|
if (getparam(u->faction->locale) == P_NOT) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
setguard(u, GUARD_NONE);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static int
|
|
|
|
|
reshow_cmd(unit * u, struct order * ord)
|
|
|
|
|
{
|
|
|
|
|
const char * s;
|
|
|
|
|
param_t p = NOPARAM;
|
2001-04-13 16:39:57 +02:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
s = getstrtoken();
|
2001-04-13 16:39:57 +02:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (findparam(s, u->faction->locale) == P_ANY) {
|
|
|
|
|
p = getparam(u->faction->locale);
|
|
|
|
|
s = NULL;
|
|
|
|
|
}
|
2004-12-03 20:08:00 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
reshow(u, ord, s, p);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2002-02-06 09:06:02 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static int
|
|
|
|
|
status_cmd(unit * u, struct order * ord)
|
|
|
|
|
{
|
|
|
|
|
const char * param;
|
|
|
|
|
|
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
|
|
|
|
|
param = getstrtoken();
|
|
|
|
|
switch (findparam(param, u->faction->locale)) {
|
|
|
|
|
case P_NOT:
|
|
|
|
|
u->status = ST_AVOID;
|
|
|
|
|
break;
|
|
|
|
|
case P_BEHIND:
|
|
|
|
|
u->status = ST_BEHIND;
|
|
|
|
|
break;
|
|
|
|
|
case P_FLEE:
|
|
|
|
|
u->status = ST_FLEE;
|
|
|
|
|
break;
|
|
|
|
|
case P_CHICKEN:
|
|
|
|
|
u->status = ST_CHICKEN;
|
|
|
|
|
break;
|
|
|
|
|
case P_AGGRO:
|
|
|
|
|
u->status = ST_AGGRO;
|
|
|
|
|
break;
|
|
|
|
|
case P_VORNE:
|
|
|
|
|
u->status = ST_FIGHT;
|
|
|
|
|
break;
|
|
|
|
|
case P_HELP:
|
|
|
|
|
if (getparam(u->faction->locale) == P_NOT) {
|
|
|
|
|
fset(u, UFL_NOAID);
|
|
|
|
|
} else {
|
|
|
|
|
freset(u, UFL_NOAID);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (strlen(param)) {
|
|
|
|
|
add_message(&u->faction->msgs,
|
|
|
|
|
msg_feedback(u, ord, "unknown_status", ""));
|
|
|
|
|
} else {
|
|
|
|
|
u->status = ST_FIGHT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static int
|
|
|
|
|
combatspell_cmd(unit * u, struct order * ord)
|
|
|
|
|
{
|
|
|
|
|
const char * s;
|
|
|
|
|
int level = 0;
|
|
|
|
|
spell * spell;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
s = getstrtoken();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
/* KAMPFZAUBER [NICHT] l<>scht alle gesetzten Kampfzauber */
|
|
|
|
|
if (!s || *s == 0 || findparam(s, u->faction->locale) == P_NOT) {
|
|
|
|
|
unset_combatspell(u, 0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
/* Optional: STUFE n */
|
|
|
|
|
if (findparam(s, u->faction->locale) == P_LEVEL) {
|
|
|
|
|
/* Merken, setzen kommt erst sp<73>ter */
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
level = atoi(s);
|
|
|
|
|
level = max(0, level);
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-10-08 17:25:21 +02:00
|
|
|
|
spell = get_spellfromtoken(u, s, u->faction->locale);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if(!spell){
|
|
|
|
|
cmistake(u, ord, 173, MSG_MAGIC);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
s = getstrtoken();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (findparam(s, u->faction->locale) == P_NOT) {
|
|
|
|
|
/* KAMPFZAUBER "<Spruchname>" NICHT l<>scht diesen speziellen
|
|
|
|
|
* Kampfzauber */
|
|
|
|
|
unset_combatspell(u, spell);
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
/* KAMPFZAUBER "<Spruchname>" setzt diesen Kampfzauber */
|
|
|
|
|
set_combatspell(u, spell, ord, level);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static void
|
|
|
|
|
instant_orders(void)
|
|
|
|
|
{
|
|
|
|
|
region *r;
|
|
|
|
|
faction *f;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
puts(" - Kontakte, Hilfe, Status, Kampfzauber, Texte, Bewachen (aus), Zeigen");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
for (f = factions; f; f = f->next) {
|
|
|
|
|
attrib *a;
|
|
|
|
|
a = a_find(f->attribs, &at_showitem);
|
2006-02-25 01:12:48 +01:00
|
|
|
|
while (a!=NULL && a->type==&at_showitem) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
const item_type * itype = (const item_type *)a->data.v;
|
|
|
|
|
const potion_type * ptype = resource2potion(itype->rtype);
|
2006-02-25 01:12:48 +01:00
|
|
|
|
attrib * an = a->next;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (ptype!=NULL) {
|
|
|
|
|
/* potions werden separat behandelt */
|
|
|
|
|
display_item(f, NULL, (const item_type *)a->data.v);
|
|
|
|
|
a_remove(&f->attribs, a);
|
2006-02-25 01:12:48 +01:00
|
|
|
|
}
|
|
|
|
|
a = an;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
parse(K_GROUP, group_cmd, false);
|
|
|
|
|
for (r = regions; r; r = r->next) {
|
|
|
|
|
unit * u;
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
order * ord;
|
2005-04-30 19:07:46 +02:00
|
|
|
|
freset(u, UFL_MOVED);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
for (ord = u->orders; ord; ord = ord->next) {
|
|
|
|
|
switch (get_keyword(ord)) {
|
2006-01-13 20:43:33 +01:00
|
|
|
|
case K_QUIT:
|
|
|
|
|
quit_cmd(u, ord);
|
|
|
|
|
break;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case K_URSPRUNG:
|
2006-01-13 20:43:33 +01:00
|
|
|
|
origin_cmd(u, ord);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
|
|
|
|
case K_ALLY:
|
2006-01-13 20:43:33 +01:00
|
|
|
|
ally_cmd(u, ord);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
|
|
|
|
case K_PREFIX:
|
2006-01-13 20:43:33 +01:00
|
|
|
|
prefix_cmd(u, ord);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
|
|
|
|
case K_SYNONYM:
|
2006-01-13 20:43:33 +01:00
|
|
|
|
synonym_cmd(u, ord);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
|
|
|
|
case K_SETSTEALTH:
|
2006-01-13 20:43:33 +01:00
|
|
|
|
setstealth_cmd(u, ord);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
2006-02-17 23:59:03 +01:00
|
|
|
|
#ifdef KARMA_MODULE
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case K_WEREWOLF:
|
2006-01-13 20:43:33 +01:00
|
|
|
|
setwere_cmd(u, ord);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
2006-02-17 23:59:03 +01:00
|
|
|
|
#endif /* KARMA_MODULE */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case K_STATUS:
|
|
|
|
|
/* KAEMPFE [ NICHT | AGGRESSIV | DEFENSIV | HINTEN | FLIEHE ] */
|
2006-01-13 20:43:33 +01:00
|
|
|
|
status_cmd(u, ord);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
|
|
|
|
case K_COMBAT:
|
|
|
|
|
/* KAMPFZAUBER [[STUFE n] "<Spruchname>"] [NICHT] */
|
2006-01-13 20:43:33 +01:00
|
|
|
|
combatspell_cmd(u, ord);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
|
|
|
|
case K_DISPLAY:
|
2006-01-13 20:43:33 +01:00
|
|
|
|
display_cmd(u, ord);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
|
|
|
|
case K_NAME:
|
2006-01-13 20:43:33 +01:00
|
|
|
|
name_cmd(u, ord);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
|
|
|
|
case K_GUARD:
|
2006-01-13 20:43:33 +01:00
|
|
|
|
guard_off_cmd(u, ord);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
|
|
|
|
case K_RESHOW:
|
2006-01-13 20:43:33 +01:00
|
|
|
|
reshow_cmd(u, ord);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
/* Beachten: einige Monster sollen auch unbewaffent die Region bewachen
|
|
|
|
|
* k<EFBFBD>nnen */
|
|
|
|
|
void
|
2005-11-20 13:58:59 +01:00
|
|
|
|
update_guards(void)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
region *r;
|
|
|
|
|
unit *u;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
for (r = regions; r; r = r->next)
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
2005-01-08 00:19:10 +01:00
|
|
|
|
if (getguard(u) && (!armedmen(u) || u->faction->age < NewbieImmunity()))
|
2004-12-03 20:08:00 +01:00
|
|
|
|
setguard(u, GUARD_NONE);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-04 12:16:21 +02:00
|
|
|
|
static int
|
|
|
|
|
guard_on_cmd(unit * u, struct order * ord)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-09-08 19:28:45 +02:00
|
|
|
|
assert(get_keyword(ord)==K_GUARD);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-09-04 12:16:21 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
2002-03-01 20:32:25 +01:00
|
|
|
|
|
2004-09-04 12:16:21 +02:00
|
|
|
|
/* GUARD NOT is handled in goard_off_cmd earlier in the turn */
|
|
|
|
|
if (getparam(u->faction->locale) == P_NOT) return 0;
|
|
|
|
|
|
2005-10-25 14:38:01 +02:00
|
|
|
|
if (fval(u->region->terrain, SEA_REGION)) {
|
|
|
|
|
cmistake(u, ord, 2, MSG_EVENT);
|
|
|
|
|
} else {
|
|
|
|
|
if (fval(u, RCF_ILLUSIONARY) || u->race == new_race[RC_SPELL]) {
|
|
|
|
|
cmistake(u, ord, 95, MSG_EVENT);
|
|
|
|
|
} else {
|
2004-09-04 12:16:21 +02:00
|
|
|
|
/* 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 {
|
|
|
|
|
guard(u, GUARD_ALL);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-09-04 12:16:21 +02:00
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static void
|
2001-01-25 10:37:55 +01:00
|
|
|
|
sinkships(void)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
region *r;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* Unbemannte Schiffe k<>nnen sinken */
|
|
|
|
|
for (r = regions; r; r = r->next) {
|
|
|
|
|
ship *sh;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
list_foreach(ship, r->ships, sh) {
|
2005-10-25 14:38:01 +02:00
|
|
|
|
if (fval(r->terrain, SEA_REGION) && (!enoughsailors(sh, r) || get_captain(sh)==NULL)) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* Schiff nicht seet<65>chtig */
|
|
|
|
|
damage_ship(sh, 0.30);
|
|
|
|
|
}
|
|
|
|
|
if (shipowner(sh)==NULL) {
|
|
|
|
|
damage_ship(sh, 0.05);
|
|
|
|
|
}
|
|
|
|
|
if (sh->damage >= sh->size * DAMAGE_SCALE)
|
|
|
|
|
destroy_ship(sh);
|
|
|
|
|
}
|
|
|
|
|
list_next(sh);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The following functions do not really belong here: */
|
|
|
|
|
#include "eressea.h"
|
|
|
|
|
#include "build.h"
|
|
|
|
|
|
|
|
|
|
static attrib_type at_number = {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
"faction_renum",
|
|
|
|
|
NULL, NULL, NULL, NULL, NULL,
|
|
|
|
|
ATF_UNIQUE
|
2001-01-25 10:37:55 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
renumber_factions(void)
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* gibt parteien neue nummern */
|
|
|
|
|
{
|
|
|
|
|
struct renum {
|
|
|
|
|
struct renum * next;
|
|
|
|
|
int want;
|
|
|
|
|
faction * faction;
|
|
|
|
|
attrib * attrib;
|
|
|
|
|
} * renum = NULL, * rp;
|
|
|
|
|
faction * f;
|
|
|
|
|
for (f=factions;f;f=f->next) {
|
|
|
|
|
attrib * a = a_find(f->attribs, &at_number);
|
|
|
|
|
int want;
|
|
|
|
|
struct renum ** rn;
|
|
|
|
|
faction * old;
|
|
|
|
|
|
|
|
|
|
if (!a) continue;
|
|
|
|
|
want = a->data.i;
|
|
|
|
|
if (fval(f, FF_NEWID)) {
|
|
|
|
|
sprintf(buf, "NUMMER PARTEI %s: Die Partei kann nicht mehr als einmal ihre Nummer wecheln", itoa36(want));
|
|
|
|
|
addmessage(0, f, buf, MSG_MESSAGE, ML_IMPORTANT);
|
|
|
|
|
}
|
|
|
|
|
old = findfaction(want);
|
|
|
|
|
if (old) {
|
|
|
|
|
a_remove(&f->attribs, a);
|
|
|
|
|
sprintf(buf, "Die Nummer %s wird von einer anderen Partei benutzt.", itoa36(want));
|
|
|
|
|
addmessage(0, f, buf, MSG_MESSAGE, ML_IMPORTANT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (!faction_id_is_unused(want)) {
|
|
|
|
|
a_remove(&f->attribs, a);
|
|
|
|
|
sprintf(buf, "Die Nummer %s wurde schon einmal von einer anderen Partei benutzt.", itoa36(want));
|
|
|
|
|
addmessage(0, f, buf, MSG_MESSAGE, ML_IMPORTANT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
for (rn=&renum; *rn; rn=&(*rn)->next) {
|
|
|
|
|
if ((*rn)->want>=want) break;
|
|
|
|
|
}
|
|
|
|
|
if (*rn && (*rn)->want==want) {
|
|
|
|
|
a_remove(&f->attribs, a);
|
|
|
|
|
sprintf(buf, "Die Nummer %s wurde bereits einer anderen Partei zugeteilt.", itoa36(want));
|
|
|
|
|
addmessage(0, f, buf, MSG_MESSAGE, ML_IMPORTANT);
|
|
|
|
|
} else {
|
|
|
|
|
struct renum * r = calloc(sizeof(struct renum), 1);
|
|
|
|
|
r->next = *rn;
|
|
|
|
|
r->attrib = a;
|
|
|
|
|
r->faction = f;
|
|
|
|
|
r->want = want;
|
|
|
|
|
*rn = r;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (rp=renum;rp;rp=rp->next) {
|
|
|
|
|
f = rp->faction;
|
|
|
|
|
a_remove(&f->attribs, rp->attrib);
|
|
|
|
|
if (f->subscription) {
|
|
|
|
|
sql_print(("UPDATE subscriptions set faction='%s' where id=%u;\n",
|
2004-07-10 19:16:15 +02:00
|
|
|
|
itoa36(rp->want), f->subscription));
|
|
|
|
|
}
|
2005-01-19 21:33:13 +01:00
|
|
|
|
funhash(f);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
f->no = rp->want;
|
2005-01-19 21:33:13 +01:00
|
|
|
|
fhash(f);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
fset(f, FF_NEWID);
|
|
|
|
|
}
|
|
|
|
|
while (renum) {
|
|
|
|
|
rp = renum->next;
|
|
|
|
|
free(renum);
|
|
|
|
|
renum = rp;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
reorder(void)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
region * r;
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
unit ** up=&r->units;
|
|
|
|
|
boolean sorted=false;
|
|
|
|
|
while (*up) {
|
|
|
|
|
unit * u = *up;
|
|
|
|
|
if (!fval(u, FL_MARK)) {
|
|
|
|
|
struct order * ord;
|
|
|
|
|
for (ord = u->orders;ord;ord=ord->next) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (get_keyword(ord)==K_SORT) {
|
|
|
|
|
const char * s;
|
|
|
|
|
param_t p;
|
|
|
|
|
int id;
|
|
|
|
|
unit *v;
|
|
|
|
|
|
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
p = findparam(s, u->faction->locale);
|
|
|
|
|
id = getid();
|
|
|
|
|
v = findunit(id);
|
|
|
|
|
|
|
|
|
|
if (v==NULL || v->faction!=u->faction || v->region!=r) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
cmistake(u, ord, 258, MSG_EVENT);
|
|
|
|
|
} else if (v->building != u->building || v->ship!=u->ship) {
|
|
|
|
|
cmistake(u, ord, 259, MSG_EVENT);
|
|
|
|
|
} else if (fval(u, UFL_OWNER)) {
|
|
|
|
|
cmistake(u, ord, 260, MSG_EVENT);
|
|
|
|
|
} else if (v == u) {
|
|
|
|
|
cmistake(u, ord, 10, MSG_EVENT);
|
|
|
|
|
} else {
|
|
|
|
|
switch(p) {
|
|
|
|
|
case P_AFTER:
|
|
|
|
|
*up = u->next;
|
|
|
|
|
u->next = v->next;
|
|
|
|
|
v->next = u;
|
|
|
|
|
break;
|
|
|
|
|
case P_BEFORE:
|
|
|
|
|
if (fval(v, UFL_OWNER)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(v, ord, 261, MSG_EVENT);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
} else {
|
|
|
|
|
unit ** vp=&r->units;
|
|
|
|
|
while (*vp!=v) vp=&(*vp)->next;
|
|
|
|
|
*vp = u;
|
|
|
|
|
*up = u->next;
|
|
|
|
|
u->next = v;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
fset(u, FL_MARK);
|
|
|
|
|
sorted = true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (u==*up) up=&u->next;
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (sorted) {
|
|
|
|
|
unit * u;
|
|
|
|
|
for (u=r->units;u;u=u->next) freset(u, FL_MARK);
|
|
|
|
|
}
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-04-21 13:23:58 +02:00
|
|
|
|
#if 0
|
2002-04-28 14:47:29 +02:00
|
|
|
|
/* Aus Geb<65>ude weisen, VERBANNE */
|
2002-04-21 13:23:58 +02:00
|
|
|
|
static void
|
|
|
|
|
evict(void)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
region *r;
|
|
|
|
|
strlist *S;
|
|
|
|
|
unit * u;
|
2002-04-21 13:23:58 +02:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
for (S = u->orders; S; S = S->next) if (get_keyword(ord)==K_EVICT) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
int id;
|
|
|
|
|
unit *u2;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* Nur der Kapit<69>n bzw Burgherr kann jemanden rausschmei<65>en */
|
|
|
|
|
if(!fval(u, UFL_OWNER)) {
|
|
|
|
|
/* Die Einheit ist nicht der Eigent<6E>mer */
|
|
|
|
|
cmistake(u,ord,49,MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
2004-12-03 20:08:00 +01:00
|
|
|
|
id = getid();
|
|
|
|
|
u2 = findunit(id);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
|
|
|
|
|
if (u2==NULL) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* Einheit nicht gefunden */
|
|
|
|
|
cmistake(u,ord,63,MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (u->building){
|
|
|
|
|
/* in der selben Burg? */
|
|
|
|
|
if (u->building != u2->building){
|
|
|
|
|
/* nicht in Burg */
|
|
|
|
|
cmistake(u,ord,33,MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
leave_building(u2);
|
|
|
|
|
/* meldung an beide */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (u->ship){
|
|
|
|
|
if (u->ship != u2->ship){
|
|
|
|
|
/* nicht an Bord */
|
|
|
|
|
cmistake(u, ord, 32, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
leave_ship(u2);
|
|
|
|
|
/* meldung an beide */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-04-21 13:23:58 +02:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2005-11-20 13:58:59 +01:00
|
|
|
|
#ifdef ENEMIES
|
2002-12-18 18:40:21 +01:00
|
|
|
|
static void
|
|
|
|
|
declare_war(void)
|
|
|
|
|
{
|
|
|
|
|
region *r;
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
unit * u;
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
strlist *S;
|
|
|
|
|
faction * f = u->faction;
|
|
|
|
|
for (S = u->orders; S; S = S->next) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
switch (get_keyword(ord)) {
|
2002-12-18 18:40:21 +01:00
|
|
|
|
case K_WAR:
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
2002-12-18 18:40:21 +01:00
|
|
|
|
for (;;) {
|
|
|
|
|
const char * s = getstrtoken();
|
|
|
|
|
if (s[0]==0) break;
|
|
|
|
|
else {
|
|
|
|
|
faction * enemy = findfaction(atoi36(s));
|
|
|
|
|
if (enemy) {
|
|
|
|
|
if (!is_enemy(f, enemy)) {
|
|
|
|
|
add_enemy(f, enemy);
|
|
|
|
|
ADDMSG(&enemy->msgs, msg_message("war_notify", "enemy", f));
|
|
|
|
|
ADDMSG(&f->msgs, msg_message("war_confirm", "enemy", enemy));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
ADDMSG(&f->msgs, msg_message("error66", "unit region command", u, r, ord));
|
2002-12-18 18:40:21 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case K_PEACE:
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
2002-12-18 18:40:21 +01:00
|
|
|
|
for (;;) {
|
|
|
|
|
const char * s = getstrtoken();
|
|
|
|
|
if (s[0]==0) break;
|
|
|
|
|
else {
|
|
|
|
|
faction * enemy = findfaction(atoi36(s));
|
|
|
|
|
if (enemy) {
|
|
|
|
|
if (is_enemy(f, enemy)) {
|
|
|
|
|
remove_enemy(f, enemy);
|
|
|
|
|
ADDMSG(&enemy->msgs, msg_message("peace_notify", "enemy", f));
|
|
|
|
|
ADDMSG(&f->msgs, msg_message("peace_confirm", "enemy", enemy));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
ADDMSG(&f->msgs, msg_message("error66", "unit region command", u, r, ord));
|
2002-12-18 18:40:21 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static void
|
|
|
|
|
renumber(void)
|
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
region *r;
|
|
|
|
|
const char *s;
|
|
|
|
|
unit * u;
|
|
|
|
|
int i;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-12-18 18:40:21 +01:00
|
|
|
|
for (r=regions;r;r=r->next) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
faction * f = u->faction;
|
|
|
|
|
struct order * ord;
|
|
|
|
|
for (ord = u->orders; ord; ord = ord->next) if (get_keyword(ord)==K_NUMBER) {
|
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
switch(findparam(s, u->faction->locale)) {
|
|
|
|
|
|
|
|
|
|
case P_FACTION:
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
if (s && *s) {
|
|
|
|
|
int id = atoi36(s);
|
|
|
|
|
attrib * a = a_find(f->attribs, &at_number);
|
|
|
|
|
if (!a) a = a_add(&f->attribs, a_new(&at_number));
|
|
|
|
|
a->data.i = id;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_UNIT:
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
if(s == NULL || *s == 0) {
|
|
|
|
|
i = newunitid();
|
|
|
|
|
} else {
|
|
|
|
|
i = atoi36(s);
|
|
|
|
|
if (i<=0 || i>MAX_UNIT_NR) {
|
|
|
|
|
cmistake(u, ord, 114, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if(forbiddenid(i)) {
|
|
|
|
|
cmistake(u, ord, 116, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if(findunitg(i, r)) {
|
|
|
|
|
cmistake(u, ord, 115, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
uunhash(u);
|
|
|
|
|
if (!ualias(u)) {
|
|
|
|
|
attrib *a = a_add(&u->attribs, a_new(&at_alias));
|
|
|
|
|
a->data.i = -u->no;
|
|
|
|
|
}
|
|
|
|
|
u->no = i;
|
|
|
|
|
uhash(u);
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_SHIP:
|
|
|
|
|
if(!u->ship) {
|
|
|
|
|
cmistake(u,ord,144,MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if(!fval(u, UFL_OWNER)) {
|
|
|
|
|
cmistake(u,ord,146,MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
if(s == NULL || *s == 0) {
|
|
|
|
|
i = newcontainerid();
|
|
|
|
|
} else {
|
|
|
|
|
i = atoi36(s);
|
|
|
|
|
if (i<=0 || i>MAX_CONTAINER_NR) {
|
|
|
|
|
cmistake(u,ord,114,MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (findship(i) || findbuilding(i)) {
|
|
|
|
|
cmistake(u,ord,115,MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sunhash(u->ship);
|
|
|
|
|
u->ship->no = i;
|
|
|
|
|
shash(u->ship);
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
case P_BUILDING:
|
|
|
|
|
case P_GEBAEUDE:
|
|
|
|
|
if(!u->building) {
|
|
|
|
|
cmistake(u,ord,145,MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if(!fval(u, UFL_OWNER)) {
|
|
|
|
|
cmistake(u,ord,148,MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
if(*s == 0) {
|
|
|
|
|
i = newcontainerid();
|
|
|
|
|
} else {
|
|
|
|
|
i = atoi36(s);
|
|
|
|
|
if (i<=0 || i>MAX_CONTAINER_NR) {
|
|
|
|
|
cmistake(u,ord,114,MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if(findship(i) || findbuilding(i)) {
|
|
|
|
|
cmistake(u,ord,115,MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bunhash(u->building);
|
|
|
|
|
u->building->no = i;
|
|
|
|
|
bhash(u->building);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
cmistake(u,ord,239,MSG_EVENT);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
renumber_factions();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2005-01-19 21:33:13 +01:00
|
|
|
|
static building *
|
|
|
|
|
age_building(building * b)
|
|
|
|
|
{
|
2005-06-10 00:10:35 +02:00
|
|
|
|
static boolean init = false;
|
|
|
|
|
static const building_type * bt_blessed;
|
|
|
|
|
static const curse_type * ct_astralblock;
|
|
|
|
|
if (!init) {
|
|
|
|
|
init = true;
|
2005-01-19 21:33:13 +01:00
|
|
|
|
bt_blessed = bt_find("blessedstonecircle");
|
|
|
|
|
ct_astralblock = ct_find("astralblock");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* blesses stone circles create an astral protection in the astral region
|
|
|
|
|
* above the shield, which prevents chaos suction and other spells.
|
|
|
|
|
* The shield is created when a magician enters the blessed stone circle,
|
|
|
|
|
* and lasts for as long as his skill level / 2 is, at no mana cost.
|
|
|
|
|
*
|
|
|
|
|
* TODO: this would be nicer in a btype->age function, but we don't have it.
|
|
|
|
|
*/
|
|
|
|
|
if (ct_astralblock && bt_blessed && b->type==bt_blessed) {
|
|
|
|
|
region * r = b->region;
|
|
|
|
|
region * rt = r_standard_to_astral(r);
|
|
|
|
|
unit * u, * mage = NULL;
|
|
|
|
|
|
|
|
|
|
/* step 1: give unicorns to people in the building,
|
|
|
|
|
* find out if there's a magician in there. */
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
if (b==u->building && inside_building(u)) {
|
|
|
|
|
if (!(u->race->ec_flags & NOGIVE)) {
|
|
|
|
|
int n, unicorns = 0;
|
|
|
|
|
for (n=0; n!=u->number; ++n) {
|
|
|
|
|
if (chance(0.02)) {
|
2005-10-31 23:34:45 +01:00
|
|
|
|
i_change(&u->items, olditemtype[I_UNICORN], 1);
|
2005-01-19 21:33:13 +01:00
|
|
|
|
++unicorns;
|
|
|
|
|
}
|
|
|
|
|
if (unicorns) {
|
|
|
|
|
ADDMSG(&u->faction->msgs, msg_message("scunicorn",
|
2005-02-06 12:55:32 +01:00
|
|
|
|
"unit amount rtype", u, unicorns,
|
2005-01-19 21:33:13 +01:00
|
|
|
|
olditemtype[I_UNICORN]->rtype));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (mage==NULL && is_mage(u)) {
|
|
|
|
|
mage = u;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if there's a magician, and a connection to astral space, create the
|
|
|
|
|
* curse. */
|
|
|
|
|
if (rt!=NULL && mage!=NULL) {
|
|
|
|
|
curse * c = get_curse(rt->attribs, ct_astralblock);
|
|
|
|
|
if (c==NULL) {
|
|
|
|
|
if (mage!=NULL) {
|
|
|
|
|
int sk = effskill(mage, SK_MAGIC);
|
2005-06-10 00:10:35 +02:00
|
|
|
|
variant effect;
|
|
|
|
|
effect.i = 100;
|
2005-01-19 21:33:13 +01:00
|
|
|
|
/* the mage reactivates the circle */
|
|
|
|
|
c = create_curse(mage, &rt->attribs, ct_astralblock,
|
2005-06-10 00:10:35 +02:00
|
|
|
|
sk, sk/2, effect, 0);
|
2005-01-19 21:33:13 +01:00
|
|
|
|
ADDMSG(&r->msgs, msg_message("astralshield_activate",
|
|
|
|
|
"region unit", r, mage));
|
|
|
|
|
}
|
|
|
|
|
} else if (mage!=NULL) {
|
|
|
|
|
int sk = effskill(mage, SK_MAGIC);
|
|
|
|
|
c->duration = max(c->duration, sk/2);
|
|
|
|
|
c->vigour = max(c->vigour, sk);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
a_age(&b->attribs);
|
|
|
|
|
handle_event(&b->attribs, "timer", b);
|
|
|
|
|
|
|
|
|
|
return b;
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static void
|
|
|
|
|
ageing(void)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
faction *f;
|
|
|
|
|
region *r;
|
|
|
|
|
|
|
|
|
|
/* altern spezieller Attribute, die eine Sonderbehandlung brauchen? */
|
|
|
|
|
for(r=regions;r;r=r->next) {
|
|
|
|
|
unit *u;
|
|
|
|
|
for(u=r->units;u;u=u->next) {
|
|
|
|
|
/* Goliathwasser */
|
|
|
|
|
int i = get_effect(u, oldpotiontype[P_STRONG]);
|
|
|
|
|
if (i > 0){
|
|
|
|
|
change_effect(u, oldpotiontype[P_STRONG], -1 * min(u->number, i));
|
|
|
|
|
}
|
|
|
|
|
/* Berserkerblut*/
|
|
|
|
|
i = get_effect(u, oldpotiontype[P_BERSERK]);
|
|
|
|
|
if (i > 0){
|
|
|
|
|
change_effect(u, oldpotiontype[P_BERSERK], -1 * min(u->number, i));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_cursed(u->attribs, C_OLDRACE, 0)){
|
|
|
|
|
curse *c = get_curse(u->attribs, ct_find("oldrace"));
|
|
|
|
|
if (c->duration == 1 && !(c->flag & CURSE_NOAGE)) {
|
|
|
|
|
u->race = new_race[curse_geteffect(c)];
|
|
|
|
|
u->irace = new_race[curse_geteffect(c)];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Borders */
|
|
|
|
|
age_borders();
|
|
|
|
|
|
|
|
|
|
/* Factions */
|
|
|
|
|
for (f=factions;f;f=f->next) {
|
|
|
|
|
a_age(&f->attribs);
|
|
|
|
|
handle_event(&f->attribs, "timer", f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Regionen */
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
building ** bp;
|
|
|
|
|
unit ** up;
|
|
|
|
|
ship ** sp;
|
|
|
|
|
|
|
|
|
|
a_age(&r->attribs);
|
|
|
|
|
handle_event(&r->attribs, "timer", r);
|
2005-01-19 21:33:13 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* Einheiten */
|
|
|
|
|
for (up=&r->units;*up;) {
|
|
|
|
|
unit * u = *up;
|
|
|
|
|
a_age(&u->attribs);
|
|
|
|
|
if (u==*up) handle_event(&u->attribs, "timer", u);
|
|
|
|
|
if (u==*up) up = &(*up)->next;
|
|
|
|
|
}
|
2005-01-19 21:33:13 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* Schiffe */
|
|
|
|
|
for (sp=&r->ships;*sp;) {
|
|
|
|
|
ship * s = *sp;
|
|
|
|
|
a_age(&s->attribs);
|
|
|
|
|
if (s==*sp) handle_event(&s->attribs, "timer", s);
|
|
|
|
|
if (s==*sp) sp = &(*sp)->next;
|
|
|
|
|
}
|
2005-01-19 21:33:13 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* Geb<65>ude */
|
|
|
|
|
for (bp=&r->buildings;*bp;) {
|
|
|
|
|
building * b = *bp;
|
2005-01-19 21:33:13 +01:00
|
|
|
|
b = age_building(b);
|
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
if (b==*bp) bp = &(*bp)->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2005-05-21 00:51:37 +02:00
|
|
|
|
maxunits(const faction *f)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2005-05-21 00:51:37 +02:00
|
|
|
|
if (global.unitsperalliance == true) {
|
|
|
|
|
float mult = 1.0;
|
2005-05-20 11:08:39 +02:00
|
|
|
|
|
2006-02-17 23:59:03 +01:00
|
|
|
|
#ifdef KARMA_MODULE
|
|
|
|
|
faction *f2;
|
2005-05-21 00:51:37 +02:00
|
|
|
|
for (f2 = factions; f2; f2 = f2->next) {
|
|
|
|
|
if (f2->alliance == f->alliance) {
|
|
|
|
|
mult += 0.4f * fspecial(f2, FS_ADMINISTRATOR);
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-02-17 23:59:03 +01:00
|
|
|
|
#endif /* KARMA_MODULE */
|
2005-05-21 00:51:37 +02:00
|
|
|
|
return (int) (global.maxunits * mult);
|
|
|
|
|
}
|
2006-02-17 23:59:03 +01:00
|
|
|
|
#ifdef KARMA_MODULE
|
2005-05-21 00:51:37 +02:00
|
|
|
|
return (int) (global.maxunits * (1 + 0.4 * fspecial(f, FS_ADMINISTRATOR)));
|
2006-02-17 23:59:03 +01:00
|
|
|
|
#else
|
|
|
|
|
return global.maxunits;
|
|
|
|
|
#endif /* KARMA_MODULE */
|
2005-05-20 11:08:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static boolean
|
2005-05-21 00:51:37 +02:00
|
|
|
|
checkunitnumber(const faction *f, int add)
|
2005-05-20 11:08:39 +02:00
|
|
|
|
{
|
2005-05-21 00:51:37 +02:00
|
|
|
|
if (global.maxunits==0) return true;
|
|
|
|
|
if (global.unitsperalliance == true) {
|
|
|
|
|
/* if unitsperalliance is true, maxunits returns the
|
|
|
|
|
number of units allowed in an alliance */
|
|
|
|
|
faction *f2;
|
|
|
|
|
int unitsinalliance = add;
|
|
|
|
|
int maxu = maxunits(f);
|
2005-05-20 11:08:39 +02:00
|
|
|
|
|
2005-05-21 00:51:37 +02:00
|
|
|
|
for (f2 = factions; f2; f2 = f2->next) {
|
|
|
|
|
if (f->alliance == f2->alliance) {
|
|
|
|
|
unitsinalliance += f2->no_units;
|
|
|
|
|
}
|
|
|
|
|
if (unitsinalliance > maxu) return false;
|
|
|
|
|
}
|
2005-05-20 11:08:39 +02:00
|
|
|
|
|
2005-05-21 00:51:37 +02:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2005-05-20 11:08:39 +02:00
|
|
|
|
|
2005-05-21 00:51:37 +02:00
|
|
|
|
return (f->no_units + add < maxunits(f));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
new_units (void)
|
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
region *r;
|
|
|
|
|
unit *u, *u2;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
/* neue einheiten werden gemacht und ihre befehle (bis zum "ende" zu
|
2004-06-27 14:19:58 +02:00
|
|
|
|
* ihnen rueberkopiert, damit diese einheiten genauso wie die alten
|
|
|
|
|
* einheiten verwendet werden koennen. */
|
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
for (r = regions; r; r = r->next) {
|
2004-06-27 14:19:58 +02:00
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
order ** ordp = &u->orders;
|
|
|
|
|
while (*ordp) {
|
|
|
|
|
order * makeord = *ordp;
|
|
|
|
|
if (get_keyword(makeord) == K_MAKE) {
|
|
|
|
|
init_tokens(makeord);
|
|
|
|
|
skip_token();
|
|
|
|
|
if (getparam(u->faction->locale) == P_TEMP) {
|
2006-01-02 22:50:57 +01:00
|
|
|
|
const char * token;
|
|
|
|
|
char * name = NULL;
|
2004-06-27 14:19:58 +02:00
|
|
|
|
int g, alias;
|
|
|
|
|
order ** newordersp;
|
|
|
|
|
|
2005-05-21 00:51:37 +02:00
|
|
|
|
if (checkunitnumber(u->faction, 1) == false) {
|
2005-05-21 00:39:22 +02:00
|
|
|
|
if (global.unitsperalliance == false) {
|
2005-05-20 11:08:39 +02:00
|
|
|
|
ADDMSG(&u->faction->msgs, msg_message("too_many_units_in_faction",
|
|
|
|
|
"command unit region allowed",
|
2005-05-21 00:39:22 +02:00
|
|
|
|
makeord, u, r, maxunits(u->faction)));
|
2005-05-20 11:08:39 +02:00
|
|
|
|
} else {
|
|
|
|
|
ADDMSG(&u->faction->msgs, msg_message("too_many_units_in_alliance",
|
|
|
|
|
"command unit region allowed",
|
2005-05-21 00:39:22 +02:00
|
|
|
|
makeord, u, r, maxunits(u->faction)));
|
2005-05-20 11:08:39 +02:00
|
|
|
|
}
|
2004-06-27 14:19:58 +02:00
|
|
|
|
ordp = &makeord->next;
|
|
|
|
|
|
|
|
|
|
while (*ordp) {
|
|
|
|
|
order * ord = *ordp;
|
|
|
|
|
if (get_keyword(ord) == K_END) break;
|
|
|
|
|
*ordp = ord->next;
|
|
|
|
|
ord->next = NULL;
|
|
|
|
|
free_order(ord);
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
alias = getid();
|
|
|
|
|
|
2006-01-02 22:50:57 +01:00
|
|
|
|
token = getstrtoken();
|
|
|
|
|
if (token && strlen(token)>0) {
|
|
|
|
|
name = strdup(token);
|
|
|
|
|
}
|
2004-06-27 14:19:58 +02:00
|
|
|
|
u2 = create_unit(r, u->faction, 0, u->faction->race, alias, name, u);
|
|
|
|
|
if (name!=NULL) free(name);
|
|
|
|
|
fset(u2, UFL_ISNEW);
|
|
|
|
|
|
|
|
|
|
a_add(&u2->attribs, a_new(&at_alias))->data.i = alias;
|
|
|
|
|
|
|
|
|
|
g = getguard(u);
|
|
|
|
|
if (g) setguard(u2, g);
|
|
|
|
|
else setguard(u, GUARD_NONE);
|
|
|
|
|
|
|
|
|
|
ordp = &makeord->next;
|
|
|
|
|
newordersp = &u2->orders;
|
|
|
|
|
while (*ordp) {
|
|
|
|
|
order * ord = *ordp;
|
|
|
|
|
if (get_keyword(ord) == K_END) break;
|
|
|
|
|
*ordp = ord->next;
|
|
|
|
|
ord->next = NULL;
|
|
|
|
|
*newordersp = ord;
|
|
|
|
|
newordersp = &ord->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (*ordp==makeord) ordp=&makeord->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
setdefaults (void)
|
|
|
|
|
{
|
2004-05-22 16:41:27 +02:00
|
|
|
|
region *r;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-05-22 16:41:27 +02:00
|
|
|
|
for (r = regions; r; r = r->next) {
|
|
|
|
|
unit *u;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-05-22 16:41:27 +02:00
|
|
|
|
for (u = r->units; u; u = u->next) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
order *ord;
|
2004-05-22 16:41:27 +02:00
|
|
|
|
boolean trade = false;
|
2005-05-21 00:26:41 +02:00
|
|
|
|
boolean hunger = LongHunger(u);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-07-26 20:14:13 +02:00
|
|
|
|
freset(u, UFL_LONGACTION);
|
2005-05-21 00:26:41 +02:00
|
|
|
|
if (hunger) {
|
2004-05-22 16:41:27 +02:00
|
|
|
|
/* Hungernde Einheiten f<>hren NUR den default-Befehl aus */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
set_order(&u->thisorder, default_order(u->faction->locale));
|
2004-05-22 16:41:27 +02:00
|
|
|
|
}
|
2005-04-30 19:07:46 +02:00
|
|
|
|
#ifdef LASTORDER
|
2005-05-21 00:26:41 +02:00
|
|
|
|
else {
|
|
|
|
|
/* by default the default long order becomes the new long order. */
|
|
|
|
|
u->thisorder = copy_order(u->lastorder);
|
|
|
|
|
}
|
2005-04-30 19:07:46 +02:00
|
|
|
|
#endif
|
2004-05-22 16:41:27 +02:00
|
|
|
|
/* check all orders for a potential new long order this round: */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
for (ord = u->orders; ord; ord = ord->next) {
|
2005-05-01 13:32:24 +02:00
|
|
|
|
#ifndef LASTORDER
|
|
|
|
|
if (u->old_orders && is_repeated(ord)) {
|
|
|
|
|
/* this new order will replace the old defaults */
|
|
|
|
|
free_orders(&u->old_orders);
|
2005-05-21 00:26:41 +02:00
|
|
|
|
if (hunger) break;
|
2005-05-01 13:32:24 +02:00
|
|
|
|
}
|
|
|
|
|
#endif
|
2005-05-21 00:26:41 +02:00
|
|
|
|
if (hunger) continue;
|
|
|
|
|
|
2005-04-30 19:07:46 +02:00
|
|
|
|
if (is_exclusive(ord)) {
|
|
|
|
|
/* <20>ber dieser Zeile nur Befehle, die auch eine idle Faction machen darf */
|
|
|
|
|
if (idle(u->faction)) {
|
|
|
|
|
set_order(&u->thisorder, default_order(u->faction->locale));
|
|
|
|
|
} else {
|
2005-05-10 00:30:43 +02:00
|
|
|
|
set_order(&u->thisorder, copy_order(ord));
|
2005-04-30 19:07:46 +02:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
keyword_t keyword = get_keyword(ord);
|
|
|
|
|
switch (keyword) {
|
|
|
|
|
/* Wenn gehandelt wird, darf kein langer Befehl ausgef<65>hrt
|
|
|
|
|
* werden. Da Handel erst nach anderen langen Befehlen kommt,
|
|
|
|
|
* mu<EFBFBD> das vorher abgefangen werden. Wir merken uns also
|
|
|
|
|
* hier, ob die Einheit handelt. */
|
|
|
|
|
case K_BUY:
|
|
|
|
|
case K_SELL:
|
|
|
|
|
/* Wenn die Einheit handelt, mu<6D> der Default-Befehl gel<65>scht
|
|
|
|
|
* werden. */
|
|
|
|
|
trade = true;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case K_CAST:
|
|
|
|
|
/* dient dazu, das neben Zaubern kein weiterer Befehl
|
|
|
|
|
* ausgef<EFBFBD>hrt werden kann, Zaubern ist ein kurzer Befehl */
|
|
|
|
|
set_order(&u->thisorder, NULL);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case K_WEREWOLF:
|
2005-05-10 00:30:43 +02:00
|
|
|
|
set_order(&u->thisorder, copy_order(ord));
|
2005-04-30 19:07:46 +02:00
|
|
|
|
break;
|
2004-05-22 16:41:27 +02:00
|
|
|
|
|
2005-04-30 19:07:46 +02:00
|
|
|
|
/* Wird je diese Ausschliesslichkeit aufgehoben, muss man aufpassen
|
|
|
|
|
* mit der Reihenfolge von Kaufen, Verkaufen etc., damit es Spielern
|
|
|
|
|
* nicht moeglich ist, Schulden zu machen. */
|
|
|
|
|
}
|
2004-05-22 16:41:27 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-05-21 00:26:41 +02:00
|
|
|
|
if (hunger) continue;
|
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
/* Wenn die Einheit handelt, mu<6D> der Default-Befehl gel<65>scht
|
|
|
|
|
* werden. */
|
|
|
|
|
|
|
|
|
|
if (trade == true) {
|
|
|
|
|
/* fset(u, UFL_LONGACTION); */
|
|
|
|
|
set_order(&u->thisorder, NULL);
|
|
|
|
|
}
|
2004-05-22 16:41:27 +02:00
|
|
|
|
/* thisorder kopieren wir nun nach lastorder. in lastorder steht
|
|
|
|
|
* der DEFAULT befehl der einheit. da MOVE kein default werden
|
|
|
|
|
* darf, wird MOVE nicht in lastorder kopiert. MACHE TEMP wurde ja
|
|
|
|
|
* schon gar nicht erst in thisorder kopiert, so dass MACHE TEMP
|
|
|
|
|
* durch diesen code auch nicht zum default wird Ebenso soll BIETE
|
|
|
|
|
* nicht hierher, da i.A. die Einheit dann ja weg ist (und damit
|
|
|
|
|
* die Einheitsnummer ungueltig). Auch Attackiere sollte nie in
|
|
|
|
|
* den Default <EFBFBD>bernommen werden */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
|
2005-04-30 19:07:46 +02:00
|
|
|
|
#ifdef LASTORDER
|
2004-06-21 18:45:27 +02:00
|
|
|
|
switch (get_keyword(u->thisorder)) {
|
2004-05-22 16:41:27 +02:00
|
|
|
|
case K_MOVE:
|
|
|
|
|
case K_ATTACK:
|
|
|
|
|
case K_WEREWOLF:
|
|
|
|
|
case NOKEYWORD:
|
2005-04-30 19:07:46 +02:00
|
|
|
|
/* these can never be default orders */
|
2004-05-22 16:41:27 +02:00
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-05-22 16:41:27 +02:00
|
|
|
|
default:
|
2005-05-10 00:30:43 +02:00
|
|
|
|
set_order(&u->lastorder, copy_order(u->thisorder));
|
2004-05-22 16:41:27 +02:00
|
|
|
|
}
|
2005-04-30 19:07:46 +02:00
|
|
|
|
#endif
|
2004-05-22 16:41:27 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2004-06-21 18:45:27 +02:00
|
|
|
|
use_item(unit * u, const item_type * itype, int amount, struct order * ord)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-05-22 16:41:27 +02:00
|
|
|
|
int i;
|
|
|
|
|
int target = read_unitid(u->faction, u->region);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
i = get_pooled(u, itype->rtype, GET_DEFAULT, amount);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-05-22 16:41:27 +02:00
|
|
|
|
if (amount>i) {
|
|
|
|
|
amount = i;
|
|
|
|
|
}
|
2004-12-03 20:08:00 +01:00
|
|
|
|
if (amount==0) {
|
|
|
|
|
cmistake(u, ord, 43, MSG_PRODUCE);
|
2004-05-22 16:41:27 +02:00
|
|
|
|
return ENOITEM;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-05-22 16:41:27 +02:00
|
|
|
|
if (target==-1) {
|
|
|
|
|
if (itype->use==NULL) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
cmistake(u, ord, 76, MSG_PRODUCE);
|
2004-05-22 16:41:27 +02:00
|
|
|
|
return EUNUSABLE;
|
|
|
|
|
}
|
2004-12-03 20:08:00 +01:00
|
|
|
|
return itype->use(u, itype, amount, ord);
|
2004-05-22 16:41:27 +02:00
|
|
|
|
} else {
|
|
|
|
|
if (itype->useonother==NULL) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
cmistake(u, ord, 76, MSG_PRODUCE);
|
2004-05-22 16:41:27 +02:00
|
|
|
|
return EUNUSABLE;
|
|
|
|
|
}
|
2004-12-03 20:08:00 +01:00
|
|
|
|
return itype->useonother(u, target, itype, amount, ord);
|
2004-05-22 16:41:27 +02:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-08-03 17:34:26 +02:00
|
|
|
|
static double
|
|
|
|
|
heal_factor(const race *rc)
|
|
|
|
|
{
|
|
|
|
|
switch(old_race(rc)) {
|
|
|
|
|
case RC_TROLL:
|
|
|
|
|
case RC_DAEMON:
|
|
|
|
|
return 1.5;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
case RC_GOBLIN:
|
2004-08-03 17:34:26 +02:00
|
|
|
|
return 2.0;
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
2004-08-03 17:34:26 +02:00
|
|
|
|
return 1.0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
monthly_healing(void)
|
|
|
|
|
{
|
2004-06-07 23:43:55 +02:00
|
|
|
|
region *r;
|
|
|
|
|
static const curse_type * heal_ct = NULL;
|
|
|
|
|
if (heal_ct==NULL) heal_ct = ct_find("healingzone");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-07 23:43:55 +02:00
|
|
|
|
for (r = regions; r; r = r->next) {
|
|
|
|
|
unit *u;
|
|
|
|
|
int healingcurse = 0;
|
2002-11-03 13:47:29 +01:00
|
|
|
|
|
2004-06-07 23:43:55 +02:00
|
|
|
|
if (heal_ct!=NULL) {
|
|
|
|
|
/* bonus zur<75>cksetzen */
|
|
|
|
|
curse * c = get_curse(r->attribs, heal_ct);
|
|
|
|
|
if (c!=NULL) {
|
|
|
|
|
healingcurse = curse_geteffect(c);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
int umhp = unit_max_hp(u) * u->number;
|
2004-08-03 17:34:26 +02:00
|
|
|
|
double p = 1.0;
|
2004-06-07 23:43:55 +02:00
|
|
|
|
|
|
|
|
|
/* hp <20>ber Maximum bauen sich ab. Wird zb durch Elixier der Macht
|
|
|
|
|
* oder ver<EFBFBD>ndertes Ausdauertalent verursacht */
|
|
|
|
|
if (u->hp > umhp) {
|
|
|
|
|
u->hp -= (int) ceil((u->hp - umhp) / 2.0);
|
2004-08-03 17:34:26 +02:00
|
|
|
|
if (u->hp < umhp) u->hp = umhp;
|
|
|
|
|
continue;
|
2004-06-07 23:43:55 +02:00
|
|
|
|
}
|
2002-11-03 13:47:29 +01:00
|
|
|
|
|
2004-08-03 17:34:26 +02:00
|
|
|
|
if (u->race->flags & RCF_NOHEAL) continue;
|
|
|
|
|
if (fval(u, UFL_HUNGER)) continue;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-10-25 14:38:01 +02:00
|
|
|
|
if (fval(r->terrain, SEA_REGION) && u->ship==NULL && !(canswim(u) || canfly(u))) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-17 23:59:03 +01:00
|
|
|
|
#ifdef KARMA_MODULE
|
|
|
|
|
if (fspecial(u->faction, FS_UNDEAD)) continue;
|
|
|
|
|
|
2004-06-07 23:43:55 +02:00
|
|
|
|
if(fspecial(u->faction, FS_REGENERATION)) {
|
|
|
|
|
u->hp = umhp;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2006-02-17 23:59:03 +01:00
|
|
|
|
#endif /* KARMA_MODULE */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-08-03 17:34:26 +02:00
|
|
|
|
p *= heal_factor(u->race);
|
|
|
|
|
if (u->hp < umhp) {
|
|
|
|
|
#ifdef NEW_DAEMONHUNGER_RULE
|
|
|
|
|
double maxheal = max(u->number, umhp/20.0);
|
|
|
|
|
#else
|
|
|
|
|
double maxheal = max(u->number, umhp/10.0);
|
|
|
|
|
#endif
|
|
|
|
|
int addhp;
|
2004-06-07 23:43:55 +02:00
|
|
|
|
struct building * b = inside_building(u);
|
|
|
|
|
const struct building_type * btype = b?b->type:NULL;
|
|
|
|
|
if (btype == bt_find("inn")) {
|
2004-08-03 17:34:26 +02:00
|
|
|
|
p *= 1.5;
|
2004-06-07 23:43:55 +02:00
|
|
|
|
}
|
2004-08-03 17:34:26 +02:00
|
|
|
|
/* pro punkt 5% h<>her */
|
|
|
|
|
p *= (1.0 + healingcurse * 0.05);
|
|
|
|
|
|
|
|
|
|
maxheal = p * maxheal;
|
|
|
|
|
addhp = (int)maxheal;
|
|
|
|
|
maxheal -= addhp;
|
|
|
|
|
if (maxheal>0.0 && chance(maxheal)) ++addhp;
|
2002-05-24 09:12:50 +02:00
|
|
|
|
|
2004-06-07 23:43:55 +02:00
|
|
|
|
/* Aufaddieren der geheilten HP. */
|
2004-08-03 17:34:26 +02:00
|
|
|
|
u->hp = min(u->hp + addhp, umhp);
|
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* soll man an negativer regeneration sterben k<>nnen? */
|
2004-08-03 17:34:26 +02:00
|
|
|
|
assert(u->hp > 0);
|
2004-06-07 23:43:55 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2005-07-16 19:18:15 +02:00
|
|
|
|
static void
|
|
|
|
|
remove_exclusive(order ** ordp)
|
|
|
|
|
{
|
|
|
|
|
while (*ordp) {
|
|
|
|
|
order * ord = *ordp;
|
|
|
|
|
if (is_exclusive(ord)) {
|
|
|
|
|
*ordp = ord->next;
|
|
|
|
|
ord->next = NULL;
|
|
|
|
|
free_order(ord);
|
|
|
|
|
} else {
|
|
|
|
|
ordp = &ord->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static void
|
|
|
|
|
defaultorders (void)
|
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
region *r;
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
unit *u;
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
2005-07-16 19:18:15 +02:00
|
|
|
|
#ifndef LASTORDER
|
|
|
|
|
boolean neworders = false;
|
|
|
|
|
#endif
|
2004-06-21 18:45:27 +02:00
|
|
|
|
order ** ordp = &u->orders;
|
|
|
|
|
while (*ordp!=NULL) {
|
|
|
|
|
order * ord = *ordp;
|
|
|
|
|
if (get_keyword(ord)==K_DEFAULT) {
|
2004-06-27 18:56:01 +02:00
|
|
|
|
char * cmd;
|
2005-06-03 18:05:54 +02:00
|
|
|
|
order * new_order;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token(); /* skip the keyword */
|
2004-06-27 18:56:01 +02:00
|
|
|
|
cmd = strdup(getstrtoken());
|
2005-06-03 18:05:54 +02:00
|
|
|
|
new_order = parse_order(cmd, u->faction->locale);
|
2005-07-16 23:18:22 +02:00
|
|
|
|
*ordp = ord->next;
|
|
|
|
|
ord->next = NULL;
|
|
|
|
|
free_order(ord);
|
2005-05-29 17:29:52 +02:00
|
|
|
|
#ifdef LASTORDER
|
2005-06-03 18:05:54 +02:00
|
|
|
|
if (new_order) set_order(&u->lastorder, new_order);
|
2005-05-29 17:29:52 +02:00
|
|
|
|
#else
|
|
|
|
|
if (!neworders) {
|
2005-07-16 19:18:15 +02:00
|
|
|
|
/* lange Befehle aus orders und old_orders l<>schen zu gunsten des neuen */
|
|
|
|
|
remove_exclusive(&u->orders);
|
|
|
|
|
remove_exclusive(&u->old_orders);
|
2005-05-29 17:29:52 +02:00
|
|
|
|
neworders = true;
|
2005-07-16 23:18:22 +02:00
|
|
|
|
ordp = &u->orders; /* we could have broken ordp */
|
2005-05-29 17:29:52 +02:00
|
|
|
|
}
|
2005-06-03 18:05:54 +02:00
|
|
|
|
if (new_order) addlist(&u->old_orders, new_order);
|
2005-05-29 17:29:52 +02:00
|
|
|
|
#endif
|
2004-06-27 18:56:01 +02:00
|
|
|
|
free(cmd);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
else ordp = &ord->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-04 19:41:27 +01:00
|
|
|
|
/* ************************************************************ */
|
|
|
|
|
/* GANZ WICHTIG! ALLE GE<47>NDERTEN SPR<50>CHE NEU ANZEIGEN */
|
|
|
|
|
/* GANZ WICHTIG! F<>GT AUCH NEUE ZAUBER IN DIE LISTE DER BEKANNTEN EIN */
|
|
|
|
|
/* ************************************************************ */
|
|
|
|
|
static void
|
|
|
|
|
update_spells(void)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
region *r;
|
|
|
|
|
for(r=regions; r; r=r->next) {
|
|
|
|
|
unit *u;
|
|
|
|
|
for(u=r->units;u;u=u->next) {
|
|
|
|
|
sc_mage *m = get_mage(u);
|
|
|
|
|
if (u->faction->no != MONSTER_FACTION && m != NULL) {
|
|
|
|
|
if (m->magietyp == M_GRAU) continue;
|
|
|
|
|
updatespelllist(u);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-03-04 19:41:27 +01:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2002-01-27 11:57:26 +01:00
|
|
|
|
static void
|
|
|
|
|
age_factions(void)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
faction *f;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
for (f = factions; f; f = f->next) {
|
|
|
|
|
++f->age;
|
2005-01-08 00:19:10 +01:00
|
|
|
|
if (f->age < NewbieImmunity()) {
|
2006-01-02 22:50:57 +01:00
|
|
|
|
ADDMSG(&f->msgs, msg_message("newbieimmunity", "turns",
|
|
|
|
|
NewbieImmunity() - f->age));
|
2004-12-03 20:08:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-01-27 11:57:26 +01:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static int
|
|
|
|
|
use_cmd(unit * u, struct order * ord)
|
2002-01-27 11:57:26 +01:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
const char * t;
|
|
|
|
|
int n;
|
|
|
|
|
const item_type * itype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
t = getstrtoken();
|
|
|
|
|
n = atoi(t);
|
|
|
|
|
if (n==0) {
|
2005-11-06 12:33:19 +01:00
|
|
|
|
if (findparam(t, u->faction->locale) == P_ANY) {
|
|
|
|
|
/* BENUTZE ALLES Yanxspirit */
|
|
|
|
|
n = INT_MAX;
|
|
|
|
|
t = getstrtoken();
|
|
|
|
|
} else {
|
|
|
|
|
/* BENUTZE Yanxspirit */
|
|
|
|
|
n = 1;
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
} else {
|
2005-11-06 12:33:19 +01:00
|
|
|
|
/* BENUTZE 42 Yanxspirit */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
t = getstrtoken();
|
|
|
|
|
}
|
|
|
|
|
itype = finditemtype(t, u->faction->locale);
|
|
|
|
|
|
|
|
|
|
if (itype!=NULL) {
|
|
|
|
|
int i = use_item(u, itype, n, ord);
|
|
|
|
|
assert(i<=0 || !"use_item should not return positive values.");
|
2005-02-13 10:08:56 +01:00
|
|
|
|
if (i>0) {
|
2005-02-12 03:18:13 +01:00
|
|
|
|
log_error(("use_item returned a value>0 for %s\n", resourcename(itype->rtype, 0)));
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
} else {
|
|
|
|
|
cmistake(u, ord, 43, MSG_PRODUCE);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2002-01-27 11:57:26 +01:00
|
|
|
|
}
|
|
|
|
|
|
2004-12-22 01:53:12 +01:00
|
|
|
|
static int
|
|
|
|
|
claim_cmd(unit * u, struct order * ord)
|
|
|
|
|
{
|
|
|
|
|
const char * t;
|
|
|
|
|
int n;
|
|
|
|
|
const item_type * itype;
|
|
|
|
|
|
|
|
|
|
init_tokens(ord);
|
|
|
|
|
skip_token();
|
|
|
|
|
|
|
|
|
|
t = getstrtoken();
|
|
|
|
|
n = atoi(t);
|
|
|
|
|
if (n==0) {
|
|
|
|
|
n = 1;
|
|
|
|
|
} else {
|
|
|
|
|
t = getstrtoken();
|
|
|
|
|
}
|
|
|
|
|
itype = finditemtype(t, u->faction->locale);
|
|
|
|
|
|
|
|
|
|
if (itype!=NULL) {
|
|
|
|
|
item ** iclaim = i_find(&u->faction->items, itype);
|
2004-12-31 02:13:04 +01:00
|
|
|
|
if (iclaim!=NULL && *iclaim!=NULL) {
|
2004-12-22 01:53:12 +01:00
|
|
|
|
n = min(n, (*iclaim)->number);
|
|
|
|
|
i_change(iclaim, itype, -n);
|
|
|
|
|
i_change(&u->items, itype, n);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
cmistake(u, ord, 43, MSG_PRODUCE);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2002-01-27 11:57:26 +01:00
|
|
|
|
void
|
|
|
|
|
processorders (void)
|
|
|
|
|
{
|
2004-12-03 20:08:00 +01:00
|
|
|
|
region *r;
|
2002-01-27 11:57:26 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
set_passw(); /* und pruefe auf illegale Befehle */
|
2002-01-27 11:57:26 +01:00
|
|
|
|
|
2004-06-23 00:00:36 +02:00
|
|
|
|
puts(" - neue Einheiten erschaffen...");
|
2004-12-03 20:08:00 +01:00
|
|
|
|
new_units();
|
2002-01-27 11:57:26 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Defaults und Instant-Befehle...");
|
|
|
|
|
setdefaults();
|
|
|
|
|
instant_orders();
|
2004-06-27 18:56:01 +02:00
|
|
|
|
|
|
|
|
|
if (alliances!=NULL) alliancekick();
|
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
parse(K_MAIL, prepare_mail_cmd, false);
|
2004-06-27 18:56:01 +02:00
|
|
|
|
parse(K_MAIL, mail_cmd, false);
|
2005-01-03 22:28:21 +01:00
|
|
|
|
puts(" - Parteien altern");
|
2004-12-03 20:08:00 +01:00
|
|
|
|
age_factions();
|
2002-01-27 11:57:26 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Benutzen");
|
2004-12-22 01:53:12 +01:00
|
|
|
|
parse(K_CLAIM, claim_cmd, false);
|
2004-12-03 20:08:00 +01:00
|
|
|
|
parse(K_USE, use_cmd, false);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Kontaktieren, Betreten von Schiffen und Geb<65>uden (1.Versuch)");
|
|
|
|
|
do_misc(false);
|
2001-04-26 19:41:06 +02:00
|
|
|
|
|
2004-06-27 18:56:01 +02:00
|
|
|
|
if (alliances!=NULL) {
|
|
|
|
|
puts(" - Testen der Allianzbedingungen");
|
|
|
|
|
alliancevictory();
|
|
|
|
|
}
|
2002-09-02 22:36:12 +02:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - GM Kommandos");
|
2004-06-21 18:45:27 +02:00
|
|
|
|
#ifdef INFOCMD_MODULE
|
2004-12-03 20:08:00 +01:00
|
|
|
|
infocommands();
|
2004-06-21 18:45:27 +02:00
|
|
|
|
#endif
|
2004-12-03 20:08:00 +01:00
|
|
|
|
gmcommands();
|
2001-04-26 19:41:06 +02:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Verlassen");
|
|
|
|
|
parse(K_LEAVE, leave_cmd, false);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Kontakte l<>schen");
|
|
|
|
|
remove_contacts();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-05-05 03:37:08 +02:00
|
|
|
|
#ifdef KARMA_MODULE
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Jihad-Angriffe");
|
|
|
|
|
jihad_attacks();
|
2005-05-05 03:37:08 +02:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Attackieren");
|
2005-06-10 00:10:35 +02:00
|
|
|
|
if (nobattle == false) do_battle();
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (turn == 0) rng_init((int)time(0));
|
|
|
|
|
else rng_init(turn);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Belagern");
|
|
|
|
|
do_siege();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Initialisieren des Pools, Reservieren");
|
|
|
|
|
init_pool();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Kontaktieren, Betreten von Schiffen und Geb<65>uden (2.Versuch)");
|
|
|
|
|
do_misc(false);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Folge auf Einheiten ersetzen");
|
|
|
|
|
follow_unit();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (turn == 0) rng_init((int)time(0));
|
|
|
|
|
else rng_init(turn);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Zerst<73>ren, Geben, Rekrutieren, Vergessen");
|
|
|
|
|
economics();
|
|
|
|
|
remove_empty_units();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Geb<65>udeunterhalt (1. Versuch)");
|
|
|
|
|
maintain_buildings(false);
|
2001-02-03 14:45:35 +01:00
|
|
|
|
|
2006-01-13 20:43:33 +01:00
|
|
|
|
puts(" - Sterben, Neustart");
|
|
|
|
|
quit();
|
|
|
|
|
parse_restart();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Zaubern");
|
|
|
|
|
magic();
|
|
|
|
|
remove_empty_units();
|
|
|
|
|
|
|
|
|
|
if (!global.disabled[K_TEACH]) {
|
|
|
|
|
puts(" - Lehren");
|
|
|
|
|
teaching();
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Lernen");
|
|
|
|
|
learn();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Produzieren, Geldverdienen, Handeln, Anwerben");
|
|
|
|
|
produce();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Kontaktieren, Betreten von Schiffen und Geb<65>uden (3.Versuch)");
|
|
|
|
|
do_misc(true);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Schiffe sinken");
|
|
|
|
|
sinkships();
|
2002-11-25 20:11:27 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Bewegungen");
|
|
|
|
|
movement();
|
2003-03-15 18:14:02 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Bewache (an)");
|
|
|
|
|
parse(K_GUARD, guard_on_cmd, false);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Zufallsbegegnungen");
|
|
|
|
|
encounters();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (turn == 0) rng_init((int)time(0));
|
|
|
|
|
else rng_init(turn);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Monster fressen und vertreiben Bauern");
|
|
|
|
|
monsters_kill_peasants();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - random events");
|
|
|
|
|
randomevents();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - newspaper commands");
|
2004-06-21 18:45:27 +02:00
|
|
|
|
#ifdef XECMD_MODULE
|
2004-12-03 20:08:00 +01:00
|
|
|
|
xecmd();
|
2004-06-21 18:45:27 +02:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - regeneration (healing & aura)");
|
|
|
|
|
monthly_healing();
|
|
|
|
|
regeneration_magiepunkte();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Defaults setzen");
|
|
|
|
|
defaultorders();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Unterhaltskosten, Nachfrage, Seuchen, Wachstum, Auswanderung");
|
|
|
|
|
demographics();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Geb<65>udeunterhalt (2. Versuch)");
|
|
|
|
|
maintain_buildings(true);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-05-05 03:37:08 +02:00
|
|
|
|
#ifdef KARMA_MODULE
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Jihads setzen");
|
|
|
|
|
karma();
|
2005-05-05 03:37:08 +02:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Einheiten Sortieren");
|
|
|
|
|
reorder();
|
2002-09-02 22:36:12 +02:00
|
|
|
|
#ifdef ALLIANCEJOIN
|
2004-12-03 20:08:00 +01:00
|
|
|
|
alliancejoin();
|
2002-12-18 18:40:21 +01:00
|
|
|
|
#endif
|
2005-11-20 13:58:59 +01:00
|
|
|
|
#ifdef ENEMIES
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Krieg & Frieden");
|
2002-12-18 18:40:21 +01:00
|
|
|
|
declare_war();
|
2002-04-21 13:23:58 +02:00
|
|
|
|
#endif
|
2004-08-03 17:34:26 +02:00
|
|
|
|
|
|
|
|
|
#ifdef HEROES
|
|
|
|
|
puts(" - Heldenbef<65>rderung");
|
2004-08-29 01:06:15 +02:00
|
|
|
|
parse(K_PROMOTION, promotion_cmd, false);
|
2004-08-03 17:34:26 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Neue Nummern");
|
|
|
|
|
renumber();
|
|
|
|
|
for (r = regions;r;r=r->next) reorder_owners(r);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-03 20:08:00 +01:00
|
|
|
|
puts(" - Attribute altern");
|
|
|
|
|
ageing();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-02-21 23:25:00 +01:00
|
|
|
|
#ifdef WORMHOLE_MODULE
|
|
|
|
|
create_wormholes();
|
|
|
|
|
#endif
|
2004-12-03 20:08:00 +01:00
|
|
|
|
/* immer ausf<73>hren, wenn neue Spr<70>che dazugekommen sind, oder sich
|
|
|
|
|
* Beschreibungen ge<EFBFBD>ndert haben */
|
|
|
|
|
update_spells();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-02-10 11:40:12 +01:00
|
|
|
|
|
2004-01-11 12:55:48 +01:00
|
|
|
|
int
|
|
|
|
|
writepasswd(void)
|
|
|
|
|
{
|
|
|
|
|
FILE * F;
|
|
|
|
|
char zText[128];
|
|
|
|
|
|
|
|
|
|
sprintf(zText, "%s/passwd", basepath());
|
|
|
|
|
F = cfopen(zText, "w");
|
|
|
|
|
if (F) {
|
|
|
|
|
faction *f;
|
|
|
|
|
puts("Schreibe Passw<73>rter...");
|
|
|
|
|
|
|
|
|
|
for (f = factions; f; f = f->next) {
|
2004-12-03 20:08:00 +01:00
|
|
|
|
fprintf(F, "%s:%s:%s:%s:%u\n",
|
2004-01-11 12:55:48 +01:00
|
|
|
|
factionid(f), f->email, f->passw, f->override, f->subscription);
|
|
|
|
|
}
|
|
|
|
|
fclose(F);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|