forked from github/server
world generation algorithm for E3
This commit is contained in:
parent
27d8628084
commit
fa2072b6e0
4 changed files with 376 additions and 185 deletions
|
@ -1,6 +1,6 @@
|
||||||
/* vi: set ts=2:
|
/* vi: set ts=2:
|
||||||
*
|
*
|
||||||
* Eressea PB(E)M host Copyright (C) 1998-2003
|
* Eressea PB(E)M host Copyright (C) 1998-2003
|
||||||
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
||||||
* Katja Zedel (katze@felidae.kn-bremen.de)
|
* Katja Zedel (katze@felidae.kn-bremen.de)
|
||||||
* Henning Peters (faroul@beyond.kn-bremen.de)
|
* Henning Peters (faroul@beyond.kn-bremen.de)
|
||||||
|
@ -72,9 +72,9 @@ struct unit_list;
|
||||||
struct weapon_type;
|
struct weapon_type;
|
||||||
|
|
||||||
typedef struct ursprung {
|
typedef struct ursprung {
|
||||||
struct ursprung *next;
|
struct ursprung *next;
|
||||||
int id;
|
int id;
|
||||||
short x, y;
|
short x, y;
|
||||||
} ursprung;
|
} ursprung;
|
||||||
|
|
||||||
/* ----------------- Befehle ----------------------------------- */
|
/* ----------------- Befehle ----------------------------------- */
|
||||||
|
@ -169,80 +169,80 @@ enum {
|
||||||
|
|
||||||
typedef unsigned char param_t;
|
typedef unsigned char param_t;
|
||||||
enum {
|
enum {
|
||||||
P_LOCALE,
|
P_LOCALE,
|
||||||
P_ANY,
|
P_ANY,
|
||||||
P_EACH,
|
P_EACH,
|
||||||
P_PEASANT,
|
P_PEASANT,
|
||||||
P_BUILDING,
|
P_BUILDING,
|
||||||
P_UNIT,
|
P_UNIT,
|
||||||
P_PRIVAT,
|
P_PRIVAT,
|
||||||
P_BEHIND,
|
P_BEHIND,
|
||||||
P_CONTROL,
|
P_CONTROL,
|
||||||
P_HERBS,
|
P_HERBS,
|
||||||
P_NOT,
|
P_NOT,
|
||||||
P_NEXT,
|
P_NEXT,
|
||||||
P_FACTION,
|
P_FACTION,
|
||||||
P_GAMENAME,
|
P_GAMENAME,
|
||||||
P_PERSON,
|
P_PERSON,
|
||||||
P_REGION,
|
P_REGION,
|
||||||
P_SHIP,
|
P_SHIP,
|
||||||
P_MONEY,
|
P_MONEY,
|
||||||
P_ROAD,
|
P_ROAD,
|
||||||
P_TEMP,
|
P_TEMP,
|
||||||
P_FLEE,
|
P_FLEE,
|
||||||
P_GEBAEUDE,
|
P_GEBAEUDE,
|
||||||
P_GIVE,
|
P_GIVE,
|
||||||
P_FIGHT,
|
P_FIGHT,
|
||||||
P_TRAVEL,
|
P_TRAVEL,
|
||||||
P_GUARD,
|
P_GUARD,
|
||||||
P_ZAUBER,
|
P_ZAUBER,
|
||||||
P_PAUSE,
|
P_PAUSE,
|
||||||
P_VORNE,
|
P_VORNE,
|
||||||
P_AGGRO,
|
P_AGGRO,
|
||||||
P_CHICKEN,
|
P_CHICKEN,
|
||||||
P_LEVEL,
|
P_LEVEL,
|
||||||
P_HELP,
|
P_HELP,
|
||||||
P_FOREIGN,
|
P_FOREIGN,
|
||||||
P_AURA,
|
P_AURA,
|
||||||
P_FOR,
|
P_FOR,
|
||||||
P_AID,
|
P_AID,
|
||||||
P_MERCY,
|
P_MERCY,
|
||||||
P_AFTER,
|
P_AFTER,
|
||||||
P_BEFORE,
|
P_BEFORE,
|
||||||
P_NUMBER,
|
P_NUMBER,
|
||||||
P_ITEMS,
|
P_ITEMS,
|
||||||
P_POTIONS,
|
P_POTIONS,
|
||||||
P_GROUP,
|
P_GROUP,
|
||||||
P_FACTIONSTEALTH,
|
P_FACTIONSTEALTH,
|
||||||
P_TREES,
|
P_TREES,
|
||||||
P_XEPOTION,
|
P_XEPOTION,
|
||||||
P_XEBALLOON,
|
P_XEBALLOON,
|
||||||
P_XELAEN,
|
P_XELAEN,
|
||||||
MAXPARAMS,
|
MAXPARAMS,
|
||||||
NOPARAM = (param_t) - 1
|
NOPARAM = (param_t) - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum { /* Fehler und Meldungen im Report */
|
typedef enum { /* Fehler und Meldungen im Report */
|
||||||
MSG_BATTLE,
|
MSG_BATTLE,
|
||||||
MSG_EVENT,
|
MSG_EVENT,
|
||||||
MSG_MOVE,
|
MSG_MOVE,
|
||||||
MSG_INCOME,
|
MSG_INCOME,
|
||||||
MSG_COMMERCE,
|
MSG_COMMERCE,
|
||||||
MSG_PRODUCE,
|
MSG_PRODUCE,
|
||||||
MSG_ORCVERMEHRUNG,
|
MSG_ORCVERMEHRUNG,
|
||||||
MSG_MESSAGE,
|
MSG_MESSAGE,
|
||||||
MSG_COMMENT,
|
MSG_COMMENT,
|
||||||
MSG_MAGIC,
|
MSG_MAGIC,
|
||||||
MAX_MSG
|
MAX_MSG
|
||||||
} msg_t;
|
} msg_t;
|
||||||
|
|
||||||
enum { /* Message-Level */
|
enum { /* Message-Level */
|
||||||
ML_IMPORTANT, /* Sachen, die IMO erscheinen _muessen_ */
|
ML_IMPORTANT, /* Sachen, die IMO erscheinen _muessen_ */
|
||||||
ML_DEBUG,
|
ML_DEBUG,
|
||||||
ML_MISTAKE,
|
ML_MISTAKE,
|
||||||
ML_WARN,
|
ML_WARN,
|
||||||
ML_INFO,
|
ML_INFO,
|
||||||
ML_MAX
|
ML_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const char *parameters[MAXPARAMS];
|
extern const char *parameters[MAXPARAMS];
|
||||||
|
@ -250,147 +250,147 @@ extern const char *parameters[MAXPARAMS];
|
||||||
/* --------------- Reports Typen ------------------------------- */
|
/* --------------- Reports Typen ------------------------------- */
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
O_REPORT, /* 1 */
|
O_REPORT, /* 1 */
|
||||||
O_COMPUTER, /* 2 */
|
O_COMPUTER, /* 2 */
|
||||||
O_ZUGVORLAGE, /* 4 */
|
O_ZUGVORLAGE, /* 4 */
|
||||||
O_UNUSED_3,
|
O_UNUSED_3,
|
||||||
O_STATISTICS, /* 16 */
|
O_STATISTICS, /* 16 */
|
||||||
O_DEBUG, /* 32 */
|
O_DEBUG, /* 32 */
|
||||||
O_COMPRESS, /* 64 */
|
O_COMPRESS, /* 64 */
|
||||||
O_NEWS, /* 128 */
|
O_NEWS, /* 128 */
|
||||||
O_UNUSED_8,
|
O_UNUSED_8,
|
||||||
O_ADRESSEN, /* 512 */
|
O_ADRESSEN, /* 512 */
|
||||||
O_BZIP2, /* 1024 - compress as bzip2 */
|
O_BZIP2, /* 1024 - compress as bzip2 */
|
||||||
O_SCORE, /* 2048 - punkte anzeigen? */
|
O_SCORE, /* 2048 - punkte anzeigen? */
|
||||||
O_SHOWSKCHANGE, /* 4096 - Skillveränderungen anzeigen? */
|
O_SHOWSKCHANGE, /* 4096 - Skillveränderungen anzeigen? */
|
||||||
O_XML, /* 8192 - XML report versenden */
|
O_XML, /* 8192 - XML report versenden */
|
||||||
MAXOPTIONS
|
MAXOPTIONS
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ------------------ Talente ---------------------------------- */
|
/* ------------------ Talente ---------------------------------- */
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SK_ALCHEMY,
|
SK_ALCHEMY,
|
||||||
SK_CROSSBOW,
|
SK_CROSSBOW,
|
||||||
SK_MINING,
|
SK_MINING,
|
||||||
SK_LONGBOW,
|
SK_LONGBOW,
|
||||||
SK_BUILDING,
|
SK_BUILDING,
|
||||||
SK_TRADE,
|
SK_TRADE,
|
||||||
SK_LUMBERJACK,
|
SK_LUMBERJACK,
|
||||||
SK_CATAPULT,
|
SK_CATAPULT,
|
||||||
SK_HERBALISM,
|
SK_HERBALISM,
|
||||||
SK_MAGIC,
|
SK_MAGIC,
|
||||||
SK_HORSE_TRAINING, /* 10 */
|
SK_HORSE_TRAINING, /* 10 */
|
||||||
SK_RIDING,
|
SK_RIDING,
|
||||||
SK_ARMORER,
|
SK_ARMORER,
|
||||||
SK_SHIPBUILDING,
|
SK_SHIPBUILDING,
|
||||||
SK_MELEE,
|
SK_MELEE,
|
||||||
SK_SAILING,
|
SK_SAILING,
|
||||||
SK_SPEAR,
|
SK_SPEAR,
|
||||||
SK_SPY,
|
SK_SPY,
|
||||||
SK_QUARRYING,
|
SK_QUARRYING,
|
||||||
SK_ROAD_BUILDING,
|
SK_ROAD_BUILDING,
|
||||||
SK_TACTICS, /* 20 */
|
SK_TACTICS, /* 20 */
|
||||||
SK_STEALTH,
|
SK_STEALTH,
|
||||||
SK_ENTERTAINMENT,
|
SK_ENTERTAINMENT,
|
||||||
SK_WEAPONSMITH,
|
SK_WEAPONSMITH,
|
||||||
SK_CARTMAKER,
|
SK_CARTMAKER,
|
||||||
SK_PERCEPTION,
|
SK_PERCEPTION,
|
||||||
SK_TAXING,
|
SK_TAXING,
|
||||||
SK_STAMINA,
|
SK_STAMINA,
|
||||||
SK_WEAPONLESS,
|
SK_WEAPONLESS,
|
||||||
MAXSKILLS,
|
MAXSKILLS,
|
||||||
NOSKILL = (skill_t) -1
|
NOSKILL = (skill_t) -1
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ------------- Typ von Einheiten ----------------------------- */
|
/* ------------- Typ von Einheiten ----------------------------- */
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RC_DWARF, /* 0 - Zwerg */
|
RC_DWARF, /* 0 - Zwerg */
|
||||||
RC_ELF,
|
RC_ELF,
|
||||||
RC_ORC,
|
RC_ORC,
|
||||||
RC_GOBLIN,
|
RC_GOBLIN,
|
||||||
RC_HUMAN,
|
RC_HUMAN,
|
||||||
|
|
||||||
RC_TROLL,
|
RC_TROLL,
|
||||||
RC_DAEMON,
|
RC_DAEMON,
|
||||||
RC_INSECT,
|
RC_INSECT,
|
||||||
RC_HALFLING,
|
RC_HALFLING,
|
||||||
RC_CAT,
|
RC_CAT,
|
||||||
|
|
||||||
RC_AQUARIAN,
|
RC_AQUARIAN,
|
||||||
RC_URUK,
|
RC_URUK,
|
||||||
RC_SNOTLING,
|
RC_SNOTLING,
|
||||||
RC_UNDEAD,
|
RC_UNDEAD,
|
||||||
RC_ILLUSION,
|
RC_ILLUSION,
|
||||||
|
|
||||||
RC_FIREDRAGON,
|
RC_FIREDRAGON,
|
||||||
RC_DRAGON,
|
RC_DRAGON,
|
||||||
RC_WYRM,
|
RC_WYRM,
|
||||||
RC_TREEMAN,
|
RC_TREEMAN,
|
||||||
RC_BIRTHDAYDRAGON,
|
RC_BIRTHDAYDRAGON,
|
||||||
|
|
||||||
RC_DRACOID,
|
RC_DRACOID,
|
||||||
RC_SPECIAL,
|
RC_SPECIAL,
|
||||||
RC_SPELL,
|
RC_SPELL,
|
||||||
RC_IRONGOLEM,
|
RC_IRONGOLEM,
|
||||||
RC_STONEGOLEM,
|
RC_STONEGOLEM,
|
||||||
|
|
||||||
RC_SHADOW,
|
RC_SHADOW,
|
||||||
RC_SHADOWLORD,
|
RC_SHADOWLORD,
|
||||||
RC_IRONKEEPER,
|
RC_IRONKEEPER,
|
||||||
RC_ALP,
|
RC_ALP,
|
||||||
RC_TOAD,
|
RC_TOAD,
|
||||||
|
|
||||||
RC_HIRNTOETER,
|
RC_HIRNTOETER,
|
||||||
RC_PEASANT,
|
RC_PEASANT,
|
||||||
RC_WOLF = 32,
|
RC_WOLF = 32,
|
||||||
|
|
||||||
RC_SONGDRAGON = 37,
|
RC_SONGDRAGON = 37,
|
||||||
|
|
||||||
RC_SEASERPENT = 51,
|
RC_SEASERPENT = 51,
|
||||||
RC_SHADOWKNIGHT,
|
RC_SHADOWKNIGHT,
|
||||||
RC_CENTAUR,
|
RC_CENTAUR,
|
||||||
RC_SKELETON,
|
RC_SKELETON,
|
||||||
|
|
||||||
RC_SKELETON_LORD,
|
RC_SKELETON_LORD,
|
||||||
RC_ZOMBIE,
|
RC_ZOMBIE,
|
||||||
RC_ZOMBIE_LORD,
|
RC_ZOMBIE_LORD,
|
||||||
RC_GHOUL,
|
RC_GHOUL,
|
||||||
RC_GHOUL_LORD,
|
RC_GHOUL_LORD,
|
||||||
|
|
||||||
RC_MUS_SPIRIT,
|
RC_MUS_SPIRIT,
|
||||||
RC_GNOME,
|
RC_GNOME,
|
||||||
RC_TEMPLATE,
|
RC_TEMPLATE,
|
||||||
RC_CLONE,
|
RC_CLONE,
|
||||||
|
|
||||||
MAXRACES,
|
MAXRACES,
|
||||||
NORACE = (race_t) - 1
|
NORACE = (race_t) - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Richtungen */
|
/* Richtungen */
|
||||||
enum {
|
enum {
|
||||||
D_NORTHWEST,
|
D_NORTHWEST,
|
||||||
D_NORTHEAST,
|
D_NORTHEAST,
|
||||||
D_EAST,
|
D_EAST,
|
||||||
D_SOUTHEAST,
|
D_SOUTHEAST,
|
||||||
D_SOUTHWEST,
|
D_SOUTHWEST,
|
||||||
D_WEST,
|
D_WEST,
|
||||||
MAXDIRECTIONS,
|
MAXDIRECTIONS,
|
||||||
D_PAUSE,
|
D_PAUSE,
|
||||||
D_SPECIAL,
|
D_SPECIAL,
|
||||||
NODIRECTION = (direction_t) - 1
|
NODIRECTION = (direction_t) - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DONT_HELP 0
|
#define DONT_HELP 0
|
||||||
#define HELP_MONEY 1 /* Mitversorgen von Einheiten */
|
#define HELP_MONEY 1 /* Mitversorgen von Einheiten */
|
||||||
#define HELP_FIGHT 2 /* Bei Verteidigung mithelfen */
|
#define HELP_FIGHT 2 /* Bei Verteidigung mithelfen */
|
||||||
#define HELP_OBSERVE 4 /* Bei Wahrnehmung mithelfen */
|
#define HELP_OBSERVE 4 /* Bei Wahrnehmung mithelfen */
|
||||||
#define HELP_GIVE 8 /* Dinge annehmen ohne KONTAKTIERE */
|
#define HELP_GIVE 8 /* Dinge annehmen ohne KONTAKTIERE */
|
||||||
#define HELP_GUARD 16 /* Laesst Steuern eintreiben etc. */
|
#define HELP_GUARD 16 /* Laesst Steuern eintreiben etc. */
|
||||||
#define HELP_FSTEALTH 32 /* Parteitarnung anzeigen. */
|
#define HELP_FSTEALTH 32 /* Parteitarnung anzeigen. */
|
||||||
#define HELP_TRAVEL 64 /* Laesst Regionen betreten. */
|
#define HELP_TRAVEL 64 /* Laesst Regionen betreten. */
|
||||||
#define HELP_ALL (127-HELP_TRAVEL-HELP_OBSERVE) /* Alle "positiven" HELPs zusammen */
|
#define HELP_ALL (127-HELP_TRAVEL-HELP_OBSERVE) /* Alle "positiven" HELPs zusammen */
|
||||||
/* HELP_OBSERVE deaktiviert */
|
/* HELP_OBSERVE deaktiviert */
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Prototypen */
|
/* Prototypen */
|
||||||
|
|
|
@ -49,23 +49,30 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
const terrain_type *
|
const terrain_type *
|
||||||
random_terrain(boolean distribution)
|
random_terrain(const terrain_type * terrains[], int distribution[], int size)
|
||||||
{
|
{
|
||||||
static int nterrains;
|
int ndistribution = size;
|
||||||
static int ndistribution;
|
|
||||||
const terrain_type * terrain;
|
const terrain_type * terrain;
|
||||||
int n;
|
int n;
|
||||||
if (nterrains==0) {
|
|
||||||
for (terrain=terrains();terrain;terrain=terrain->next) {
|
if (distribution) {
|
||||||
ndistribution += terrain->distribution;
|
ndistribution = 0;
|
||||||
++nterrains;
|
for (n=0;n!=size;++n) {
|
||||||
|
ndistribution += distribution[n];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n = rng_int() % (distribution?ndistribution:nterrains);
|
n = rng_int() % ndistribution;
|
||||||
for (terrain=terrains();terrain;terrain=terrain->next) {
|
if (distribution) {
|
||||||
n -= distribution?terrain->distribution:1;
|
int i;
|
||||||
if (n<0) break;
|
for (i=0;i!=size;++i) {
|
||||||
|
n -= distribution[i];
|
||||||
|
if (n<0) break;
|
||||||
|
}
|
||||||
|
assert(i<size);
|
||||||
|
terrain = terrains[i];
|
||||||
|
} else {
|
||||||
|
terrain = terrains[n];
|
||||||
}
|
}
|
||||||
return terrain;
|
return terrain;
|
||||||
}
|
}
|
||||||
|
@ -412,9 +419,7 @@ free_newfaction(newfaction * nf)
|
||||||
free(nf->password);
|
free(nf->password);
|
||||||
free(nf);
|
free(nf);
|
||||||
}
|
}
|
||||||
/** create new island with up to nsize players
|
|
||||||
* returns the number of players placed on the new island.
|
|
||||||
*/
|
|
||||||
static void
|
static void
|
||||||
frame_regions(int age, const terrain_type * terrain)
|
frame_regions(int age, const terrain_type * terrain)
|
||||||
{
|
{
|
||||||
|
@ -435,6 +440,7 @@ frame_regions(int age, const terrain_type * terrain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
prepare_starting_region(region * r)
|
prepare_starting_region(region * r)
|
||||||
{
|
{
|
||||||
|
@ -467,6 +473,9 @@ prepare_starting_region(region * r)
|
||||||
fix_demand(r);
|
fix_demand(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** create new island with up to nsize players
|
||||||
|
* returns the number of players placed on the new island.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
autoseed(newfaction ** players, int nsize, int max_agediff)
|
autoseed(newfaction ** players, int nsize, int max_agediff)
|
||||||
{
|
{
|
||||||
|
@ -477,7 +486,27 @@ autoseed(newfaction ** players, int nsize, int max_agediff)
|
||||||
int isize = REGIONS_PER_FACTION; /* target size for the island */
|
int isize = REGIONS_PER_FACTION; /* target size for the island */
|
||||||
int psize = 0; /* players on this island */
|
int psize = 0; /* players on this island */
|
||||||
const terrain_type * volcano_terrain = get_terrain("volcano");
|
const terrain_type * volcano_terrain = get_terrain("volcano");
|
||||||
|
static int nterrains = -1;
|
||||||
|
static const terrain_type ** terrainarr = 0;
|
||||||
|
static int * distribution;
|
||||||
|
|
||||||
|
if (nterrains<0) {
|
||||||
|
int n = 0;
|
||||||
|
const terrain_type * terrain = terrains();
|
||||||
|
for (nterrains=0;terrain;terrain=terrain->next) {
|
||||||
|
if (terrain->distribution) {
|
||||||
|
++nterrains;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
terrainarr = malloc(sizeof(terrain_type *) * nterrains);
|
||||||
|
distribution = malloc(sizeof(int) * nterrains);
|
||||||
|
for (terrain = terrains();terrain;terrain = terrain->next) {
|
||||||
|
if (terrain->distribution) {
|
||||||
|
terrainarr[n] = terrain;
|
||||||
|
distribution[n++] = terrain->distribution;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
frame_regions(16, newterrain(T_FIREWALL));
|
frame_regions(16, newterrain(T_FIREWALL));
|
||||||
|
|
||||||
if (listlen(*players)<MINFACTIONS) return 0;
|
if (listlen(*players)<MINFACTIONS) return 0;
|
||||||
|
@ -633,7 +662,7 @@ autoseed(newfaction ** players, int nsize, int max_agediff)
|
||||||
--isize;
|
--isize;
|
||||||
if (psize>=PLAYERS_PER_ISLAND) break;
|
if (psize>=PLAYERS_PER_ISLAND) break;
|
||||||
} else {
|
} else {
|
||||||
terraform_region(r, random_terrain(true));
|
terraform_region(r, random_terrain(terrainarr, distribution, nterrains));
|
||||||
--isize;
|
--isize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -664,7 +693,7 @@ autoseed(newfaction ** players, int nsize, int max_agediff)
|
||||||
const struct terrain_type * terrain = newterrain(T_OCEAN);
|
const struct terrain_type * terrain = newterrain(T_OCEAN);
|
||||||
rn = new_region(r->x + delta_x[d], r->y + delta_y[d], 0);
|
rn = new_region(r->x + delta_x[d], r->y + delta_y[d], 0);
|
||||||
if (rng_int() % SPECIALCHANCE < special) {
|
if (rng_int() % SPECIALCHANCE < special) {
|
||||||
terrain = random_terrain(true);
|
terrain = random_terrain(terrainarr, distribution, nterrains);
|
||||||
special = SPECIALCHANCE / 3; /* 33% chance auf noch eines */
|
special = SPECIALCHANCE / 3; /* 33% chance auf noch eines */
|
||||||
} else {
|
} else {
|
||||||
special = 1;
|
special = 1;
|
||||||
|
@ -706,3 +735,157 @@ autoseed(newfaction ** players, int nsize, int max_agediff)
|
||||||
}
|
}
|
||||||
return tsize;
|
return tsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void get_neighbours(const region * r, region ** list)
|
||||||
|
{
|
||||||
|
direction_t dir;
|
||||||
|
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||||
|
list[dir] = rconnect(r, dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
region_list * regionqueue_push(region_list ** rlist, region * r)
|
||||||
|
{
|
||||||
|
region_list * rnew = malloc(sizeof(region_list));
|
||||||
|
rnew->data = r;
|
||||||
|
rnew->next = 0;
|
||||||
|
while (*rlist) { rlist = &(*rlist)->next; }
|
||||||
|
*rlist = rnew;
|
||||||
|
return rnew;
|
||||||
|
}
|
||||||
|
|
||||||
|
region * regionqueue_pop(region_list ** rlist)
|
||||||
|
{
|
||||||
|
if (*rlist) {
|
||||||
|
region * r = (*rlist)->data;
|
||||||
|
region_list * rpop = *rlist;
|
||||||
|
*rlist = rpop->next;
|
||||||
|
free(rpop);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GEOMAX 8
|
||||||
|
static struct geo {
|
||||||
|
int distribution;
|
||||||
|
terrain_t type;
|
||||||
|
} geography_e3[GEOMAX] = {
|
||||||
|
{ 8, T_OCEAN },
|
||||||
|
{ 3, T_SWAMP },
|
||||||
|
{ 1, T_VOLCANO },
|
||||||
|
{ 3, T_DESERT },
|
||||||
|
{ 3, T_HIGHLAND },
|
||||||
|
{ 3, T_MOUNTAIN },
|
||||||
|
{ 2, T_GLACIER },
|
||||||
|
{ 1, T_PLAIN }
|
||||||
|
};
|
||||||
|
|
||||||
|
const terrain_type * random_terrain_e3(direction_t dir)
|
||||||
|
{
|
||||||
|
static const terrain_type ** terrainarr = 0;
|
||||||
|
static int * distribution = 0;
|
||||||
|
|
||||||
|
if (!distribution) {
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
terrainarr = malloc(GEOMAX * sizeof(const terrain_type *));
|
||||||
|
distribution = malloc(GEOMAX * sizeof(int));
|
||||||
|
for (n=0;n!=GEOMAX;++n) {
|
||||||
|
terrainarr[n] = newterrain(geography_e3[n].type);
|
||||||
|
distribution[n] = geography_e3[n].distribution;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return random_terrain(terrainarr, distribution, GEOMAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
random_neighbours(region * r, region_list ** rlist, const terrain_type *(*terraformer)(direction_t))
|
||||||
|
{
|
||||||
|
int nsize = 0;
|
||||||
|
direction_t dir;
|
||||||
|
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||||
|
region * rn = rconnect(r, dir);
|
||||||
|
if (rn==NULL) {
|
||||||
|
const terrain_type * terrain = terraformer(dir);
|
||||||
|
rn = new_region(r->x+delta_x[dir], r->y+delta_y[dir], 0);
|
||||||
|
terraform_region(rn, terrain);
|
||||||
|
if (rn->land) {
|
||||||
|
regionqueue_push(rlist, rn);
|
||||||
|
++nsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
const terrain_type * get_ocean(direction_t dir)
|
||||||
|
{
|
||||||
|
return newterrain(T_OCEAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
int region_quality(const region * r)
|
||||||
|
{
|
||||||
|
region * rn[MAXDIRECTIONS];
|
||||||
|
int n, result = 0;
|
||||||
|
get_neighbours(r, rn);
|
||||||
|
for (n=0;n!=MAXDIRECTIONS;++n) {
|
||||||
|
if (rn[n] && rn[n]->land) {
|
||||||
|
result += rn[n]->land->peasants;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// result += r->land->peasants * 2;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* E3A island generation */
|
||||||
|
int
|
||||||
|
build_island_e3(short x, short y, int numfactions, int minsize)
|
||||||
|
{
|
||||||
|
int nfactions = 0;
|
||||||
|
region_list * rlist = NULL;
|
||||||
|
region_list * island = NULL;
|
||||||
|
region * r = new_region(x, y, 0);
|
||||||
|
int nsize = 1;
|
||||||
|
int q, maxq = INT_MIN, minq = INT_MAX;
|
||||||
|
|
||||||
|
terraform_region(r, random_terrain_e3(NODIRECTION));
|
||||||
|
|
||||||
|
while (r) {
|
||||||
|
if (r->land) {
|
||||||
|
fset(r, RF_MARK);
|
||||||
|
regionqueue_push(&island, r);
|
||||||
|
}
|
||||||
|
if (nsize<minsize) {
|
||||||
|
nsize += random_neighbours(r, &rlist, &random_terrain_e3);
|
||||||
|
} else {
|
||||||
|
nsize += random_neighbours(r, &rlist, &get_ocean);
|
||||||
|
}
|
||||||
|
r = regionqueue_pop(&rlist);
|
||||||
|
}
|
||||||
|
for (rlist=island;rlist;rlist=rlist->next) {
|
||||||
|
r = rlist->data;
|
||||||
|
if (fval(r, RF_MARK)) {
|
||||||
|
region *rn[MAXDIRECTIONS];
|
||||||
|
int n;
|
||||||
|
unit * u;
|
||||||
|
|
||||||
|
freset(r, RF_MARK);
|
||||||
|
get_neighbours(r, rn);
|
||||||
|
for (n=0;n!=MAXDIRECTIONS;++n) {
|
||||||
|
freset(rn[n], RF_MARK);
|
||||||
|
}
|
||||||
|
q = region_quality(r);
|
||||||
|
if (q>1500 && nfactions<numfactions) {
|
||||||
|
terraform_region(r, newterrain(T_PLAIN));
|
||||||
|
minq = MIN(minq, q);
|
||||||
|
maxq = MAX(maxq, q);
|
||||||
|
prepare_starting_region(r);
|
||||||
|
u = addplayer(r, addfaction("enno@eressea.de", itoa36(rng_int()), races,
|
||||||
|
default_locale, 0));
|
||||||
|
++nfactions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nfactions;
|
||||||
|
}
|
||||||
|
|
|
@ -39,9 +39,10 @@ extern int autoseed(newfaction ** players, int nsize, int max_agediff);
|
||||||
extern newfaction * read_newfactions(const char * filename);
|
extern newfaction * read_newfactions(const char * filename);
|
||||||
extern void get_island(struct region * root, struct region_list ** rlist);
|
extern void get_island(struct region * root, struct region_list ** rlist);
|
||||||
extern int fix_demand(struct region *r);
|
extern int fix_demand(struct region *r);
|
||||||
extern const struct terrain_type * random_terrain(boolean use_distribution);
|
extern const struct terrain_type * random_terrain(const struct terrain_type * terrains[], int distribution[], int size);
|
||||||
|
|
||||||
extern int seed_adamantium(struct region * r, int base);
|
extern int seed_adamantium(struct region * r, int base);
|
||||||
|
extern int build_island_e3(short x, short y, int numfactions, int minsize);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <modules/arena.h>
|
#include <modules/arena.h>
|
||||||
#endif
|
#endif
|
||||||
#include <modules/wormhole.h>
|
#include <modules/wormhole.h>
|
||||||
|
#include <modules/autoseed.h>
|
||||||
#if DUNGEON_MODULE
|
#if DUNGEON_MODULE
|
||||||
#include <modules/dungeon.h>
|
#include <modules/dungeon.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -56,6 +57,7 @@
|
||||||
#include <items/itemtypes.h>
|
#include <items/itemtypes.h>
|
||||||
|
|
||||||
#include <util/log.h>
|
#include <util/log.h>
|
||||||
|
#include <util/rng.h>
|
||||||
#include <util/base36.h>
|
#include <util/base36.h>
|
||||||
#include <util/storage.h>
|
#include <util/storage.h>
|
||||||
|
|
||||||
|
@ -727,6 +729,7 @@ handlekey(state * st, int c)
|
||||||
region *r;
|
region *r;
|
||||||
char sbuffer[80];
|
char sbuffer[80];
|
||||||
static char kbuffer[80];
|
static char kbuffer[80];
|
||||||
|
int n;
|
||||||
|
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case FAST_RIGHT:
|
case FAST_RIGHT:
|
||||||
|
@ -785,7 +788,11 @@ handlekey(state * st, int c)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'B':
|
case 'B':
|
||||||
|
/*
|
||||||
make_block((short)st->cursor.x, (short)st->cursor.y, 6, select_terrain(st, NULL));
|
make_block((short)st->cursor.x, (short)st->cursor.y, 6, select_terrain(st, NULL));
|
||||||
|
*/
|
||||||
|
n = rng_int() % 8 + 8;
|
||||||
|
build_island_e3((short)st->cursor.x, (short)st->cursor.y, n, n*4);
|
||||||
st->modified = 1;
|
st->modified = 1;
|
||||||
st->wnd_info->update |= 1;
|
st->wnd_info->update |= 1;
|
||||||
st->wnd_status->update |= 1;
|
st->wnd_status->update |= 1;
|
||||||
|
|
Loading…
Reference in a new issue