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>
|
2005-02-06 09:23:28 +01:00
|
|
|
|
#include <attributes/otherfaction.h>
|
2002-04-27 21:40:31 +02:00
|
|
|
|
#include <modules/xecmd.h>
|
2005-04-11 23:49:30 +02:00
|
|
|
|
#include <modules/autoseed.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* gamecode includes */
|
2004-06-27 18:56:01 +02:00
|
|
|
|
#include <gamecode/economy.h>
|
|
|
|
|
#include <gamecode/monster.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* kernel includes */
|
2004-06-27 18:56:01 +02:00
|
|
|
|
#include <kernel/alchemy.h>
|
|
|
|
|
#include <kernel/alliance.h>
|
|
|
|
|
#include <kernel/border.h>
|
|
|
|
|
#include <kernel/building.h>
|
|
|
|
|
#include <kernel/faction.h>
|
|
|
|
|
#include <kernel/item.h>
|
|
|
|
|
#include <kernel/magic.h>
|
|
|
|
|
#include <kernel/message.h>
|
|
|
|
|
#include <kernel/movement.h>
|
|
|
|
|
#include <kernel/names.h>
|
|
|
|
|
#include <kernel/pathfinder.h>
|
|
|
|
|
#include <kernel/plane.h>
|
|
|
|
|
#include <kernel/pool.h>
|
|
|
|
|
#include <kernel/race.h>
|
|
|
|
|
#include <kernel/region.h>
|
|
|
|
|
#include <kernel/reports.h>
|
|
|
|
|
#include <kernel/resources.h>
|
|
|
|
|
#include <kernel/ship.h>
|
|
|
|
|
#include <kernel/skill.h>
|
|
|
|
|
#include <kernel/spell.h>
|
|
|
|
|
#include <kernel/study.h>
|
|
|
|
|
#include <kernel/teleport.h>
|
|
|
|
|
#include <kernel/unit.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>
|
2004-08-08 13:14:45 +02:00
|
|
|
|
#include <util/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);
|
2005-01-03 22:28:57 +01:00
|
|
|
|
extern int incomplete_data;
|
2001-02-13 00:06:44 +01:00
|
|
|
|
|
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) {
|
2005-06-10 00:10:35 +02:00
|
|
|
|
variant effect;
|
|
|
|
|
curse * c;
|
|
|
|
|
effect.i = 0;
|
|
|
|
|
c = create_curse(NULL, &r->attribs, ct, 100, 100, effect, 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) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * bo = shipowner(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)
|
|
|
|
|
{
|
2004-10-15 20:01:14 +02:00
|
|
|
|
const curse_type * slave_ct = ct_find("slavery");
|
2004-06-27 18:56:01 +02:00
|
|
|
|
region *r;
|
|
|
|
|
|
|
|
|
|
for(r=regions;r;r=r->next) {
|
|
|
|
|
unit *u;
|
|
|
|
|
|
|
|
|
|
for(u=r->units;u;u=u->next) {
|
2004-10-15 20:01:14 +02:00
|
|
|
|
if (u->faction->no != MONSTER_FACTION && playerrace(u->faction->race)
|
2004-06-27 18:56:01 +02:00
|
|
|
|
&& is_migrant(u) && kor_teure_talente(u))
|
|
|
|
|
{
|
2004-10-15 20:01:14 +02:00
|
|
|
|
if (slave_ct && curse_active(get_curse(u->attribs, slave_ct)))
|
|
|
|
|
continue;
|
2004-06-27 18:56:01 +02:00
|
|
|
|
log_warning(("Teurer Migrant: %s, Partei %s\n",
|
|
|
|
|
unitname(u), factionname(u->faction)));
|
|
|
|
|
if (convert) {
|
|
|
|
|
u->race = u->faction->race;
|
|
|
|
|
u->irace = u->faction->race;
|
|
|
|
|
u->faction->num_migrants -= u->number;
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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-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",
|
2005-01-19 21:33:13 +01:00
|
|
|
|
regionname(r, NULL), regionname(r2, NULL)));
|
2004-05-31 13:50:32 +02:00
|
|
|
|
b = get_borders(r, r2);
|
|
|
|
|
} else {
|
|
|
|
|
b = b->next;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
b = b->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
r = r->next;
|
|
|
|
|
}
|
2001-09-05 21:40:40 +02:00
|
|
|
|
}
|
|
|
|
|
|
2005-02-05 20:05:47 +01:00
|
|
|
|
static void
|
|
|
|
|
fix_otherfaction(void)
|
|
|
|
|
{
|
|
|
|
|
int count = 0;
|
|
|
|
|
region * r;
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
unit * u;
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
attrib * a = a_find(u->attribs, &at_otherfaction);
|
2005-02-06 09:23:28 +01:00
|
|
|
|
if (a!=NULL) {
|
|
|
|
|
faction * f = (faction*)a->data.v;
|
|
|
|
|
if (f==u->faction) {
|
|
|
|
|
a_remove(&u->attribs, a);
|
|
|
|
|
++count;
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-02-05 20:05:47 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2005-02-06 09:23:28 +01:00
|
|
|
|
if (count) log_warning(("%u units had otherfaction=own faction.\n", count));
|
2005-02-05 20:05:47 +01: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
|
|
|
|
static int
|
2005-04-11 23:49:30 +02:00
|
|
|
|
fix_demands(void)
|
2001-02-03 14:45:35 +01:00
|
|
|
|
{
|
2005-04-11 23:49:30 +02:00
|
|
|
|
region *r;
|
2001-02-03 14:45:35 +01:00
|
|
|
|
|
2005-04-11 23:49:30 +02:00
|
|
|
|
for (r=regions; r; r=r->next) {
|
2005-04-12 00:11:02 +02:00
|
|
|
|
if (r->land!=NULL && r->land->demands==NULL) {
|
|
|
|
|
fix_demand(r);
|
2005-04-11 23:49:30 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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 <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
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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) {
|
2004-08-07 09:42:22 +02:00
|
|
|
|
if (!isalnum((unsigned char)*c)) pwok = false;
|
2002-03-09 16:16:35 +01:00
|
|
|
|
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)
|
|
|
|
|
{
|
2005-01-03 22:28:57 +01:00
|
|
|
|
#define MAXDEL 10000
|
|
|
|
|
border *deleted[MAXDEL];
|
2004-05-31 13:50:32 +02:00
|
|
|
|
int hash;
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
2005-01-03 22:28:57 +01:00
|
|
|
|
if (incomplete_data) return;
|
|
|
|
|
for(hash=0; hash<BMAXHASH && i!=MAXDEL; hash++) {
|
2004-05-31 13:50:32 +02:00
|
|
|
|
border * bhash;
|
2005-01-03 22:28:57 +01:00
|
|
|
|
for (bhash=borders[hash];bhash && i!=MAXDEL;bhash=bhash->nexthash) {
|
2004-05-31 13:50:32 +02:00
|
|
|
|
border * b;
|
2005-01-03 22:28:57 +01:00
|
|
|
|
for (b=bhash;b && i!=MAXDEL;b=b->next) {
|
2004-05-31 13:50:32 +02:00
|
|
|
|
if (b->type == &bt_road) {
|
2005-06-10 00:10:35 +02:00
|
|
|
|
short x1, x2, y1, y2;
|
2004-05-31 13:50:32 +02:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-14 00:16:12 +02:00
|
|
|
|
f = findfaction(MONSTER_FACTION);
|
|
|
|
|
if (f==NULL) return;
|
|
|
|
|
|
2003-12-12 18:17:13 +01:00
|
|
|
|
/* it is not, so we create it */
|
2003-12-15 20:33:16 +01:00
|
|
|
|
r = random_land_region();
|
2004-06-14 00:16:12 +02:00
|
|
|
|
phoenix = createunit(r, f, 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-16 17:55:16 +02:00
|
|
|
|
static int
|
|
|
|
|
fix_familiars(void)
|
|
|
|
|
{
|
2005-04-16 18:59:08 +02:00
|
|
|
|
const struct locale * lang = find_locale("en");
|
2005-04-16 17:55:16 +02:00
|
|
|
|
region * r;
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
unit * u;
|
|
|
|
|
for (u=r->units;u;u=u->next) if (u->faction->no!=MONSTER_FACTION) {
|
2005-04-16 18:59:08 +02:00
|
|
|
|
if (u->race->init_familiar && u->race->maintenance==0) {
|
2005-04-16 17:55:16 +02:00
|
|
|
|
/* this is a familiar */
|
|
|
|
|
unit * mage = get_familiar_mage(u);
|
|
|
|
|
if (mage==0) {
|
2005-04-16 18:59:08 +02:00
|
|
|
|
log_error(("%s is a %s familiar with no mage for faction %s\n",
|
|
|
|
|
unitid(u), racename(lang, u, u->race),
|
2005-04-16 18:44:00 +02:00
|
|
|
|
factionid(u->faction)));
|
2005-04-16 17:55:16 +02:00
|
|
|
|
} else if (!is_mage(mage)) {
|
2005-04-16 18:59:08 +02:00
|
|
|
|
log_error(("%s is a %s familiar, but %s is not a mage for faction %s\n",
|
|
|
|
|
unitid(u), racename(lang, u, u->race), unitid(mage),
|
2005-04-16 18:44:00 +02:00
|
|
|
|
factionid(u->faction)));
|
2005-04-16 17:55:16 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-30 21:00:57 +02:00
|
|
|
|
#define REPORT_NR (1 << O_REPORT)
|
|
|
|
|
#define REPORT_CR (1 << O_COMPUTER)
|
|
|
|
|
#define REPORT_ZV (1 << O_ZUGVORLAGE)
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
disable_templates(void)
|
|
|
|
|
{
|
|
|
|
|
faction * f;
|
|
|
|
|
for (f=factions;f;f=f->next) {
|
|
|
|
|
if (f->options & REPORT_CR) {
|
|
|
|
|
f->options &= ~REPORT_ZV;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
nothing(void)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2005-06-12 01:02:52 +02:00
|
|
|
|
static int
|
|
|
|
|
fix_attribflags(void)
|
|
|
|
|
{
|
|
|
|
|
region * r;
|
|
|
|
|
for (r = regions; r; r=r->next) {
|
|
|
|
|
unit * u = r->units;
|
|
|
|
|
for (u=r->units;u!=NULL;u=u->next) {
|
2005-06-12 10:52:46 +02:00
|
|
|
|
const attrib *a = u->attribs;
|
2005-06-12 01:02:52 +02:00
|
|
|
|
while (a) {
|
2005-06-12 01:10:06 +02:00
|
|
|
|
if (a->type==&at_guard) {
|
2005-06-12 01:02:52 +02:00
|
|
|
|
fset(u, UFL_GUARD);
|
2005-06-12 11:48:19 +02:00
|
|
|
|
break;
|
2005-06-12 01:02:52 +02:00
|
|
|
|
}
|
|
|
|
|
a = a->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-06-12 01:10:06 +02:00
|
|
|
|
return 0;
|
2005-06-12 01:02:52 +02:00
|
|
|
|
}
|
|
|
|
|
|
2005-05-07 00:30:19 +02:00
|
|
|
|
static int
|
|
|
|
|
fix_chaosgates(void)
|
|
|
|
|
{
|
|
|
|
|
region * r;
|
|
|
|
|
for (r = regions; r; r=r->next) {
|
|
|
|
|
const attrib *a = a_findc(r->attribs, &at_direction);
|
|
|
|
|
|
|
|
|
|
while (a!=NULL) {
|
|
|
|
|
spec_direction * sd = (spec_direction *)a->data.v;
|
|
|
|
|
region * r2 = findregion(sd->x, sd->y);
|
|
|
|
|
border * b = get_borders(r, r2);
|
|
|
|
|
while (b) {
|
|
|
|
|
if (b->type==&bt_chaosgate) break;
|
|
|
|
|
b = b->next;
|
|
|
|
|
}
|
|
|
|
|
if (b==NULL) {
|
|
|
|
|
b = new_border(&bt_chaosgate, r, r2);
|
|
|
|
|
}
|
|
|
|
|
a = a->nexttype;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
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
|
2005-04-30 21:00:57 +02:00
|
|
|
|
if (turn>400) {
|
|
|
|
|
do_once("zvrm", disable_templates());
|
|
|
|
|
} else {
|
|
|
|
|
do_once("zvrm", nothing());
|
|
|
|
|
}
|
|
|
|
|
|
2005-05-07 00:30:19 +02:00
|
|
|
|
do_once("chgt", fix_chaosgates());
|
2005-06-12 01:02:52 +02:00
|
|
|
|
do_once("attr", fix_attribflags());
|
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(); */
|
2004-06-27 18:56:01 +02:00
|
|
|
|
/* In Vin 3+ k<>nnen Parteien komplett <20>bergeben werden. */
|
|
|
|
|
if (!ExpensiveMigrants()) {
|
|
|
|
|
no_teurefremde(true);
|
|
|
|
|
}
|
2005-04-11 23:49:30 +02:00
|
|
|
|
fix_allies();
|
|
|
|
|
update_gmquests(); /* test gm quests */
|
|
|
|
|
/* fix_unitrefs(); */
|
|
|
|
|
warn_password();
|
|
|
|
|
fix_road_borders();
|
|
|
|
|
if (turn>1000) curse_emptiness(); /*** disabled ***/
|
|
|
|
|
/* seems something fishy is going on, do this just
|
|
|
|
|
* to be on the safe side:
|
|
|
|
|
*/
|
|
|
|
|
fix_demands();
|
2005-02-05 20:05:47 +01:00
|
|
|
|
fix_otherfaction();
|
2005-04-16 17:55:16 +02:00
|
|
|
|
fix_familiars();
|
2005-04-11 23:49:30 +02:00
|
|
|
|
/* trade_orders(); */
|
|
|
|
|
|
|
|
|
|
/* 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
|
|
|
|
|
}
|