PixelWars/old_code/generator_default.c
2016-05-16 00:34:44 +02:00

235 lines
4.8 KiB
C

#include "main.h"
#define MAX_POWER 10
#define MAX_EPICENTER_BY_TYPE 7
#define DIST_MIN_INTER_EPICENTRE 50
#define MIN_RADIUS 25
#define OFFSET_RADIUS 50
//map type ----> not used for now
enum{
FLAT, VALLEY,
};
//biome type
enum{
VILLAGE, PLAINS, FOREST,MOUNTAINS,NB_BIOMES
};
// probability for each biomes
// in following order {GRASS,TREE,BERRIES, ROCK, IRON_ORE}
char proba_table[NB_BIOMES][5] = {{97,2,1,0,0},{85,13,2,0,0},{40,40,20,0,0},{0,0,0,80,20}};
typedef struct{
int x;
int y;
int type;
int power;
int radius;
} t_biome;
// variables
int sp_x[NB_TEAMS], sp_y[NB_TEAMS];
t_biome* l_biomes;
int size_biomes;
int nb_plains, nb_forests, nb_mountains;
int cpt_biome = 0;
int width, height;
// functions
int distance_manhattan(int x1,int y1, int x2, int y2);
int absolute(int val);
void set_spawns(t_pixel** map, t_team* teams);
void create_biome(int x, int y, int type);
void create_biome_random(int type);
int check_nears_biomes(int x, int y);
int check_nears_spawn(int x, int y);
int in_radius(int x,int y,t_biome e);
int generate(int x, int y);
void init_generator();
void create_map(int w, int h){
int i,j;
//biome variable
width = w;
height = h;
init_generator();
//Epicenters generation
// random choice for numbers of biomes
nb_plains = (rand()%MAX_EPICENTER_BY_TYPE)+3;
nb_forests = (rand()%MAX_EPICENTER_BY_TYPE)+3;
nb_mountains = (rand()%MAX_EPICENTER_BY_TYPE)+3;
size_biomes = nb_plains+ nb_forests + nb_mountains + NB_TEAMS;
l_biomes = malloc(sizeof(t_biome)*size_biomes);
// Spawn generations
set_spawns(map,teams);
for(i=0;i<nb_plains;i++)
create_biome_random(PLAINS);
for(i=0;i<nb_forests;i++)
create_biome_random(FOREST);
for(i=0;i<nb_mountains;i++)
create_biome_random(MOUNTAINS);
// */
//génération de la carte
for (i=0;i<width;i++){
for(j=0;j<height;j++){
if (i == 0 || j == 0 || i == w-1 || j == h-1){
map[i][j].type = BEDROCK;
}else if((i == sp_x[PURPLE] && j == sp_y[PURPLE])){
map[i][j].type = SPAWN;
map[i][j].data=malloc(sizeof(int));
*((int*)(map[i][j].data)) = PURPLE;
}else if(i == sp_x[ORANGE] && j == sp_y[ORANGE]){
map[i][j].type = SPAWN;
map[i][j].data=malloc(sizeof(int));
*((int*)(map[i][j].data)) = ORANGE;
}else{
map[i][j].type = generate(i,j);
}
}
}
}
void init_generator(){
}
void set_spawns(t_pixel** map, t_team* teams){
int i;
int tier_w, tier_h;
tier_w = width/6;
tier_h = height/3;
sp_x[0] = (rand()%tier_w)+tier_w;
sp_y[0] = (rand()%tier_h)+tier_h;
sp_x[1] = width-sp_x[0];
sp_y[1] = height-sp_y[0];
for(i=0;i<2;i++){
teams[i].spawn.x = sp_x[i];
teams[i].spawn.y = sp_y[i];
create_biome(sp_x[i],sp_y[i],VILLAGE);
}
}
void create_biome(int x, int y, int type){
t_biome *biome = malloc(sizeof(t_biome));
biome->x=x;
biome->y=y;
biome->type = type;
switch(type){
case VILLAGE:
biome->power = (rand()%MAX_POWER)+1;
biome->radius = (rand()%(25-10))+10;
break;
case PLAINS:
case FOREST:
case MOUNTAINS:
default:
biome->power = (rand()%MAX_POWER)+1;
biome->radius = (rand()%(OFFSET_RADIUS))+MIN_RADIUS;
break;
}
l_biomes[cpt_biome++]=*biome;
}
void create_biome_random(int type){
int x,y;
do {
x=rand()%width;
y=rand()%height;
} while ((check_nears_biomes(x,y) != 0) || (check_nears_spawn(x,y) != 0)); //prevent biome superposition
create_biome(x,y,type);
}
int check_nears_biomes(int x, int y){
int i, c=0;
for(i=0;i<cpt_biome;i++){
if (in_radius(x,y,l_biomes[i]) != -1) c++;
}
return c;
}
int check_nears_spawn(int x, int y){
int i,c = 0;
for(i=0;i<2;i++)
if (distance_manhattan(x,y,sp_x[i],sp_y[i]) < 75) c++;
return c;
}
int in_radius(int x,int y,t_biome e){
int d = distance_manhattan(x,y,e.x,e.y);
return d < e.radius ? d : -1;
}
int generate(int x, int y){
int i, j;
int proba[5];
int sum, dist, ratio, val, seuil=0;
t_biome biome;
memset(&proba,0,sizeof(int)*5);
sum=0;
for(i=0;i<size_biomes;i++){
biome = l_biomes[i];
if ((dist=in_radius(x,y,biome)) != -1){
ratio=(((biome.radius-dist)*100)/biome.radius);
//ne marche pas correctement, besoin de fractale à la place
/* if (biome.type == MOUNTAINS && (ratio < 20)){
sum += biome.power*ratio*100;
proba[0] += biome.power*ratio*20;
proba[3] += biome.power*ratio*75;
proba[4] += biome.power*ratio*5;
}else{*/
sum += biome.power*ratio*100;
for(j=0;j<5;j++){
proba[j]+=(proba_table[biome.type][j])*(biome.power)*ratio;
}
}
}
if (sum!=0){
val = rand()%sum;
for (i=0;i<5;i++){
seuil += proba[i];
if(val < seuil)
return i+1;
}
}else{
val = rand()%100;
if (val <95){
return GRASS;
}else{
return TREE;
}
}
return GRASS;
}
int distance_manhattan(int x1,int y1, int x2, int y2){
return absolute(x1-x2) + absolute(y1-y2);
}
int absolute(int val){
return val > 0 ? val : -val;
}