2001-01-25 10:37:55 +01:00
|
|
|
|
/* vi: set ts=2:
|
|
|
|
|
*
|
2003-07-29 11:48:03 +02: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>
|
|
|
|
|
#include <eressea.h>
|
|
|
|
|
|
2001-05-11 22:19:22 +02:00
|
|
|
|
/* misc includes */
|
|
|
|
|
#include <attributes/key.h>
|
2002-09-02 22:36:12 +02:00
|
|
|
|
#include <items/questkeys.h>
|
|
|
|
|
#include <items/catapultammo.h>
|
2002-04-27 21:40:31 +02:00
|
|
|
|
#include <modules/xecmd.h>
|
2002-09-02 22:36:12 +02:00
|
|
|
|
#ifdef ALLIANCES
|
|
|
|
|
#include <modules/alliance.h>
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* gamecode includes */
|
|
|
|
|
#include <economy.h>
|
|
|
|
|
|
|
|
|
|
/* kernel includes */
|
|
|
|
|
#include <border.h>
|
|
|
|
|
#include <building.h>
|
2001-02-13 00:06:44 +01:00
|
|
|
|
#include <ship.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <faction.h>
|
|
|
|
|
#include <item.h>
|
|
|
|
|
#include <magic.h>
|
|
|
|
|
#include <message.h>
|
|
|
|
|
#include <monster.h>
|
|
|
|
|
#include <movement.h>
|
|
|
|
|
#include <names.h>
|
|
|
|
|
#include <pathfinder.h>
|
|
|
|
|
#include <plane.h>
|
|
|
|
|
#include <pool.h>
|
|
|
|
|
#include <race.h>
|
|
|
|
|
#include <region.h>
|
|
|
|
|
#include <reports.h>
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#include <resources.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <skill.h>
|
|
|
|
|
#include <teleport.h>
|
|
|
|
|
#include <unit.h>
|
|
|
|
|
#include <spell.h>
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#include <alchemy.h>
|
|
|
|
|
#include <study.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* util includes */
|
|
|
|
|
#include <attrib.h>
|
2003-01-19 10:10:28 +01:00
|
|
|
|
#include <language.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <base36.h>
|
2003-09-21 11:30:09 +02:00
|
|
|
|
#include <log.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <cvector.h>
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#include <event.h>
|
2002-05-05 11:37:43 +02:00
|
|
|
|
#include <goodies.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <resolve.h>
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#include <sql.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <vset.h>
|
|
|
|
|
|
|
|
|
|
/* libc includes */
|
|
|
|
|
#include <stdio.h>
|
2002-03-09 16:16:35 +01:00
|
|
|
|
#include <ctype.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
/* attributes includes */
|
|
|
|
|
#include <attributes/targetregion.h>
|
|
|
|
|
#include <attributes/key.h>
|
|
|
|
|
|
2004-02-13 20:14:38 +01:00
|
|
|
|
#undef XMAS1999
|
|
|
|
|
#undef XMAS2000
|
|
|
|
|
#undef XMAS2001
|
2003-01-08 22:44:01 +01:00
|
|
|
|
#undef XMAS2002
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2001-02-13 00:06:44 +01:00
|
|
|
|
extern void reorder_owners(struct region * r);
|
|
|
|
|
|
2002-09-02 22:36:12 +02:00
|
|
|
|
static int
|
|
|
|
|
curse_emptiness(void)
|
|
|
|
|
{
|
|
|
|
|
const curse_type * ct = ct_find("godcursezone");
|
2002-09-12 21:07:41 +02:00
|
|
|
|
region * r;
|
|
|
|
|
for (r=regions;r!=NULL;r=r->next) {
|
|
|
|
|
unit * u = r->units;
|
|
|
|
|
if (r->land==NULL) continue;
|
|
|
|
|
if (fval(r, RF_CHAOTIC)) continue;
|
|
|
|
|
if (r->terrain==T_GLACIER) continue;
|
2002-10-08 08:48:47 +02:00
|
|
|
|
if (r->age<=200) continue;
|
2002-09-12 21:07:41 +02:00
|
|
|
|
if (get_curse(r->attribs, ct)) continue;
|
|
|
|
|
while (u && u->faction->no==MONSTER_FACTION) u=u->next;
|
|
|
|
|
if (u==NULL) fset(r, FL_MARK);
|
|
|
|
|
}
|
|
|
|
|
for (r=regions;r!=NULL;r=r->next) {
|
|
|
|
|
if (fval(r, FL_MARK)) {
|
|
|
|
|
direction_t d;
|
|
|
|
|
for (d=0;d!=MAXDIRECTIONS;++d) {
|
|
|
|
|
region * rn = rconnect(r,d);
|
|
|
|
|
if (rn==NULL) continue;
|
|
|
|
|
if (fval(rn, FL_MARK) || get_curse(rn->attribs, ct)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (d!=MAXDIRECTIONS) {
|
2002-09-02 22:36:12 +02:00
|
|
|
|
curse * c = create_curse(NULL, &r->attribs, ct,
|
2002-09-12 21:07:41 +02:00
|
|
|
|
100, 100, 0, 0);
|
2002-09-02 22:36:12 +02:00
|
|
|
|
curse_setflag(c, CURSE_ISNEW|CURSE_IMMUNE);
|
|
|
|
|
}
|
2002-09-12 21:07:41 +02:00
|
|
|
|
freset(r, FL_MARK);
|
2002-09-02 22:36:12 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2003-05-13 17:43:18 +02:00
|
|
|
|
void
|
|
|
|
|
french_testers(void)
|
|
|
|
|
{
|
|
|
|
|
faction * f = factions;
|
|
|
|
|
const struct locale * french = find_locale("fr");
|
|
|
|
|
while (f!=NULL) {
|
|
|
|
|
if (f->locale==french) fset(f, FFL_NOTIMEOUT);
|
|
|
|
|
f = f->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-02-13 00:06:44 +01:00
|
|
|
|
static void
|
|
|
|
|
verify_owners(boolean bOnce)
|
|
|
|
|
{
|
|
|
|
|
region * r;
|
|
|
|
|
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
unit * u;
|
|
|
|
|
boolean bFail = false;
|
|
|
|
|
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
if (u->building) {
|
|
|
|
|
unit * bo = buildingowner(r, u->building);
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (!fval(bo, UFL_OWNER)) {
|
|
|
|
|
log_error(("[verify_owners] %u ist Besitzer von %s, hat aber UFL_OWNER nicht.\n", unitname(bo), buildingname(u->building)));
|
2001-02-13 00:06:44 +01:00
|
|
|
|
bFail = true;
|
|
|
|
|
if (bOnce) break;
|
|
|
|
|
}
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (bo!=u && fval(u, UFL_OWNER)) {
|
|
|
|
|
log_error(("[verify_owners] %u ist NICHT Besitzer von %s, hat aber UFL_OWNER.\n", unitname(u), buildingname(u->building)));
|
2001-02-13 00:06:44 +01:00
|
|
|
|
bFail = true;
|
|
|
|
|
if (bOnce) break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (u->ship) {
|
|
|
|
|
unit * bo = shipowner(r, u->ship);
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (!fval(bo, UFL_OWNER)) {
|
|
|
|
|
log_error(("[verify_owners] %u ist Besitzer von %s, hat aber UFL_OWNER nicht.\n", unitname(bo), shipname(u->ship)));
|
2001-02-13 00:06:44 +01:00
|
|
|
|
bFail = true;
|
|
|
|
|
if (bOnce) break;
|
|
|
|
|
}
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (bo!=u && fval(u, UFL_OWNER)) {
|
|
|
|
|
log_error(("[verify_owners] %u ist NICHT Besitzer von %s, hat aber UFL_OWNER.\n", unitname(u), shipname(u->ship)));
|
2001-02-13 00:06:44 +01:00
|
|
|
|
bFail = true;
|
|
|
|
|
if (bOnce) break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (bFail) reorder_owners(r);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-02-02 09:40:49 +01:00
|
|
|
|
/* make sure that this is done only once! */
|
|
|
|
|
#define do_once(magic, fun) \
|
|
|
|
|
{ \
|
2001-09-05 21:40:40 +02:00
|
|
|
|
attrib * a = find_key(global.attribs, atoi36(magic)); \
|
2002-04-07 02:44:01 +02:00
|
|
|
|
if (!a) { \
|
|
|
|
|
log_warning(("[do_once] a unique fix %d=\"%s\" was applied.\n", atoi36(magic), magic)); \
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (fun == 0) a_add(&global.attribs, make_key(atoi36(magic))); \
|
2001-02-20 23:54:05 +01:00
|
|
|
|
} \
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-03-10 11:09:16 +01:00
|
|
|
|
int
|
|
|
|
|
warn_items(void)
|
|
|
|
|
{
|
|
|
|
|
boolean found = 0;
|
|
|
|
|
region * r;
|
2002-04-07 02:44:01 +02:00
|
|
|
|
const item_type * it_money = it_find("money");
|
2002-03-10 11:09:16 +01:00
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
unit * u;
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
item * itm;
|
|
|
|
|
for (itm=u->items;itm;itm=itm->next) {
|
2002-04-07 02:44:01 +02:00
|
|
|
|
if (itm->number>100000 && itm->type!=it_money) {
|
2002-03-10 11:09:16 +01:00
|
|
|
|
found = 1;
|
2002-05-02 23:19:45 +02:00
|
|
|
|
log_error(("Einheit %s hat %u %s\n",
|
|
|
|
|
unitid(u), itm->number,
|
2002-03-10 11:09:16 +01:00
|
|
|
|
resourcename(itm->type->rtype, 0)));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-03-10 11:09:16 +01:00
|
|
|
|
return found;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static boolean
|
|
|
|
|
kor_teure_talente(unit *u)
|
|
|
|
|
{
|
|
|
|
|
if(effskill(u, SK_TACTICS) >= 1 ||
|
|
|
|
|
effskill(u, SK_MAGIC) >= 1 ||
|
|
|
|
|
effskill(u, SK_ALCHEMY) >= 1 ||
|
|
|
|
|
effskill(u, SK_HERBALISM) >= 1 ||
|
|
|
|
|
effskill(u, SK_SPY) >= 1) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
no_teurefremde(boolean convert)
|
|
|
|
|
{
|
|
|
|
|
region *r;
|
|
|
|
|
unit *u;
|
|
|
|
|
|
|
|
|
|
for(r=regions;r;r=r->next) {
|
|
|
|
|
for(u=r->units;u;u=u->next) {
|
2004-05-30 05:25:10 +02:00
|
|
|
|
if (u->faction->no != MONSTER_FACTION
|
|
|
|
|
&& playerrace(u->faction->race)
|
2001-12-10 01:13:39 +01:00
|
|
|
|
&& is_migrant(u)
|
2002-05-02 23:19:45 +02:00
|
|
|
|
&& kor_teure_talente(u))
|
2001-12-10 01:13:39 +01:00
|
|
|
|
{
|
2002-05-02 23:19:45 +02:00
|
|
|
|
log_printf("* Warnung, teurer Migrant: %s %s\n",
|
2001-12-10 01:13:39 +01:00
|
|
|
|
unitname(u), factionname(u->faction));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if(convert) {
|
|
|
|
|
u->race = u->faction->race;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
u->irace = u->faction->race;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
u->faction->num_migrants -= u->number;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
sprintf(buf, "Die G<>tter segnen %s mit der richtigen Rasse",
|
|
|
|
|
unitname(u));
|
|
|
|
|
addmessage(0, u->faction, buf, MSG_MESSAGE, ML_IMPORTANT);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attrib_type at_roadfix = {
|
|
|
|
|
"roadfix",
|
|
|
|
|
DEFAULT_INIT,
|
|
|
|
|
DEFAULT_FINALIZE,
|
|
|
|
|
DEFAULT_AGE,
|
|
|
|
|
#if RELEASE_VERSION<DISABLE_ROADFIX
|
|
|
|
|
DEFAULT_WRITE,
|
|
|
|
|
#else
|
|
|
|
|
NULL, /* disable writing them so they will disappear */
|
|
|
|
|
#endif
|
|
|
|
|
DEFAULT_READ,
|
|
|
|
|
ATF_UNIQUE
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* ************************************************************ */
|
|
|
|
|
/* 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
|
|
|
|
|
show_newspells(void)
|
|
|
|
|
{
|
2004-04-10 22:25:40 +02:00
|
|
|
|
region *r;
|
|
|
|
|
/* Alle ge<67>nderten Zauber in das array newspellids[]. mit SPL_NOSPELL
|
|
|
|
|
* terminieren */
|
|
|
|
|
|
|
|
|
|
spellid_t newspellids[] = {
|
|
|
|
|
SPL_NOSPELL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* die id's der neuen oder ver<65>nderten Spr<70>che werden in newspellids[]
|
|
|
|
|
* abgelegt */
|
|
|
|
|
|
|
|
|
|
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) continue;
|
|
|
|
|
if (m != NULL) {
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (m->magietyp == M_GRAU) continue;
|
|
|
|
|
|
|
|
|
|
for (i = 0; newspellids[i] != SPL_NOSPELL; i++) {
|
|
|
|
|
spell *sp = find_spellbyid(newspellids[i]);
|
|
|
|
|
|
|
|
|
|
if (!sp) continue;
|
|
|
|
|
|
|
|
|
|
if (m->magietyp == sp->magietyp || has_spell(u, sp)) {
|
|
|
|
|
attrib * a = a_find(u->faction->attribs, &at_reportspell);
|
|
|
|
|
while (a && a->data.i != sp->id) a = a->nexttype;
|
|
|
|
|
if (!a) {
|
|
|
|
|
/* spell is not being shown yet. if seen before, remove to show again */
|
|
|
|
|
a = a_find(u->faction->attribs, &at_seenspell);
|
|
|
|
|
while (a && a->data.i != sp->id) a = a->nexttype;
|
|
|
|
|
if (a) a_remove(&u->faction->attribs, a);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2003-01-19 10:10:28 +01:00
|
|
|
|
static int
|
|
|
|
|
fix_foreign(void)
|
|
|
|
|
{
|
|
|
|
|
region * r;
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
struct locale * lang;
|
|
|
|
|
for (lang=locales;lang;lang=nextlocale(lang)) {
|
|
|
|
|
const char * udefault = LOC(lang, "unitdefault");
|
|
|
|
|
size_t udlen = strlen(udefault);
|
|
|
|
|
unit * u;
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
size_t unlen = strlen(u->name);
|
|
|
|
|
if (unlen<udlen) continue;
|
|
|
|
|
if (strncmp(u->name, udefault, udlen)==0) {
|
|
|
|
|
fset(u, FL_UNNAMED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
extern plane * arena;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fix_age(void)
|
|
|
|
|
{
|
|
|
|
|
faction * f;
|
2002-03-24 13:43:12 +01:00
|
|
|
|
const race * oldorc = rc_find("orc");
|
|
|
|
|
const race * uruk = rc_find("uruk");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for (f=factions;f;f=f->next) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (f->no!=MONSTER_FACTION && playerrace(f->race)) continue;
|
2002-03-24 13:43:12 +01:00
|
|
|
|
if (f->race==oldorc) f->race= uruk;
|
|
|
|
|
else if (f->age!=turn) {
|
2001-04-14 14:11:45 +02:00
|
|
|
|
log_printf("Alter von Partei %s auf %d angepasst.\n", factionid(f), turn);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
f->age = turn;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#if 1
|
2001-02-10 14:20:09 +01:00
|
|
|
|
static int
|
2001-02-03 14:45:35 +01:00
|
|
|
|
count_demand(const region *r)
|
|
|
|
|
{
|
|
|
|
|
struct demand *dmd;
|
|
|
|
|
int c = 0;
|
2001-02-10 20:24:05 +01:00
|
|
|
|
if (r->land) {
|
|
|
|
|
for (dmd=r->land->demands;dmd;dmd=dmd->next) c++;
|
|
|
|
|
}
|
2001-02-03 14:45:35 +01:00
|
|
|
|
return c;
|
|
|
|
|
}
|
2001-02-20 23:54:05 +01:00
|
|
|
|
#endif
|
2001-02-03 14:45:35 +01:00
|
|
|
|
|
2001-02-10 20:24:05 +01:00
|
|
|
|
static int
|
2004-02-21 13:18:29 +01:00
|
|
|
|
recurse_regions(region * r, region_list **rlist, boolean(*fun)(const region * r))
|
2001-02-03 14:45:35 +01:00
|
|
|
|
{
|
2001-02-10 20:24:05 +01:00
|
|
|
|
if (!fun(r)) return 0;
|
|
|
|
|
else {
|
|
|
|
|
int len = 0;
|
|
|
|
|
direction_t d;
|
2004-02-21 13:18:29 +01:00
|
|
|
|
region_list * rl = calloc(sizeof(region_list), 1);
|
2001-02-10 20:24:05 +01:00
|
|
|
|
rl->next = *rlist;
|
2004-02-21 13:18:29 +01:00
|
|
|
|
rl->data = r;
|
2001-02-10 20:24:05 +01:00
|
|
|
|
(*rlist) = rl;
|
|
|
|
|
fset(r, FL_MARK);
|
|
|
|
|
for (d=0;d!=MAXDIRECTIONS;++d) {
|
|
|
|
|
region * nr = rconnect(r, d);
|
|
|
|
|
if (nr && !fval(nr, FL_MARK)) len += recurse_regions(nr, rlist, fun);
|
|
|
|
|
}
|
|
|
|
|
return len+1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-02-03 14:45:35 +01:00
|
|
|
|
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#if 1
|
2001-09-05 21:40:40 +02:00
|
|
|
|
static int maxluxuries = 0;
|
|
|
|
|
|
2001-02-10 20:24:05 +01:00
|
|
|
|
static boolean
|
|
|
|
|
f_nolux(const region * r)
|
|
|
|
|
{
|
|
|
|
|
if (r->land && count_demand(r) != maxluxuries) return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2001-02-03 14:45:35 +01:00
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
static int
|
2001-02-10 20:24:05 +01:00
|
|
|
|
fix_demand_region(region *r)
|
|
|
|
|
{
|
2004-02-21 13:18:29 +01:00
|
|
|
|
region_list *rl, *rlist = NULL;
|
2001-02-10 20:24:05 +01:00
|
|
|
|
static const luxury_type **mlux = 0, ** ltypes;
|
|
|
|
|
const luxury_type *sale = NULL;
|
|
|
|
|
int maxlux = 0;
|
|
|
|
|
|
|
|
|
|
recurse_regions(r, &rlist, f_nolux);
|
|
|
|
|
if (mlux==0) {
|
|
|
|
|
int i = 0;
|
|
|
|
|
if (maxluxuries==0) for (sale=luxurytypes;sale;sale=sale->next) {
|
|
|
|
|
maxluxuries++;
|
|
|
|
|
}
|
|
|
|
|
mlux = (const luxury_type **)gc_add(calloc(maxluxuries, sizeof(const luxury_type *)));
|
|
|
|
|
ltypes = (const luxury_type **)gc_add(calloc(maxluxuries, sizeof(const luxury_type *)));
|
|
|
|
|
for (sale=luxurytypes;sale;sale=sale->next) {
|
|
|
|
|
ltypes[i++] = sale;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
int i;
|
|
|
|
|
for (i=0;i!=maxluxuries;++i) mlux[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
for (rl=rlist;rl;rl=rl->next) {
|
2004-02-21 13:18:29 +01:00
|
|
|
|
region * r = rl->data;
|
2001-02-10 20:24:05 +01:00
|
|
|
|
direction_t d;
|
|
|
|
|
for (d=0;d!=MAXDIRECTIONS;++d) {
|
|
|
|
|
region * nr = rconnect(r, d);
|
|
|
|
|
if (nr && nr->land && nr->land->demands) {
|
|
|
|
|
struct demand * dmd;
|
|
|
|
|
for (dmd = nr->land->demands;dmd;dmd=dmd->next) {
|
|
|
|
|
if (dmd->value == 0) {
|
|
|
|
|
int i;
|
|
|
|
|
for (i=0;i!=maxluxuries;++i) {
|
|
|
|
|
if (mlux[i]==NULL) {
|
|
|
|
|
maxlux = i;
|
|
|
|
|
mlux[i] = dmd->type;
|
|
|
|
|
break;
|
|
|
|
|
} else if (mlux[i]==dmd->type) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-02-03 14:45:35 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-02-10 20:24:05 +01:00
|
|
|
|
freset(r, FL_MARK); /* undo recursive marker */
|
|
|
|
|
}
|
|
|
|
|
if (maxlux<2) {
|
|
|
|
|
int i;
|
|
|
|
|
for (i=maxlux;i!=2;++i) {
|
|
|
|
|
int j;
|
|
|
|
|
do {
|
|
|
|
|
int k = rand() % maxluxuries;
|
|
|
|
|
mlux[i] = ltypes[k];
|
|
|
|
|
for (j=0;j!=i;++j) {
|
|
|
|
|
if (mlux[j]==mlux[i]) break;
|
|
|
|
|
}
|
|
|
|
|
} while (j!=i);
|
|
|
|
|
}
|
|
|
|
|
maxlux=2;
|
|
|
|
|
}
|
|
|
|
|
for (rl=rlist;rl;rl=rl->next) {
|
2004-02-21 13:18:29 +01:00
|
|
|
|
region * r = rl->data;
|
2004-01-25 09:45:18 +01:00
|
|
|
|
if (!fval(r, RF_CHAOTIC)) log_warning(("fixing demand in %s\n", regionname(r, NULL)));
|
2001-02-10 20:24:05 +01:00
|
|
|
|
setluxuries(r, mlux[rand() % maxlux]);
|
|
|
|
|
}
|
|
|
|
|
while (rlist) {
|
|
|
|
|
rl = rlist->next;
|
|
|
|
|
free(rlist);
|
|
|
|
|
rlist = rl;
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
return 0;
|
2001-02-10 20:24:05 +01:00
|
|
|
|
}
|
2001-02-20 23:54:05 +01:00
|
|
|
|
#endif
|
2001-02-10 20:24:05 +01:00
|
|
|
|
|
2001-09-05 21:40:40 +02:00
|
|
|
|
static void
|
|
|
|
|
fix_firewalls(void)
|
|
|
|
|
{
|
2004-05-31 13:50:32 +02:00
|
|
|
|
region * r = regions;
|
|
|
|
|
while (r) {
|
|
|
|
|
direction_t d;
|
|
|
|
|
for (d=0;d!=MAXDIRECTIONS;++d) {
|
|
|
|
|
region * r2 = rconnect(r, d);
|
|
|
|
|
if (r2) {
|
|
|
|
|
border * b = get_borders(r, r2);
|
|
|
|
|
while (b) {
|
|
|
|
|
if (b->type==&bt_firewall) {
|
|
|
|
|
attrib * a = a_find(b->attribs, &at_countdown);
|
|
|
|
|
if (a==NULL || a->data.i <= 0) {
|
|
|
|
|
erase_border(b);
|
|
|
|
|
log_warning(("firewall between regions %s and %s was bugged. removed.\n",
|
|
|
|
|
regionid(r), regionid(r2)));
|
|
|
|
|
b = get_borders(r, r2);
|
|
|
|
|
} else {
|
|
|
|
|
b = b->next;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
b = b->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
r = r->next;
|
|
|
|
|
}
|
2001-09-05 21:40:40 +02:00
|
|
|
|
}
|
|
|
|
|
|
2001-02-10 20:24:05 +01:00
|
|
|
|
extern attrib * make_atgmcreate(const struct item_type * itype);
|
|
|
|
|
extern attrib * make_atpermissions(void);
|
|
|
|
|
extern struct attrib_type at_permissions;
|
2001-09-05 21:40:40 +02:00
|
|
|
|
extern struct attrib_type at_gmcreate;
|
|
|
|
|
|
2001-02-10 20:24:05 +01:00
|
|
|
|
|
|
|
|
|
static void
|
2001-05-11 22:19:22 +02:00
|
|
|
|
update_gms(void)
|
2001-02-10 20:24:05 +01:00
|
|
|
|
{
|
2001-05-11 22:19:22 +02:00
|
|
|
|
faction * f;
|
|
|
|
|
for (f=factions;f;f=f->next) {
|
2001-09-05 21:40:40 +02:00
|
|
|
|
attrib * permissions = a_find(f->attribs, &at_permissions);
|
|
|
|
|
if (permissions) {
|
2002-02-24 10:20:38 +01:00
|
|
|
|
const char * keys[] = { "gmgate", "gmmsgr", "gmkill", "gmmsgu", NULL };
|
2002-01-28 02:55:31 +01:00
|
|
|
|
int k;
|
2001-09-05 21:40:40 +02:00
|
|
|
|
item_t i;
|
2002-01-28 02:55:31 +01:00
|
|
|
|
for (k=0;keys[k];++k) {
|
2002-03-02 20:26:39 +01:00
|
|
|
|
add_key((attrib**)&permissions->data.v, atoi36(keys[k]));
|
2001-09-05 21:40:40 +02:00
|
|
|
|
}
|
2002-01-28 02:55:31 +01:00
|
|
|
|
for (i=I_GREATSWORD;i!=I_KEKS;++i) {
|
2002-05-09 13:10:39 +02:00
|
|
|
|
attrib * a = a_find((attrib*)permissions->data.v, &at_gmcreate);
|
2002-01-28 02:55:31 +01:00
|
|
|
|
while (a && a->data.v!=(void*)olditemtype[i]) a=a->nexttype;
|
|
|
|
|
if (!a) a_add((attrib**)&permissions->data.v, make_atgmcreate(olditemtype[i]));
|
2001-09-05 21:40:40 +02:00
|
|
|
|
}
|
2002-01-28 02:55:31 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#if 1
|
|
|
|
|
static int
|
2001-02-03 14:45:35 +01:00
|
|
|
|
fix_demand(void)
|
|
|
|
|
{
|
|
|
|
|
region *r;
|
2001-02-10 20:24:05 +01:00
|
|
|
|
const luxury_type *sale = NULL;
|
|
|
|
|
|
|
|
|
|
if (maxluxuries==0) for (sale=luxurytypes;sale;sale=sale->next) ++maxluxuries;
|
2001-02-03 14:45:35 +01:00
|
|
|
|
|
2001-02-10 20:24:05 +01:00
|
|
|
|
for (r=regions; r; r=r->next) {
|
2004-01-25 09:45:18 +01:00
|
|
|
|
if (r->land!=NULL && r->land->peasants>=100 && count_demand(r) != maxluxuries) {
|
2001-02-10 20:24:05 +01:00
|
|
|
|
fix_demand_region(r);
|
|
|
|
|
}
|
2001-02-03 14:45:35 +01:00
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
return 0;
|
2001-02-03 14:45:35 +01:00
|
|
|
|
}
|
2001-02-20 23:54:05 +01:00
|
|
|
|
#endif
|
2001-02-03 14:45:35 +01:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include "group.h"
|
|
|
|
|
static void
|
2002-10-08 08:48:47 +02:00
|
|
|
|
fix_allies(void)
|
2002-09-02 22:36:12 +02:00
|
|
|
|
{
|
2001-01-25 10:37:55 +01:00
|
|
|
|
faction * f;
|
|
|
|
|
for (f=factions;f;f=f->next) {
|
|
|
|
|
group * g;
|
|
|
|
|
for (g=f->groups;g;g=g->next) {
|
|
|
|
|
ally ** ap=&g->allies;
|
|
|
|
|
while (*ap) {
|
|
|
|
|
ally * an, * a = *ap;
|
|
|
|
|
for (an = a->next;an;an=an->next) {
|
|
|
|
|
if (a->faction==an->faction) {
|
|
|
|
|
*ap = a->next;
|
|
|
|
|
free(a);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (an==NULL) ap = &(*ap)->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef FUZZY_BASE36
|
|
|
|
|
extern boolean enable_fuzzy;
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-02-10 14:20:09 +01:00
|
|
|
|
static void
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fix_icastles(void)
|
|
|
|
|
{
|
|
|
|
|
region * r;
|
|
|
|
|
for (r=regions; r; r=r->next) {
|
|
|
|
|
building * b;
|
|
|
|
|
for (b=r->buildings; b; b=b->next) {
|
|
|
|
|
attrib * a;
|
2002-03-27 22:49:27 +01:00
|
|
|
|
const building_type * btype = bt_find("castle");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
icastle_data * data;
|
|
|
|
|
a = a_find(b->attribs, &at_icastle);
|
2002-03-27 22:49:27 +01:00
|
|
|
|
if (b->type!=bt_find("illusion") && !a) continue;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
if (!a) {
|
|
|
|
|
/* attribut hat gefehle */
|
|
|
|
|
a = a_add(&b->attribs, a_new(&at_icastle));
|
|
|
|
|
}
|
2002-03-27 22:49:27 +01:00
|
|
|
|
if (b->type!=bt_find("illusion")) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* geb<65>udetyp war falsch */
|
|
|
|
|
btype = b->type;
|
2002-03-27 22:49:27 +01:00
|
|
|
|
b->type = bt_find("illusion");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
data = (icastle_data*)a->data.v;
|
|
|
|
|
if (data->time<=0) {
|
|
|
|
|
/* zeit war kaputt oder abgelaufen */
|
|
|
|
|
data->time = 1;
|
|
|
|
|
}
|
|
|
|
|
if (!data->type) {
|
|
|
|
|
/* typ muss gesetzt werden, weil er nicht geladen wurde */
|
|
|
|
|
data->type = btype;
|
|
|
|
|
}
|
|
|
|
|
if (data->building!=b) {
|
|
|
|
|
/* r<>ckw<6B>rtszeiger auf das geb<65>ude reparieren */
|
|
|
|
|
data->building=b;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-09-21 11:30:09 +02:00
|
|
|
|
typedef struct stats_t {
|
|
|
|
|
struct stats_t * next;
|
|
|
|
|
const struct item_type * type;
|
|
|
|
|
double number;
|
|
|
|
|
} stats_t;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
s_change(stats_t** s, const struct item_type * type, int count)
|
|
|
|
|
{
|
|
|
|
|
while (*s && (*s)->type!=type) s=&(*s)->next;
|
2003-09-21 11:45:25 +02:00
|
|
|
|
if (*s==NULL) {
|
|
|
|
|
*s = calloc(1, sizeof(stats_t));
|
|
|
|
|
(*s)->type = type;
|
|
|
|
|
}
|
2003-09-21 11:30:09 +02:00
|
|
|
|
(*s)->number += count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static stats_t *
|
|
|
|
|
s_find(stats_t * s, const struct item_type * type)
|
|
|
|
|
{
|
|
|
|
|
while (s && s->type!=type) s=s->next;
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static void
|
|
|
|
|
stats(void)
|
|
|
|
|
{
|
|
|
|
|
FILE * F;
|
2003-09-21 11:30:09 +02:00
|
|
|
|
stats_t * items = NULL;
|
2001-02-03 14:45:35 +01:00
|
|
|
|
char zText[MAX_PATH];
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-02-03 14:45:35 +01:00
|
|
|
|
strcat(strcpy(zText, resourcepath()), "/stats");
|
|
|
|
|
F = fopen(zText, "wt");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (F) {
|
|
|
|
|
region * r;
|
|
|
|
|
const item_type * itype;
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
unit * u;
|
|
|
|
|
item * itm;
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
|
|
|
|
|
for (itm=u->items;itm;itm=itm->next) {
|
2002-03-11 01:06:14 +01:00
|
|
|
|
if (itm->number>10000000) {
|
2003-09-21 11:30:09 +02:00
|
|
|
|
log_error(("unit %s has %d %s\n", unitname(u), itm->number, resourcename(itm->type->rtype, 0)));
|
2003-09-28 10:05:50 +02:00
|
|
|
|
/* itm->number=1; */
|
2002-03-11 01:06:14 +01:00
|
|
|
|
}
|
2003-09-21 11:30:09 +02:00
|
|
|
|
s_change(&items, itm->type, itm->number);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (itype=itemtypes;itype;itype=itype->next) {
|
2003-09-21 11:30:09 +02:00
|
|
|
|
stats_t * itm = s_find(items, itype);
|
|
|
|
|
if (itm && itm->number>0.0)
|
2003-10-05 09:29:31 +02:00
|
|
|
|
fprintf(F, "%4.0f %s\n", itm->number, locale_string(NULL, resourcename(itype->rtype, 0)));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
else
|
2003-10-05 09:29:31 +02:00
|
|
|
|
fprintf(F, "%4.0f %s\n", 0.0, locale_string(NULL, resourcename(itype->rtype, 0)));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
fclose(F);
|
|
|
|
|
} else {
|
2001-02-03 14:45:35 +01:00
|
|
|
|
perror(zText);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2002-01-21 02:20:45 +01:00
|
|
|
|
#if 0
|
2001-02-25 20:31:40 +01:00
|
|
|
|
static void
|
|
|
|
|
fix_herbs(void)
|
2001-02-09 20:52:59 +01:00
|
|
|
|
{
|
2001-02-25 20:31:40 +01:00
|
|
|
|
const char * plain_herbs[] = {"Flachwurz", "W<EFBFBD>rziger Wagemut", "Eulenauge", "Gr<EFBFBD>ner Spinnerich", "Blauer Baumringel", "Elfenlieb"};
|
|
|
|
|
const herb_type * htypes[6];
|
|
|
|
|
int herbs[6];
|
|
|
|
|
int hneed[6];
|
2001-02-09 20:52:59 +01:00
|
|
|
|
region *r;
|
2001-02-25 20:31:40 +01:00
|
|
|
|
int i, hsum = 0, left = 0;
|
|
|
|
|
|
|
|
|
|
for (i=0;i!=6;++i) {
|
|
|
|
|
htypes[i] = resource2herb(finditemtype(plain_herbs[i], NULL)->rtype);
|
|
|
|
|
herbs[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (r=regions; r; r=r->next) if (rterrain(r) == T_PLAIN) {
|
|
|
|
|
const herb_type *htype = rherbtype(r);
|
2001-04-14 14:11:45 +02:00
|
|
|
|
if (htype==NULL) {
|
|
|
|
|
htype = htypes[i];
|
|
|
|
|
rsetherbtype(r, htype);
|
|
|
|
|
}
|
2001-02-25 20:31:40 +01:00
|
|
|
|
for (i=0;i!=6;++i) if (htypes[i]==htype) break;
|
|
|
|
|
assert(i!=6);
|
|
|
|
|
herbs[i]++;
|
|
|
|
|
hsum++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i=0;i!=6;++i) {
|
|
|
|
|
int hwant = hsum / (6-i);
|
|
|
|
|
hneed[i] = hwant - herbs[i];
|
|
|
|
|
if (hneed[i]>0) left += hneed[i];
|
|
|
|
|
hsum -= hwant;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (r=regions; r; r=r->next) if (rterrain(r) == T_PLAIN) {
|
|
|
|
|
const herb_type *htype = rherbtype(r);
|
|
|
|
|
assert(htype);
|
|
|
|
|
for (i=0;i!=6;++i) if (htypes[i]==htype) break;
|
|
|
|
|
assert(i!=6);
|
|
|
|
|
if (hneed[i]<0) {
|
|
|
|
|
int p;
|
|
|
|
|
int k = rand() % left;
|
|
|
|
|
for (p=0;p!=6;++p) if (hneed[p]>0) {
|
|
|
|
|
k-=hneed[p];
|
|
|
|
|
if (k<0) break;
|
|
|
|
|
}
|
|
|
|
|
assert(p!=6);
|
|
|
|
|
hneed[p]--;
|
|
|
|
|
hneed[i]++;
|
|
|
|
|
left--;
|
|
|
|
|
rsetherbtype(r, htypes[p]);
|
2001-02-09 20:52:59 +01:00
|
|
|
|
}
|
2001-02-25 20:31:40 +01:00
|
|
|
|
hsum++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i=0;i!=6;++i) herbs[i] = 0;
|
|
|
|
|
|
|
|
|
|
for (r=regions; r; r=r->next) if (rterrain(r) == T_PLAIN) {
|
|
|
|
|
const herb_type *htype = rherbtype(r);
|
|
|
|
|
assert(htype);
|
|
|
|
|
for (i=0;i!=6;++i) if (htypes[i]==htype) break;
|
|
|
|
|
assert(i!=6);
|
|
|
|
|
herbs[i]++;
|
|
|
|
|
}
|
|
|
|
|
for (i=0;i!=6;++i) {
|
|
|
|
|
fprintf(stderr, "%s : %d\n", locale_string(NULL, resourcename(htypes[i]->itype->rtype, 0)), herbs[i]);
|
2001-02-09 20:52:59 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-09-05 21:40:40 +02:00
|
|
|
|
#endif
|
2001-02-09 20:52:59 +01:00
|
|
|
|
|
2001-02-25 20:31:40 +01:00
|
|
|
|
#include <event.h>
|
|
|
|
|
#include <triggers/timeout.h>
|
|
|
|
|
#include <triggers/changerace.h>
|
|
|
|
|
#include <triggers/changefaction.h>
|
|
|
|
|
#include <triggers/createcurse.h>
|
|
|
|
|
#include <triggers/createunit.h>
|
|
|
|
|
#include <triggers/killunit.h>
|
|
|
|
|
#include <triggers/giveitem.h>
|
|
|
|
|
|
|
|
|
|
typedef struct handler_info {
|
|
|
|
|
char * event;
|
|
|
|
|
trigger * triggers;
|
|
|
|
|
} handler_info;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct timeout_data {
|
|
|
|
|
trigger * triggers;
|
|
|
|
|
int timer;
|
|
|
|
|
variant trigger_data;
|
|
|
|
|
} timeout_data;
|
|
|
|
|
|
|
|
|
|
trigger *
|
|
|
|
|
get_timeout(trigger * td, trigger * tfind)
|
|
|
|
|
{
|
|
|
|
|
trigger * t = td;
|
|
|
|
|
while (t) {
|
|
|
|
|
if (t->type==&tt_timeout) {
|
|
|
|
|
timeout_data * tdata = (timeout_data *)t->data.v;
|
|
|
|
|
trigger * tr = tdata->triggers;
|
|
|
|
|
while (tr) {
|
|
|
|
|
if (tr==tfind) break;
|
|
|
|
|
tr=tr->next;
|
|
|
|
|
}
|
|
|
|
|
if (tr==tfind) break;
|
|
|
|
|
}
|
|
|
|
|
t=t->next;
|
|
|
|
|
}
|
|
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-01 08:58:45 +02:00
|
|
|
|
#include <modules/gmcmd.h>
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
secondfaction(faction * pf)
|
|
|
|
|
{
|
|
|
|
|
unit * u = findunit(atoi36("5q9w"));
|
|
|
|
|
if (u!=NULL) {
|
|
|
|
|
plane * p = rplane(u->region);
|
|
|
|
|
if (p!=NULL) {
|
|
|
|
|
region * center = findregion((p->maxx-p->minx)/2, (p->maxy-p->miny)/2);
|
|
|
|
|
if (center!=NULL) {
|
|
|
|
|
gm_addfaction(pf->email, p, center);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
- 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
|
|
|
|
static void
|
|
|
|
|
update_gmquests(void)
|
|
|
|
|
{
|
2001-09-05 21:40:40 +02:00
|
|
|
|
faction * f = findfaction(atoi36("gm04"));
|
- 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
|
|
|
|
if (f) {
|
|
|
|
|
unit * u = f->units;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
potion_t p;
|
|
|
|
|
attrib * permissions = a_find(f->attribs, &at_permissions);
|
|
|
|
|
|
2001-09-05 21:40:40 +02:00
|
|
|
|
if (u!=NULL) {
|
|
|
|
|
plane * p = rplane(u->region);
|
2002-03-12 21:48:10 +01:00
|
|
|
|
/* gm04 will keine Orks */
|
2001-09-05 21:40:40 +02:00
|
|
|
|
if (p!=NULL) p->flags |= PFL_NOORCGROWTH;
|
2002-03-12 21:48:10 +01:00
|
|
|
|
/* gm04 will keine Monster */
|
|
|
|
|
if (p!=NULL) p->flags |= PFL_NOMONSTERS;
|
2001-09-05 21:40:40 +02:00
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
for (p=0;p!=MAX_POTIONS;++p) {
|
2002-05-09 13:10:39 +02:00
|
|
|
|
attrib * a = a_find((attrib*)permissions->data.v, &at_gmcreate);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
while (a && a->data.v!=(void*)oldpotiontype[p]->itype) a=a->nexttype;
|
|
|
|
|
if (!a) a_add((attrib**)&permissions->data.v, make_atgmcreate(oldpotiontype[p]->itype));
|
|
|
|
|
}
|
2002-03-12 21:48:10 +01:00
|
|
|
|
do_once("et02", secondfaction(f));
|
- 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
|
|
|
|
}
|
2003-01-19 10:10:28 +01:00
|
|
|
|
do_once("renm", fix_foreign());
|
- 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-04-16 16:34:19 +02:00
|
|
|
|
#define TEST_LOCALES 0
|
|
|
|
|
#if TEST_LOCALES
|
|
|
|
|
static void
|
2001-09-05 21:40:40 +02:00
|
|
|
|
setup_locales(void)
|
2001-04-16 16:34:19 +02:00
|
|
|
|
{
|
|
|
|
|
locale * lang = find_locale("en");
|
|
|
|
|
faction * f = factions;
|
|
|
|
|
while (f) {
|
|
|
|
|
f->locale = lang;
|
|
|
|
|
f = f->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-04-22 20:14:07 +02:00
|
|
|
|
#include <triggers/shock.h>
|
|
|
|
|
#include <triggers/killunit.h>
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2001-12-15 13:26:04 +01:00
|
|
|
|
#if RESOURCE_CONVERSION
|
2001-12-10 01:13:39 +01:00
|
|
|
|
extern struct attrib_type at_resources;
|
|
|
|
|
void
|
|
|
|
|
init_resourcefix(void)
|
|
|
|
|
{
|
|
|
|
|
at_register(&at_resources);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-12-15 13:26:04 +01:00
|
|
|
|
#if GROWING_TREES
|
2001-12-10 01:13:39 +01:00
|
|
|
|
int
|
|
|
|
|
growing_trees(void)
|
|
|
|
|
{
|
|
|
|
|
region *r;
|
|
|
|
|
|
|
|
|
|
for(r=regions; r; r=r->next) {
|
|
|
|
|
if(rtrees(r, 2)) {
|
|
|
|
|
rsettrees(r, 1, rtrees(r, 2)/4);
|
|
|
|
|
rsettrees(r, 0, rtrees(r, 2)/2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2001-09-05 21:40:40 +02:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#include <triggers/gate.h>
|
|
|
|
|
#include <triggers/unguard.h>
|
|
|
|
|
typedef struct gate_data {
|
|
|
|
|
struct building * gate;
|
|
|
|
|
struct region * target;
|
|
|
|
|
} gate_data;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fix_gates(void)
|
|
|
|
|
{
|
|
|
|
|
region * r;
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
unit * u;
|
|
|
|
|
building * b;
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
trigger ** triggers = get_triggers(u->attribs, "timer");
|
|
|
|
|
if (triggers) {
|
|
|
|
|
trigger * t = *triggers;
|
|
|
|
|
while (t && t->type!= &tt_gate) t=t->next;
|
|
|
|
|
if (t!=NULL) {
|
|
|
|
|
gate_data * gd = (gate_data*)t->data.v;
|
|
|
|
|
struct building * b = gd->gate;
|
|
|
|
|
struct region * rtarget = gd->target;
|
|
|
|
|
if (r!=b->region) {
|
|
|
|
|
add_trigger(&b->attribs, "timer", trigger_gate(b, rtarget));
|
|
|
|
|
add_trigger(&b->attribs, "create", trigger_unguard(b));
|
|
|
|
|
fset(b, BLD_UNGUARDED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
remove_triggers(&u->attribs, "timer", &tt_gate);
|
|
|
|
|
remove_triggers(&u->attribs, "create", &tt_unguard);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (b=r->buildings;b;b=b->next) {
|
|
|
|
|
trigger ** triggers = get_triggers(b->attribs, "timer");
|
|
|
|
|
if (triggers) {
|
|
|
|
|
trigger * t = *triggers;
|
|
|
|
|
while (t && t->type!= &tt_gate) t=t->next;
|
|
|
|
|
if (t!=NULL) {
|
|
|
|
|
gate_data * gd = (gate_data*)t->data.v;
|
|
|
|
|
struct building * b = gd->gate;
|
|
|
|
|
struct region * rtarget = gd->target;
|
|
|
|
|
remove_triggers(&b->attribs, "timer", &tt_gate);
|
|
|
|
|
remove_triggers(&b->attribs, "create", &tt_unguard);
|
|
|
|
|
if (r!=b->region) {
|
|
|
|
|
add_trigger(&b->attribs, "timer", trigger_gate(b, rtarget));
|
|
|
|
|
add_trigger(&b->attribs, "create", trigger_unguard(b));
|
|
|
|
|
fset(b, BLD_UNGUARDED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-01-28 02:55:31 +01:00
|
|
|
|
static int
|
2002-01-28 01:25:32 +01:00
|
|
|
|
fix_astralplane(void)
|
|
|
|
|
{
|
2004-05-25 23:50:23 +02:00
|
|
|
|
plane * astralplane = get_astralplane();
|
2003-12-17 10:46:17 +01:00
|
|
|
|
region * r;
|
|
|
|
|
region_list * rlist = NULL;
|
2004-05-31 12:42:23 +02:00
|
|
|
|
faction * monsters = findfaction(MONSTER_FACTION);
|
|
|
|
|
|
|
|
|
|
if (astralplane==NULL || monsters==NULL) return 0;
|
|
|
|
|
|
|
|
|
|
freset(astralplane, PFL_NOCOORDS);
|
|
|
|
|
freset(astralplane, PFL_NOFEED);
|
|
|
|
|
set_ursprung(monsters, astralplane->id, 0, 0);
|
2003-12-17 10:46:17 +01:00
|
|
|
|
|
2004-05-25 23:50:23 +02:00
|
|
|
|
for (r=regions;r;r=r->next) if (rplane(r)==astralplane) {
|
2003-12-17 10:46:17 +01:00
|
|
|
|
region * ra = r_standard_to_astral(r);
|
|
|
|
|
if (ra==NULL) continue;
|
|
|
|
|
if (r->terrain!=T_FIREWALL) continue;
|
|
|
|
|
if (ra->terrain==T_ASTRALB) continue;
|
|
|
|
|
if (ra->units!=NULL) {
|
2004-02-21 13:18:29 +01:00
|
|
|
|
add_regionlist(&rlist, ra);
|
2003-12-17 10:46:17 +01:00
|
|
|
|
}
|
2004-05-26 08:24:22 +02:00
|
|
|
|
log_printf("protecting firewall in %s by blocking astral space in %s.\n", regionname(r, NULL), regionname(ra, NULL));
|
2003-12-17 10:46:17 +01:00
|
|
|
|
terraform(ra, T_ASTRALB);
|
|
|
|
|
}
|
2004-05-25 23:50:23 +02:00
|
|
|
|
while (rlist!=NULL) {
|
2003-12-17 10:46:17 +01:00
|
|
|
|
region_list * rnew = rlist;
|
|
|
|
|
region * r = rnew->data;
|
|
|
|
|
direction_t dir;
|
2003-12-17 18:30:10 +01:00
|
|
|
|
rlist = rlist->next;
|
2003-12-17 10:46:17 +01:00
|
|
|
|
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
|
|
|
|
region * rnext = rconnect(r, dir);
|
|
|
|
|
if (rnext==NULL) continue;
|
|
|
|
|
if (rnext->terrain!=T_ASTRAL) continue;
|
|
|
|
|
while (r->units) {
|
|
|
|
|
unit * u = r->units;
|
|
|
|
|
move_unit(u, rnext, NULL);
|
|
|
|
|
if (u->faction->no==MONSTER_FACTION) {
|
|
|
|
|
set_number(u, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (r->units!=NULL) {
|
|
|
|
|
unit * u;
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
if (u->faction->no!=MONSTER_FACTION) {
|
|
|
|
|
log_error(("Einheit %s in %u, %u steckt im Nebel fest.\n",
|
|
|
|
|
unitname(u), r->x, r->y));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
free(rnew);
|
|
|
|
|
}
|
2004-05-25 23:50:23 +02:00
|
|
|
|
return 0;
|
2002-02-18 22:41:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-03-09 16:16:35 +01:00
|
|
|
|
static int
|
|
|
|
|
warn_password(void)
|
|
|
|
|
{
|
|
|
|
|
faction * f = factions;
|
|
|
|
|
while (f) {
|
|
|
|
|
boolean pwok = true;
|
|
|
|
|
const char * c = f->passw;
|
|
|
|
|
while (*c) {
|
|
|
|
|
if (!isalnum(*c)) pwok = false;
|
|
|
|
|
c++;
|
|
|
|
|
}
|
|
|
|
|
if (pwok == false) {
|
2002-05-02 23:19:45 +02:00
|
|
|
|
ADDMSG(&f->msgs, msg_message("msg_errors", "string",
|
2002-03-09 16:16:35 +01:00
|
|
|
|
"Dein Passwort enth<74>lt Zeichen, die bei der Nachsendung "
|
|
|
|
|
"von Reports Probleme bereiten k<>nnen. Bitte w<>hle ein neues "
|
2002-03-10 11:09:16 +01:00
|
|
|
|
"Passwort, bevorzugt nur aus Buchstaben und Zahlen bestehend."));
|
2002-03-09 16:16:35 +01:00
|
|
|
|
}
|
|
|
|
|
f = f->next;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2002-04-28 17:37:48 +02:00
|
|
|
|
extern border *borders[];
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fix_road_borders(void)
|
|
|
|
|
{
|
2004-05-31 13:50:32 +02:00
|
|
|
|
border *deleted[10000];
|
|
|
|
|
int hash;
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
for(hash=0; hash<BMAXHASH; hash++) {
|
|
|
|
|
border * bhash;
|
|
|
|
|
for (bhash=borders[hash];bhash;bhash=bhash->nexthash) {
|
|
|
|
|
border * b;
|
|
|
|
|
for (b=bhash;b;b=b->next) {
|
|
|
|
|
if (b->type == &bt_road) {
|
|
|
|
|
int x1, x2, y1, y2;
|
|
|
|
|
region *r1, *r2;
|
|
|
|
|
|
|
|
|
|
x1 = b->from->x;
|
|
|
|
|
y1 = b->from->y;
|
|
|
|
|
x2 = b->to->x;
|
|
|
|
|
y2 = b->to->y;
|
|
|
|
|
|
|
|
|
|
r1 = findregion(x1, y1);
|
|
|
|
|
r2 = findregion(x2, y2);
|
|
|
|
|
|
|
|
|
|
if (r1->land == NULL || r2->land == NULL
|
|
|
|
|
|| terrain[r1->terrain].roadreq == 0
|
|
|
|
|
|| terrain[r2->terrain].roadreq == 0)
|
|
|
|
|
{
|
|
|
|
|
deleted[i++] = b;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-04-28 17:37:48 +02:00
|
|
|
|
|
2004-05-31 13:50:32 +02:00
|
|
|
|
while (i>0) {
|
|
|
|
|
i--;
|
|
|
|
|
erase_border(deleted[i]);
|
|
|
|
|
}
|
2002-04-28 17:37:48 +02:00
|
|
|
|
}
|
|
|
|
|
|
2003-12-12 18:17:13 +01:00
|
|
|
|
#ifdef WDW_PHOENIX
|
|
|
|
|
static region *
|
2003-12-16 02:05:16 +01:00
|
|
|
|
random_land_region(void)
|
2003-12-12 18:17:13 +01:00
|
|
|
|
{
|
|
|
|
|
region *r;
|
|
|
|
|
int c = 0;
|
|
|
|
|
|
|
|
|
|
/* count the available regions */
|
|
|
|
|
for(r=regions; r; r=r->next) {
|
2003-12-16 02:05:16 +01:00
|
|
|
|
if (r->land && rplane(r)==NULL) ++c;
|
2003-12-12 18:17:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* choose one */
|
|
|
|
|
c = rand()%c;
|
|
|
|
|
|
|
|
|
|
/* this is a bit obfuscated, but should be correct */
|
|
|
|
|
for(r=regions; c > 0; r=r->next) {
|
2003-12-16 02:05:16 +01:00
|
|
|
|
if (r->land && rplane(r)==NULL) --c;
|
2003-12-12 18:17:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return(r);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
check_phoenix(void)
|
|
|
|
|
{
|
|
|
|
|
const race * phoenix_race = rc_find("phoenix");
|
|
|
|
|
unit * phoenix;
|
|
|
|
|
region * r;
|
|
|
|
|
faction *f;
|
|
|
|
|
|
|
|
|
|
/* check if there is a phoenix in the world */
|
|
|
|
|
for(f=factions; f; f=f->next) {
|
|
|
|
|
unit *u;
|
|
|
|
|
|
|
|
|
|
for(u=f->units; u; u=u->nextF) {
|
|
|
|
|
if(u->race == phoenix_race) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* it is not, so we create it */
|
2003-12-15 20:33:16 +01:00
|
|
|
|
r = random_land_region();
|
2003-12-12 18:17:13 +01:00
|
|
|
|
phoenix = createunit(r, findfaction(MONSTER_FACTION), 1, phoenix_race);
|
2003-12-28 16:30:43 +01:00
|
|
|
|
phoenix->name = strdup("Der Ph<50>nix");
|
2003-12-12 18:17:13 +01:00
|
|
|
|
|
2003-12-28 16:30:43 +01:00
|
|
|
|
/* TODO: generate an appropriate region message */
|
2003-12-12 18:17:13 +01:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2004-02-13 20:14:38 +01:00
|
|
|
|
static void
|
|
|
|
|
fix_dissolve(unit * u, int value, char mode)
|
|
|
|
|
{
|
|
|
|
|
attrib * a = a_find(u->attribs, &at_unitdissolve);
|
2004-02-13 20:24:14 +01:00
|
|
|
|
|
2004-02-13 20:14:38 +01:00
|
|
|
|
if (a!=NULL) return;
|
|
|
|
|
a = a_add(&u->attribs, a_new(&at_unitdissolve));
|
|
|
|
|
a->data.ca[0] = mode;
|
2004-02-21 13:18:29 +01:00
|
|
|
|
a->data.ca[1] = (char)value;
|
2004-02-13 20:14:38 +01:00
|
|
|
|
log_warning(("unit %s has race %s and no dissolve-attrib\n", unitname(u), rc_name(u->race, 0)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
check_dissolve(void)
|
|
|
|
|
{
|
|
|
|
|
region * r;
|
|
|
|
|
for (r=regions;r!=NULL;r=r->next) {
|
|
|
|
|
unit * u;
|
2004-02-13 20:24:14 +01:00
|
|
|
|
for (u=r->units;u!=NULL;u=u->next) if (u->faction->no!=MONSTER_FACTION) {
|
2004-02-13 20:14:38 +01:00
|
|
|
|
if (u->race==new_race[RC_STONEGOLEM]) {
|
|
|
|
|
fix_dissolve(u, STONEGOLEM_CRUMBLE, 0);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (u->race==new_race[RC_IRONGOLEM]) {
|
|
|
|
|
fix_dissolve(u, IRONGOLEM_CRUMBLE, 0);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (u->race==new_race[RC_PEASANT]) {
|
|
|
|
|
fix_dissolve(u, 15, 1);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (u->race==new_race[RC_TREEMAN]) {
|
|
|
|
|
fix_dissolve(u, 5, 2);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
void
|
|
|
|
|
korrektur(void)
|
|
|
|
|
{
|
2004-02-13 20:14:38 +01:00
|
|
|
|
check_dissolve();
|
2003-05-13 17:43:18 +02:00
|
|
|
|
french_testers();
|
2001-04-16 16:34:19 +02:00
|
|
|
|
#if TEST_LOCALES
|
|
|
|
|
setup_locales();
|
2002-02-03 03:36:12 +01:00
|
|
|
|
#endif
|
2002-01-28 01:25:32 +01:00
|
|
|
|
fix_astralplane();
|
2001-09-05 21:40:40 +02:00
|
|
|
|
fix_firewalls();
|
2001-12-10 01:13:39 +01:00
|
|
|
|
fix_gates();
|
2001-05-11 22:19:22 +02:00
|
|
|
|
update_gms();
|
2001-02-13 00:06:44 +01:00
|
|
|
|
verify_owners(false);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* fix_herbtypes(); */
|
2003-09-28 10:05:50 +02:00
|
|
|
|
/* In Vin3 k<>nnen Parteien komplett <20>bergeben werden. */
|
|
|
|
|
#ifdef ENHANCED_QUIT
|
|
|
|
|
no_teurefremde(0);
|
|
|
|
|
#else
|
2003-10-05 09:29:31 +02:00
|
|
|
|
no_teurefremde(1);
|
2003-09-28 10:05:50 +02:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fix_allies();
|
- 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
|
|
|
|
update_gmquests(); /* test gm quests */
|
2001-12-10 01:13:39 +01:00
|
|
|
|
/* fix_unitrefs(); */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
stats();
|
2002-03-09 16:16:35 +01:00
|
|
|
|
warn_password();
|
2002-04-28 17:37:48 +02:00
|
|
|
|
fix_road_borders();
|
2002-10-08 08:48:47 +02:00
|
|
|
|
if (turn>1000) curse_emptiness(); /*** disabled ***/
|
2002-09-02 22:36:12 +02:00
|
|
|
|
#ifdef ALLIANCES
|
2002-09-29 23:20:04 +02:00
|
|
|
|
/* init_alliances(); */
|
2002-09-02 22:36:12 +02:00
|
|
|
|
#endif
|
2002-05-02 23:19:45 +02:00
|
|
|
|
/* seems something fishy is going on, do this just
|
|
|
|
|
* to be on the safe side:
|
2002-02-06 09:06:02 +01:00
|
|
|
|
*/
|
|
|
|
|
fix_demand();
|
2003-12-12 18:17:13 +01:00
|
|
|
|
/* trade_orders(); */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* immer ausf<73>hren, wenn neue Spr<70>che dazugekommen sind, oder sich
|
|
|
|
|
* Beschreibungen ge<EFBFBD>ndert haben */
|
|
|
|
|
show_newspells();
|
|
|
|
|
fix_age();
|
|
|
|
|
|
|
|
|
|
/* Immer ausf<73>hren! Erschafft neue Teleport-Regionen, wenn n<>tig */
|
|
|
|
|
create_teleport_plane();
|
|
|
|
|
|
2003-12-12 18:17:13 +01:00
|
|
|
|
#ifdef WDW_PHOENIX
|
|
|
|
|
check_phoenix();
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (global.data_version<TYPES_VERSION) fix_icastles();
|
|
|
|
|
#ifdef FUZZY_BASE36
|
|
|
|
|
enable_fuzzy = true;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
korrektur_end(void)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
init_conversion(void)
|
|
|
|
|
{
|
|
|
|
|
}
|