? ddddd ? fastwar ? server_autoattack.diff ? unitsforattack.gz ? server/.autoattack.c.swp Index: client/control.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/control.c,v retrieving revision 1.86 diff -u -r1.86 control.c --- client/control.c 2002/11/14 09:14:50 1.86 +++ client/control.c 2002/11/17 21:35:10 @@ -643,6 +643,17 @@ unit_list_iterate_end; } +void wakeup_server_auto_attack_unit(int x, int y) +{ + unit_list_iterate(map_get_tile(x,y)->units, punit) { + if(punit->activity==ACTIVITY_SERVER_AUTO_ATTACK + && game.player_idx==punit->owner) { + request_new_unit_activity(punit, ACTIVITY_IDLE); + } + } + unit_list_iterate_end; +} + /************************************************************************** Player pressed 'b' or otherwise instructed unit to build or add to city. If the unit can build a city, we popup the appropriate dialog. @@ -893,6 +904,16 @@ } /**************************************************************** +... server auto attac"k" +*****************************************************************/ +void request_unit_server_auto_attack(struct unit *punit) +{ + if(punit->activity!=ACTIVITY_SERVER_AUTO_ATTACK && + can_unit_do_activity(punit, ACTIVITY_SERVER_AUTO_ATTACK)) + request_new_unit_activity(punit, ACTIVITY_SERVER_AUTO_ATTACK); +} + +/**************************************************************** ... *****************************************************************/ void request_unit_fortify(struct unit *punit) @@ -1718,6 +1739,16 @@ if(get_unit_in_focus()) if(can_unit_do_activity(punit_focus, ACTIVITY_SENTRY)) request_new_unit_activity(punit_focus, ACTIVITY_SENTRY); +} + +/************************************************************************** +... +**************************************************************************/ +void key_unit_server_auto_attack(void) +{ + if(get_unit_in_focus()) + if(can_unit_do_activity(punit_focus, ACTIVITY_SERVER_AUTO_ATTACK)) + request_new_unit_activity(punit_focus, ACTIVITY_SERVER_AUTO_ATTACK); } /************************************************************************** Index: client/control.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/control.h,v retrieving revision 1.29 diff -u -r1.29 control.h --- client/control.h 2002/11/01 17:51:12 1.29 +++ client/control.h 2002/11/17 21:35:10 @@ -146,6 +146,7 @@ void key_unit_pollution(void); void key_unit_road(void); void key_unit_sentry(void); +void key_unit_server_auto_attack(void); void key_unit_traderoute(void); void key_unit_transform(void); void key_unit_unload(void); Index: client/tilespec.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v retrieving revision 1.89 diff -u -r1.89 tilespec.c --- client/tilespec.c 2002/11/17 02:21:11 1.89 +++ client/tilespec.c 2002/11/17 21:35:11 @@ -1157,6 +1157,11 @@ case ACTIVITY_SENTRY: s = sprites.unit.sentry; break; + /* + case ACTIVITY_SERVER_AUTO_ATTACK + s = sprites.unit.server_auto_attack; + break; + */ case ACTIVITY_GOTO: s = sprites.unit.go_to; break; Index: client/gui-gtk/menu.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/menu.c,v retrieving revision 1.70 diff -u -r1.70 menu.c --- client/gui-gtk/menu.c 2002/11/14 09:14:54 1.70 +++ client/gui-gtk/menu.c 2002/11/17 21:35:11 @@ -105,6 +105,7 @@ MENU_ORDER_POLLUTION, /* shared with PARADROP */ MENU_ORDER_FALLOUT, MENU_ORDER_SENTRY, + MENU_ORDER_SERVER_AUTO_ATTACK, MENU_ORDER_PILLAGE, MENU_ORDER_HOMECITY, MENU_ORDER_UNLOAD, @@ -354,6 +355,9 @@ case MENU_ORDER_SENTRY: key_unit_sentry(); break; + case MENU_ORDER_SERVER_AUTO_ATTACK: + key_unit_server_auto_attack(); + break; case MENU_ORDER_PILLAGE: key_unit_pillage(); break; @@ -662,6 +666,8 @@ NULL, 0, "" }, { "/" N_("Orders") "/" N_("_Sentry"), "s", orders_menu_callback, MENU_ORDER_SENTRY }, +{ "/" N_("Orders") "/" N_("_Server auto attac_k"), "k", + orders_menu_callback, MENU_ORDER_SERVER_AUTO_ATTACK }, { "/" N_("Orders") "/" N_("Pillage"), "p", orders_menu_callback, MENU_ORDER_PILLAGE }, { "/" N_("Orders") "/sep2", NULL, Index: common/unit.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v retrieving revision 1.165 diff -u -r1.165 unit.c --- common/unit.c 2002/11/15 21:24:30 1.165 +++ common/unit.c 2002/11/17 21:35:12 @@ -547,6 +547,7 @@ case ACTIVITY_FORTIFIED: text = _("Fortified"); break; case ACTIVITY_FORTRESS: text = _("Fortress"); break; case ACTIVITY_SENTRY: text = _("Sentry"); break; + case ACTIVITY_SERVER_AUTO_ATTACK: text = _("Autoattack"); break; case ACTIVITY_RAILROAD: text = _("Railroad"); break; case ACTIVITY_PILLAGE: text = _("Pillage"); break; case ACTIVITY_GOTO: text = _("Goto"); break; @@ -650,6 +651,9 @@ case ACTIVITY_PATROL: return TRUE; + case ACTIVITY_SERVER_AUTO_ATTACK: + return is_military_unit(punit); + case ACTIVITY_POLLUTION: return unit_flag(punit, F_SETTLERS) && tile_has_special(ptile, S_POLLUTION); @@ -922,6 +926,7 @@ case ACTIVITY_AIRBASE: case ACTIVITY_FORTRESS: case ACTIVITY_SENTRY: + case ACTIVITY_SERVER_AUTO_ATTACK: case ACTIVITY_GOTO: case ACTIVITY_EXPLORE: case ACTIVITY_PATROL: Index: common/unit.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/unit.h,v retrieving revision 1.90 diff -u -r1.90 unit.h --- common/unit.h 2002/11/15 21:24:30 1.90 +++ common/unit.h 2002/11/17 21:35:12 @@ -26,7 +26,7 @@ ACTIVITY_IRRIGATE, ACTIVITY_FORTIFIED, ACTIVITY_FORTRESS, ACTIVITY_SENTRY, ACTIVITY_RAILROAD, ACTIVITY_PILLAGE, ACTIVITY_GOTO, ACTIVITY_EXPLORE, ACTIVITY_TRANSFORM, ACTIVITY_UNKNOWN, ACTIVITY_AIRBASE, ACTIVITY_FORTIFYING, - ACTIVITY_FALLOUT, ACTIVITY_PATROL, + ACTIVITY_FALLOUT, ACTIVITY_PATROL, ACTIVITY_SERVER_AUTO_ATTACK, ACTIVITY_LAST /* leave this one last */ }; Index: server/autoattack.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/autoattack.c,v retrieving revision 1.40 diff -u -r1.40 autoattack.c --- server/autoattack.c 2002/09/30 13:08:56 1.40 +++ server/autoattack.c 2002/11/17 21:35:12 @@ -191,6 +191,49 @@ } /************************************************************************** +copied, because i don't like the ACTIVITY_IDLE +**************************************************************************/ +static void do_auto_attack_unit(struct unit *pattacker, struct unit *pdefender) +{ + int id = pattacker->id; + int attacker_x, attacker_y; + + freelog(LOG_DEBUG, "launching attack"); + + notify_player_ex(unit_owner(pattacker), pdefender->x, pdefender->y, E_NOEVENT, + _("Game: Auto-Attack: %s attacking %s's %s"), + unit_name(pattacker->type), unit_owner(pdefender)->name, + unit_name(pdefender->type)); + + attacker_x = pattacker->x; + attacker_y = pattacker->y; + + set_unit_activity(pattacker, ACTIVITY_GOTO); + pattacker->goto_dest_x=pdefender->x; + pattacker->goto_dest_y=pdefender->y; + + send_unit_info(NULL, pattacker); + (void) do_unit_goto(pattacker, GOTO_MOVE_ANY, FALSE); + + pattacker = find_unit_by_id(id); + + if (pattacker) { + set_unit_activity(pdefender, ACTIVITY_GOTO); + pattacker->goto_dest_x=attacker_x; + pattacker->goto_dest_y=attacker_y; + send_unit_info(NULL, pattacker); + + (void) do_unit_goto(pattacker, GOTO_MOVE_ANY, FALSE); + + if (unit_list_find(&map_get_tile(attacker_x, attacker_y)->units, id)) { + handle_unit_activity_request(pattacker, ACTIVITY_SERVER_AUTO_ATTACK); + } + } + + return; /* or maybe: do you want to play again? */ +} + +/************************************************************************** ... **************************************************************************/ static void auto_attack_city(struct player *pplayer, struct city *pcity) @@ -257,3 +300,67 @@ 1000.0*read_timer_seconds(t)); } } + +/************************************************************************** +... +**************************************************************************/ +void enemy_unit_auto_attack(struct unit *pautoattacker, struct unit *pmover) +{ + int chance_to_win, value_autoattacker, value_defending_unit; + int attackpower, defensepower, attack_firepower, defense_firepower; + int magic_number = 1; + int mv_cost, range, server_auto_attack_value; + struct unit *defender; + + /* perhaps can_unit_attack_unit_at_tile is more correct */ + if (can_unit_attack_tile(pautoattacker, pmover->x, pmover->y)){ + + /* if a 'F_ONEATTACK' unit, + range is larger, because they are not going to return this turn anyways + */ + range = unit_flag(pautoattacker, F_ONEATTACK) ? + pautoattacker->moves_left : + pautoattacker->moves_left/2; + /* attack the next to this place */ + range = range<4 ? 3 : range; + + defender = get_defender(pautoattacker, pmover->x, pmover->y); + freelog(LOG_DEBUG, "defender is %s", unit_name(defender->type)); + + /* from unit_versus_unit */ + attackpower = get_total_attack_power(pautoattacker,defender); + defensepower = get_total_defense_power(pautoattacker,defender); + get_modified_firepower(pautoattacker, defender, + &attack_firepower, &defense_firepower); + + chance_to_win = (attackpower * attack_firepower * pautoattacker->hp * 100) / + ((defensepower * defense_firepower * defender->hp) + + (attackpower * attack_firepower * pautoattacker->hp)); + freelog(LOG_DEBUG, "chance to win is %d", chance_to_win); + + value_autoattacker = unit_value(pautoattacker->type); + if (pautoattacker->veteran) value_autoattacker=(value_autoattacker*3)/2; + + value_defending_unit = unit_value(pmover->type); + /* here should be some modifications for stacks ... */ + + server_auto_attack_value = (value_autoattacker * 100 / + (value_defending_unit + value_autoattacker)); + + freelog(LOG_DEBUG, "server_auto_attack_value=%d",server_auto_attack_value); + + /* when do we want to attack? */ + + if (chance_to_win >= server_auto_attack_value * magic_number){ + mv_cost = calculate_move_cost(pautoattacker, defender->x, defender->y); + if (mv_cost > range) { + freelog(LOG_DEBUG, "too far away: %d", mv_cost); + } else { + do_auto_attack_unit(pautoattacker, defender); + } + + + } + } +} + Index: server/autoattack.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/autoattack.h,v retrieving revision 1.2 diff -u -r1.2 autoattack.h --- server/autoattack.h 1999/07/11 12:57:57 1.2 +++ server/autoattack.h 2002/11/17 21:35:12 @@ -14,5 +14,6 @@ #define FC__AUTOATTACK_H void auto_attack(void); +void enemy_unit_auto_attack(struct unit *pautoattacker, struct unit *pmover); #endif /* FC__AUTOATTACK_H */ Index: server/unittools.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v retrieving revision 1.195 diff -u -r1.195 unittools.c --- server/unittools.c 2002/11/14 09:15:05 1.195 +++ server/unittools.c 2002/11/17 21:35:13 @@ -1738,7 +1738,7 @@ send_unit_info(NULL, punit); maybe_make_first_contact(x, y, unit_owner(punit)); wakeup_neighbor_sentries(punit); - + /* The unit may have changed the available tiles in nearby cities. */ map_city_radius_iterate(x, y, x1, y1) { struct city *pcity = map_get_city(x1, y1); @@ -2817,6 +2817,34 @@ } } unit_list_iterate_end; } square_iterate_end; + + /* Wakeup the units which are setted to server_auto_attack and let them + * attack + * */ + square_iterate(punit->x, punit->y, 3, x, y) { + unit_list_iterate(map_get_tile(x, y)->units, penemy) { + int range; + enum unit_move_type move_type = unit_type(penemy)->move_type; + enum tile_terrain_type terrain = map_get_terrain(x, y); + + if (map_has_special(x, y, S_FORTRESS) + && unit_profits_of_watchtower(penemy)) + range = get_watchtower_vision(penemy); + else + range = unit_type(penemy)->vision_range; + + if (!pplayers_allied(unit_owner(punit), unit_owner(penemy)) + && penemy->activity == ACTIVITY_SERVER_AUTO_ATTACK + && map_get_known_and_seen(punit->x, punit->y, unit_owner(penemy)) + && range >= real_map_distance(punit->x, punit->y, x, y) + && player_can_see_unit(unit_owner(penemy), punit) + /* on board transport; don't awaken */ + && !(move_type == LAND_MOVING && terrain == T_OCEAN)) { + enemy_unit_auto_attack(penemy, punit); + send_unit_info(NULL, penemy); + } + } unit_list_iterate_end; + } square_iterate_end; } /**************************************************************************