PixelWars/main.c

436 lines
10 KiB
C
Executable File

#include "main.h"
#include "team.h"
#include "tools.h"
#include "generator.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
typedef struct{
t_dude dude1;
t_dude dude2;
int attack;
} t_fight;
// temp code
t_action purple_update(void* my_info, void* com_data, int my_id, int success);
t_action orange_update(void* my_info, void* com_data, int my_id, int success);
int get_purple_size();
int get_orange_size();
t_dude* current_dude;
void initWorld(int width, int height){
int i;
// allocations
printf("Allocating memory...\n");
teams = malloc(sizeof(t_team)*NB_TEAMS);
for(i=0; i<NB_TEAMS; i++){
teams[i].team = i;
switch(i){
case ORANGE :
teams[i].dude_size = get_orange_size();
teams[i].update = orange_update;
break;
case PURPLE :
teams[i].dude_size = get_purple_size();
teams[i].update = purple_update;
break;
}
teams[i].nb_dudes = 0;
teams[i].dudes = malloc(sizeof(t_dude)*MAX_DUDES);
teams[i].spawn.x = 0;
teams[i].spawn.y = 0;
teams[i].spawn_food = 10;
teams[i].spawn_count = 0;
}
map = (t_pixel**)malloc(sizeof(t_pixel*)*width);
for(i=0; i<width; i++)
map[i] = (t_pixel*)malloc(sizeof(t_pixel)*height);
// generate map
printf("Generating map...\n");
create_map(width, height);
// create image from map
printf("Creating image from map...\n");
generateImg(width, height);
}
void addFight(t_dude dude, t_dude other_dude){
}
void updateTeam(t_team team){
int i;
t_action action;
for(i=0; i<team.nb_dudes; i++){
current_dude = team.dudes + i;
action = team.update((void*)(team.dudes[i].custom_data), (void*)(team.dudes[i].com_data), i, team.dudes[i].success);
handleAction(action, team.dudes+i);
}
}
t_coord getPos(t_coord coord, int dir){
switch(dir){
case NORTH :
coord.y++;
break;
case SOUTH :
coord.y--;
break;
case WEST :
coord.x++;
break;
case EAST :
coord.x--;
break;
}
return coord;
}
int getNear(int dir){
t_coord coord = getPos(current_dude->pos, dir);
return map[coord.x][coord.y].type;
}
void spawnDudes(){
int i;
t_dude new_dude;
for(i=0; i<NB_TEAMS; i++){
if(teams[i].spawn_food > 0)
teams[i].spawn_count++;
if(teams[i].spawn_count > 10 && map[teams[i].spawn.x][teams[i].spawn.y].type == SPAWN){
teams[i].spawn_food--;
teams[i].spawn_count = 0;
new_dude.pos = teams[i].spawn;
new_dude.team = teams[i].team;
new_dude.inventory = -1;
new_dude.success = 1;
new_dude.ground = map[teams[i].spawn.x][teams[i].spawn.y];
new_dude.custom_data = malloc(teams[i].dude_size);
memset(new_dude.custom_data, 0, teams[i].dude_size);
new_dude.com_data = NULL;
teams[i].dudes[teams[i].nb_dudes++] = new_dude;
}
}
}
void handleAction(t_action action, t_dude* dude){
t_coord target_pos = getPos(dude->pos, action.dir);
t_pixel target = map[target_pos.x][target_pos.y];
int* nb_res;
switch(action.type){
case MOVE :
dude->success = 0;
if( target.type != WALL
&& target.type != ROCK
&& target.type != BEDROCK
&& target.type != IRON_ORE
&& target.type != DUDE
&& target.type != TREE
)
add_move(dude, target_pos);
break;
case ATTACK :
printf("forbidden action\n"); // TODO : implement that
//if(target.type == DUDE)
// addFight(dude, *((t_dude*)(target.data)));
break;
case PICK :
nb_res = target.data;
if(target.type >= FOOD && target.type <= SWORD && dude->inventory == -1){
dude->inventory = target.type;
(*nb_res)--;
if(*nb_res < 1){
free(nb_res);
map[target_pos.x][target_pos.y].type = GRASS;
map[target_pos.x][target_pos.y].data = NULL;
}
putpixel(img, target_pos.x, target_pos.y, getColor(map[target_pos.x][target_pos.y]));
}else
dude->success = 0;
break;
case PUT :
if(dude->inventory != -1 && (target.type == GRASS || target.type == dude->inventory)){
if(target.type == GRASS || target.type == MARK){
map[target_pos.x][target_pos.y].type = dude->inventory;
nb_res = malloc(sizeof(int));
*nb_res = 1;
map[target_pos.x][target_pos.y].data = nb_res;
}else{
nb_res = target.data;
(*nb_res)++;
}
dude->inventory = -1;
putpixel(img, target_pos.x, target_pos.y, getColor(map[target_pos.x][target_pos.y]));
}else
dude->success = 0;
break;
case WORK :
dude->success = 1;
switch(target.type){
case ROCK :
map[target_pos.x][target_pos.y].type = STONE;
nb_res = malloc(sizeof(int));
*nb_res = 1;
map[target_pos.x][target_pos.y].data = nb_res;
break;
case BERRIES :
map[target_pos.x][target_pos.y].type = FOOD;
nb_res = malloc(sizeof(int));
*nb_res = 1;
map[target_pos.x][target_pos.y].data = nb_res;
break;
case TREE :
map[target_pos.x][target_pos.y].type = WOOD;
nb_res = malloc(sizeof(int));
*nb_res = 1;
map[target_pos.x][target_pos.y].data = nb_res;
break;
case IRON_ORE :
map[target_pos.x][target_pos.y].type = IRON;
nb_res = malloc(sizeof(int));
*nb_res = 1;
map[target_pos.x][target_pos.y].data = nb_res;
break;
case GRASS :
map[target_pos.x][target_pos.y].type = MARK;
map[target_pos.x][target_pos.y].data = NULL;
break;
case MARK :
map[target_pos.x][target_pos.y].type = GRASS;
map[target_pos.x][target_pos.y].data = NULL;
break;
case WOOD :
nb_res = target.data;
if(*nb_res != 1)
dude->success = 0;
else{
free(target.data);
map[target_pos.x][target_pos.y].type = WALL;
map[target_pos.x][target_pos.y].data = NULL;
}
break;
case STONE :
nb_res = target.data;
if(*nb_res != 1)
dude->success = 0;
else{
free(target.data);
map[target_pos.x][target_pos.y].type = ROAD;
map[target_pos.x][target_pos.y].data = NULL;
}
break;
case IRON :
nb_res = target.data;
if(*nb_res != 1)
dude->success = 0;
else
map[target_pos.x][target_pos.y].type = SWORD;
break;
default :
dude->success = 0;
break;
}
if(dude->success)
putpixel(img, target_pos.x, target_pos.y, getColor(map[target_pos.x][target_pos.y]));
break;
case WAIT :
dude->success = 1;
break;
case COMMUNICATE :
printf("forbidden action\n"); // TODO : implement that
// if target is sign -> set sign message
// if target is dude -> sent message to dude
break;
}
}
void generateImg(int width, int height){
img = SDL_CreateRGBSurface(0, width, height, 32, 0, 0, 0, 0);
int i, j;
for(i=0; i<width; i++){
for(j=0; j<height; j++){
putpixel(img, i, j, getColor(map[i][j]));
}
}
}
SDL_Surface* initSDL(int width, int height, int fullscreen)
{
SDL_Surface* screen;
srand(time(NULL));
if(fullscreen)
screen = SDL_SetVideoMode(width, height, 32, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN);
else
screen = SDL_SetVideoMode(width, height, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
SDL_WM_SetCaption("Pixel Wars", NULL);
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
fprintf(stderr, "Erreur d'initialisation de la SDL");// and you don't want my french comment :p
exit(EXIT_FAILURE);
}
return screen;
}
void render(SDL_Surface* screen, int x_offset, int y_offset, int zoom_level){
int i, j, x, y;
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
for(i=0; i<screen->w; i++){
for(j=0; j<screen->h; j++){
x = (i - img->w/2)/zoom_level + x_offset;
y = (j - img->h/2)/zoom_level + y_offset;
if(x >= 0 && x < img->w && y >= 0 && y < img->h)
putpixel(screen, i, j, getpixel(img, x, y));
}
}
}
int MAIN
{
SDL_Surface* screen;
SDL_Event event;
int i;
int paused = 0;
int x_offset = 0;
int y_offset = 0;
int zoom_level = 1;
int seuil_x; // limit for x_offset
int seuil_y; // limit for y_offset
int over = 0;
int time = 0;
int wait_time = 100;
int new_time = 0;
int remaining_time = -1;
int fullscreen = 0;
int width = DEFAULT_WIDTH;
int height = DEFAULT_HEIGHT;
#ifndef _WIN32
argv++;
while(argc > 1){ // pas initialisé sur windows
printf("%s\n", argv[0]);
switch(argv[0][0]){
case 'f' :
fullscreen = 1;
break;
case 'w' :
width = atoi(argv[0]+2);
break;
case 'h' :
height = atoi(argv[0]+2);
break;
default :
break;
}
argv++;
argc--;
}
#endif
screen = initSDL(width, height, fullscreen);
initWorld(width, height);
SDL_Flip(img);
x_offset = width/2;
y_offset = height/2;
printf("Launching simulation...\n");
time = SDL_GetTicks();
while (!over){
while(SDL_PollEvent(&event)){
switch (event.type){
case SDL_KEYDOWN:
switch(event.key.keysym.sym) {
case SDLK_ESCAPE :
over = 1;
break;
case SDLK_w :
y_offset -= 5;
break;
case SDLK_s :
y_offset += 5;
break;
case SDLK_a :
x_offset -= 5;
break;
case SDLK_d :
x_offset += 5;
break;
case SDLK_UP :
wait_time *= 2;
break;
case SDLK_DOWN :
if(wait_time > 2)
wait_time /= 2;
break;
case SDLK_LEFT :
zoom_level++;
break;
case SDLK_RIGHT :
zoom_level--;
if(zoom_level < 1)
zoom_level = 1;
break;
case SDLK_SPACE :
paused = !paused;
break;
default :
break;
}
break;
case SDL_MOUSEMOTION:
x_offset += event.motion.xrel;
y_offset += event.motion.yrel;
break;
case SDL_QUIT:
over = 1;
break;
default :
break;
}
}
/* check x and y offset*/
seuil_x = width/(2*zoom_level);
if (x_offset < seuil_x) x_offset=seuil_x;
if (x_offset > width-seuil_x) x_offset=width-seuil_x;
seuil_y = height/(2*zoom_level);
if (y_offset < seuil_y) y_offset=seuil_y;
if(y_offset > height-seuil_y) y_offset=height-seuil_y;
/* */
new_time = SDL_GetTicks();
remaining_time -= new_time - time;
time = new_time;
if(remaining_time < 0 && !paused){
spawnDudes();
for(i=0; i<NB_TEAMS; i++)
updateTeam(teams[i]);
resolve_moves();
remaining_time = wait_time;
}
render(screen, x_offset, y_offset, zoom_level);
SDL_Delay(30);
SDL_Flip(screen);
}
SDL_FreeSurface(screen);
SDL_Quit();
return 0;
}