[Freeciv-Dev] Re: (PR#2415) autoattack patch
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
On Mon, Nov 25, 2002 at 05:14:36PM -0800, Per I. Mathisen via RT wrote:
>
> Changes:
> - autoattack now controlled by old autoattack menu & key, and is a
> separate activity like sentry and fortify
> - will now kill diplomats
> - removed stupid bug (didn't idle before moving)
> - saves autoattack setting
> - sends autoattack setting to client
>
> TODO:
> - add autoattack to unit popup-dialog in city dialog
> - allow AI to use autoattack even if game.autoattack == FALSE
> - testing!!
>
> Please have a go at this patch and report what you find.
Autoattack isn't working outside from cities.
+ cleaned up my patch a little bit.
Thomas
? autoattack-pille4.diff
? autoattack3.diff
? autoattack4.diff
? ddddd
? fastwar
? horse-chariot.gz
? nice.gz
? server_autoattack.diff
? server_autoattack2.diff
? server_autoattack3.diff
? test1.gz
? tri-war.gz
? unitsforattack.gz
? server/.unittools.c.swp
Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.87
diff -u -r1.87 control.c
--- client/control.c 2002/11/22 18:52:12 1.87
+++ client/control.c 2002/11/26 18:36:26
@@ -643,6 +643,17 @@
unit_list_iterate_end;
}
+void wakeup_auto_attack_unit(int x, int y)
+{
+ unit_list_iterate(map_get_tile(x,y)->units, punit) {
+ if(punit->activity==ACTIVITY_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 "a"uto attack
+*****************************************************************/
+void request_unit_auto_attack(struct unit *punit)
+{
+ if(punit->activity!=ACTIVITY_AUTO_ATTACK &&
+ can_unit_do_activity(punit, ACTIVITY_AUTO_ATTACK))
+ request_new_unit_activity(punit, ACTIVITY_AUTO_ATTACK);
+}
+
+/****************************************************************
...
*****************************************************************/
void request_unit_fortify(struct unit *punit)
@@ -1593,17 +1614,6 @@
/**************************************************************************
...
**************************************************************************/
-void key_unit_auto_attack(void)
-{
- if(get_unit_in_focus())
- if(!unit_flag(punit_focus, F_SETTLERS) &&
- can_unit_do_auto(punit_focus))
- request_unit_auto(punit_focus);
-}
-
-/**************************************************************************
-...
-**************************************************************************/
void key_unit_auto_explore(void)
{
if(get_unit_in_focus())
@@ -1731,6 +1741,16 @@
if(get_unit_in_focus())
if(can_unit_do_activity(punit_focus, ACTIVITY_SENTRY))
request_new_unit_activity(punit_focus, ACTIVITY_SENTRY);
+}
+
+/**************************************************************************
+We use the new activity AUTO_ATTACK for that.
+**************************************************************************/
+void key_unit_auto_attack(void)
+{
+ if(get_unit_in_focus())
+ if(can_unit_do_activity(punit_focus, ACTIVITY_AUTO_ATTACK))
+ request_new_unit_activity(punit_focus, ACTIVITY_AUTO_ATTACK);
}
/**************************************************************************
Index: client/control.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.h,v
retrieving revision 1.30
diff -u -r1.30 control.h
--- client/control.h 2002/11/22 18:52:12 1.30
+++ client/control.h 2002/11/26 18:36:26
@@ -148,6 +148,7 @@
void key_unit_pollution(void);
void key_unit_road(void);
void key_unit_sentry(void);
+void key_unit_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.91
diff -u -r1.91 tilespec.c
--- client/tilespec.c 2002/11/21 02:26:48 1.91
+++ client/tilespec.c 2002/11/26 18:36:27
@@ -1170,6 +1170,9 @@
case ACTIVITY_SENTRY:
s = sprites.unit.sentry;
break;
+ case ACTIVITY_AUTO_ATTACK:
+ s = sprites.unit.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.71
diff -u -r1.71 menu.c
--- client/gui-gtk/menu.c 2002/11/22 18:52:12 1.71
+++ client/gui-gtk/menu.c 2002/11/26 18:36:27
@@ -106,6 +106,7 @@
MENU_ORDER_POLLUTION, /* shared with PARADROP */
MENU_ORDER_FALLOUT,
MENU_ORDER_SENTRY,
+ MENU_ORDER_AUTO_ATTACK,
MENU_ORDER_PILLAGE,
MENU_ORDER_HOMECITY,
MENU_ORDER_UNLOAD,
@@ -361,6 +362,9 @@
case MENU_ORDER_SENTRY:
key_unit_sentry();
break;
+ case MENU_ORDER_AUTO_ATTACK:
+ key_unit_auto_attack();
+ break;
case MENU_ORDER_PILLAGE:
key_unit_pillage();
break;
@@ -375,7 +379,10 @@
break;
case MENU_ORDER_AUTO_SETTLER:
if(get_unit_in_focus())
- request_unit_auto(get_unit_in_focus());
+ if (is_military_unit(get_unit_in_focus()))
+ key_unit_auto_attack();
+ else
+ request_unit_auto(get_unit_in_focus());
break;
case MENU_ORDER_AUTO_EXPLORE:
key_unit_auto_explore();
@@ -672,6 +679,8 @@
NULL, 0,
"<Separator>" },
{ "/" N_("Orders") "/" N_("_Sentry"), "s",
orders_menu_callback, MENU_ORDER_SENTRY
},
+{ "/" N_("Orders") "/" N_("Server _auto attack"), NULL,
+ orders_menu_callback, MENU_ORDER_AUTO_ATTACK
},
{ "/" N_("Orders") "/" N_("Pillage"), "<shift>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/26 18:36:29
@@ -500,7 +500,7 @@
{
if (unit_flag(punit, F_SETTLERS))
return TRUE;
- if (is_military_unit(punit) && map_get_city(punit->x, punit->y))
+ if (is_military_unit(punit))
return TRUE;
return FALSE;
}
@@ -547,6 +547,7 @@
case ACTIVITY_FORTIFIED: text = _("Fortified"); break;
case ACTIVITY_FORTRESS: text = _("Fortress"); break;
case ACTIVITY_SENTRY: text = _("Sentry"); break;
+ case ACTIVITY_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_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_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/26 18:36:29
@@ -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_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/26 18:36:29
@@ -191,6 +191,19 @@
}
/**************************************************************************
+Attacking unit in adjacent tile.
+**************************************************************************/
+static bool do_auto_attack_unit(struct unit *pattacker, struct unit *pdefender)
+{
+ freelog(LOG_DEBUG, "launching attack");
+ if (handle_unit_move_request(pattacker, pdefender->x, pdefender->y, FALSE,
FALSE)){
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/**************************************************************************
...
**************************************************************************/
static void auto_attack_city(struct player *pplayer, struct city *pcity)
@@ -257,3 +270,45 @@
1000.0*read_timer_seconds(t));
}
}
+
+/**************************************************************************
+This is called when a enemy unit is moving into the range of a unit with
+the AUTO_ATTACK Flag.
+**************************************************************************/
+void enemy_unit_auto_attack(struct unit *pautoattacker, struct unit *pmover)
+{
+ double punitwin, attackvalue;
+ int value_autoattacker, value_defending_unit;
+ int magic_number = 1;
+ struct unit *defender;
+
+ /* perhaps can_unit_attack_unit_at_tile is more correct */
+ if (can_unit_attack_tile(pautoattacker, pmover->x, pmover->y)){
+
+ defender = get_defender(pautoattacker, pmover->x, pmover->y);
+ freelog(LOG_DEBUG, "defender is %s", unit_name(defender->type));
+
+ /* from unit_versus_unit */
+ punitwin= unit_win_chance(pautoattacker, defender);
+
+ 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 ... */
+
+ attackvalue = (value_autoattacker /
+ (value_defending_unit + value_autoattacker));
+
+ freelog(LOG_DEBUG, "server_auto_attack_value=%f",attackvalue);
+
+ /* when do we want to attack? */
+
+ if (punitwin >= 0.5 &&
+ punitwin >= (attackvalue * magic_number)){
+ (void) 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/26 18:36:29
@@ -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.197
diff -u -r1.197 unittools.c
--- server/unittools.c 2002/11/22 17:44:45 1.197
+++ server/unittools.c 2002/11/26 18:36:32
@@ -2847,6 +2847,41 @@
}
} unit_list_iterate_end;
} square_iterate_end;
+
+ /* Wakeup the units which are setted to autoattack and let them
+ * attack
+ * */
+ square_iterate(punit->x, punit->y, 1, 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_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)) {
+ int sanity1 = punit->id, sanity2 = penemy->id;
+ enemy_unit_auto_attack(penemy, punit);
+
+ if (find_unit_by_id(sanity2)) {
+ send_unit_info(NULL, penemy);
+ }
+ if (find_unit_by_id(sanity1)) {
+ send_unit_info(NULL, punit);
+ } else {
+ return; /* done, gone */
+ }
+ }
+ } unit_list_iterate_end;
+ } square_iterate_end;
}
/**************************************************************************
|
|