Re: [Freeciv-Dev] Diplomat can't "attack" city
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
> > Sometimes when I try to send a diplomat into a city, I get the message
> > "You can't attack there". This is an enemy city I've never sent a
> > diplomat into previously.
>
> This means the diplomat doesn't have enough movement left
> to move onto the square where the city is. It's kind of a
> bug that this isn't handled more gracefully.
I see. Looking at the code and experimenting a bit, it seems three
different
things can happen in this situation:
- The message "You can't attack there", if the city is occupied.
- The message "Only ground troops can take over a city", if the city is
empty
and a random number goes in favor of allowing you to move.
- Nothing at all, if the city is empty and the random number goes
against
letting you move.
Anyway, here's a patch so we always get the message "You don't have
enough movement left".
This patch also fixes what I assume is another bug -- a diplomat can't
infiltrate a city built on a mountain, even if the diplomat hasn't moved
at all this turn. Please feel free to apply the patch in CVS, if you so
desire. It is based on the Dec 7 CVS snapshot.
--
patsmith@xxxxxxxxx
diff -r -u old/client/mapctrl.c freeciv/client/mapctrl.c
--- old/client/mapctrl.c Fri Oct 23 06:35:42 1998
+++ freeciv/client/mapctrl.c Wed Dec 9 23:52:16 1998
@@ -191,17 +191,16 @@
}
}
}
- else if(unit_flag(punit->type, F_DIPLOMAT)) {
- if(diplomat_can_do_action(punit, DIPLOMAT_BRIBE, dest_x, dest_y) ||
- diplomat_can_do_action(punit, DIPLOMAT_SABOTAGE, dest_x, dest_y)
||
- (unit_flag(punit->type, F_SPY) &&
- diplomat_can_do_action(punit, SPY_SABOTAGE_UNIT, dest_x,
dest_y)) ||
- diplomat_can_do_action(punit, DIPLOMAT_EMBASSY, dest_x, dest_y))
{
+ else if(unit_flag(punit->type, F_DIPLOMAT) &&
+ is_diplomat_action_available(punit, DIPLOMAT_ANY_ACTION,
+ dest_x, dest_y)) {
+ if (diplomat_can_do_action(punit, DIPLOMAT_ANY_ACTION, dest_x,
dest_y))
popup_diplomat_dialog(punit, dest_x, dest_y);
- return;
- }
+ else
+ append_output_window("Game: You don't have enough movement
left");
+ return;
}
-
+
req_unit=*punit;
req_unit.x=dest_x;
req_unit.y=dest_y;
diff -r -u old/common/unit.c freeciv/common/unit.c
--- old/common/unit.c Mon Nov 9 06:34:15 1998
+++ freeciv/common/unit.c Wed Dec 9 23:50:44 1998
@@ -150,46 +150,72 @@
**************************************************************************/
/**************************************************************************
-...
+Whether a diplomat can move to a particular tile and perform a
+particular action there.
**************************************************************************/
int diplomat_can_do_action(struct unit *pdiplomat,
enum diplomat_actions action,
int destx, int desty)
{
+ if(!is_diplomat_action_available(pdiplomat, action, destx, desty))
+ return 0;
+
+ if(!is_tiles_adjacent(pdiplomat->x, pdiplomat->y, destx, desty))
+ return 0;
+
+ if(pdiplomat->moves_left >= unit_move_rate(pdiplomat))
+ return 1; /* Hasn't moved yet this turn */
+
+ if(pdiplomat->moves_left >= map_move_cost(pdiplomat, destx, desty))
+ return 1;
+
+ return 0;
+}
+
+/**************************************************************************
+Whether a diplomat can perform a particular action at a particular
+tile. This does _not_ check whether the diplomat can move there.
+If the action is DIPLOMAT_ANY_ACTION, checks whether there is any
+action the diplomat can perform at the tile.
+**************************************************************************/
+int is_diplomat_action_available(struct unit *pdiplomat,
+ enum diplomat_actions action,
+ int destx, int desty)
+{
struct city *pcity=map_get_city(destx, desty);
- struct tile *ptile=map_get_tile(destx, desty);
- int move_cost = tile_move_cost(pdiplomat,pdiplomat->x,pdiplomat->y,
destx, desty);
- if(is_tiles_adjacent(pdiplomat->x, pdiplomat->y, destx, desty) &&
pdiplomat->moves_left >= move_cost) {
-
- if(pcity) {
- if(pcity->owner!=pdiplomat->owner) {
- if(action==DIPLOMAT_SABOTAGE)
- return 1;
-
- if(action==DIPLOMAT_EMBASSY &&
- !player_has_embassy(&game.players[pdiplomat->owner],
- &game.players[pcity->owner]))
- return 1;
- if(action==SPY_POISON && unit_flag(pdiplomat->type, F_SPY))
- return 1;
- if(action==DIPLOMAT_INVESTIGATE)
- return 1;
- if(action==DIPLOMAT_STEAL)
- return 1;
- if(action==DIPLOMAT_INCITE)
- return 1;
- }
- }
- else {
- if(action==SPY_SABOTAGE_UNIT && unit_list_size(&ptile->units)>=1
&&
- unit_list_get(&ptile->units, 0)->owner!=pdiplomat->owner &&
- unit_flag(pdiplomat->type, F_SPY))
- return 1;
- if(action==DIPLOMAT_BRIBE && unit_list_size(&ptile->units)==1 &&
- unit_list_get(&ptile->units, 0)->owner!=pdiplomat->owner)
- return 1;
+ if(pcity) {
+ if(pcity->owner!=pdiplomat->owner) {
+ if(action==DIPLOMAT_SABOTAGE)
+ return 1;
+
+ if(action==DIPLOMAT_EMBASSY &&
+ !player_has_embassy(&game.players[pdiplomat->owner],
+ &game.players[pcity->owner]))
+ return 1;
+ if(action==SPY_POISON && unit_flag(pdiplomat->type, F_SPY))
+ return 1;
+ if(action==DIPLOMAT_INVESTIGATE)
+ return 1;
+ if(action==DIPLOMAT_STEAL)
+ return 1;
+ if(action==DIPLOMAT_INCITE)
+ return 1;
+ if(action==DIPLOMAT_ANY_ACTION)
+ return 1;
}
+ }
+ else {
+ struct tile *ptile=map_get_tile(destx, desty);
+ if((action==SPY_SABOTAGE_UNIT || action==DIPLOMAT_ANY_ACTION) &&
+ unit_list_size(&ptile->units)>=1 &&
+ unit_list_get(&ptile->units, 0)->owner!=pdiplomat->owner &&
+ unit_flag(pdiplomat->type, F_SPY))
+ return 1;
+ if((action==DIPLOMAT_BRIBE || action==DIPLOMAT_ANY_ACTION) &&
+ unit_list_size(&ptile->units)==1 &&
+ unit_list_get(&ptile->units, 0)->owner!=pdiplomat->owner)
+ return 1;
}
return 0;
}
diff -r -u old/common/unit.h freeciv/common/unit.h
--- old/common/unit.h Thu Nov 5 06:30:15 1998
+++ freeciv/common/unit.h Wed Dec 9 21:05:14 1998
@@ -92,7 +92,8 @@
enum diplomat_actions {
DIPLOMAT_BRIBE, DIPLOMAT_EMBASSY, DIPLOMAT_SABOTAGE,
DIPLOMAT_STEAL, DIPLOMAT_INCITE, SPY_POISON,
- DIPLOMAT_INVESTIGATE, SPY_SABOTAGE_UNIT
+ DIPLOMAT_INVESTIGATE, SPY_SABOTAGE_UNIT,
+ DIPLOMAT_ANY_ACTION
};
struct unit_ai {
@@ -198,6 +199,11 @@
int diplomat_can_do_action(struct unit *pdiplomat,
enum diplomat_actions action,
int destx, int desty);
+
+int is_diplomat_action_available(struct unit *pdiplomat,
+ enum diplomat_actions action,
+ int destx, int desty);
+
struct unit *find_unit_by_id(int id);
char *get_unit_name(enum unit_type_id id);
diff -r -u old/server/unithand.c freeciv/server/unithand.c
--- old/server/unithand.c Thu Nov 12 06:38:04 1998
+++ freeciv/server/unithand.c Thu Dec 10 00:35:42 1998
@@ -187,7 +187,8 @@
}
move_cost = tile_move_cost(pdiplomat,pdiplomat->x,pdiplomat->y, x,
y);
- if(pdiplomat && pdiplomat->moves_left >= move_cost) {
+ if(pdiplomat->moves_left >= move_cost ||
+ pdiplomat->moves_left >= unit_move_rate(pdiplomat)) {
switch(packet->action_type) {
case DIPLOMAT_BRIBE:
|
|