[Freeciv-Dev] (PR#6948) Quickselect unit
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: |
undisclosed-recipients: ; |
Subject: |
[Freeciv-Dev] (PR#6948) Quickselect unit |
From: |
"Arnstein Lindgard" <a-l@xxxxxxx> |
Date: |
Tue, 25 Nov 2003 09:28:26 -0800 |
Reply-to: |
rt@xxxxxxxxxxx |
<URL: http://rt.freeciv.org/Ticket/Display.html?id=6948 >
Feature: Quickselect a unit from a tile, bypassing stack or city
popups. Gtk[12] and xaw.
Use <control> left/right click, for sea/land units. Priorities:
SEA: Transporter
Sea unit
Any unit
LAND: Military land unit
Non-combatant
Sea unit
Any unit
Units with moves left before exhausted. Focus unit is excluded.
Repeat click to get another unit.
It's a simple patch which is enormously useful for tactical
situations in multiplayer, and otherwise convenient.
Arnstein
diff -ruN -Xdiff_ignore freeciv/client/control.c quickselect/client/control.c
--- freeciv/client/control.c Sat Nov 22 23:37:20 2003
+++ quickselect/client/control.c Mon Nov 24 23:54:27 2003
@@ -73,6 +73,8 @@
static struct unit *find_best_focus_candidate(bool accept_current);
static void store_focus(void);
+static struct unit *quickselect(struct tile *ptile,
+ enum quickselect_type qtype);
/**************************************************************************
...
@@ -1298,7 +1300,7 @@
/**************************************************************************
Handles everything when the user clicked a tile
**************************************************************************/
-void do_map_click(int xtile, int ytile)
+void do_map_click(int xtile, int ytile, enum quickselect_type qtype)
{
struct city *pcity = map_get_city(xtile, ytile);
struct tile *ptile = map_get_tile(xtile, ytile);
@@ -1336,7 +1338,18 @@
update_unit_info_label(punit);
return;
}
-
+
+ /* Bypass stack popup if quickselect is specified. */
+ if (qtype) {
+ struct unit *qunit = quickselect(ptile, qtype);
+ if (qunit) {
+ set_unit_focus_and_select(qunit);
+ }
+ return;
+ }
+
+ /* Otherwise use popups. */
+
if (pcity && game.player_idx==pcity->owner) {
popup_city_dialog(pcity, FALSE);
return;
@@ -1365,6 +1378,104 @@
}
/**************************************************************************
+ Quickselecting a unit is normally done with <control> left/right click.
+ Bypassing the stack popup is quite convenient, and can be tactically
+ important in furious multiplayer games.
+**************************************************************************/
+static struct unit *quickselect(struct tile *ptile,
+ enum quickselect_type qtype)
+{
+ int listsize = unit_list_size(&ptile->units);
+ struct unit *panytransporter = NULL,
+ *panymovesea = NULL, *panysea = NULL,
+ *panymoveland = NULL, *panyland = NULL,
+ *panymoveunit = NULL, *panyunit = NULL;
+
+ assert(qtype > SELECT_POPUP);
+
+ if (listsize == 0) {
+ return NULL;
+ } else if (listsize == 1) {
+ struct unit *punit = unit_list_get(&ptile->units, 0);
+ return (game.player_idx == punit->owner) ? punit : NULL;
+ }
+
+ /* Quickselect priorities. Units with moves left
+ * before exhausted. Focus unit is excluded.
+ *
+ * SEA: Transporter
+ * Sea unit
+ * Any unit
+ *
+ * LAND: Military land unit
+ * Non-combatant
+ * Sea unit
+ * Any unit
+ */
+
+ unit_list_iterate(ptile->units, punit) {
+ if(game.player_idx != punit->owner || punit == punit_focus) {
+ continue;
+ }
+ if (qtype == SELECT_SEA) {
+ /* transporter */
+ if (get_transporter_capacity(punit)) {
+ if (punit->moves_left > 0)
+ return punit;
+ else if (!panytransporter)
+ panytransporter = punit;
+ }
+ /* any sea, pref. moves left */
+ else if (is_sailing_unit(punit)) {
+ if (punit->moves_left > 0) {
+ if (!panymovesea)
+ panymovesea = punit;
+ } else if (!panysea)
+ panysea = punit;
+ }
+ } else if (qtype == SELECT_LAND) {
+ if (is_ground_unit(punit)) {
+ if (punit->moves_left > 0) {
+ if (is_military_unit(punit)) {
+ return punit;
+ } else if (!panymoveland)
+ panymoveland = punit;
+ }
+ else if (!panyland)
+ panyland = punit;
+ }
+ else if (is_sailing_unit(punit)) {
+ if (punit->moves_left > 0)
+ panymovesea = punit;
+ else
+ panysea = punit;
+ }
+ }
+ if (punit->moves_left > 0 && !panymoveunit)
+ panymoveunit = punit;
+ if (!panyunit)
+ panyunit = punit;
+ } unit_list_iterate_end;
+
+ if (qtype == SELECT_SEA) {
+ if (panytransporter) return panytransporter;
+ else if (panymovesea) return panymovesea;
+ else if (panysea) return panysea;
+ else if (panymoveunit) return panymoveunit;
+ else if (panyunit) return panyunit;
+ }
+ else if (qtype == SELECT_LAND) {
+ if (panymoveland) return panymoveland;
+ else if (panyland) return panyland;
+ else if (panymovesea) return panymovesea;
+ else if (panysea) return panysea;
+ else if (panymoveunit) return panymoveunit;
+ else if (panyunit) return panyunit;
+ }
+ return NULL;
+}
+
+/**************************************************************************
Finish the goto mode and let the unit which is stored in hover_unit move
to a given location.
**************************************************************************/
diff -ruN -Xdiff_ignore freeciv/client/control.h quickselect/client/control.h
--- freeciv/client/control.h Wed Nov 19 18:32:57 2003
+++ quickselect/client/control.h Mon Nov 24 22:34:56 2003
@@ -24,6 +24,11 @@
HOVER_PATROL
};
+/* Selecting unit from a stack without popup. */
+enum quickselect_type {
+ SELECT_POPUP = 0, SELECT_SEA, SELECT_LAND
+};
+
extern int hover_unit; /* unit hover_state applies to */
extern enum cursor_hover_state hover_state;
extern bool draw_goto_line;
@@ -34,7 +39,7 @@
void do_unit_nuke(struct unit *punit);
void do_unit_paradrop_to(struct unit *punit, int x, int y);
void do_unit_patrol_to(struct unit *punit, int x, int y);
-void do_map_click(int xtile, int ytile);
+void do_map_click(int xtile, int ytile, enum quickselect_type qtype);
void set_hover_state(struct unit *punit, enum cursor_hover_state state);
void request_center_focus_unit(void);
diff -ruN -Xdiff_ignore freeciv/client/gui-gtk/mapctrl.c
quickselect/client/gui-gtk/mapctrl.c
--- freeciv/client/gui-gtk/mapctrl.c Fri Nov 14 13:30:55 2003
+++ quickselect/client/gui-gtk/mapctrl.c Mon Nov 24 21:58:33 2003
@@ -226,6 +226,10 @@
if ((ev->state & GDK_SHIFT_MASK) && (ev->state & GDK_CONTROL_MASK)) {
adjust_workers_button_pressed(ev->x, ev->y);
}
+ /* <CONTROL> + LMB : Quickselect a sea unit. */
+ else if (ev->state & GDK_CONTROL_MASK) {
+ action_button_pressed(ev->x, ev->y, SELECT_SEA);
+ }
/* <SHIFT> + LMB: Copy Production. */
else if(is_real && (ev->state & GDK_SHIFT_MASK)) {
clipboard_copy_production(xtile, ytile);
@@ -238,9 +242,7 @@
}
/* Plain LMB click. */
else {
- if (is_real) {
- action_button_pressed(ev->x, ev->y);
- }
+ action_button_pressed(ev->x, ev->y, SELECT_POPUP);
}
break;
@@ -258,8 +260,12 @@
case 3: /* RIGHT mouse button */
+ /* <CONTROL> + RMB : Quickselect a land unit. */
+ if (ev->state & GDK_CONTROL_MASK) {
+ action_button_pressed(ev->x, ev->y, SELECT_LAND);
+ }
/* <SHIFT> + RMB: Paste Production. */
- if(ev->state & GDK_SHIFT_MASK) {
+ else if(ev->state & GDK_SHIFT_MASK) {
clipboard_paste_production(pcity);
cancel_tile_hiliting();
}
diff -ruN -Xdiff_ignore freeciv/client/gui-gtk-2.0/mapctrl.c
quickselect/client/gui-gtk-2.0/mapctrl.c
--- freeciv/client/gui-gtk-2.0/mapctrl.c Fri Nov 14 13:30:56 2003
+++ quickselect/client/gui-gtk-2.0/mapctrl.c Mon Nov 24 23:11:01 2003
@@ -206,6 +206,10 @@
if ((ev->state & GDK_SHIFT_MASK) && (ev->state & GDK_CONTROL_MASK)) {
adjust_workers_button_pressed(ev->x, ev->y);
}
+ /* <CONTROL> + LMB : Quickselect a sea unit. */
+ else if (ev->state & GDK_CONTROL_MASK) {
+ action_button_pressed(ev->x, ev->y, SELECT_SEA);
+ }
/* <SHIFT> + LMB: Copy Production. */
else if(is_real && (ev->state & GDK_SHIFT_MASK)) {
clipboard_copy_production(xtile, ytile);
@@ -218,9 +222,7 @@
}
/* Plain LMB click. */
else {
- if (is_real) {
- action_button_pressed(ev->x, ev->y);
- }
+ action_button_pressed(ev->x, ev->y, SELECT_POPUP);
}
break;
@@ -238,8 +240,12 @@
case 3: /* RIGHT mouse button */
+ /* <CONTROL> + RMB : Quickselect a land unit. */
+ if (ev->state & GDK_CONTROL_MASK) {
+ action_button_pressed(ev->x, ev->y, SELECT_LAND);
+ }
/* <SHIFT> + RMB: Paste Production. */
- if(ev->state & GDK_SHIFT_MASK) {
+ else if(ev->state & GDK_SHIFT_MASK) {
clipboard_paste_production(pcity);
cancel_tile_hiliting();
}
diff -ruN -Xdiff_ignore freeciv/client/gui-sdl/mapctrl.c
quickselect/client/gui-sdl/mapctrl.c
--- freeciv/client/gui-sdl/mapctrl.c Fri Nov 14 13:30:56 2003
+++ quickselect/client/gui-sdl/mapctrl.c Mon Nov 24 23:12:45 2003
@@ -1888,7 +1888,7 @@
}
}
} else {
- action_button_pressed(pButtonEvent->x, pButtonEvent->y);
+ action_button_pressed(pButtonEvent->x, pButtonEvent->y, SELECT_POPUP);
}
} else {
if (pButtonEvent->button == SDL_BUTTON_MIDDLE) {
diff -ruN -Xdiff_ignore freeciv/client/gui-win32/mapctrl.c
quickselect/client/gui-win32/mapctrl.c
--- freeciv/client/gui-win32/mapctrl.c Fri Nov 14 13:30:56 2003
+++ quickselect/client/gui-win32/mapctrl.c Mon Nov 24 23:13:47 2003
@@ -238,7 +238,7 @@
LOWORD(lParam), HIWORD(lParam))) {
popit(LOWORD(lParam),HIWORD(lParam),xtile,ytile);
} else {
- action_button_pressed(LOWORD(lParam), HIWORD(lParam));
+ action_button_pressed(LOWORD(lParam), HIWORD(lParam), SELECT_POPUP);
}
break;
case WM_MBUTTONDOWN:
diff -ruN -Xdiff_ignore freeciv/client/gui-xaw/mapctrl.c
quickselect/client/gui-xaw/mapctrl.c
--- freeciv/client/gui-xaw/mapctrl.c Fri Nov 14 13:30:56 2003
+++ quickselect/client/gui-xaw/mapctrl.c Mon Nov 24 23:35:01 2003
@@ -207,11 +207,15 @@
return;
}
- if (ev->button == Button1) {
- action_button_pressed(ev->x, ev->y);
- } else if (canvas_to_map_pos(&x, &y, ev->x, ev->y)
- && (ev->button == Button2 || ev->state & ControlMask)) {
+ if (ev->button == Button1 && (ev->state & ControlMask)) {
+ action_button_pressed(ev->x, ev->y, SELECT_SEA);
+ } else if (ev->button == Button1) {
+ action_button_pressed(ev->x, ev->y, SELECT_POPUP);
+ } else if (ev->button == Button2 &&
+ canvas_to_map_pos(&x, &y, ev->x, ev->y)) {
popit(ev->x, ev->y, x, y);
+ } else if (ev->button == Button3 && (ev->state & ControlMask)) {
+ action_button_pressed(ev->x, ev->y, SELECT_LAND);
} else if (ev->button == Button3) {
recenter_button_pressed(ev->x, ev->y);
}
diff -ruN -Xdiff_ignore freeciv/client/mapctrl_common.c
quickselect/client/mapctrl_common.c
--- freeciv/client/mapctrl_common.c Mon Nov 17 19:27:28 2003
+++ quickselect/client/mapctrl_common.c Mon Nov 24 21:54:11 2003
@@ -423,7 +423,8 @@
left-click) is pressed. For more sophisticated user control use (or
write) a different xxx_button_pressed function.
**************************************************************************/
-void action_button_pressed(int canvas_x, int canvas_y)
+void action_button_pressed(int canvas_x, int canvas_y,
+ enum quickselect_type qtype)
{
int map_x, map_y;
@@ -431,7 +432,7 @@
/* FIXME: Some actions here will need to check can_client_issue_orders.
* But all we can check is the lowest common requirement. */
if (canvas_to_map_pos(&map_x, &map_y, canvas_x, canvas_y)) {
- do_map_click(map_x, map_y);
+ do_map_click(map_x, map_y, qtype);
}
}
}
diff -ruN -Xdiff_ignore freeciv/client/mapctrl_common.h
quickselect/client/mapctrl_common.h
--- freeciv/client/mapctrl_common.h Fri Nov 14 13:30:54 2003
+++ quickselect/client/mapctrl_common.h Mon Nov 24 22:36:26 2003
@@ -17,6 +17,8 @@
#include "map.h" /* enum direction8 */
#include "shared.h" /* bool type */
+#include "control.h" /* quickselect_type */
+
extern bool rbutton_down;
extern bool rectangle_active;
extern bool tiles_hilited_cities;
@@ -34,7 +36,8 @@
void release_right_button(int canvas_x, int canvas_y);
bool get_turn_done_button_state(void);
void scroll_mapview(enum direction8 gui_dir);
-void action_button_pressed(int canvas_x, int canvas_y);
+void action_button_pressed(int canvas_x, int canvas_y,
+ enum quickselect_type qtype);
void wakeup_button_pressed(int canvas_x, int canvas_y);
void adjust_workers_button_pressed(int canvas_x, int canvas_y);
void recenter_button_pressed(int canvas_x, int canvas_y);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] (PR#6948) Quickselect unit,
Arnstein Lindgard <=
|
|