// --------- Begin of function Unit::teleport --------// // return 1 on success int Unit::teleport(int targetXLoc, int targetYLoc ) { // ###### begin Gilbert 21/3 ########// if( !is_visible() ) return 0; // ###### end Gilbert 21/3 ########// if( world.check_unit_space( targetXLoc, targetYLoc, targetXLoc+loc_width-1, targetYLoc+loc_height-1, mobile_type) ) { stop_order(); int dx, dy; for( dy = 0; dy < loc_width; ++dy ) for( dx = 0; dx < loc_height; ++dx ) world.get_loc(next_x_loc()+dx, next_y_loc()+dy)->remove_unit( mobile_type ); cur_x = go_x = next_x = targetXLoc * LOCATE_WIDTH; cur_y = go_y = next_y = targetYLoc * LOCATE_HEIGHT; for( dy = 0; dy < loc_width; ++dy ) for( dx = 0; dx < loc_height; ++dx ) world.get_loc( next_x_loc()+dx, next_y_loc()+dy)->set_unit( sprite_recno, mobile_type ); explore_area(); return 1; } return 0; }
//--------- Begin of function Unit::init_sprite ---------// // // <int> startXLoc, startYLoc - the starting location of the unit // void Unit::init_sprite(int startXLoc, int startYLoc) { Sprite::init( unit_res[unit_id]->sprite_id, startXLoc, startYLoc ); // BUGHERE use unit_id temporarily //-------- set loc_width and loc_height ------// loc_width = (char) sprite_info->loc_width; loc_height = (char) sprite_info->loc_height; // copy the vars for fast access // ###### begin Gilbert 30/4 ##########// move_to_loc_x = startXLoc; // * LOCATE_WIDTH; move_to_loc_y = startYLoc; // * LOCATE_HEIGHT; // ###### end Gilbert 30/4 ##########// //-------- set the cargo_recno -------------// int w, h, x, y; err_if(!sprite_recno) // sprite_recno must be initialized first before calling UnitB::init() err_here(); for(h=0, y=startYLoc; h<loc_height; h++, y++) { for(w=0, x=startXLoc; w<loc_width; w++, x++) { err_if( !world.get_loc(x, y)->can_move(mobile_type) ) // it must be 0 to put the sprite in this location err_here(); world.get_loc(x, y)->set_unit(sprite_recno, mobile_type); } } explore_area(); }
//--------- Begin of function Unit::change_nation ---------// // // This function is called when a unit change nation. // It is not necessarily a result of betray, when a spy // hands over his new nation to his parent nation, this // function will also be called. // // <int> newNationRecno - change the nation of the unit. // void Unit::change_nation(int newNationRecno) { err_when( newNationRecno && nation_array.is_deleted(newNationRecno) ); err_when( unit_mode == UNIT_MODE_REBEL ); // rebels do not change nation //--- special case: units in Monster Fortress cannot change nation ---// if( unit_mode == UNIT_MODE_OVERSEE && firm_array[unit_mode_para]->firm_id == FIRM_FORTRESS ) { return; } //---------------------------------// int oldAiUnit = is_ai; int oldNationRecno = nation_recno; //-- if the player is giving a command to this unit, cancel the command --// if( nation_recno == nation_array.player_recno && sprite_recno == unit_array.selected_recno && power.command_id ) { power.command_id = 0; } //---------- stop all action to attack this unit ------------// unit_array.stop_attack_obj(base_obj_recno); //---- update nation_unit_count_array[] ----// unit_res[unit_id]->unit_change_nation(newNationRecno, nation_recno, rank_id); //------- if the nation has an AI action -------// stop_order(); // clear the existing order //---------------- update vars ----------------// // unit_group_id = unit_array.cur_group_id++; // separate from the current group nation_recno = newNationRecno; home_camp_firm_recno = 0; // reset it if( race_id ) { nation_contribution = 0; // contribution to the nation total_reward = 0; } // #### begin Gilbert 24/12 #######// // -------- reset royal -------// is_royal = 0; // #### end Gilbert 24/12 #######// //-------- if change to one of the existing nations ------// is_ai = nation_recno && nation_array[nation_recno]->is_ai(); //------------ update AI info --------------// if( oldNationRecno ) { Nation* nationPtr = nation_array[oldNationRecno]; if( rank_id == RANK_GENERAL || rank_id == RANK_KING ) nationPtr->del_general_info(sprite_recno); else if( unit_res[unit_id]->unit_class == UNIT_CLASS_CARAVAN ) nationPtr->del_caravan_info(sprite_recno); else if( unit_res[unit_id]->unit_class == UNIT_CLASS_SHIP ) nationPtr->del_ship_info(sprite_recno); } if( nation_recno ) { Nation* nationPtr = nation_array[nation_recno]; if( rank_id == RANK_GENERAL || rank_id == RANK_KING ) nationPtr->add_general_info(sprite_recno); else if( unit_res[unit_id]->unit_class == UNIT_CLASS_CARAVAN ) nationPtr->add_caravan_info(sprite_recno); else if( unit_res[unit_id]->unit_class == UNIT_CLASS_SHIP ) nationPtr->add_ship_info(sprite_recno); } //------ if this unit oversees a firm -----// if( unit_mode==UNIT_MODE_OVERSEE ) firm_array[unit_mode_para]->change_nation(newNationRecno); //----- this unit was defending the town before it gets killed ----// else if( unit_mode==UNIT_MODE_TOWN_DEFENDER ) { if( !town_array.is_deleted(unit_mode_para) ) town_array[unit_mode_para]->reduce_defender_count(); set_mode(0); // reset unit mode } //---- if the unit is no longer the same nation as the leader ----// if( leader_unit_recno ) { Unit* leaderUnit = unit_array[leader_unit_recno]; if( leaderUnit->nation_recno != nation_recno ) { err_when( !leaderUnit->team_info ); leaderUnit->team_info->del_member(sprite_recno); leader_unit_recno = 0; // team_id = 0; } } // ##### begin Gilbert 9/2 #######// explore_area(); // ##### end Gilbert 9/2 #######// //------ if it is currently selected -------// if( selected_flag ) info.disp(); err_when( spy_recno && spy_array[spy_recno]->cloaked_nation_recno != nation_recno ); if( spy_recno && spy_array[spy_recno]->cloaked_nation_recno != nation_recno ) // BUGHERE - fix bug on-fly spy_array[spy_recno]->cloaked_nation_recno = nation_recno; }
/*aktualisiert eine Map gemäß einem Event*/ void process_event(KeyAction action, Map *map){ Spawn *player=get_player_spawn(map); Spawn *npc; Tile *tile; bool should_run_ai = true; /*Aktion des Spielers*/ switch(action){ case UP: npc=get_spawn_at(player->x,player->y-1, map); player->direction=NORTH; /*kein NPC in Laufrichtung*/ if(npc==NULL){ /*auf Laufbarem laufen*/ tile=&(map->tiles[player->x+map->x*(player->y-1)]); player->y--; spawn_tile_collision(player,tile,map); explore_area(player,map); } /*NPC in Laufrichtung*/ else{ spawn_spawn_collision(player,npc,map); } break; case DOWN: npc=get_spawn_at(player->x,player->y+1, map); player->direction=SOUTH; /*kein NPC in Laufrichtung*/ if(npc==NULL){ /*auf Laufbarem laufen*/ tile=&(map->tiles[player->x+map->x*(player->y+1)]); player->y++; spawn_tile_collision(player,tile,map); explore_area(player,map); } /*NPC in Laufrichtung*/ else{ spawn_spawn_collision(player,npc,map); } break; case LEFT: npc=get_spawn_at(player->x-1,player->y, map); /*kein NPC in Laufrichtung*/ player->direction=WEST; if(npc==NULL){ /*auf Laufbarem laufen*/ tile=&(map->tiles[player->x-1+map->x*player->y]); player->x--; spawn_tile_collision(player,tile,map); explore_area(player,map); } /*NPC in Laufrichtung*/ else{ spawn_spawn_collision(player,npc,map); } break; case RIGHT: npc=get_spawn_at(player->x+1,player->y, map); player->direction=EAST; /*kein NPC in Laufrichtung*/ if(npc==NULL){ /*auf Laufbarem laufen*/ tile=&(map->tiles[player->x+1+map->x*player->y]); player->x++; spawn_tile_collision(player,tile,map); explore_area(player,map); } /*NPC in Laufrichtung*/ else{ spawn_spawn_collision(player,npc,map); } break; case ACTION: /*zu toggelnden Spawn/Tile feststellen*/ switch(player->direction){ case NORTH: npc=get_spawn_at(player->x,player->y-1, map); tile=&(map->tiles[player->x+map->x*(player->y-1)]); break; case SOUTH: npc=get_spawn_at(player->x,player->y+1, map); tile=&(map->tiles[player->x+map->x*(player->y+1)]); break; case WEST: npc=get_spawn_at(player->x-1,player->y, map); tile=&(map->tiles[player->x-1+map->x*player->y]); break; case EAST: npc=get_spawn_at(player->x+1,player->y, map); tile=&(map->tiles[player->x+1+map->x*player->y]); break; } /* wenn kein NPC dasteht */ if(npc == NULL){ /* checken, ob Button, und ob von hier aus drückbar */ if(tile->type == TILE_TYPE_BUTTON) { ButtonProperties* btn_props = (ButtonProperties*)tile->properties; /* von Süden? Player guckt nach Norden */ if( (player->direction == NORTH && (btn_props->directions & SOUTH)) || (player->direction == SOUTH && (btn_props->directions & NORTH)) || (player->direction == EAST && (btn_props->directions & WEST)) || (player->direction == WEST && (btn_props->directions & EAST)) ) { toggle_tile(tile, map); } } else { toggle_tile(tile, map); } } else{ /*vll noch sowas wie spawn_toggle_spawn?*/ } break; case NEXT_ITEM: should_run_ai = false; /*Inventar durchschalten*/ if(player->inventory!=NULL && player->inventory_size!=0){ player->selected_item=(player->selected_item+1)%player->inventory_size; } break; case PREV_ITEM: should_run_ai = false; if(player->inventory!=NULL && player->inventory_size!=0){ if(player->selected_item) player->selected_item=player->selected_item-1; else player->selected_item=player->inventory_size-1; } break; case NEXT_MSG: should_run_ai = false; /*durch die History scrollen, nicht wrappen*/ if(map->current_msg!=map->latest_msg && map->msg_hist[map->current_msg+1]!=NULL){ map->current_msg++; } break; case PREV_MSG: should_run_ai = false; if(map->current_msg!=0 && map->msg_hist[map->current_msg-1]!=NULL) --map->current_msg; break; case USE: if(player->inventory != NULL && player->inventory[player->selected_item] != NULL) { spawn_uses_item (player, player->inventory[player->selected_item], map); } break; default: break; } /*jetzt handeln die NPCs*/ unsigned int i; if (should_run_ai) { for(i=0;i<map->number_of_spawns;i++){ /*den Spieler auslassen*/ if(map->spawns[i]->npc) spawn_action(map->spawns[i], map); } } }
int main(int argc, char *argv[]){ Spawn *player; InterfaceData idata = {0, NULL, -1, NULL, 1}; SDL_Event event; int num_tiles = OUTPUT_IN_GLYPHS_X * OUTPUT_IN_GLYPHS_Y, i; /*SDL anmachen*/ if(SDL_Init(SDL_INIT_VIDEO)) return EXIT_FAILURE; SDL_EnableKeyRepeat(200, 50); /*Karte laden*/ if(argc==2) map=load_map(argv[1]); else{ fprintf(stderr,"Kartennamen angeben\n"); return EXIT_FAILURE; } if(map == NULL) { fprintf(stderr,"Fehler beim Laden der Karte\n"); return EXIT_FAILURE; } player = get_player_spawn(map); if(player==NULL){ fprintf(stderr, "Kein Spieler auf der Karte\n"); return EXIT_FAILURE; } /*Map zeichnen*/ /* Ausgabepuffer initialisieren */ buf = (BufferTile*)ex_malloc(sizeof(BufferTile) * num_tiles); for(i = 0; i < num_tiles; ++i) { BufferTile bt = {' ', 0x00000000}; buf[i] = bt; } output_init(OUTPUT_IN_GLYPHS_X, OUTPUT_IN_GLYPHS_Y, map->name); explore_area(player, map); create_output_buffer(map, buf, num_tiles); get_interface_data(map, &idata); output_draw(buf, num_tiles, &idata); /*Eingabeloop*/ int quit=0; KeyAction current_action = INVALID; while(SDL_WaitEvent(&event)){ if(event.type == SDL_KEYDOWN) { current_action = get_action(event.key.keysym.sym); /*bei Escape beenden*/ if(event.key.keysym.sym == SDLK_ESCAPE){ quit=1; break; } if(current_action != INVALID) { process_event(current_action, map); } create_output_buffer(map, buf, num_tiles); get_interface_data(map, &idata); output_draw(buf, num_tiles, &idata); } else if(event.type == SDL_QUIT) { quit=1; break; } SDL_Delay(1); /*Affe tot => Klappe zu*/ if(player->hp<=0){ game_over(0); break; } /* Ende erreicht */ if(map->finished) { game_over(1); break; } } if(!quit){ while(SDL_WaitEvent(&event)){ /*bei Escape beenden*/ if(event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE)) { break; } SDL_Delay(1); } } free(buf); flush_map(map); free(idata.message); free(idata.item_name); output_close(); SDL_Quit(); return EXIT_SUCCESS; }