[Freeciv-Dev] (PR#7344) Expanded Orders
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: |
undisclosed-recipients: ; |
Subject: |
[Freeciv-Dev] (PR#7344) Expanded Orders |
From: |
"Arnstein Lindgard" <a-l@xxxxxxx> |
Date: |
Thu, 29 Jan 2004 06:05:30 -0800 |
Reply-to: |
rt@xxxxxxxxxxx |
<URL: http://rt.freeciv.org/Ticket/Display.html?id=7344 >
Expanded Orders is Mission Orders minus client interface.
Now expanding the struct unit_orders, not using unions or
chained enums.
Arnstein
diff -pruN -Xdiff_ignore clean-E1/common/capstr.c E1/common/capstr.c
--- clean-E1/common/capstr.c Sun Jan 25 11:18:53 2004
+++ E1/common/capstr.c Thu Jan 29 14:55:26 2004
@@ -75,7 +75,7 @@ const char * const our_capability = our_
*/
#define CAPABILITY "+1.14.delta +last_turns_shield_surplus veteran +orders " \
- "+starter"
+ "+starter +expanded_orders"
/* "+1.14.delta" is the new delta protocol for 1.14.0-dev.
*
@@ -88,6 +88,9 @@ const char * const our_capability = our_
* "veteran" means the extended veteran system.
*
* "starter" means the Starter terrain flag is supported.
+ *
+ * "expanded_orders" is a preparation for mission orders, with no client
+ * interface.
*/
void init_our_capability(void)
diff -pruN -Xdiff_ignore clean-E1/common/packets.def E1/common/packets.def
--- clean-E1/common/packets.def Tue Jan 20 23:08:40 2004
+++ E1/common/packets.def Thu Jan 29 14:55:26 2004
@@ -176,6 +176,7 @@ type AUTH_TYPE = uint8(enum authenticat
type IMPR_RANGE = uint8(enum impr_range)
type DIRECTION = uint8(enum direction8)
type ORDERS = uint8(enum unit_orders)
+type MOVEMENT_TYPE = uint8(enum movement_type)
# typedefs for IDs
type PLAYER = UINT8
@@ -599,6 +600,8 @@ PACKET_UNIT_INFO=49; is-info,sc
BOOL veteran_old; remove-cap(veteran)
BOOL ai, paradropped, connecting, carried, done_moving;
BOOL has_orders, repeat, vigilant;
+ ORDERS mission;
+ MOVEMENT_TYPE move_type;
UNIT_TYPE type;
UINT8 movesleft, hp, fuel, activity_count;
diff -pruN -Xdiff_ignore clean-E1/common/unit.c E1/common/unit.c
--- clean-E1/common/unit.c Sun Jan 25 11:18:54 2004
+++ E1/common/unit.c Thu Jan 29 14:55:26 2004
@@ -222,6 +222,18 @@ bool unit_has_orders(struct unit *punit)
return punit->has_orders;
}
+/****************************************************************************
+ TRUE if the order is an action or activity, other than move. Determines
+ sprites in the client and helpful for server to examine the orders list.
+****************************************************************************/
+bool order_is_action(enum unit_orders order)
+{
+ return (order != ORDER_LAST &&
+ order != ORDER_MOVE &&
+ order != ORDER_NONE &&
+ order != ORDER_FINISH_TURN);
+}
+
/**************************************************************************
...
**************************************************************************/
diff -pruN -Xdiff_ignore clean-E1/common/unit.h E1/common/unit.h
--- clean-E1/common/unit.h Sun Jan 25 11:18:54 2004
+++ E1/common/unit.h Thu Jan 29 14:55:26 2004
@@ -37,10 +37,24 @@ enum unit_activity {
/* Changing this enum will break savegame and network compatability. */
enum unit_orders {
- ORDER_MOVE, ORDER_FINISH_TURN,
+ ORDER_MOVE, ORDER_FINISH_TURN, ORDER_NONE,
+ /* "Actions" not technically "activities". */
+ ORDER_AUTO_ATTACK, ORDER_AUTO_SETTLE, ORDER_BUILD_CITY,
+ ORDER_BUILD_WONDER, ORDER_DISBAND, ORDER_HOMECITY,
+ ORDER_TRADEROUTE, ORDER_UNLOAD,
+ /* These duplicate items from "enum unit_activity". */
+ ORDER_AIRBASE, ORDER_EXPLORE, ORDER_FALLOUT, ORDER_FORTIFYING,
+ ORDER_FORTRESS, ORDER_IRRIGATE, ORDER_MINE, ORDER_PILLAGE,
+ ORDER_POLLUTION, ORDER_ROAD, ORDER_RAILROAD, ORDER_SENTRY,
+ ORDER_TRANSFORM,
ORDER_LAST
};
+/* For client to determine which sprite to display. */
+enum movement_type {
+ GOTO_ORDERS, PATROL_ORDERS, STATIONARY_ORDERS
+};
+
enum unit_focus_status {
FOCUS_AVAIL, FOCUS_WAIT, FOCUS_DONE
};
@@ -65,10 +79,6 @@ enum goto_move_restriction {
GOTO_MOVE_STRAIGHTEST
};
-enum goto_route_type {
- ROUTE_GOTO, ROUTE_PATROL
-};
-
enum unit_move_result {
MR_OK, MR_BAD_TYPE_FOR_CITY_TAKE_OVER, MR_NO_WAR, MR_ZOC,
MR_BAD_ACTIVITY, MR_BAD_DESTINATION, MR_BAD_MAP_POSITION,
@@ -168,6 +178,9 @@ struct unit {
bool repeat; /* The path is to be repeated on completion. */
bool vigilant; /* Orders should be cleared if an enemy is met. */
struct unit_order *list; /* server only */
+ /* Information for client to display sprites correctly. */
+ enum unit_orders mission; /* The last order in the list. */
+ enum movement_type move_type; /* Goto, Patrol, Stationary. */
} orders;
};
@@ -238,6 +251,7 @@ bool unit_can_est_traderoute_here(struct
bool unit_can_defend_here(struct unit *punit);
bool unit_can_airlift_to(struct unit *punit, struct city *pcity);
bool unit_has_orders(struct unit *punit);
+bool order_is_action(enum unit_orders order);
bool can_unit_paradrop(struct unit *punit);
bool can_unit_change_homecity(struct unit *punit);
diff -pruN -Xdiff_ignore clean-E1/server/savegame.c E1/server/savegame.c
--- clean-E1/server/savegame.c Tue Jan 20 23:08:47 2004
+++ E1/server/savegame.c Thu Jan 29 14:55:26 2004
@@ -1131,6 +1131,10 @@ static void player_load(struct player *p
punit->orders.list[j].order = orders_buf[j] - 'a';
punit->orders.list[j].dir = dir_buf[j] - 'a';
}
+ punit->orders.mission = secfile_lookup_int_default(file,
+ (int) ORDER_NONE, "player%d.u%d.orders_mission", plrno, i);
+ punit->orders.move_type = secfile_lookup_int_default(file,
+ (int) STATIONARY_ORDERS, "player%d.u%d.move_type", plrno, i);
punit->has_orders = TRUE;
} else {
punit->has_orders = FALSE;
@@ -1561,6 +1565,11 @@ static void player_save(struct player *p
"player%d.u%d.orders_list", plrno, i);
secfile_insert_str(file, dir_buf,
"player%d.u%d.dir_list", plrno, i);
+
+ secfile_insert_int(file, punit->orders.mission,
+ "player%d.u%d.orders_mission", plrno, i);
+ secfile_insert_int(file, punit->orders.move_type,
+ "player%d.u%d.move_type", plrno, i);
} else {
secfile_insert_int(file, 0, "player%d.u%d.orders_length", plrno, i);
}
diff -pruN -Xdiff_ignore clean-E1/server/unithand.c E1/server/unithand.c
--- clean-E1/server/unithand.c Wed Jan 28 08:42:38 2004
+++ E1/server/unithand.c Thu Jan 29 14:55:26 2004
@@ -1509,6 +1509,26 @@ void handle_unit_orders(struct player *p
}
break;
case ORDER_FINISH_TURN:
+ case ORDER_AUTO_ATTACK:
+ case ORDER_AUTO_SETTLE:
+ case ORDER_BUILD_CITY:
+ case ORDER_BUILD_WONDER:
+ case ORDER_DISBAND:
+ case ORDER_HOMECITY:
+ case ORDER_TRADEROUTE:
+ case ORDER_UNLOAD:
+ case ORDER_AIRBASE:
+ case ORDER_EXPLORE:
+ case ORDER_FALLOUT:
+ case ORDER_FORTIFYING:
+ case ORDER_FORTRESS:
+ case ORDER_IRRIGATE:
+ case ORDER_MINE:
+ case ORDER_PILLAGE:
+ case ORDER_POLLUTION:
+ case ORDER_ROAD:
+ case ORDER_SENTRY:
+ case ORDER_TRANSFORM:
break;
default:
/* An invalid order. This is handled in execute_orders. */
@@ -1536,6 +1556,9 @@ void handle_unit_orders(struct player *p
punit->orders.list[i].order = packet->orders[i];
punit->orders.list[i].dir = packet->dir[i];
}
+ /* For client to display correct sprites. */
+ punit->orders.mission = packet->orders[packet->length - 1];
+ punit->orders.move_type = packet->repeat ? PATROL_ORDERS : GOTO_ORDERS;
if (!packet->repeat) {
set_goto_dest(punit, packet->dest_x, packet->dest_y);
diff -pruN -Xdiff_ignore clean-E1/server/unittools.c E1/server/unittools.c
--- clean-E1/server/unittools.c Thu Jan 29 12:01:18 2004
+++ E1/server/unittools.c Thu Jan 29 14:55:26 2004
@@ -1898,8 +1898,12 @@ void package_unit(struct unit *punit, st
if (punit->has_orders) {
packet->repeat = punit->orders.repeat;
packet->vigilant = punit->orders.vigilant;
+ packet->mission = punit->orders.mission;
+ packet->move_type = punit->orders.move_type;
} else {
packet->repeat = packet->vigilant = FALSE;
+ packet->mission = ORDER_NONE;
+ packet->move_type = STATIONARY_ORDERS;
}
}
@@ -3167,10 +3171,12 @@ static bool maybe_cancel_patrol_due_to_e
bool execute_orders(struct unit *punit)
{
int dest_x, dest_y;
- bool res, last_order;
int unitid = punit->id;
- struct player *pplayer = unit_owner(punit);
int moves_made = 0;
+ bool res, is_last_order;
+ enum unit_activity activity;
+ struct player *pplayer = unit_owner(punit);
+ struct city *pcity;
assert(unit_has_orders(punit));
@@ -3182,18 +3188,34 @@ bool execute_orders(struct unit *punit)
while (TRUE) {
struct unit_order order;
- if (punit->moves_left == 0) {
- /* FIXME: this check won't work when actions take 0 MP. */
+ order = punit->orders.list[punit->orders.index];
+
+ is_last_order = (!punit->orders.repeat &&
+ punit->orders.index + 1 == punit->orders.length);
+
+ if (is_last_order && order_is_action(order.order)) {
+ /* Don't display goto/patrol sprite any more. In practice, this is
+ * only for exhausted settlers with Mission Order: Build city. */
+ punit->orders.move_type = STATIONARY_ORDERS;
+
+ if (punit->moves_left == 0 && order.order == ORDER_BUILD_CITY) {
+ freelog(LOG_DEBUG, " ran out of MPs and will build city later.");
+ return TRUE;
+ }
+ }
+
+ else if (punit->moves_left == 0) {
freelog(LOG_DEBUG, " stopping because of no more move points");
return TRUE;
}
- if (punit->done_moving) {
+ else if (punit->done_moving) {
freelog(LOG_DEBUG, " stopping because we're done this turn");
return TRUE;
}
- if (punit->orders.vigilant && maybe_cancel_patrol_due_to_enemy(punit)) {
+ else if (punit->orders.vigilant
+ && maybe_cancel_patrol_due_to_enemy(punit)) {
/* "Patrol" orders are stopped if an enemy is near. */
freelog(LOG_DEBUG, " stopping because of nearby enemy");
free_unit_orders(punit);
@@ -3204,17 +3226,13 @@ bool execute_orders(struct unit *punit)
return TRUE;
}
- if (moves_made == punit->orders.length) {
+ else if (moves_made == punit->orders.length) {
/* For repeating orders, don't repeat more than once per turn. */
freelog(LOG_DEBUG, " stopping because we ran a round");
return TRUE;
}
- last_order = (!punit->orders.repeat
- && punit->orders.index + 1 == punit->orders.length);
-
- order = punit->orders.list[punit->orders.index];
- if (last_order) {
+ if (is_last_order) {
/* Clear the orders before we engage in the move. That way any
* has_orders checks will yield FALSE and this will be treated as
* a normal move. This is important: for instance a caravan goto
@@ -3222,6 +3240,7 @@ bool execute_orders(struct unit *punit)
free_unit_orders(punit);
}
+ activity = ACTIVITY_LAST;
switch (order.order) {
case ORDER_FINISH_TURN:
punit->done_moving = TRUE;
@@ -3240,7 +3259,7 @@ bool execute_orders(struct unit *punit)
return TRUE;
}
- if (!last_order
+ if (!is_last_order
&& maybe_cancel_goto_due_to_enemy(punit, dest_x, dest_y)) {
freelog(LOG_DEBUG, " orders canceled because of enemy");
free_unit_orders(punit);
@@ -3253,7 +3272,7 @@ bool execute_orders(struct unit *punit)
freelog(LOG_DEBUG, " moving to %d,%d", dest_x, dest_y);
res = handle_unit_move_request(punit, dest_x, dest_y,
- FALSE, !last_order);
+ FALSE, !is_last_order);
if (!player_find_unit_by_id(pplayer, unitid)) {
freelog(LOG_DEBUG, " unit died while moving.");
/* A player notification should already have been sent. */
@@ -3276,9 +3295,81 @@ bool execute_orders(struct unit *punit)
unit_name(punit->type));
return TRUE;
}
-
break;
- case ORDER_LAST:
+ case ORDER_AUTO_ATTACK:
+ case ORDER_AUTO_SETTLE:
+ freelog(LOG_DEBUG, " entering auto mode.");
+ handle_unit_auto(pplayer, unitid);
+ break;
+ case ORDER_BUILD_CITY:
+ /* We don't need extra 2-way communication about city names,
+ * since this function may be called when sniff_packets() is
+ * not active. Player will just have to accept that
+ * Build Missions take default city name. */
+ freelog(LOG_DEBUG, " founding new city.");
+ handle_unit_build_city(pplayer, unitid,
+ city_name_suggestion(pplayer, punit->x, punit->y));
+ break;
+ case ORDER_BUILD_WONDER:
+ freelog(LOG_DEBUG, " building wonder.");
+ handle_unit_help_build_wonder(pplayer, unitid);
+ break;
+ case ORDER_DISBAND:
+ freelog(LOG_DEBUG, " disbanding unit.");
+ handle_unit_disband(pplayer, unitid);
+ break;
+ case ORDER_HOMECITY:
+ freelog(LOG_DEBUG, " changing homecity.");
+ pcity = map_get_city(punit->x, punit->y);
+ handle_unit_change_homecity(pplayer, unitid, pcity ? pcity->id : -1);
+ break;
+ case ORDER_TRADEROUTE:
+ freelog(LOG_DEBUG, " establishing a trade route.");
+ handle_unit_establish_trade(pplayer, unitid);
+ break;
+ case ORDER_UNLOAD:
+ freelog(LOG_DEBUG, " unloading.");
+ handle_unit_unload(pplayer, unitid);
+ break;
+ case ORDER_AIRBASE:
+ activity = ACTIVITY_AIRBASE;
+ break;
+ case ORDER_EXPLORE:
+ activity = ACTIVITY_EXPLORE;
+ break;
+ case ORDER_FALLOUT:
+ activity = ACTIVITY_FALLOUT;
+ break;
+ case ORDER_FORTIFYING:
+ activity = ACTIVITY_FORTIFYING;
+ break;
+ case ORDER_FORTRESS:
+ activity = ACTIVITY_FORTRESS;
+ break;
+ case ORDER_IRRIGATE:
+ activity = ACTIVITY_IRRIGATE;
+ break;
+ case ORDER_MINE:
+ activity = ACTIVITY_MINE;
+ break;
+ case ORDER_PILLAGE:
+ activity = ACTIVITY_PILLAGE;
+ break;
+ case ORDER_POLLUTION:
+ activity = ACTIVITY_POLLUTION;
+ break;
+ case ORDER_SENTRY:
+ activity = ACTIVITY_SENTRY;
+ break;
+ case ORDER_TRANSFORM:
+ activity = ACTIVITY_TRANSFORM;
+ break;
+ case ORDER_ROAD:
+ case ORDER_RAILROAD:
+ activity = map_has_special(punit->x, punit->y, S_ROAD)
+ ? ACTIVITY_RAILROAD : ACTIVITY_ROAD;
+ break;
+ default:
freelog(LOG_DEBUG, " client sent invalid order!");
free_unit_orders(punit);
notify_player_ex(pplayer, punit->x, punit->y, E_UNIT_ORDERS,
@@ -3287,7 +3378,25 @@ bool execute_orders(struct unit *punit)
return TRUE;
}
- if (last_order) {
+ if (activity == ACTIVITY_EXPLORE) {
+ /* This generates new orders. */
+ free_unit_orders(punit);
+ freelog(LOG_DEBUG, " entering explore mode.");
+ handle_unit_change_activity(pplayer, unitid, activity, S_NO_SPECIAL);
+ return player_find_unit_by_id(pplayer, unitid) ? TRUE : FALSE;
+ }
+
+ if (activity != ACTIVITY_LAST) {
+ freelog(LOG_DEBUG, " setting new activity.");
+ handle_unit_change_activity(pplayer, unitid, activity, S_NO_SPECIAL);
+ }
+
+ if (!player_find_unit_by_id(pplayer, unitid)) {
+ freelog(LOG_DEBUG, " unit died from executing order.");
+ return FALSE;
+ }
+
+ if (is_last_order) {
assert(punit->has_orders == FALSE);
freelog(LOG_DEBUG, " stopping because orders are complete");
return TRUE;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] (PR#7344) Expanded Orders,
Arnstein Lindgard <=
|
|