bool Units::can_convert (const symbol from, const symbol to) const { if (from == to) return true; // Defined? if (!has_unit(from) || !has_unit (to)) { if (!allow_old ()) return false; else return Oldunits::can_convert (from, to); } const Unit& from_unit = get_unit (from); const Unit& to_unit = get_unit (to); if (compatible (from_unit, to_unit)) return true; if (!allow_old ()) return false; return Oldunits::can_convert (from, to); }
bool Units::can_convert (const symbol from, const symbol to, const double value) const { if (from == to) return true; // Defined? if (!has_unit(from) || !has_unit (to)) { if (!allow_old ()) return false; else return Oldunits::can_convert (from, to, value); } const Unit& from_unit = get_unit (from); const Unit& to_unit = get_unit (to); if (!compatible (from_unit, to_unit)) return false; if (!from_unit.in_native (value)) return false; const double base = from_unit.to_base (value); // We don't have to worry about [cm] and [hPa] as all values are valid. return to_unit.in_base (base); }
action::error attack::check_validity() const { // Verify that the unit that planned this attack exists if(!get_unit()) { return NO_UNIT; } // Verify that the target hex is still valid if(!target_hex_.valid()) { return INVALID_LOCATION; } // Verify that the target hex isn't empty if(resources::units->find(target_hex_) == resources::units->end()){ return NO_TARGET; } // Verify that the attacking unit has attacks left if(get_unit()->attacks_left() <= 0) { return NO_ATTACK_LEFT; } // Verify that the attacker and target are enemies if(!(*resources::teams)[get_unit()->side() - 1].is_enemy(resources::units->find(target_hex_)->side())){ return NOT_AN_ENEMY; } //@todo: (maybe) verify that the target hex contains the same unit that before, // comparing for example the unit ID return move::check_validity(); }
// Read until one whole character is decoded. boost::int_fast32_t decode() { int pk = is->peek(); if(pk == EOF) return EOF; boost::uint16_t ch = get_unit(); if( istream().good() && (ch >= 0xD800 && ch <= 0xDBFF) ) // If ch is the first unit in a surrogate pair... { boost::uint16_t ch2 = get_unit(); // Get the following unit. if( istream().good() && (ch2 >= 0xDC00 && ch2 <= 0xDFFF) ) // If the following unit appropriately completes the surrogate pair... { ch = (boost::uint16_t)((ch - (boost::uint16_t)0xD800) << 10) + (ch2 - (boost::uint16_t)0xDC00) + 0x0010000; // Magic } else { throw "Unpaired surrogate."; } } return ch; }
void move_result::do_check_before() { LOG_AI_ACTIONS << " check_before " << *this << std::endl; const game_info& s_info = get_subjective_info(); const game_info& info = get_info(); const unit_map& s_units = s_info.units; const unit_map& units = info.units; const gamemap& s_map = s_info.map; const team& s_my_team = get_my_team(s_info); const std::vector<team> &s_teams = s_info.teams; const std::vector<team> &teams = info.teams; const unit *s_unit = get_unit(s_units, s_teams); if (!s_unit || (is_execution() && using_subjective_info() && !get_unit(units, teams, true))) { return; } if (!test_route(*s_unit, s_my_team, s_units, s_teams, s_map)) { //impossible to test using real info without revealing anything //prematurely, since moves are done 'in steps' return; } }
int move(int x1, int y1, int x2, int y2) { /*fprintf(stderr, "coords = %d %d %d %d\n", x1, y1, x2, y2); fprintf(stderr, "x1 and board size = %d %d\n", x1, board.size - 1); fprintf(stderr, "x2 and board size = %d %d\n", x2, board.size - 1); fprintf(stderr, "y1 and board size = %d %d\n", y1, board.size - 1); fprintf(stderr, "y2 and board size = %d %d\n", y2, board.size - 1); fprintf(stderr, "empty = %d\n",is_empty(x1, y1)); fprintf(stderr, "our unit = %d\n",(get_unit(x1, y1)->owner == PLAYER_1) != player_1_turn); fprintf(stderr, "unit owner = %d\n", get_unit(x1, y1)->owner); fprintf(stderr, "Player 1 = %d\n", PLAYER_1); fprintf(stderr, "unit owner is player 1 = %d\n", get_unit(x1, y1)->owner == PLAYER_1); fprintf(stderr, "player 1 turn = %d\n", player_1_turn); fprintf(stderr, "our turn = %d\n", our_turn); fprintf(stderr, "non empty theirs + their unit = %d\n",!(is_empty(x2, y2)) && (get_unit(x2, y2)->owner == PLAYER_1) == player_1_turn); fprintf(stderr, "not adjacent = %d\n", not_adjacent(x1, y1, x2, y2)); fprintf(stderr, "cant move = %d\n", get_unit(x1, y1)->last_move == cur_turn);*/ if(can_move(x1, y1, x2, y2)) { if(is_empty(x2, y2)) { unit_ptr unit_temp = get_unit(x1, y1); unit_temp->x = x2; unit_temp->y = y2; unit_temp->last_move = cur_turn; } else { unit_ptr my_unit = get_unit(x1, y1); unit_ptr their_unit = get_unit(x2, y2); if(their_unit->type < my_unit->type) { if(their_unit->type == KING) { if(player_1_turn) player_2.king = null; else player_1.king = null; } erase_unit(their_unit); my_unit->x = x2; my_unit->y = y2; my_unit->last_move = cur_turn; } else if(their_unit->type == my_unit->type) { if(their_unit->type == KING) { player_1.king = null; player_2.king = null; } erase_unit(their_unit); erase_unit(my_unit); } else { if(my_unit->type == KING) { if(player_1_turn) player_1.king = null; else player_2.king = null; } erase_unit(my_unit); } } return OK; } else return MOVE_ERROR; }
void attack_result::do_execute() { LOG_AI_ACTIONS << "start of execution of: "<< *this << std::endl; // Stop the user from issuing any commands while the unit is attacking const events::command_disabler disable_commands; //@note: yes, this is a decision done here. It's that way because we want to allow a simpler attack 'with whatever weapon is considered best', and because we want to allow the defender to pick it's weapon. That's why aggression is needed. a cleaner solution is needed. battle_context bc(get_info().units, attacker_loc_, defender_loc_, attacker_weapon_, -1, aggression_); int attacker_weapon = bc.get_attacker_stats().attack_num; int defender_weapon = bc.get_defender_stats().attack_num; if(attacker_weapon < 0) { set_error(E_UNABLE_TO_CHOOSE_ATTACKER_WEAPON); return; } const unit *d_ = get_unit(get_info(),defender_loc_); const unit *a_ = get_unit(get_info(),attacker_loc_); //@todo 1.9: change ToD to be location specific for the defender unit recorder.add_attack(attacker_loc_, defender_loc_, attacker_weapon, defender_weapon, a_->type_id(), d_->type_id(), a_->level(), d_->level(), resources::tod_manager->turn(), resources::tod_manager->get_time_of_day()); rand_rng::invalidate_seed(); rand_rng::clear_new_seed_callback(); while (!rand_rng::has_valid_seed()) { manager::raise_user_interact(); manager::raise_sync_network(); SDL_Delay(10); } recorder.add_seed("attack", rand_rng::get_last_seed()); attack_unit(attacker_loc_, defender_loc_, attacker_weapon, defender_weapon); dialogs::advance_unit(attacker_loc_, true); const unit_map::const_iterator defender = get_info().units.find(defender_loc_); if(defender != get_info().units.end()) { const size_t defender_team = size_t(defender->second.side()) - 1; if(defender_team < get_info().teams.size()) { dialogs::advance_unit(defender_loc_ , !get_info().teams[defender_team].is_human()); } } set_gamestate_changed(); //start of ugly hack. @todo 1.9 rework that via extended event system //until event system is reworked, we note the attack this way get_info().recent_attacks.insert(defender_loc_); //end of ugly hack try { manager::raise_gamestate_changed(); } catch (...) { is_ok(); //Silences "unchecked result" warning throw; } }
void move::init() { // If a unit is invalid, return immediately to avoid crashes such as trying to plan a move for a planned recruit. // As per Bug #18637, this should be fixed so that planning moves on planned recruits work properly. // The alternative is to disable movement on planned recruits altogether, // possibly in select_or_action() where the fake unit is selected in the first place. if (get_unit() == NULL) return; assert(get_unit()); unit_id_ = get_unit()->id(); //This action defines the future position of the unit, make its fake unit more visible //than previous actions' fake units if (fake_unit_) { fake_unit_->anim_comp().set_ghosted(true); } side_actions_ptr side_actions = resources::teams->at(team_index()).get_side_actions(); side_actions::iterator action = side_actions->find_last_action_of(*(get_unit())); if (action != side_actions->end()) { if (move_ptr move = boost::dynamic_pointer_cast<class move>(*action)) { if (move->fake_unit_) move->fake_unit_->anim_comp().set_disabled_ghosted(true); } } this->calculate_move_cost(); // Initialize arrow_brightness_ and arrow_texture_ using arrow_->style_ arrow::STYLE arrow_style = arrow_->get_style(); if(arrow_style == arrow::STYLE_STANDARD) { arrow_brightness_ = ARROW_BRIGHTNESS_STANDARD; arrow_texture_ = ARROW_TEXTURE_VALID; } else if(arrow_style == arrow::STYLE_HIGHLIGHTED) { arrow_brightness_ = ARROW_BRIGHTNESS_HIGHLIGHTED; arrow_texture_ = ARROW_TEXTURE_VALID; } else if(arrow_style == arrow::STYLE_FOCUS) { arrow_brightness_ = ARROW_BRIGHTNESS_FOCUS; arrow_texture_ = ARROW_TEXTURE_VALID; } else if(arrow_style == arrow::STYLE_FOCUS_INVALID) { arrow_brightness_ = ARROW_BRIGHTNESS_STANDARD; arrow_texture_ = ARROW_TEXTURE_INVALID; } }
//--------- Begin of function UnitGroup::formation ---------// // // set the units to form formation // void UnitGroup::formation(int formationType, char remoteAction) { //-- only form formation when there is a general in the group --// for( int i=size() ; i>0 ; i-- ) { Unit* unitPtr = get_unit(i); if( unitPtr->rank_id >= RANK_GENERAL ) break; } if( i==0 ) // no general in the group. return; //---------------------------------// if( !remoteAction && remote.is_enable() ) { // packet structure : <formation id> <write_mem...> short *shortPtr = (short *)remote.new_send_queue_msg(MSG_UNITS_FORMATION, sizeof(short) + get_write_len() ); shortPtr[0] = formationType; write_mem(shortPtr+1); return; } // ##### begin Gilbert 25/2 ######// // -------- set team_info's formation_id ------// for( i=size() ; i>0 ; i-- ) { Unit* unitPtr = get_unit(i); if( unitPtr->team_info ) { unitPtr->team_info->formation_id = formationType; } } // ------- if any formation execute now --------// if( formationType != 0 ) { group_by_mobile_type(); //-------- set formation now ---------// unit_group_land.exe_formation(formationType); unit_group_air.exe_formation(formationType); } // ##### end Gilbert 25/2 ######// }
void allocate_board(int n, int x1, int y1, int x2, int y2) { board.size = n; produce_unit(x1, y1, PLAYER_1, KING); produce_unit(x1 + 2, y1, PLAYER_1, KNIGHT); produce_unit(x1 + 3, y1, PLAYER_1, KNIGHT); produce_unit(x1 + 1, y1, PLAYER_1, PEASANT); produce_unit(x2, y2, PLAYER_2, KING); produce_unit(x2 + 2, y2, PLAYER_2, KNIGHT); produce_unit(x2 + 3, y2, PLAYER_2, KNIGHT); produce_unit(x2 + 1, y2, PLAYER_2, PEASANT); player_1.king = get_unit(x1, y1); player_2.king = get_unit(x2, y2); board.init = true; }
void attack::remove_temp_modifier(unit_map& unit_map) { assert(get_unit()); unit& unit = *get_unit(); DBG_WB << unit.name() << " [" << unit.id() << "] has " << unit.attacks_left() << " attacks, increasing by one" << "\n"; unit.set_attacks(unit.attacks_left() + 1); DBG_WB << "Attack: Changing movement points for unit " << unit.name() << " [" << unit.id() << "] from " << unit.movement_left() << " to " << unit.movement_left() + temp_movement_subtracted_ << ".\n"; unit.set_movement(unit.movement_left() + temp_movement_subtracted_, true); temp_movement_subtracted_ = 0; move::remove_temp_modifier(unit_map); }
void stopunit_result::do_check_before() { LOG_AI_ACTIONS << " check_before " << *this << std::endl; const game_info& s_info = get_subjective_info(); const game_info& info = get_info(); const unit_map& s_units = s_info.units; const unit_map& units = info.units; if (!get_unit(s_units) || (is_execution() && using_subjective_info() && !get_unit(units, true))) { return; } }
void UnitGroup::attack(int targetObjRecno, char remoteAction) { if( base_obj_array.is_deleted(targetObjRecno) ) // may be deleted after multiplayer message delay return; //----- player can only order his own units to attack, cannot order his spies cloaked in other nations to attack, as this can easy lead nations into wars ----// if( remoteAction==COMMAND_PLAYER ) { for(int i=size() ; i>0 ; i-- ) { if( get_unit(i)->nation_recno != nation_array.player_recno ) del_unit(i); } } if( !remoteAction && remote.is_enable() ) { // packet structure : <target baseobj recno> <write_mem...> short *shortPtr = (short *)remote.new_send_queue_msg(MSG_UNIT_ATTACK, sizeof(short) + get_write_len() ); shortPtr[0] = targetObjRecno; write_mem(shortPtr+1); return; } group_by_mobile_type(); if(unit_group_land.size()) unit_group_land.exe_attack(targetObjRecno); if(unit_group_air.size()) unit_group_air.exe_attack(targetObjRecno); }
//----------Begin of function UnitGroup::formation_turn--------// // void UnitGroup::formation_turn(int direction, char remoteAction ) { if( !remoteAction && remote.is_enable() ) { // packet structure : <direction id> <write_mem...> short *shortPtr = (short *)remote.new_send_queue_msg(MSG_UNITS_FORM_TURN, sizeof(short) + get_write_len() ); shortPtr[0] = direction; write_mem(shortPtr+1); return; } //-- only form formation when there is a general in the group --// for( int i=size() ; i>0 ; i-- ) { Unit* unitPtr = get_unit(i); if( unitPtr->rank_id >= RANK_GENERAL ) break; } if( i==0 ) // no general in the group. return; group_by_mobile_type(); if(unit_group_land.size()) unit_group_land.exe_formation_turn(direction); if(unit_group_air.size()) unit_group_air.exe_formation_turn(direction); }
void recall::draw_hex(map_location const& hex) { if (hex == recall_hex_) { const double x_offset = 0.5; const double y_offset = 0.7; //position 0,0 in the hex is the upper left corner std::stringstream number_text; unit &it = *get_unit(); int cost = statistics::un_recall_unit_cost(it); if (cost < 0) { number_text << utils::unicode_minus << resources::teams->at(team_index()).recall_cost(); } else { number_text << utils::unicode_minus << cost; } size_t font_size = 16; SDL_Color color; color.r = 255; color.g = 0; color.b = 0; //red resources::screen->draw_text_in_hex(hex, display::LAYER_ACTIONS_NUMBERING, number_text.str(), font_size, color, x_offset, y_offset); } }
//--------- Begin of function UnitGroup::group_by_mobile_type ---------// // void UnitGroup::group_by_mobile_type() { err_when( &unit_group_land==this || &unit_group_air==this ); // unit_group_land & unit_group_air are for storing the result, this UnitGroup cannot be one of them //--- add the selected units to UnitGroup ----// unit_group_land.zap(); unit_group_air.zap(); for( int i=size() ; i>0 ; i-- ) { Unit* unitPtr = get_unit(i); if( unit_array.is_deleted(unitPtr->sprite_recno) ) continue; if( unitPtr->mobile_type == UNIT_LAND ) unit_group_land.add_unit(unitPtr->sprite_recno); else unit_group_air.add_unit(unitPtr->sprite_recno); } unit_group_land.mobile_type = UNIT_LAND; unit_group_air.mobile_type = UNIT_AIR; err_when( (size() > 0) && (unit_group_land.size()==0 && unit_group_air.size()==0) ); // there should be at least one unit selected }
void shrink(WWindow *wwin) { if(!resize_mode) resize_vert(wwin); resize(wwin, -get_unit(wwin), ANY, TRUE); set_timer(&resize_timer, wglobal.resize_delay); }
void move::init() { assert(get_unit()); unit_id_ = get_unit()->id(); //This action defines the future position of the unit, make its fake unit more visible //than previous actions' fake units if (fake_unit_) { fake_unit_->set_ghosted(true); } side_actions_ptr side_actions = resources::teams->at(team_index()).get_side_actions(); side_actions::iterator action = side_actions->find_last_action_of(*(get_unit())); if (action != side_actions->end()) { if (move_ptr move = boost::dynamic_pointer_cast<class move>(*action)) { if (move->fake_unit_) move->fake_unit_->set_disabled_ghosted(true); } } this->calculate_move_cost(); // Initialize arrow_brightness_ and arrow_texture_ using arrow_->style_ arrow::STYLE arrow_style = arrow_->get_style(); if(arrow_style == arrow::STYLE_STANDARD) { arrow_brightness_ = ARROW_BRIGHTNESS_STANDARD; arrow_texture_ = ARROW_TEXTURE_VALID; } else if(arrow_style == arrow::STYLE_HIGHLIGHTED) { arrow_brightness_ = ARROW_BRIGHTNESS_HIGHLIGHTED; arrow_texture_ = ARROW_TEXTURE_VALID; } else if(arrow_style == arrow::STYLE_FOCUS) { arrow_brightness_ = ARROW_BRIGHTNESS_FOCUS; arrow_texture_ = ARROW_TEXTURE_VALID; } else if(arrow_style == arrow::STYLE_FOCUS_INVALID) { arrow_brightness_ = ARROW_BRIGHTNESS_STANDARD; arrow_texture_ = ARROW_TEXTURE_INVALID; } }
int produce_peasant(int x1, int y1, int x2, int y2) { if(can_produce(x1, y1, x2, y2)) { produce_unit(x2, y2, player_1_turn ? PLAYER_1 : PLAYER_2, PEASANT); get_unit(x1, y1)->last_move = cur_turn; return OK; } else return PRODUCE_ERROR; }
void stopunit_result::do_check_before() { LOG_AI_ACTIONS << " check_before " << *this << std::endl; if (!get_unit()) { return; } }
bool Units::can_convert (const symbol from, const symbol to, Treelog& msg) const { if (from == to) return true; // Defined? if (!has_unit(from) || !has_unit (to)) { if (!allow_old ()) { if (has_unit (from)) msg.message ("Original dimension [" + from + "] known."); else msg.message ("Original dimension [" + from + "] not known."); if (has_unit (to)) msg.message ("Target dimension [" + to + "] known."); else msg.message ("Target dimension [" + to + "] not known."); return false; } msg.message (std::string ("Trying old conversion of ") + (has_unit (from) ? "" : "unknown ") + "[" + from + "] to " + (has_unit (to) ? "" : "unknown ") + "[" + to + "]." ); return Oldunits::can_convert (from, to); } const Unit& from_unit = get_unit (from); const Unit& to_unit = get_unit (to); if (compatible (from_unit, to_unit)) return true; // Not compatible. std::ostringstream tmp; tmp << "Cannot convert [" << from << "] with base [" << from_unit.base_name () << "] to [" << to << "] with base [" << to_unit.base_name () << "]"; msg.message (tmp.str ()); if (!allow_old ()) return false; msg.message ("Trying old conversion."); return Oldunits::can_convert (from, to); }
// Read until one while character is decoded. boost::int_fast32_t decode() { int pk = is->peek(); if(pk == EOF) return EOF; return get_unit(); }
bool prevg() // Move get-pointer back one full character. { is->seekg(std::ios::cur, -2); // Previous unit. boost::uint16_t ch = get_unit(); if(ch < 0xDC00 || ch > 0xDFFF) // If this is the second unit in a surrogate pair... { // Go back another unit to the first part of the surrogate pair. is->seekg(std::ios::cur, -2); boost::uint16_t ch = get_unit(); if(ch < 0xD800 || ch > 0xDBFF) { } } return true; }
bool can_move(int x1, int y1, int x2, int y2) { if(x1 < 0 || x2 < 0 || y1 < 0 || y2 < 0) return false; else if(x1 > board.size - 1 || x2 > board.size - 1 || y1 > board.size - 1 || y2 > board.size - 1) return false; else if(is_empty(x1, y1)) return false; else if((get_unit(x1, y1)->owner == PLAYER_1) != player_1_turn) return false; else if(!(is_empty(x2, y2)) && (get_unit(x2, y2)->owner == PLAYER_1) == player_1_turn) return false; else if(not_adjacent(x1, y1, x2, y2)) return false; else if(get_unit(x1, y1)->last_move == cur_turn) return false; else return true; }
move::move(config const& cfg, bool hidden) : action(cfg,hidden) , unit_underlying_id_(0) , unit_id_() , route_(new pathfind::marked_route()) , movement_cost_(0) , turn_number_(0) , arrow_(new arrow(hidden)) , fake_unit_() , arrow_brightness_() , arrow_texture_() , mover_() , fake_unit_hidden_(false) { // Construct and validate unit_ unit_map::iterator unit_itor = resources::units->find(cfg["unit_"]); if(unit_itor == resources::units->end()) throw action::ctor_err("move: Invalid underlying_id"); unit_underlying_id_ = unit_itor->underlying_id(); // Construct and validate route_ config const& route_cfg = cfg.child("route_"); if(!route_cfg) throw action::ctor_err("move: Invalid route_"); route_->move_cost = route_cfg["move_cost"]; BOOST_FOREACH(config const& loc_cfg, route_cfg.child_range("step")) { route_->steps.push_back(map_location(loc_cfg["x"],loc_cfg["y"])); } BOOST_FOREACH(config const& mark_cfg, route_cfg.child_range("mark")) { route_->marks[map_location(mark_cfg["x"],mark_cfg["y"])] = pathfind::marked_route::mark(mark_cfg["turns"], mark_cfg["zoc"].to_bool(), mark_cfg["capture"].to_bool(), mark_cfg["invisible"].to_bool()); } // Validate route_ some more std::vector<map_location> const& steps = route_->steps; if(steps.empty()) throw action::ctor_err("move: Invalid route_"); // Construct arrow_ arrow_->set_color(team::get_side_color_index(side_number())); arrow_->set_style(arrow::STYLE_STANDARD); arrow_->set_path(route_->steps); // Construct fake_unit_ fake_unit_.reset(new game_display::fake_unit(*get_unit()) ); if(hidden) fake_unit_->set_hidden(true); fake_unit_->place_on_game_display(resources::screen); fake_unit_->set_ghosted(true); unit_display::move_unit(route_->steps, *fake_unit_, false); //get facing right fake_unit_->set_location(route_->steps.back()); this->init(); }
unit *get_unit(unit *head, const int index) { if (head != NULL && index > 0) { return get_unit(head->next, index - 1); } return head; }
attack::attack(size_t team_index, bool hidden, unit& u, const map_location& target_hex, int weapon_choice, const pathfind::marked_route& route, arrow_ptr arrow, fake_unit_ptr fake_unit) : move(team_index, hidden, u, route, arrow, fake_unit), target_hex_(target_hex), weapon_choice_(weapon_choice), attack_movement_cost_(get_unit()->attacks()[weapon_choice_].movement_used()), temp_movement_subtracted_(0) { this->init(); }
int check_value(int n){ /*测值: printf("N=%d,DEC=>%dU=>%d\n",n,get_decade(n),get_unit(n)); */ if(get_decade(n) == 9) return 1; if(get_unit(n) == 9) return 1; return 0; }
//--------- Begin of function UnitGroup::has_unit ---------// // // Return whether the given unit is in this UnitGroup. // int UnitGroup::has_unit(int unitRecno) { for( int i=size() ; i>0 ; i-- ) { if( get_unit(i)->sprite_recno == unitRecno ) return 1; } return 0; }
void UnitGroup::exe_formation_turn(int direction) { Unit* unitPtr = NULL; int formationMode=0; for(int i=1; i<=size(); i++) { unitPtr = get_unit(i); if(unitPtr->team_info) { formationMode = unitPtr->team_info->formation_id; break; } else if(unitPtr->leader_unit_recno && !unit_array.is_deleted(unitPtr->leader_unit_recno) && (unitPtr = unit_array[unitPtr->leader_unit_recno])->team_info) { formationMode = unitPtr->team_info->formation_id; break; } } // if(!formationMode) // formationMode = unit_array[get_unit(1)->leader_unit_recno]->team_info->formation_id; switch(formationMode) { case FORMATION_VANGUARD: vanguard_formation(direction); break; case FORMATION_LINE: line_formation(direction); break; case FORMATION_CIRCLE: circle_formation(direction); break; case FORMATION_ARC: arc_formation(direction); break; case FORMATION_STAGGERED: staggered_formation(direction); break; case FORMATION_SANDWICH: sandwich_formation(direction); break; case FORMATION_SQUARE: square_formation(direction); break; default: return; } if(unitPtr && unitPtr->team_info) unitPtr->team_info->formation_direction = direction; }