[Freeciv-Dev] (PR#15935) cursors for editing mode
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=15935 >
This patch adds two cursors for editing mode, with the infrastructure to
add more.
A couple of new editor functions are added to test the result of
clicking on a tile. The result is one of CURSOR_EDITOR_PAINT,
CURSOR_EDITOR_ADD, or CURSOR_EDITOR_INVALID. Another new function (now
used in two placces) tests whether an editor click is possible at all.
I fixed a bug that prevented painting terrain or adding units beneath an
existing city (now instead, you can't open cities while in edit mode).
There are still some problems. You can't open a city or select a unit
while in edit mode...at all. And the INVALID cursor isn't set properly
for unit-adding or city-adding because there are no checks for validity
in editor.c.
The graphics leave a bit to be desired. Presumably the artists will
eventually improve them.
-jason
Index: data/misc/cursors.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: data/misc/cursors.spec
===================================================================
--- data/misc/cursors.spec (revision 11776)
+++ data/misc/cursors.spec (working copy)
@@ -8,6 +8,9 @@
artists = "
Andreas Røsdal <andrearo@xxxxxxxxxxxx>
+
+ edit_paint cursor take from GIMP
+
"
[file]
@@ -64,4 +67,16 @@
3, 6, "cursor.attack3", 16, 16
4, 6, "cursor.attack4", 16, 16
5, 6, "cursor.attack5", 16, 16
+ 0, 7, "cursor.edit_paint0", 16, 16
+ 1, 7, "cursor.edit_paint1", 16, 16
+ 2, 7, "cursor.edit_paint2", 16, 16
+ 3, 7, "cursor.edit_paint3", 16, 16
+ 4, 7, "cursor.edit_paint4", 16, 16
+ 5, 7, "cursor.edit_paint5", 16, 16
+ 0, 8, "cursor.edit_add0", 16, 16
+ 1, 8, "cursor.edit_add1", 16, 16
+ 2, 8, "cursor.edit_add2", 16, 16
+ 3, 8, "cursor.edit_add3", 16, 16
+ 4, 8, "cursor.edit_add4", 16, 16
+ 5, 8, "cursor.edit_add5", 16, 16
}
Index: common/tile.c
===================================================================
--- common/tile.c (revision 11776)
+++ common/tile.c (working copy)
@@ -91,6 +91,14 @@
}
/****************************************************************************
+ Returns TRUE iff the given tile has any specials.
+****************************************************************************/
+bool tile_has_any_specials(const struct tile *ptile)
+{
+ return contains_any_specials(ptile->special);
+}
+
+/****************************************************************************
Add the given special or specials to the tile.
Note that this does not erase any existing specials already on the tile
Index: common/tile.h
===================================================================
--- common/tile.h (revision 11776)
+++ common/tile.h (working copy)
@@ -60,6 +60,7 @@
bv_special tile_get_special(const struct tile *ptile);
bool tile_has_special(const struct tile *ptile,
enum tile_special_type to_test_for);
+bool tile_has_any_specials(const struct tile *ptile);
void tile_set_special(struct tile *ptile, enum tile_special_type spe);
const struct resource *tile_get_resource(const struct tile *ptile);
void tile_set_resource(struct tile *ptile, const struct resource *presource);
Index: common/terrain.c
===================================================================
--- common/terrain.c (revision 11776)
+++ common/terrain.c (working copy)
@@ -372,6 +372,14 @@
}
/****************************************************************************
+ Returns TRUE iff any specials are set on the tile.
+****************************************************************************/
+bool contains_any_specials(bv_special set)
+{
+ return BV_ISSET_ANY(set);
+}
+
+/****************************************************************************
Returns TRUE iff any tile adjacent to (map_x,map_y) has the given special.
****************************************************************************/
bool is_special_near_tile(const struct tile *ptile, enum tile_special_type spe)
Index: common/terrain.h
===================================================================
--- common/terrain.h (revision 11776)
+++ common/terrain.h (working copy)
@@ -214,6 +214,7 @@
void clear_all_specials(bv_special *set);
bool contains_special(bv_special all,
enum tile_special_type to_test_for);
+bool contains_any_specials(bv_special all);
/* Functions to operate on a terrain special. */
bool is_special_near_tile(const struct tile *ptile,
Index: client/control.c
===================================================================
--- client/control.c (revision 11776)
+++ client/control.c (working copy)
@@ -35,6 +35,7 @@
#include "clinet.h"
#include "combat.h"
#include "dialogs_g.h"
+#include "editor.h"
#include "goto.h"
#include "gui_main_g.h"
#include "mapctrl_g.h"
@@ -889,6 +890,7 @@
/* hover_tile is the tile which is currently under the mouse cursor. */
ptile = hover_tile;
} else {
+ update_mouse_cursor(mouse_cursor_type);
return;
}
}
@@ -898,7 +900,9 @@
switch (hover_state) {
case HOVER_NONE:
- if (punit && game.player_ptr == punit->owner) {
+ if (can_do_editor_click(ptile)) {
+ mouse_cursor_type = editor_test_click(ptile);
+ } else if (punit && game.player_ptr == punit->owner) {
/* Set mouse cursor to select a unit. */
mouse_cursor_type = CURSOR_SELECT;
} else if (pcity
Index: client/tilespec.c
===================================================================
--- client/tilespec.c (revision 11776)
+++ client/tilespec.c (working copy)
@@ -2019,9 +2019,10 @@
for (f = 0; f < NUM_CURSOR_FRAMES; f++) {
const char *names[CURSOR_LAST] =
{"goto", "patrol", "paradrop", "nuke", "select",
- "invalid", "attack"};
+ "invalid", "attack", "edit_paint", "edit_add"};
struct small_sprite *ss;
+ assert(ARRAY_SIZE(names) == CURSOR_LAST);
my_snprintf(buffer, sizeof(buffer), "cursor.%s%d", names[i], f);
SET_SPRITE(cursor[i].frame[f], buffer);
ss = hash_lookup_data(t->sprite_hash, buffer);
Index: client/mapctrl_common.c
===================================================================
--- client/mapctrl_common.c (revision 11776)
+++ client/mapctrl_common.c (working copy)
@@ -531,7 +531,7 @@
{
struct tile *ptile = canvas_pos_to_tile(canvas_x, canvas_y);
- if (!ptile->city && can_conn_edit(&aconnection)) {
+ if (can_do_editor_click(ptile)) {
editor_do_click(ptile);
} else if (can_client_change_view() && ptile) {
/* FIXME: Some actions here will need to check can_client_issue_orders.
Index: client/tilespec.h
===================================================================
--- client/tilespec.h (revision 11776)
+++ client/tilespec.h (working copy)
@@ -160,6 +160,8 @@
CURSOR_SELECT,
CURSOR_INVALID,
CURSOR_ATTACK,
+ CURSOR_EDIT_PAINT,
+ CURSOR_EDIT_ADD,
CURSOR_LAST,
CURSOR_DEFAULT,
};
Index: client/editor.c
===================================================================
--- client/editor.c (revision 11776)
+++ client/editor.c (working copy)
@@ -30,6 +30,7 @@
#include "clinet.h"
#include "control.h"
#include "editor.h"
+#include "tilespec.h"
/* where the selected terrain and specials for editing are stored */
static enum editor_tool_type selected_tool = ETOOL_PAINT;
@@ -117,48 +118,60 @@
problem: could be multiple units on a particular tile
TODO: edit existing units
****************************************************************************/
-static void do_unit(struct tile *ptile)
+static enum cursor_type editor_unit(struct tile *ptile, bool testing)
{
- struct packet_edit_unit packet;
+ /* FIXME: Do checks to see if the placement is allowed, so that the
+ * cursor can be set properly. */
+ if (!testing) {
+ struct packet_edit_unit packet;
- packet.create_new = TRUE; /* ? */
- packet.delete = FALSE;
+ packet.create_new = TRUE; /* ? */
+ packet.delete = FALSE;
- packet.id = selected_unit->id;
- packet.owner = selected_unit->owner->player_no;
+ packet.id = selected_unit->id;
+ packet.owner = selected_unit->owner->player_no;
- packet.x = ptile->x;
- packet.y = ptile->y;
+ packet.x = ptile->x;
+ packet.y = ptile->y;
- packet.homecity = selected_unit->homecity;
+ packet.homecity = selected_unit->homecity;
- packet.veteran = selected_unit->veteran;
- packet.paradropped = selected_unit->paradropped;
+ packet.veteran = selected_unit->veteran;
+ packet.paradropped = selected_unit->paradropped;
- packet.type = selected_unit->type->index;
- packet.transported_by = selected_unit->transported_by;
+ packet.type = selected_unit->type->index;
+ packet.transported_by = selected_unit->transported_by;
- packet.movesleft = selected_unit->moves_left;
- packet.hp = selected_unit->hp;
- packet.fuel = selected_unit->fuel;
+ packet.movesleft = selected_unit->moves_left;
+ packet.hp = selected_unit->hp;
+ packet.fuel = selected_unit->fuel;
- packet.activity_count = selected_unit->activity_count;
+ packet.activity_count = selected_unit->activity_count;
- send_packet_edit_unit(&aconnection, &packet);
+ send_packet_edit_unit(&aconnection, &packet);
+ }
+
+ return CURSOR_EDIT_ADD;
}
/****************************************************************************
basically package_city in citytools.c
****************************************************************************/
-static void do_city(struct tile *ptile)
+static enum cursor_type editor_city(struct tile *ptile, bool testing)
{
- struct packet_edit_create_city packet = {
- .owner = selected_city->owner->player_no,
- .x = ptile->x,
- .y = ptile->y
- };
+ /* FIXME: Do checks to see if the placement is allowed, so that the
+ * cursor can be set properly. */
+ if (!testing) {
+ struct packet_edit_create_city packet = {
+ .owner = selected_city->owner->player_no,
+ .x = ptile->x,
+ .y = ptile->y
+ };
- send_packet_edit_create_city(&aconnection, &packet);
+ send_packet_edit_create_city(&aconnection, &packet);
+ }
+
+ return CURSOR_EDIT_ADD;
}
#if 0
@@ -179,61 +192,105 @@
For instance, if the paint operation is paint-terrain, then we just change
the current tile's terrain to the selected terrain.
****************************************************************************/
-static void do_paint(struct tile *ptile)
+static enum cursor_type editor_paint(struct tile *ptile, bool testing)
{
struct tile tile = *ptile;
switch (selected_paint_type) {
case EPAINT_TERRAIN:
- if (selected_terrain) {
+ if (selected_terrain && tile.terrain != selected_terrain) {
tile.terrain = selected_terrain;
+ } else {
+ return CURSOR_INVALID;
}
break;
case EPAINT_SPECIAL:
/* add new special to existing specials on the tile */
- if (selected_special == S_LAST) {
+ if (selected_special == S_LAST && tile_has_any_specials(&tile)) {
tile_clear_all_specials(&tile);
+ } else if (selected_special != S_LAST
+ && !tile_has_special(&tile, selected_special)) {
+ tile_add_special(&tile, selected_special);
} else {
- tile_add_special(&tile, selected_special);
+ return CURSOR_INVALID;
}
break;
case EPAINT_LAST:
- return;
- }
+ default:
+ return CURSOR_INVALID;
+ }
- /* send the result to the server for changing */
- /* FIXME: No way to change resources. */
- dsend_packet_edit_tile(&aconnection, ptile->x, ptile->y,
- tile.terrain->index,
- tile.resource ? tile.resource->index : -1,
- tile.special);
+ if (!testing) {
+ /* send the result to the server for changing */
+ /* FIXME: No way to change resources. */
+ dsend_packet_edit_tile(&aconnection, ptile->x, ptile->y,
+ tile.terrain->index,
+ tile.resource ? tile.resource->index : -1,
+ tile.special);
+ }
+
+ return CURSOR_EDIT_PAINT;
}
/****************************************************************************
if the client is in edit_mode, then this function captures clicks on the
map canvas.
+
+ If the testing parameter is given then no actions are taken, but the
+ return value indicates what would happen if a click was made.
****************************************************************************/
-void editor_do_click(struct tile *ptile)
+static enum cursor_type editor_click(struct tile *ptile, bool testing)
{
/* Editing tiles that we can't see (or are fogged) will only lead to
* problems. */
if (client_tile_get_known(ptile) != TILE_KNOWN) {
- return;
+ return CURSOR_INVALID;
}
switch (selected_tool) {
case ETOOL_PAINT:
- do_paint(ptile);
- break;
+ return editor_paint(ptile, testing);
case ETOOL_UNIT:
- do_unit(ptile);
- break;
+ return editor_unit(ptile, testing);
case ETOOL_CITY:
- do_city(ptile);
- break;
+ return editor_city(ptile, testing);
case ETOOL_PLAYER:
case ETOOL_DELETE:
case ETOOL_LAST:
break;
}
+ return CURSOR_INVALID;
}
+
+/****************************************************************************
+ Return TRUE if an editor click on this tile is allowed - if not then a
+ normal click should be done instead.
+****************************************************************************/
+bool can_do_editor_click(struct tile *ptile)
+{
+ /* Previously, editor clicks were not allowed on city tiles; instead
+ * a click here would cause a regular click and the citydlg would open.
+ * This made it impossible to add a unit or paint a terrain underneath
+ * a city. */
+ return can_conn_edit(&aconnection);
+}
+
+/****************************************************************************
+ if the client is in edit_mode, then this function captures clicks on the
+ map canvas.
+****************************************************************************/
+void editor_do_click(struct tile *ptile)
+{
+ (void) editor_click(ptile, FALSE);
+}
+
+/****************************************************************************
+ if the client is in edit_mode, then this function returns the cursor_type
+ indicating what action would be taken on a click. This can be used by
+ the code to set the cursor so the user can anticipate what clicking will
+ do.
+****************************************************************************/
+enum cursor_type editor_test_click(struct tile *ptile)
+{
+ return editor_click(ptile, TRUE);
+}
Index: client/editor.h
===================================================================
--- client/editor.h (revision 11776)
+++ client/editor.h (working copy)
@@ -44,6 +44,8 @@
struct unit *editor_get_selected_unit(void);
struct city *editor_get_selected_city(void);
+bool can_do_editor_click(struct tile *ptile);
void editor_do_click(struct tile *ptile);
+enum cursor_type editor_test_click(struct tile *ptile);
#endif /* FC__TOOLS_H */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] (PR#15935) cursors for editing mode,
Jason Short <=
|
|