# include # include # include # include # include # include # include "msg_fr.h" # include "itemsizes.h" # include "gamesettings.h" # include "worldgen.h" # include "itoa.h" # define ERROR(error, errorcode) dclear(C_WHITE); \ dprint(1, 1, C_BLACK, "ERROR"); \ dprint(1, 6, C_BLACK, "LINE : %d", __LINE__); \ dprint(1, 12, C_BLACK, "FILE : %d", __FILE__); \ dprint(1, 18, C_BLACK, "ERROR NUM : %d", errorcode); \ dprint(1, 24, C_BLACK, "%c", error); \ dupdate(); \ getkey(); \ return errorcode; extern bopti_image_t title_img; extern bopti_image_t soil_tile; extern bopti_image_t grass_tile; extern bopti_image_t stone_tile; extern bopti_image_t coal_tile; extern bopti_image_t steel_tile; extern bopti_image_t wood_tile; extern bopti_image_t woodplanks_tile; extern bopti_image_t woodsteps_1_tile; extern bopti_image_t woodsteps_2_tile; extern bopti_image_t woodstick_tile; extern bopti_image_t fire_tile; extern bopti_image_t skin1_player_left1; extern bopti_image_t skin1_player_left2; extern bopti_image_t skin1_player_right1; extern bopti_image_t skin1_player_right2; extern bopti_image_t select_tool; extern bopti_image_t pickaxe_tool; extern bopti_image_t invnormal; extern bopti_image_t invselected; extern bopti_image_t craftselection; extern bopti_image_t arrow_1; extern bopti_image_t arrow_2; extern bopti_image_t overlay_break_1; extern bopti_image_t overlay_break_2; extern bopti_image_t overlay_break_3; extern bopti_image_t overlay_break_4; extern font_t microfont; # include "objects.h" //int x, y, pos, hour, animation, orient, timing, falling, jumping, jumpheight; int pos, hour; char tmp_char[2]; Player player; Crafting crafting; Tool hand; Tool wood_pickaxe; Destroy destroy; const int canbeplaced_lenght = 7; const int canbeplaced[7] = {1, 2, 3, 4, 5, 6, 8}; const int hasmenu_lenght = 1; const int hasmenu[1] = {8}; void drawtile(int x, int y, int tilenum) { switch(tilenum){ case 1: dimage(x, y, &soil_tile); break; case 2: dimage(x, y, &stone_tile); break; case 3: dimage(x, y, &coal_tile); break; case 4: dimage(x, y, &steel_tile); break; case 5: dimage(x, y, &wood_tile); break; case 6: dimage(x, y, &woodplanks_tile); break; case 7: dimage(x, y, &pickaxe_tool); break; case 8: dimage(x, y, &fire_tile); break; } } void drawoverlay() { /* Calculation details : x = x - 60 y = y - 24 ftx = x>>3 fty = y>>3 sx = ftx*8-x sy = fty*8-y rx = sx+(tx-ftx)*8 ry = sy+(ty-fty)*8 */ int rx = (((player.x-60)>>3)*8-(player.x-60))+(player.select_tx-((player.x-60)>>3))*8; int ry = (((player.y-24)>>3)*8-(player.y-24))+(player.select_ty-((player.y-24)>>3))*8; switch(player.overlayframe){ case 1: dimage(rx, ry, &overlay_break_1);break; case 2: dimage(rx, ry, &overlay_break_2);break; case 3: dimage(rx, ry, &overlay_break_3);break; case 4: dimage(rx, ry, &overlay_break_4);break; } } void drawselectedgame(int selected) { dclear(C_WHITE); // dimage(16, 8, &title_img); for(int i=0;i!=GAMESNUM;i++){ dtext(1, WORLDSEL_MARGIN + i*(LINEHEIGHT), C_BLACK, WORLDSEL_EMPTY); } drect(1, WORLDSEL_MARGIN+selected*(LINEHEIGHT)-(int)(LINEPADDING/2), 128, WORLDSEL_MARGIN+(selected+1)*(LINEHEIGHT)-(int)(LINEPADDING/2), C_INVERT); dupdate(); } void addtree(int pos, unsigned short int * terrain, int n){ int i; srand(clock()); for(i=pos-rand()%6;i!=pos;i++){ terrain[i*WORLD_WIDTH+(n>>3)] = 5; } } void addtrees(unsigned short int * terrain){ int n, i; for(n=0;n!=WORLD_WIDTH;n++){ if(rand()%11 == 1){ for(i=0;i!=WORLD_HEIGHT;i++){ if(terrain[i*WORLD_WIDTH+(n>>3)] != 0){ pos = i; break; } } if(n != (player.x>>3)){ addtree(pos, terrain, n); } } } } void mappartdisplaying(int x, int y, unsigned short int * terrain, int player) { x = x-60; y = y-24; int firsttile_x = x>>3, firsttile_y = y>>3; int base_x = firsttile_x*8, base_y = firsttile_y*8; int sx = base_x - x, sy = base_y - y, tx = (SCREEN_WIDTH>>3) + 1, ty = (SCREEN_HEIGHT>>3) + 1; int cx, cy, px = sx, py = sy; unsigned short type, type_over; dclear(C_WHITE); for(cy = 0;cy != ty;cy++){ for(cx = 0;cx != tx;cx++){ type = terrain[(firsttile_y+cy)*WORLD_WIDTH+(firsttile_x+cx)]; type_over = terrain[(firsttile_y+cy-1)*WORLD_WIDTH+(firsttile_x+cx)]; switch(type){ case 1: if(type_over == 0){dimage(px, py, &grass_tile);}else{dimage(px, py, &soil_tile);} break; case 2: dimage(px, py, &stone_tile); break; case 3: dimage(px, py, &coal_tile); break; case 4: dimage(px, py, &steel_tile); break; case 5: dimage(px, py, &wood_tile); break; case 6: dimage(px, py, &woodplanks_tile); break; case 8: dimage(px, py, &fire_tile); break; } px += 8; } py += 8; px = sx; } switch(player){ case 2: dimage(60, 24, &skin1_player_right2); break; case 3: dimage(60, 24, &skin1_player_left1); break; case 4: dimage(60, 24, &skin1_player_left2); break; default: dimage(60, 24, &skin1_player_right1); break; } } int exists(unsigned short int * terrain, short type) { int i; for(i=0;i!=WORLD_WIDTH*WORLD_HEIGHT;i++){ if(terrain[i]==type){ return 1; } } return 0; } int pointoverrectangle(int rx1, int ry1, int rx2, int ry2, int x, int y){ if ((x>=rx1 && y>=ry1) && (x<=rx2 && y<=ry2)){ return 1; } return 0; } int collisiononmap(int x, int y, unsigned short int * terrain, int testx, int testy) { x = x-60; y = y-24; int firsttile_x = x>>3, firsttile_y = y>>3; int base_x = firsttile_x*8, base_y = firsttile_y*8; int sx = base_x - x, sy = base_y - y, tx = (SCREEN_WIDTH>>3) + 1, ty = (SCREEN_HEIGHT>>3) + 1; int cx, cy, px = sx, py = sy; unsigned short type; dclear(C_WHITE); for(cy = 0;cy != ty;cy++){ for(cx = 0;cx != tx;cx++){ type = terrain[(firsttile_y+cy)*WORLD_WIDTH+(firsttile_x+cx)]; if(type != 0){ if(pointoverrectangle(px, py, px+8, py+8, testx, testy)){ return 1; } } px += 8; } py += 8; px = sx; } return 0; } void drawinventory(){ int i; for(i=0;i!=5;i++){ if(i == player.invselect){ dimage(26+i*15, 49, &invselected); }else{ dimage(26+i*15, 49, &invnormal); } drawtile(26+i*15+3, 52, player.inventoryitems[i]); } } void drawdetailinv(){ int i; dtext(1, 1, C_BLACK, INV_INFO); for(i=0;i!=INVENTORY_SIZE;i++){ pos = i*8+16; drawtile(5, pos, player.inventoryitems[i]); itoa(player.inventorynum[i], tmp_char); dtext(20, pos, C_BLACK, tmp_char); if(i == player.invselect){ dtext(60, pos, C_BLACK, SELECTED); } if(i == player.invmoving){ dtext(66, pos, C_BLACK, MOVING); } } } void drawcrafting(){ int i; dfont(µfont); dimage(32, 0, &craftselection); dimage(4, 28, &arrow_2); dimage(116, 28, &arrow_1); drawtile(36, 28, craftingitem[crafting.selected]); dtext(36, 38, C_BLACK, MULTIPLY); itoa(craftingnum[crafting.selected], tmp_char); dtext(36, 44, C_BLACK, tmp_char); pos = 4; for(i=crafting.selected*CRAFTSIZE;i!=(crafting.selected+1)*CRAFTSIZE;i++){ if(craftingsnum[i]!=0){ switch(craftingsitems[i]){ case 1: dtext(58, pos, C_BLACK, SOIL_TILE); break; case 2: dtext(58, pos, C_BLACK, STONE_TILE); break; case 3: dtext(58, pos, C_BLACK, COAL_TILE); break; case 4: dtext(58, pos, C_BLACK, STEEL_TILE); break; case 5: dtext(58, pos, C_BLACK, WOOD_TILE); break; case 6: dtext(58, pos, C_BLACK, WOODPLANKS_TILE); break; case 7: dtext(58, pos, C_BLACK, WOODPICKAXE_TILE); break; case 8: dtext(58, pos, C_BLACK, FIRE_TILE); break; } itoa(craftingsnum[i], tmp_char); dtext(46, pos, C_BLACK, tmp_char); dtext(52, pos, C_BLACK, MULTIPLY); pos+=6; } } dfont(dfont_default()); } void drawdestroy() { int i; dtext(1, 1, C_BLACK, DESTROY_INFO); for(i=0;i!=INVENTORY_SIZE;i++){ pos = i*8+16; drawtile(5, pos, player.inventoryitems[i]); itoa(player.inventorynum[i], tmp_char); dtext(20, pos, C_BLACK, tmp_char); if(i == destroy.selected){ dtext(60, pos, C_BLACK, SELECTED); } } } bool is_in(int item, int* array, int len){ for(int i=0;i!=len;i++){ if(array[i] == item){ return 1; } } return 0; } int main(void) { // Tools // // Hand hand.easy_lenght = 1; hand.middle_lenght = 1; hand.hard_lenght = 1; hand.very_hard_lenght = 2; hand.breakable_middle = NULL; hand.breakable_hard = NULL; hand.breakable_very_hard = NULL; hand.breakable_middle = malloc(sizeof(int)); hand.breakable_hard = malloc(sizeof(int)); hand.breakable_very_hard = malloc(hand.very_hard_lenght*sizeof(int)); if(hand.breakable_middle == NULL || hand.breakable_hard == NULL || hand.breakable_very_hard == NULL){ ERROR("Need more ram !", 2) } hand.breakable_middle[0] = 1; hand.breakable_hard[0] = 6; hand.breakable_very_hard[0] = 5; hand.breakable_very_hard[1] = 8; hand.attack = 1; // Wooden pickaxe wood_pickaxe.easy_lenght = 1; wood_pickaxe.middle_lenght = 1; wood_pickaxe.hard_lenght = 3; wood_pickaxe.very_hard_lenght = 3; wood_pickaxe.breakable_middle = NULL; wood_pickaxe.breakable_hard = NULL; wood_pickaxe.breakable_very_hard = NULL; wood_pickaxe.breakable_middle = malloc(sizeof(int)); wood_pickaxe.breakable_hard = malloc(wood_pickaxe.hard_lenght*sizeof(int)); wood_pickaxe.breakable_very_hard = malloc(wood_pickaxe.very_hard_lenght*sizeof(int)); if(wood_pickaxe.breakable_middle == NULL || wood_pickaxe.breakable_hard == NULL || wood_pickaxe.breakable_very_hard == NULL){ ERROR("Need more ram !", 3) } wood_pickaxe.breakable_middle[0] = 1; wood_pickaxe.breakable_hard[0] = 6; wood_pickaxe.breakable_hard[1] = 2; wood_pickaxe.breakable_hard[2] = 8; wood_pickaxe.breakable_very_hard[0] = 5; wood_pickaxe.breakable_very_hard[1] = 3; wood_pickaxe.breakable_very_hard[2] = 4; wood_pickaxe.attack = 2; /////////// dclear(C_WHITE); dimage(16, TITLE_IMAGE_MARGIN, &title_img); dtext(1, TITLE_MARGIN, C_BLACK, TITLE_START); dupdate(); int key = 0, game = 0, selected = 0, i, n; unsigned short int* terrain = NULL; terrain = malloc(WORLD_WIDTH*WORLD_HEIGHT*sizeof(unsigned short int)); if(terrain == NULL){ ERROR("Need more ram !", 0) } while(keydown(KEY_EXIT) == 0){ ////////// TITLE SCREEN ////////// if(game == 0){ key=getkey().key; if(key==KEY_EXE){ drawselectedgame(selected); game = 1; } } ////////// GAME CHOOSING SCREEN ////////// else if(game == 1){ key=getkey().key; if(key==KEY_DOWN){ if(selected0){ selected--; }else{ selected = GAMESNUM - 1; } drawselectedgame(selected); }else if(key==KEY_EXE){ dclear(C_WHITE); game = 2; } }else if(game == 2){ dtext(1, 1, C_BLACK, WORLDGEN_INFO); dupdate(); for(i=0;i!=WORLD_WIDTH*WORLD_HEIGHT;i++){ terrain[i] = 0; } srand(clock()); generateworld(terrain, WORLD_WIDTH, WORLD_HEIGHT, (int)((rand() % ((WORLD_HEIGHT - 50) - (WORLD_HEIGHT - 60) + 1)) + WORLD_HEIGHT - 60), WORLD_HEIGHT - 60, WORLD_HEIGHT - 50, 0, 1); srand(clock()); generateworld(terrain, WORLD_WIDTH, WORLD_HEIGHT, (int)((rand() % ((WORLD_HEIGHT - 40) - (WORLD_HEIGHT - 50) + 1)) + WORLD_HEIGHT - 50), WORLD_HEIGHT - 50, WORLD_HEIGHT - 40, 3, 2); srand(clock()); generateworld(terrain, WORLD_WIDTH, WORLD_HEIGHT, (int)((rand() % ((WORLD_HEIGHT - 30) - (WORLD_HEIGHT - 40) + 1)) + WORLD_HEIGHT - 40), WORLD_HEIGHT - 40, WORLD_HEIGHT - 30, 4, 2); // dtext(1, 1, C_BLACK, "Adding trees"); ///// Add trees ///// addtrees(terrain); ///////////////////// player.x = 0; /*for(i=0;i!=WORLD_HEIGHT;i++){ if(terrain[i*WORLD_WIDTH+(x>>3)] != 0){ y = i*8-8; break; } } */ player.y = 0; game = 3; hour = 0; player.timing = 0; player.jumping = 0; player.jumpheight = 0; player.falling = 0; player.overlayframe = 0; player.overlaytimer = 0; player.wasdestroyingbefore = 0; player.destroytime = 3; player.select_tx = 0; player.select_ty = 0; player.invselect = 0; player.invmoving = 0; for(i=0;i!=INVENTORY_SIZE;i++){ player.inventoryitems[i] = 0; player.inventorynum[i] = 0; } player.tool = hand; }else if(game == 3){ clock_t begin = clock(); switch(player.inventoryitems[player.invselect]){ case 7: player.tool = wood_pickaxe; break; default: player.tool = hand; break; }; player.select_tx = ((player.x+player.selx)>>3); player.select_ty = ((player.y+player.sely)>>3); clearevents(); if(keydown(KEY_RIGHT) && (collisiononmap(player.x, player.y, terrain, 67, 35) == 0 && collisiononmap(player.x, player.y, terrain, 67, 25) == 0)){ player.x++; if(player.animation == 0 && player.timing == 5){ player.animation = 1; player.timing = 0; }else if(player.animation == 1 && player.timing == 5){ player.animation = 0; player.timing = 0; } player.timing++; player.orient = 1; }else if(keydown(KEY_LEFT) && (collisiononmap(player.x, player.y, terrain, 61, 35) == 0 && collisiononmap(player.x, player.y, terrain, 61, 25) == 0)){ player.x--; if(player.animation == 0 && player.timing == 5){ player.animation = 1; player.timing = 0; }else if(player.animation == 1 && player.timing == 5){ player.animation = 0; player.timing = 0; } player.timing++; player.orient = 3; } if(collisiononmap(player.x, player.y, terrain, 62, 40) == 0 && collisiononmap(player.x, player.y, terrain, 66, 40) == 0 && collisiononmap(player.x, player.y, terrain, 60, 40) == 0 && player.jumping == 0){ player.y++; player.falling = 1; }else{ player.falling = 0; } /* clearevents(); if(keydown(KEY_UP)){ y--; }else if(keydown(KEY_DOWN)){ y++; } */ clearevents(); if(keydown(KEY_SHIFT) && player.jumping == 0 && player.falling == 0 && player.jumpheight == 0){ player.jumping = 1; player.jumpheight = 1; } if(player.jumping == 1 && player.jumpheight == 12){ player.jumping = 0; player.jumpheight = 0; }else if(collisiononmap(player.x, player.y, terrain, 62, 23) || collisiononmap(player.x, player.y, terrain, 66, 23) || collisiononmap(player.x, player.y, terrain, 60, 23)){ player.jumping = 0; player.jumpheight = 0; }else if(player.jumping == 1){ player.jumpheight++; player.y--; } if(exists(terrain, 5)==0){ addtrees(terrain); } if(player.y>>3>WORLD_HEIGHT){ player.y = 0; } clearevents(); if (keydown(KEY_8) && player.sely>-8){ player.sely--; }else if (keydown(KEY_5) && player.sely<24){ player.sely++; } clearevents(); if (keydown(KEY_4) && player.selx>-8){ player.selx--; }else if (keydown(KEY_6) && player.selx<16){ player.selx++; } if(((player.x+player.selx)>>3)!=player.select_tx||((player.y+player.sely)>>3)!=player.select_ty){ player.overlayframe = 0; player.overlaytimer = 0; player.wasdestroyingbefore = 0; } pos = ((player.y+player.sely)>>3)*WORLD_WIDTH+((player.x+player.selx)>>3); if(pos<=WORLD_WIDTH*WORLD_HEIGHT && pos>=0){ player.is_breakable = 1; if(is_in(terrain[pos], player.tool.breakable_easy, player.tool.easy_lenght)){ player.destroytime = 4; }else if(is_in(terrain[pos], player.tool.breakable_middle, player.tool.middle_lenght)){ player.destroytime = 8; }else if(is_in(terrain[pos], player.tool.breakable_hard, player.tool.hard_lenght)){ player.destroytime = 16; }else if(is_in(terrain[pos], player.tool.breakable_very_hard, player.tool.very_hard_lenght)){ player.destroytime = 32; }else{ player.is_breakable = 0; } clearevents(); if (keydown(KEY_EXE)){ int placed = 0; if(terrain[pos] == 0 && player.inventorynum[player.invselect] != 0 && is_in(player.inventoryitems[player.invselect], (int*)canbeplaced, canbeplaced_lenght)){ placed = player.inventoryitems[player.invselect]; terrain[pos] = player.inventoryitems[player.invselect]; player.inventorynum[player.invselect]--; if(player.inventorynum[player.invselect] == 0) { player.inventoryitems[player.invselect] = 0; } if(is_in(placed, (int*)hasmenu, hasmenu_lenght)){ clearevents(); while(keydown(KEY_EXE)){ clearevents(); } } }else if(terrain[pos] == 8){ game = 6; clearevents(); while(keydown(KEY_EXE)){ clearevents(); } } }else if (keydown(KEY_1) && terrain[pos] != 0 && player.is_breakable && player.overlaytimer == player.destroytime && player.overlayframe == 4 && (player.select_tx == player.old_select_tx && player.select_ty == player.old_select_ty)){ for(i=0;i!=INVENTORY_SIZE;i++){ if((terrain[pos] == player.inventoryitems[i] && player.inventorynum[i] < 64 && terrain[pos] != 0) || (player.inventoryitems[i] == 0 && player.inventorynum[i] == 0 && terrain[pos] != 0)) { player.inventoryitems[i] = terrain[pos]; terrain[pos] = 0; player.inventorynum[i]++; break; } } player.overlayframe = 0; player.overlaytimer = 0; player.wasdestroyingbefore = 0; }else if (keydown(KEY_1) && terrain[pos] != 0 && player.is_breakable && (player.select_tx == player.old_select_tx && player.select_ty == player.old_select_ty)){ if(player.overlaytimer == player.destroytime){ player.overlaytimer = 0; player.overlayframe++; } player.overlaytimer++; if(player.wasdestroyingbefore == 0){ player.wasdestroyingbefore = 1; } }else if(player.wasdestroyingbefore == 1 && keydown(KEY_1) == 0){ player.overlayframe = 0; player.overlaytimer = 0; player.wasdestroyingbefore = 0; } } clearevents(); if (keydown(KEY_0)){ if(player.invselect0){ crafting.selected--; }else{ crafting.selected=CRAFTINGS-1; } clearevents(); while(keydown(KEY_LEFT)){ clearevents(); } } if (keydown(KEY_RIGHT)){ if(crafting.selected 0 && player.inventoryitems[destroy.selected] != 0){ player.inventorynum[destroy.selected]--; if(player.inventorynum[destroy.selected] == 0){ player.inventoryitems[destroy.selected] = 0; } clearevents(); while(keydown(KEY_SHIFT)){ clearevents(); } }else if(keydown(KEY_DEL)){ player.inventoryitems[destroy.selected] = 0; player.inventorynum[destroy.selected] = 0; clearevents(); while(keydown(KEY_DEL)){ clearevents(); } }else if (keydown(KEY_0)){ if(destroy.selected