[Freeciv-Dev] Re: (PR#11340) Unit orders aborted glitch
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: |
[Freeciv-Dev] Re: (PR#11340) Unit orders aborted glitch |
From: |
"Dave Vandervies" <dj3vande@xxxxxxxxxx> |
Date: |
Sat, 4 Dec 2004 22:06:06 -0800 |
Reply-to: |
rt@xxxxxxxxxxx |
<URL: http://rt.freeciv.org/Ticket/Display.html?id=11340 >
Jason Short wrote:
>
> > [dj3vande@xxxxxxxxxx - Sun Dec 05 00:38:34 2004]:
>
> > I'm willing to share my changes if anybody is interested in cleaning
> > them up and getting them into the official code repository.
>
> Great. Why don't you clean them up while you're at it ;-). Follow the
> instructions on "how to contribute" to make a patch of the changes.
I've cleaned up what I can without guidance from somebody who knows
more than just the few lines around the change in execute_orders.
This patch calls execute_orders recursively to have the unit carry on
with its orders; this should probably be changed to do it The Right
Way. I can make the change and re-submit if somebody tells me what The
Right Way is.
Attached:
server-patch Patch in server directory (unittools.c)
common-patch Patch in common directory (unit.c and unit.h)
dave
--- unit.c.orig 2004-11-11 17:51:13.000000000 -0500
+++ unit.c 2004-12-05 00:53:43.000000000 -0500
@@ -990,6 +990,167 @@
return FALSE;
}
+
+/**************************************************************************
+...
+**************************************************************************/
+bool can_unit_fake_activity(struct unit *punit, enum unit_activity activity)
+{
+ return can_unit_fake_activity_targeted(punit, activity, S_NO_SPECIAL);
+}
+
+/**************************************************************************
+ Return whether the unit can fake the targeted activity at its current
+ location.
+**************************************************************************/
+bool can_unit_fake_activity_targeted(struct unit *punit,
+ enum unit_activity activity,
+ enum tile_special_type target)
+{
+ return can_unit_fake_activity_targeted_at(punit, activity, target,
+ punit->tile);
+}
+
+/**************************************************************************
+ Return TRUE if the unit can fake the targeted activity at the given
+ location (whatever it's being asked to do has already been done there,
+ and had it not been done this unit would be able to do it)
+
+ If the unit can actually DO the activity, FALSE will always be returned;
+ this is intended as an additional check to avoid getting "Orders for
+ unit aborted since they gave an invalid activity" if, f'rexample, we're
+ asking them to connect with a road and there's already a road there. --DV
+**************************************************************************/
+bool can_unit_fake_activity_targeted_at(struct unit *punit,
+ enum unit_activity activity,
+ enum tile_special_type target,
+ const struct tile *ptile)
+{
+ struct player *pplayer = unit_owner(punit);
+ struct tile_type *type = get_tile_type(ptile->terrain);
+
+ switch(activity) {
+
+ case ACTIVITY_POLLUTION:
+ return (unit_flag(punit, F_SETTLERS)
+ && !tile_has_special(ptile, S_POLLUTION));
+
+ case ACTIVITY_FALLOUT:
+ return (unit_flag(punit, F_SETTLERS)
+ && !tile_has_special(ptile, S_FALLOUT));
+
+ case ACTIVITY_ROAD:
+ return (terrain_control.may_road
+ && unit_flag(punit, F_SETTLERS)
+ && tile_has_special(ptile, S_ROAD)
+ && type->road_time != 0
+ && (!tile_has_special(ptile, S_RIVER)
+ || player_knows_techs_with_flag(pplayer, TF_BRIDGE)));
+
+ case ACTIVITY_MINE:
+ /* Don't allow it if someone else is irrigating this tile.
+ * *Do* allow it if they're transforming - the mine may survive */
+ if (terrain_control.may_mine
+ && unit_flag(punit, F_SETTLERS)
+ && ((ptile->terrain == type->mining_result
+ && tile_has_special(ptile, S_MINE))
+ || (ptile->terrain != type->mining_result
+ && type->mining_result != T_NONE
+ && (!is_ocean(ptile->terrain)
+ || is_ocean(type->mining_result)
+ || can_reclaim_ocean(ptile))
+ && (is_ocean(ptile->terrain)
+ || !is_ocean(type->mining_result)
+ || can_channel_land(ptile))
+ && (!is_ocean(type->mining_result)
+ || !map_get_city(ptile))))) {
+ unit_list_iterate(ptile->units, tunit) {
+ if (tunit->activity == ACTIVITY_IRRIGATE) {
+ return FALSE;
+ }
+ } unit_list_iterate_end;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+
+ case ACTIVITY_IRRIGATE:
+ /* Don't allow it if someone else is mining this tile.
+ * *Do* allow it if they're transforming - the irrigation may survive */
+ if (terrain_control.may_irrigate
+ && unit_flag(punit, F_SETTLERS)
+ && (tile_has_special(ptile, S_IRRIGATION)
+ || (tile_has_special(ptile, S_FARMLAND)
+ && player_knows_techs_with_flag(pplayer, TF_FARMLAND)))
+ && ((ptile->terrain == type->irrigation_result
+ && is_water_adjacent_to_tile(ptile))
+ || (ptile->terrain != type->irrigation_result
+ && type->irrigation_result != T_NONE
+ && (!is_ocean(ptile->terrain)
+ || is_ocean(type->irrigation_result)
+ || can_reclaim_ocean(ptile))
+ && (is_ocean(ptile->terrain)
+ || !is_ocean(type->irrigation_result)
+ || can_channel_land(ptile))
+ && (!is_ocean(type->irrigation_result)
+ || !map_get_city(ptile))))) {
+ unit_list_iterate(ptile->units, tunit) {
+ if (tunit->activity == ACTIVITY_MINE) {
+ return FALSE;
+ }
+ } unit_list_iterate_end;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+
+ case ACTIVITY_FORTIFYING:
+ return (is_ground_unit(punit)
+ && punit->activity == ACTIVITY_FORTIFIED
+ && !unit_flag(punit, F_SETTLERS)
+ && !is_ocean(ptile->terrain));
+
+ case ACTIVITY_FORTRESS:
+ return (unit_flag(punit, F_SETTLERS)
+ && !map_get_city(ptile)
+ && player_knows_techs_with_flag(pplayer, TF_FORTRESS)
+ && tile_has_special(ptile, S_FORTRESS)
+ && !is_ocean(ptile->terrain));
+
+ case ACTIVITY_AIRBASE:
+ return (unit_flag(punit, F_AIRBASE)
+ && player_knows_techs_with_flag(pplayer, TF_AIRBASE)
+ && tile_has_special(ptile, S_AIRBASE)
+ && !is_ocean(ptile->terrain));
+
+ case ACTIVITY_RAILROAD:
+ /* if the tile has road, the terrain must be ok.. */
+ return (terrain_control.may_road
+ && unit_flag(punit, F_SETTLERS)
+ && tile_has_special(ptile, S_ROAD)
+ && tile_has_special(ptile, S_RAILROAD)
+ && player_knows_techs_with_flag(pplayer, TF_RAILROAD));
+
+ case ACTIVITY_IDLE:
+ case ACTIVITY_FORTIFIED:
+ case ACTIVITY_SENTRY:
+ case ACTIVITY_PILLAGE:
+ case ACTIVITY_GOTO:
+ case ACTIVITY_EXPLORE:
+ case ACTIVITY_TRANSFORM:
+ case ACTIVITY_UNKNOWN:
+ case ACTIVITY_PATROL_UNUSED:
+ case ACTIVITY_LAST:
+ /*Non-fakable activity or we wouldn't've been able to do it here if
+ it hadn't already been done
+ */
+ return FALSE;
+ }
+
+ assert(0);
+ return FALSE;
+}
+
/**************************************************************************
assign a new task to a unit.
**************************************************************************/
--- unit.h.orig 2004-11-16 16:33:55.000000000 -0500
+++ unit.h 2004-12-05 00:47:19.000000000 -0500
@@ -245,6 +245,14 @@
enum unit_activity activity,
enum tile_special_type target,
const struct tile *ptile);
+bool can_unit_fake_activity(struct unit *punit, enum unit_activity activity);
+bool can_unit_fake_activity_targeted(struct unit *punit,
+ enum unit_activity activity,
+ enum tile_special_type target);
+bool can_unit_fake_activity_targeted_at(struct unit *punit,
+ enum unit_activity activity,
+ enum tile_special_type target,
+ const struct tile *ptile);
void set_unit_activity(struct unit *punit, enum unit_activity new_activity);
void set_unit_activity_targeted(struct unit *punit,
enum unit_activity new_activity,
--- unittools.c.orig 2004-11-11 17:51:15.000000000 -0500
+++ unittools.c 2004-12-05 00:57:35.000000000 -0500
@@ -2952,6 +2952,12 @@
case ORDER_ACTIVITY:
activity = order.activity;
if (!can_unit_do_activity(punit, activity)) {
+ if (can_unit_fake_activity(punit,activity)) {
+ if(unit_has_orders(punit))
+ return execute_orders(punit);
+ else
+ return TRUE;
+ }
cancel_orders(punit, " orders canceled because of failed activity");
notify_player_ex(pplayer, punit->tile, E_UNIT_ORDERS,
_("Game: Orders for %s aborted since they "
- [Freeciv-Dev] Re: (PR#11340) Unit orders aborted glitch,
Dave Vandervies <=
|
|