diff --git a/src/common/attributes/attributes.vcproj b/src/common/attributes/attributes.vcproj
index 68b3a41a4..4271a2097 100644
--- a/src/common/attributes/attributes.vcproj
+++ b/src/common/attributes/attributes.vcproj
@@ -114,6 +114,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c
index bc0013960..86ccec792 100644
--- a/src/common/gamecode/economy.c
+++ b/src/common/gamecode/economy.c
@@ -1771,7 +1771,13 @@ buy(unit * u, request ** buyorders, struct order * ord)
}
} else {
/* ...oder in der Region muß es eine Burg geben. */
- if (!rbuildings(r)) {
+ building * b;
+ static const struct building_type * bt_castle;
+ if (!bt_castle) bt_castle = bt_find("castle");
+ for (b=r->buildings;b;b=b->next) {
+ if (b->type==bt_castle && b->size>2) break;
+ }
+ if (b==NULL) {
cmistake(u, ord, 119, MSG_COMMERCE);
return;
}
@@ -2568,6 +2574,11 @@ steal_cmd(unit * u, struct order * ord, request ** stealorders)
region * r = u->region;
faction * f = NULL;
+ if (rterrain(r) == T_OCEAN && u->race != new_race[RC_AQUARIAN]) {
+ cmistake(u, ord, 242, MSG_INCOME);
+ return;
+ }
+
if (r->planep && fval(r->planep, PFL_NOATTACK)) {
cmistake(u, ord, 270, MSG_INCOME);
return;
diff --git a/src/common/gamecode/gamecode.vcproj b/src/common/gamecode/gamecode.vcproj
index 68365ba2a..7fd0e6863 100644
--- a/src/common/gamecode/gamecode.vcproj
+++ b/src/common/gamecode/gamecode.vcproj
@@ -72,12 +72,12 @@
ATLMinimizesCRunTimeLibraryUsage="FALSE">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c
index 60de80e2c..b82e759f2 100644
--- a/src/common/kernel/eressea.c
+++ b/src/common/kernel/eressea.c
@@ -1862,6 +1862,7 @@ createunitid(unit *u, int id)
unit *
createunit(region * r, faction * f, int number, const struct race * rc)
{
+ assert(rc);
return create_unit(r, f, number, rc, 0, NULL, NULL);
}
@@ -1870,6 +1871,7 @@ create_unit(region * r, faction * f, int number, const struct race *urace, int i
{
unit * u = calloc(1, sizeof(unit));
+ assert(urace);
assert(f->alive);
u_setfaction(u, f);
set_order(&u->thisorder, NULL);
diff --git a/src/common/kernel/faction.c b/src/common/kernel/faction.c
index 87aa27029..10dd7ab59 100644
--- a/src/common/kernel/faction.c
+++ b/src/common/kernel/faction.c
@@ -96,7 +96,7 @@ addfaction(const char *email, const char * password,
int i;
faction * f = calloc(sizeof(faction), 1);
- assert(frace != new_race[RC_ORC]);
+ assert(frace && frace != new_race[RC_ORC]);
if (set_email(&f->email, email)!=0) {
log_error(("Invalid email address for faction %s: %s\n", itoa36(f->no), email));
diff --git a/src/common/kernel/kernel.vcproj b/src/common/kernel/kernel.vcproj
index 51bcf4db3..eff2bfdf9 100644
--- a/src/common/kernel/kernel.vcproj
+++ b/src/common/kernel/kernel.vcproj
@@ -19,12 +19,12 @@
ATLMinimizesCRunTimeLibraryUsage="FALSE">
units; u; u=u->next) {
- if (get_keyword(u->thisorder) == K_DRIVE && !fval(u, UFL_LONGACTION) && !LongHunger(u)) {
+ if (get_keyword(u->thisorder) == K_DRIVE && can_move(u) && !fval(u, UFL_LONGACTION) && !LongHunger(u)) {
unit * ut;
init_tokens(u->thisorder);
@@ -980,7 +980,7 @@ init_transportation(void)
ut = getunit(r, u->faction);
if (ut==NULL) continue;
- if (get_keyword(ut->thisorder) == K_DRIVE && !fval(ut, UFL_LONGACTION) && !LongHunger(ut)) {
+ if (get_keyword(ut->thisorder) == K_DRIVE && can_move(u) && !fval(ut, UFL_LONGACTION) && !LongHunger(ut)) {
init_tokens(ut->thisorder);
skip_token();
if (getunit(r, ut->faction) == u) {
@@ -1800,7 +1800,7 @@ travel_i(unit * u, region_list * route_begin, region_list * route_end, order * o
ut = getunit(r, u->faction);
if (ut!=NULL) {
boolean found = false;
- if (get_keyword(ut->thisorder) == K_DRIVE) {
+ if (get_keyword(ut->thisorder) == K_DRIVE && can_move(ut)) {
if (!fval(ut, UFL_LONGACTION) && !LongHunger(ut)) {
init_tokens(ut->thisorder);
skip_token();
diff --git a/src/common/kernel/spell.c b/src/common/kernel/spell.c
index 99956958c..fbdeb474b 100644
--- a/src/common/kernel/spell.c
+++ b/src/common/kernel/spell.c
@@ -9717,7 +9717,7 @@ static spell spelldaten[] =
SPL_ENTERASTRAL, "Astraler Weg",
"Alte arkane Formeln ermöglichen es dem Magier, sich und andere in die "
"astrale Ebene zu bringen. Der Magier kann (Stufe-3)*15 GE durch das "
- "kurzzeitig entstehende Tor bringen. Ist der Magier erfahren genug, "
+ "kurzzeitig entstehende Tor schicken. Ist der Magier erfahren genug, "
"den Zauber auf Stufen von 11 oder mehr zu zaubern, kann er andere "
"Einheiten auch gegen ihren Willen auf die andere Ebene zwingen.", NULL,
"u+",
diff --git a/src/common/modules/autoseed.c b/src/common/modules/autoseed.c
index 05bb9819d..8ace91d9e 100644
--- a/src/common/modules/autoseed.c
+++ b/src/common/modules/autoseed.c
@@ -228,79 +228,177 @@ preferred_terrain(const struct race * rc)
}
#define REGIONS_PER_FACTION 2
+#define PLAYERS_PER_ISLAND 20
+#define TURNS_PER_ISLAND 3
#define MINFACTIONS 1
#define MAXAGEDIFF 5
#define VOLCANO_CHANCE 100
+static boolean
+virgin_region(const region * r)
+{
+ direction_t d;
+ if (r==NULL) return true;
+ if (r->age>MAXAGEDIFF) return false;
+ if (r->units) return false;
+ for (d=0;d!=MAXDIRECTIONS;++d) {
+ const region * rn = rconnect(r, d);
+ if (rn) {
+ if (rn->age>MAXAGEDIFF) return false;
+ if (rn->units) return false;
+ }
+ }
+ return true;
+}
+
+void
+get_island(region * root, region_list ** rlist)
+{
+ region_list ** rnext = rlist;
+ while (*rnext) rnext=&(*rnext)->next;
+
+ fset(root, FL_MARK);
+ add_regionlist(rnext, root);
+
+ while (*rnext) {
+ direction_t dir;
+
+ region * rcurrent = (*rnext)->data;
+ rnext = &(*rnext)->next;
+
+ for (dir=0;dir!=MAXDIRECTIONS;++dir) {
+ region * r = rconnect(rcurrent, dir);
+ if (r!=NULL && r->land && !fval(r, FL_MARK)) {
+ fset(r, FL_MARK);
+ add_regionlist(rnext, r);
+ }
+ }
+ }
+ rnext=rlist;
+ while (*rnext) {
+ region_list * rptr = *rnext;
+ freset(rptr->data, FL_MARK);
+ rnext = &rptr->next;
+ }
+}
+
+/** create new island with up to nsize players
+ * returns the number of players placed on the new island.
+ */
int
autoseed(newfaction ** players, int nsize)
{
int x = 0, y = 0;
- region * r;
+ region * r = NULL;
region_list * rlist = NULL;
- int rsize, isize=0;
- region * rmin = NULL;
- direction_t d;
- int dist;
-
- for (r=regions;r;r=r->next) {
- struct plane * p = rplane(r);
- if (r->terrain==T_OCEAN && p==NULL && (rmin==NULL || r->age<=MAXAGEDIFF)) {
- direction_t d;
- for (d=0;d!=MAXDIRECTIONS;++d) {
- if (rconnect(r, d)==NULL) break;
- }
- if (d!=MAXDIRECTIONS) rmin=r;
- }
- }
- r = NULL;
- for (dist=1;r!=rmin;++dist) {
- for (d=0;r!=rmin && d!=MAXDIRECTIONS;++d) {
- int i;
- region * rn = rmin;
- for (i=0;i!=dist;++i) rn=rconnect(rn, d);
- if (rn==NULL) {
- r = rmin;
- x = rmin->x + delta_x[d] * dist;
- y = rmin->y + delta_y[d] * dist;
- }
- }
- }
+ int rsize, tsize = 0;
+ int isize = REGIONS_PER_FACTION; /* target size for the island */
+ int psize = 0; /* players on this island */
if (listlen(*players)next) {
+ struct plane * p = rplane(r);
+ if (r->terrain==T_OCEAN && p==NULL && virgin_region(r)) {
+ direction_t d;
+ for (d=0;d!=MAXDIRECTIONS;++d) {
+ region * rn = rconnect(r, d);
+ if (rn && rn->land) break;
+ }
+ if (d!=MAXDIRECTIONS) rmin = r;
+ }
+ }
+ if (rmin!=NULL) {
+ region_list * rlist = NULL, * rptr;
+ faction * f;
+ get_island(rmin, &rlist);
+ for (rptr=rlist;rptr;rptr=rptr->next) {
+ region * r = rlist->data;
+ unit * u;
+ for (u=r->units;u;u->next) {
+ f = u->faction;
+ if (!fval(f, FL_MARK)) {
+ ++psize;
+ fset(f, FL_MARK);
+ }
+ }
+ }
+ free_regionlist(rlist);
+ if (psize>0) for (f=factions;f;f=f->next) freset(f, FL_MARK);
+ if (psizenext) {
+ struct plane * p = rplane(r);
+ if (r->terrain==T_OCEAN && p==NULL && (rmin==NULL || r->age<=MAXAGEDIFF)) {
+ direction_t d;
+ for (d=0;d!=MAXDIRECTIONS;++d) {
+ if (rconnect(r, d)==NULL) break;
+ }
+ if (d!=MAXDIRECTIONS) {
+ rmin=r;
+ dmin=d;
+ }
+ }
+ }
+
+ /* create a new region where we found the empty spot, and make it the first
+ * in our island. island regions are kept in rlist, so only new regions can
+ * get populated, and old regions are not overwritten */
+ if (rmin!=NULL) {
+ assert(virgin_region(rconnect(rmin, dmin)));
+ x = rmin->x + delta_x[dmin];
+ y = rmin->y + delta_y[dmin];
+ }
+ r = new_region(x, y);
+ terraform(r, T_OCEAN); /* we change the terrain later */
+ }
+
+ add_regionlist(&rlist, r);
+ rsize = 1;
+
+ while (rsize && (nsize || isize>=REGIONS_PER_FACTION)) {
int i = rand() % rsize;
region_list ** rnext = &rlist;
direction_t d;
while (i--) rnext=&(*rnext)->next;
r = (*rnext)->data;
*rnext = (*rnext)->next;
- if (rsize==0) {
- log_error(("Could not place all factions on the same island as requested\n"));
- break;
- }
--rsize;
- assert(r->terrain==T_OCEAN);
for (d=0;d!=MAXDIRECTIONS;++d) {
region * rn = rconnect(r, d);
- if (rn==NULL) {
- rn = new_region(r->x + delta_x[d], r->y + delta_y[d]);
- terraform(rn, T_OCEAN);
+ if (virgin_region(rn)) {
+ if (rn==NULL) {
+ rn = new_region(r->x + delta_x[d], r->y + delta_y[d]);
+ terraform(rn, T_OCEAN);
+ }
add_regionlist(&rlist, rn);
++rsize;
}
}
if (rand() % VOLCANO_CHANCE == 0) {
terraform(r, T_VOLCANO);
- } else if (rand() % REGIONS_PER_FACTION == 0 || rsize==0) {
+ } else if (nsize && (rand() % isize == 0 || rsize==0)) {
newfaction ** nfp, * nextf = *players;
unit * u;
+
+ isize += REGIONS_PER_FACTION;
terraform(r, preferred_terrain(nextf->race));
- ++isize;
+ ++tsize;
u = addplayer(r, addfaction(nextf->email, nextf->password, nextf->race, nextf->lang,
nextf->subscription));
u->faction->alliance = nextf->allies;
@@ -315,13 +413,22 @@ autoseed(newfaction ** players, int nsize)
}
else nfp = &nf->next;
}
+ ++psize;
--nsize;
- }
- else {
+ --isize;
+ if (psize>=PLAYERS_PER_ISLAND) break;
+ } else {
terraform(r, (terrain_t)((rand() % T_GLACIER)+1));
+ --isize;
}
}
- if (rlist) {
+
+ if (nsize!=0) {
+ log_error(("Could not place all factions on the same island as requested\n"));
+ }
+
+
+ if (rlist) {
#define MINOCEANDIST 3
#define MAXFILLDIST 10
#define SPECIALCHANCE 80
@@ -378,5 +485,5 @@ autoseed(newfaction ** players, int nsize)
}
}
}
- return isize;
+ return tsize;
}
diff --git a/src/common/modules/autoseed.h b/src/common/modules/autoseed.h
index 6174f8c64..d53834f29 100644
--- a/src/common/modules/autoseed.h
+++ b/src/common/modules/autoseed.h
@@ -34,6 +34,7 @@ typedef struct newfaction {
extern int autoseed(newfaction ** players, int nsize);
extern newfaction * read_newfactions(const char * filename);
+extern void get_island(struct region * root, struct region_list ** rlist);
#ifdef __cplusplus
}
diff --git a/src/common/modules/modules.vcproj b/src/common/modules/modules.vcproj
index ca021c483..645fd988b 100644
--- a/src/common/modules/modules.vcproj
+++ b/src/common/modules/modules.vcproj
@@ -113,6 +113,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/common/races/races.vcproj b/src/common/races/races.vcproj
index e71ee63e4..4bb6cb9b7 100644
--- a/src/common/races/races.vcproj
+++ b/src/common/races/races.vcproj
@@ -113,6 +113,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/common/spells/spells.vcproj b/src/common/spells/spells.vcproj
index 3503cb2e7..10aceae66 100644
--- a/src/common/spells/spells.vcproj
+++ b/src/common/spells/spells.vcproj
@@ -113,6 +113,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/common/triggers/triggers.vcproj b/src/common/triggers/triggers.vcproj
index fb86affbd..f6ea99dc3 100644
--- a/src/common/triggers/triggers.vcproj
+++ b/src/common/triggers/triggers.vcproj
@@ -113,6 +113,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/common/util/util.vcproj b/src/common/util/util.vcproj
index bfae99d9c..c6a24cb18 100644
--- a/src/common/util/util.vcproj
+++ b/src/common/util/util.vcproj
@@ -71,12 +71,12 @@
ATLMinimizesCRunTimeLibraryUsage="FALSE">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/res/messages.xml b/src/res/messages.xml
index 5f1126437..cf7028fd5 100644
--- a/src/res/messages.xml
+++ b/src/res/messages.xml
@@ -4301,9 +4301,9 @@
- "$unit($unit) in $region($region): '$order($command)' - Ohne eine Burg gibt es keinen Markt."
- "$unit($unit) in $region($region): '$order($command)' - There is no market place without a castle."
- "$unit($unit) in $region($region): '$order($command)' - There is no market place without a castle."
+ "$unit($unit) in $region($region): '$order($command)' - Ohne einen Handelsposten gibt es keinen Markt."
+ "$unit($unit) in $region($region): '$order($command)' - There is no marketplace without at least a tradepost."
+ "$unit($unit) in $region($region): '$order($command)' - There is no marketplace without at least a tradepost."
diff --git a/src/scripts/eressea.lua b/src/scripts/eressea.lua
index 37d7f855a..4965ef8dd 100644
--- a/src/scripts/eressea.lua
+++ b/src/scripts/eressea.lua
@@ -65,10 +65,12 @@ function process(orders)
f = get_faction(atoi36(name))
if f ~= nil then
f.locale = loc
- print("LOCALECHANGE ", f, loc)
- end
+ print("LOCALECHANGE ", f, loc)
+ end
end
end
+
+ autoseed(basepath .. "/newfactions")
write_passwords()
write_reports()