#include #include #include #include "level.h" #include "engine.h" extern Entity missing_no; void start_engine(Level * level) { Engine game; dclear(C_WHITE); init_engine(level, &game); expo(level->script->prologue, level->script->nb_pro); display(&game); while(!game.defeat && !game.victory) { while(game.event_posgame.map->width-4) game.x_view=game.map->width-4; if(game.y_view>game.map->height-4) game.y_view=game.map->height-4; display(&game); if(game.event_list[game.event_pos].ev_func!=NULL) { (*game.event_list[game.event_pos].ev_func)(&game); } textbox(game.event_list[game.event_pos].dialog); while(getkey().key!=KEY_EXE); drect(57,30,127,63,C_WHITE); game.event_pos++; } if(game.entity_list[game.turn%game.nb_entity].HP != 0 && game.entity_list[game.turn%game.nb_entity].MP!=0) { game.x_cursor=game.entity_list[game.turn%game.nb_entity].x; game.y_cursor=game.entity_list[game.turn%game.nb_entity].y; game.x_view = game.x_cursor; game.y_view = game.y_cursor; if(game.x_view<3) game.x_view=3; if(game.y_view<3) game.y_view=3; if(game.x_view>game.map->width-4) game.x_view=game.map->width-4; if(game.y_view>game.map->height-4) game.y_view=game.map->height-4; switch(game.entity_list[game.turn%game.nb_entity].side) { case Ally: display(&game); player(&game); break; case Foe: display(&game); ia(&game); display(&game); break; default: game.turn++; break; } }else{game.turn++;} } if(game.victory) { expo(level->script->epilogue, level->script->nb_epi); } else { dclear(C_WHITE); dtext(35,25,"Game Over", C_BLACK, C_WHITE); dupdate(); getkey(); } } void textbox(char * str) { int len = strlen(str); int lines = (len/11)+1; char buff[12]; memset(buff,0,12); drect(57,30,127,63,C_WHITE); for(int i = 0; imap = level->map; engine->nb_event = level->script->nb_event; engine->event_list = level->script->event_list; engine->nb_entity = level->nb_entity; engine->entity_list = level->entity_list; engine->nb_ally = 0; engine->nb_foe = 0; for (int i = 0; i < engine->nb_entity; i++) { switch(engine->entity_list[i].side) { case Ally: engine->nb_ally++; break; case Foe: engine->nb_foe++; break; default:break; } } engine->turn = 0; engine->event_pos=0; engine->x_view = 3; engine->y_view = 3; engine->x_cursor = 3; engine->y_cursor = 3; engine->victory = false; engine->defeat = false; } void move (Engine * engine) { Entity * player = &engine->entity_list[engine->turn%engine->nb_entity]; switch(getkey().key) { case KEY_UP: case KEY_8: if(player->y>0) { if(engine->map->tile[((player->y - 1)*engine->map->width+player->x)].entity->side == Zero) { engine->map->tile[(player->y - 1)*engine->map->width+player->x].entity = player; engine->map->tile[(player->y)*engine->map->width+player->x].entity = &missing_no; player->y--; player->MP--; engine->turn++; } } break; case KEY_DOWN: case KEY_2: if(player->ymap->height-1) { if(engine->map->tile[((player->y + 1)*engine->map->width+player->x)].entity->side == Zero) { engine->map->tile[(player->y + 1)*engine->map->width+player->x].entity = player; engine->map->tile[(player->y)*engine->map->width+player->x].entity = &missing_no; player->y++; player->MP--; engine->turn++; } } break; case KEY_LEFT: case KEY_4: if(player->x>0) { if(engine->map->tile[((player->y)*engine->map->width+player->x - 1)].entity->side == Zero) { engine->map->tile[(player->y)*engine->map->width+player->x-1].entity = player; engine->map->tile[(player->y)*engine->map->width+player->x].entity = &missing_no; player->x--; player->MP--; engine->turn++; } } break; case KEY_RIGHT: case KEY_6: if(player->xmap->width-1) { if(engine->map->tile[((player->y)*engine->map->width+player->x + 1)].entity->side == Zero) { engine->map->tile[(player->y)*engine->map->width+player->x + 1].entity = player; engine->map->tile[(player->y)*engine->map->width+player->x].entity = &missing_no; player->x++; player->MP--; engine->turn++; } } break; case KEY_5: player->MP--; engine->turn++; break; default: break; } } void sprint(Engine * engine) { Entity * player = &engine->entity_list[engine->turn%engine->nb_entity]; switch(getkey().key) { case KEY_UP: case KEY_8: if(player->y>1) { if(engine->map->tile[((player->y - 2)*engine->map->width+player->x)].entity->side == Zero) { engine->map->tile[(player->y - 2)*engine->map->width+player->x].entity = player; engine->map->tile[(player->y)*engine->map->width+player->x].entity = &missing_no; player->y-=2; player->MP-=2; engine->turn++; } } break; case KEY_DOWN: case KEY_2: if(player->ymap->height-2) { if(engine->map->tile[((player->y + 2)*engine->map->width+player->x)].entity->side == Zero) { engine->map->tile[(player->y + 2)*engine->map->width+player->x].entity = player; engine->map->tile[(player->y)*engine->map->width+player->x].entity = &missing_no; player->y+=2; player->MP-=2; engine->turn++; } } break; case KEY_LEFT: case KEY_4: if(player->x>1) { if(engine->map->tile[((player->y)*engine->map->width+player->x - 2)].entity->side == Zero) { engine->map->tile[(player->y)*engine->map->width+player->x-2].entity = player; engine->map->tile[(player->y)*engine->map->width+player->x].entity = &missing_no; player->x-=2; player->MP-=2; engine->turn++; } } break; case KEY_RIGHT: case KEY_6: if(player->xmap->width-2) { if(engine->map->tile[((player->y)*engine->map->width+player->x + 2)].entity->side == Zero) { engine->map->tile[(player->y)*engine->map->width+player->x + 2].entity = player; engine->map->tile[(player->y)*engine->map->width+player->x].entity = &missing_no; player->x+=2; player->MP-=2; engine->turn++; } } break; case KEY_5: player->MP--; engine->turn++; break; default: break; } } void atk (Engine * engine) { Entity * player = &engine->entity_list[engine->turn%engine->nb_entity]; switch(getkey().key) { case KEY_UP: case KEY_8: if(player->y>0) { if(engine->map->tile[((player->y - 1)*engine->map->width+player->x)].entity->side != Zero) { engine->map->tile[(player->y - 1)*engine->map->width+player->x].entity->HP -= player->ATK; if(engine->map->tile[(player->y - 1)*engine->map->width+player->x].entity->HP<=0) { engine->nb_foe--; engine->map->tile[(player->y - 1)*engine->map->width+player->x].entity = &missing_no; } player->MP--; engine->turn++; } } break; case KEY_DOWN: case KEY_2: if(player->ymap->height-1) { if(engine->map->tile[((player->y + 1)*engine->map->width+player->x)].entity->side != Zero) { engine->map->tile[(player->y + 1)*engine->map->width+player->x].entity->HP = player->ATK; if(engine->map->tile[(player->y + 1)*engine->map->width+player->x].entity->HP<=0) { engine->nb_foe--; engine->map->tile[(player->y + 1)*engine->map->width+player->x].entity = &missing_no; } player->MP--; engine->turn++; } } break; case KEY_LEFT: case KEY_4: if(player->x>0) { if(engine->map->tile[((player->y)*engine->map->width+player->x - 1)].entity->side != Zero) { engine->map->tile[(player->y)*engine->map->width+player->x-1].entity->HP -= player->ATK; if(engine->map->tile[(player->y)*engine->map->width+player->x-1].entity->HP<=0) { engine->nb_foe--; engine->map->tile[(player->y)*engine->map->width+player->x-1].entity = &missing_no; } player->MP--; engine->turn++; } } break; case KEY_RIGHT: case KEY_6: if(player->xmap->width-1) { if(engine->map->tile[((player->y)*engine->map->width+player->x + 1)].entity->side != Zero) { engine->map->tile[(player->y)*engine->map->width+player->x + 1].entity->HP -= player->ATK; if(engine->map->tile[(player->y)*engine->map->width+player->x+1].entity->HP<=0) { engine->nb_foe--; engine->map->tile[(player->y)*engine->map->width+player->x+1].entity = &missing_no; } player->MP--; engine->turn++; } } break; default: break; } engine->victory = (engine->nb_foe==0); } void atk2(Engine * engine) { Entity * player = &engine->entity_list[engine->turn%engine->nb_entity]; switch(getkey().key) { case KEY_UP: case KEY_8: if(player->y>1) { if(engine->map->tile[((player->y - 2)*engine->map->width+player->x)].entity->side != Zero) { engine->map->tile[(player->y - 2)*engine->map->width+player->x].entity->HP -= player->ATK; if(engine->map->tile[(player->y - 2)*engine->map->width+player->x].entity->HP<=0) { engine->nb_foe--; engine->map->tile[(player->y - 1)*engine->map->width+player->x].entity = &missing_no; } player->MP--; engine->turn++; } } break; case KEY_DOWN: case KEY_2: if(player->ymap->height-2) { if(engine->map->tile[((player->y + 2)*engine->map->width+player->x)].entity->side != Zero) { engine->map->tile[(player->y + 2)*engine->map->width+player->x].entity->HP = player->ATK; if(engine->map->tile[(player->y + 2)*engine->map->width+player->x].entity->HP<=0) { engine->nb_foe--; engine->map->tile[(player->y + 2)*engine->map->width+player->x].entity = &missing_no; } player->MP--; engine->turn++; } } break; case KEY_LEFT: case KEY_4: if(player->x>1) { if(engine->map->tile[((player->y)*engine->map->width+player->x - 2)].entity->side != Zero) { engine->map->tile[(player->y)*engine->map->width+player->x-2].entity->HP -= player->ATK; if(engine->map->tile[(player->y)*engine->map->width+player->x-2].entity->HP<=0) { engine->nb_foe--; engine->map->tile[(player->y)*engine->map->width+player->x-2].entity = &missing_no; } player->MP--; engine->turn++; } } break; case KEY_RIGHT: case KEY_6: if(player->xmap->width-2) { if(engine->map->tile[((player->y)*engine->map->width+player->x + 2)].entity->side != Zero) { engine->map->tile[(player->y)*engine->map->width+player->x + 2].entity->HP -= player->ATK; if(engine->map->tile[(player->y)*engine->map->width+player->x+2].entity->HP<=0) { engine->nb_foe--; engine->map->tile[(player->y)*engine->map->width+player->x+2].entity = &missing_no; } player->MP--; engine->turn++; } } break; default: break; } engine->victory = (engine->nb_foe==0); } void display(Engine * engine) { extern image_t img_grid; extern image_t img_forest; extern image_t img_mountain; extern image_t img_path; extern image_t img_cloud; extern image_t img_forest_big; extern image_t img_mountain_big; extern image_t img_path_big; extern image_t img_cloud_big; extern image_t img_foe; extern image_t img_ally; extern image_t img_cursor; dclear(C_WHITE); dimage(0,0,&img_grid); for(int i = 0; i < 7; i++) { for( int j = 0; j < 7 ; j++) { switch(engine->map->tile[(engine->x_view)-3+j+(engine->map->width)*(engine->y_view-3+i)].type) { case Forest: dimage(j*8+1,i*8+1,&img_forest); break; case Mountain: dimage(j*8+1,i*8+1,&img_mountain); break; case Path: dimage(j*8+1,i*8+1,&img_path); break; case Cloud: dimage(j*8+1,i*8+1,&img_cloud); break; } } } for(int i = 0; i < engine->nb_entity; i++) { if((engine->entity_list[i].x - engine->x_view)>=-3 && (engine->entity_list[i].y - engine->y_view)>=-3 && (engine->entity_list[i].x - engine->x_view)<=3 && (engine->entity_list[i].y - engine->y_view)<=3) { switch(engine->entity_list[i].side) { case Ally: dimage((engine->entity_list[i].x - engine->x_view + 3)*8+1,(engine->entity_list[i].y - engine->y_view + 3)*8+1, &img_ally); break; case Foe: dimage((engine->entity_list[i].x - engine->x_view + 3)*8+1,(engine->entity_list[i].y - engine->y_view + 3)*8+1, &img_foe); break; default:break; } } } if(engine->map->tile[engine->x_cursor+(engine->map->width)*(engine->y_cursor)].entity->side==Zero) { switch(engine->map->tile[engine->x_cursor+(engine->map->width)*(engine->y_cursor)].type) { case Forest: dimage(58,0,&img_forest_big); dtext(58,30,"Forest",C_BLACK,C_WHITE); break; case Mountain: dimage(58,0,&img_mountain_big); dtext(58,30,"Mountain",C_BLACK,C_WHITE); break; case Path: dimage(58,0,&img_path_big); dtext(58,30,"Path",C_BLACK,C_WHITE); break; case Cloud: dimage(58,0,&img_cloud_big); dtext(58,30,"Cloud",C_BLACK,C_WHITE); break; } }else{ Entity * focus =engine->map->tile[engine->x_cursor+(engine->map->width)*(engine->y_cursor)].entity; if(focus->side!=Zero) { dimage(58,0,focus->picture); dprint(90,0,C_BLACK,C_WHITE,"%s",focus->name); dprint(90,9,C_BLACK,C_WHITE,"HP:%d",focus->HP); dprint(90,19,C_BLACK,C_WHITE,"MP:%d",focus->MP); } } if((engine->x_cursor - engine->x_view)>=-3 && (engine->y_cursor - engine->y_view)>=-3 && (engine->x_cursor - engine->x_view)<=3 && (engine->y_cursor - engine->y_view)<=3) dimage((engine->x_cursor - engine->x_view + 3)*8,(engine->y_cursor - engine->y_view + 3)*8, &img_cursor); dupdate(); } void player(Engine * engine) { const int old_turn=engine->turn; while(old_turn==engine->turn) { switch(getkey().key) { case KEY_UP: if(engine->y_cursor>0)engine->y_cursor--; break; case KEY_DOWN: if(engine->y_cursormap->height-1)engine->y_cursor++; break; case KEY_LEFT: if(engine->x_cursor>0)engine->x_cursor--; break; case KEY_RIGHT: if(engine->x_cursormap->width-1)engine->x_cursor++; break; case KEY_8: if(engine->y_view>3)engine->y_view--; break; case KEY_2: if(engine->y_viewmap->height-4)engine->y_view++; break; case KEY_4: if(engine->x_view>3)engine->x_view--; break; case KEY_6: if(engine->x_viewmap->width-4)engine->x_view++; break; case KEY_5: engine->x_view = engine->x_cursor; engine->y_view = engine->y_cursor; if(engine->x_view<3) engine->x_view=3; if(engine->y_view<3) engine->y_view=3; if(engine->x_view>engine->map->width-4) engine->x_view=engine->map->width-4; if(engine->y_view>engine->map->height-4) engine->y_view=engine->map->height-4; break; case KEY_EXIT: engine->defeat= true; engine->turn++; break; case KEY_F1: move(engine); break; case KEY_F2: sprint(engine); break; case KEY_F3: atk(engine); break; case KEY_F4: atk2(engine); break; default: break; } display(engine); } if(engine->entity_list[old_turn%engine->nb_entity].MP<=0) { engine->nb_ally--; engine->map->tile[engine->entity_list[old_turn%engine->nb_entity].x+(engine->map->width)*engine->entity_list[old_turn%engine->nb_entity].y].entity = &missing_no; engine->defeat = (engine->nb_ally == 0); } } void ia(Engine * engine) { Entity * foe = &engine->entity_list[engine->turn%engine->nb_entity]; if(foe->x>0 && engine->map->tile[foe->x-1+foe->y*engine->map->width].entity->side == Ally) { Entity * target = engine->map->tile[foe->x-1+foe->y*engine->map->width].entity; dtext(0,0,"0",C_BLACK,C_WHITE); dupdate(); getkey(); target->HP-=foe->ATK; if(target->HP<=0) { engine->nb_ally--; engine->map->tile[target->x+(engine->map->width)*target->y].entity = &missing_no; engine->defeat = (engine->nb_ally == 0); } foe->MP--; engine->turn++; } else if(foe->y>0 && engine->map->tile[foe->x+(foe->y-1)*engine->map->width].entity->side == Ally) { Entity * target = engine->map->tile[foe->x+(foe->y-1)*engine->map->width].entity; dtext(0,0,"1",C_BLACK,C_WHITE); dupdate(); getkey(); target->HP-=foe->ATK; if(target->HP<=0) { engine->nb_ally--; engine->map->tile[target->x+(engine->map->width)*target->y].entity = &missing_no; engine->defeat = (engine->nb_ally == 0); } foe->MP--; engine->turn++; } else if(foe->xmap->width-1 && engine->map->tile[foe->x+1+(foe->y)*engine->map->width].entity->side == Ally) { Entity * target = engine->map->tile[foe->x+1+(foe->y)*engine->map->width].entity; dtext(0,0,"2",C_BLACK,C_WHITE); dupdate(); getkey(); target->HP-=foe->ATK; if(target->HP<=0) { engine->nb_ally--; engine->map->tile[target->x+(engine->map->width)*target->y].entity = &missing_no; engine->defeat = (engine->nb_ally == 0); } foe->MP--; engine->turn++; } else if(foe->ymap->height-1 && engine->map->tile[foe->x+(foe->y+1)*engine->map->width].entity->side == Ally) { Entity * target = engine->map->tile[foe->x+(foe->y+1)*engine->map->width].entity; dtext(0,0,"3",C_BLACK,C_WHITE); dupdate(); getkey(); target->HP-=foe->ATK; if(target->HP<=0) { engine->nb_ally--; engine->map->tile[target->x+(engine->map->width)*target->y].entity = &missing_no; engine->defeat = (engine->nb_ally == 0); } foe->MP--; engine->turn++; }else if(foe->x>1 && engine->map->tile[foe->x-2+foe->y*engine->map->width].entity->side == Ally) { Entity * target = engine->map->tile[foe->x-2+foe->y*engine->map->width].entity; dtext(0,0,"4",C_BLACK,C_WHITE); dupdate(); getkey(); target->HP-=foe->ATK; if(target->HP<=0) { engine->nb_ally--; engine->map->tile[target->x+(engine->map->width)*target->y].entity = &missing_no; engine->defeat = (engine->nb_ally == 0); } foe->MP-=2; engine->turn++; } else if(foe->y>1 && engine->map->tile[foe->x+(foe->y-2)*engine->map->width].entity->side == Ally) { Entity * target = engine->map->tile[foe->x+(foe->y-2)*engine->map->width].entity; dtext(0,0,"5",C_BLACK,C_WHITE); dupdate(); getkey(); target->HP-=foe->ATK; if(target->HP<=0) { engine->nb_ally--; engine->map->tile[target->x+(engine->map->width)*target->y].entity = &missing_no; engine->defeat = (engine->nb_ally == 0); } foe->MP-=2; engine->turn++; } else if(foe->xmap->width-2 && engine->map->tile[foe->x+2+(foe->y)*engine->map->width].entity->side == Ally) { Entity * target = engine->map->tile[foe->x+2+(foe->y)*engine->map->width].entity; dtext(0,0,"6",C_BLACK,C_WHITE); dupdate(); getkey(); target->HP-=foe->ATK; if(target->HP<=0) { engine->nb_ally--; engine->map->tile[target->x+(engine->map->width)*target->y].entity = &missing_no; engine->defeat = (engine->nb_ally == 0); } foe->MP-=2; engine->turn++; } else if(foe->ymap->height-2 && engine->map->tile[foe->x+(foe->y+2)*engine->map->width].entity->side == Ally) { Entity * target = engine->map->tile[foe->x+(foe->y+2)*engine->map->width].entity; dtext(0,0,"7",C_BLACK,C_WHITE); dupdate(); getkey(); target->HP-=foe->ATK; if(target->HP<=0) { engine->nb_ally--; engine->map->tile[target->x+(engine->map->width)*target->y].entity = &missing_no; engine->defeat = (engine->nb_ally == 0); } foe->MP-=2; engine->turn++; }else{ int target_id=0; dtext(0,0,"8",C_BLACK,C_WHITE); dupdate(); getkey(); while(engine->entity_list[target_id].HP == 0 ||engine->entity_list[target_id].MP==0) { target_id++; } Entity * target = &engine->entity_list[target_id]; int dx = target->x - foe->x; int dy = target->y - foe->y; if (dy > 2) { dtext(0,0,"9",C_BLACK,C_WHITE); dupdate(); getkey(); if(engine->map->tile[foe->x+engine->map->width*(foe->y+2)].entity->side==Zero) { foe->MP-=2; engine->map->tile[foe->x+engine->map->width*(foe->y+2)].entity = foe; engine->map->tile[foe->x+engine->map->width*(foe->y)].entity = &missing_no; foe->y+=2; }else if(engine->map->tile[foe->x+engine->map->width*(foe->y+1)].entity->side==Zero) { foe->MP--; engine->map->tile[foe->x+engine->map->width*(foe->y+1)].entity = foe; engine->map->tile[foe->x+engine->map->width*(foe->y)].entity = &missing_no; foe->y+=1; }else{ foe->MP--; } }else if (dy < -2) { if(engine->map->tile[foe->x+engine->map->width*(foe->y-2)].entity->side==Zero) { foe->MP-=2; engine->map->tile[foe->x+engine->map->width*(foe->y-2)].entity = foe; engine->map->tile[foe->x+engine->map->width*(foe->y)].entity = &missing_no; foe->y-=2; }else if(engine->map->tile[foe->x+engine->map->width*(foe->y-1)].entity->side==Zero) { foe->MP--; engine->map->tile[foe->x+engine->map->width*(foe->y-1)].entity = foe; engine->map->tile[foe->x+engine->map->width*(foe->y)].entity = &missing_no; foe->y-=1; }else{ foe->MP--; } }else if (dx > 2) { if(engine->map->tile[foe->x+2+engine->map->width*(foe->y)].entity->side==Zero) { foe->MP-=2; engine->map->tile[foe->x+2+engine->map->width*(foe->y)].entity = foe; engine->map->tile[foe->x+engine->map->width*(foe->y)].entity = &missing_no; foe->x+=2; }else if(engine->map->tile[foe->x+1+engine->map->width*(foe->y)].entity->side==Zero) { foe->MP--; engine->map->tile[foe->x+1+engine->map->width*(foe->y)].entity = foe; engine->map->tile[foe->x+engine->map->width*(foe->y)].entity = &missing_no; foe->x+=1; }else{ foe->MP--; } }else if (dx < -2) { if(engine->map->tile[foe->x-2+engine->map->width*(foe->y)].entity->side==Zero) { foe->MP-=2; engine->map->tile[foe->x-2+engine->map->width*(foe->y)].entity = foe; engine->map->tile[foe->x+engine->map->width*(foe->y)].entity = &missing_no; foe->x-=2; }else if(engine->map->tile[foe->x-1+engine->map->width*(foe->y)].entity->side==Zero) { foe->MP--; engine->map->tile[foe->x-1+engine->map->width*(foe->y)].entity = foe; engine->map->tile[foe->x+engine->map->width*(foe->y)].entity = &missing_no; foe->x-=1; }else{ foe->MP--; } }else if (dy == 1) { if(engine->map->tile[foe->x+engine->map->width*(foe->y+1)].entity->side==Zero) { foe->MP--; engine->map->tile[foe->x+engine->map->width*(foe->y+1)].entity = foe; engine->map->tile[foe->x+engine->map->width*(foe->y)].entity = &missing_no; foe->y+=1; }else{ foe->MP--; } }else if (dy == -1) { if(engine->map->tile[foe->x+engine->map->width*(foe->y-1)].entity->side==Zero) { foe->MP--; engine->map->tile[foe->x+engine->map->width*(foe->y-1)].entity = foe; engine->map->tile[foe->x+engine->map->width*(foe->y)].entity = &missing_no; foe->y-=1; }else{ foe->MP--; } }else if (dx == 1) { if(engine->map->tile[foe->x+1+engine->map->width*(foe->y)].entity->side==Zero) { foe->MP--; engine->map->tile[foe->x+1+engine->map->width*(foe->y)].entity = foe; engine->map->tile[foe->x+engine->map->width*(foe->y)].entity = &missing_no; foe->x+=1; }else{ foe->MP--; } }else if (dx == -1) { if(engine->map->tile[foe->x-1+engine->map->width*(foe->y)].entity->side==Zero) { foe->MP--; engine->map->tile[foe->x-1+engine->map->width*(foe->y)].entity = foe; engine->map->tile[foe->x+engine->map->width*(foe->y)].entity = &missing_no; foe->x-=1; }else{ foe->MP--; } } engine->turn++; } if (foe->MP<=0) { engine->nb_foe--; engine->map->tile[foe->x+(engine->map->width)*foe->y].entity = &missing_no; engine->victory = (engine->nb_foe == 0); } }