<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40483 >
Patch implements the "game" object type and one of its editable properties, 'year', in the property editor system. There are also two changes outside the editor code; the first is a call to update_info_label() in handle_game_info in the client. This is so that the 'year' label is properly updated when the server sends back the result of modifying the 'year' property. The second change is that the minimum and maximum endyear setting values were changed to -32768 and 32767 respectively. I think it might be a good idea anyway to change the 'year' variable to a signed int. That way mod/scenario authors could for example make a dinosaur scenario in 300,000,000 BC, or a scenario about the awakening of some "settlers" frozen in stasis for 2 billion years. :) ---------------------------------------------------------------------- 麻薬の使用はどうですか。
client/editor.h | 1 + client/gui-gtk-2.0/editgui.c | 3 +- client/gui-gtk-2.0/editprop.c | 116 +++++++++++++++++++++++++++++++++++++--- client/gui-gtk-2.0/editprop.h | 2 +- client/packhand.c | 6 ++ common/game.h | 4 +- common/packets.def | 6 ++- server/edithand.c | 35 ++++++++++++ 8 files changed, 159 insertions(+), 14 deletions(-) diff --git a/client/editor.h b/client/editor.h index 7dc520f..43e5201 100644 --- a/client/editor.h +++ b/client/editor.h @@ -23,6 +23,7 @@ enum editor_object_type { OBJTYPE_UNIT, OBJTYPE_CITY, OBJTYPE_PLAYER, + OBJTYPE_GAME, NUM_OBJTYPES }; diff --git a/client/gui-gtk-2.0/editgui.c b/client/gui-gtk-2.0/editgui.c index ca1b987..9cf03f6 100644 --- a/client/gui-gtk-2.0/editgui.c +++ b/client/gui-gtk-2.0/editgui.c @@ -396,7 +396,8 @@ static void editbar_player_properties_button_clicked(GtkButton *b, } pe = editprop_get_property_editor(); - property_editor_reload_players(pe); + property_editor_reload(pe, OBJTYPE_GAME); + property_editor_reload(pe, OBJTYPE_PLAYER); property_editor_popup(pe); } diff --git a/client/gui-gtk-2.0/editprop.c b/client/gui-gtk-2.0/editprop.c index bf3c71d..67d6012 100644 --- a/client/gui-gtk-2.0/editprop.c +++ b/client/gui-gtk-2.0/editprop.c @@ -78,6 +78,7 @@ union packetdata { struct packet_edit_city *city; struct packet_edit_unit *unit; struct packet_edit_player *player; + struct packet_edit_game *game; }; @@ -251,7 +252,9 @@ enum object_property_ids { OPID_PLAYER_NAME, OPID_PLAYER_NATION, OPID_PLAYER_ADDRESS, - OPID_PLAYER_INVENTIONS + OPID_PLAYER_INVENTIONS, + + OPID_GAME_YEAR }; enum object_property_flags { @@ -524,6 +527,10 @@ static const char *objtype_get_name(int objtype) return _("Player"); break; + case OBJTYPE_GAME: + return Q_("?play:Game"); + break; + default: break; } @@ -565,6 +572,10 @@ static int objtype_get_id_from_object(int objtype, gpointer object) id = player_number(pplayer); break; + case OBJTYPE_GAME: + id = 1; + break; + default: break; } @@ -1040,6 +1051,9 @@ static gpointer objbind_get_object(struct objbind *ob) case OBJTYPE_PLAYER: return valid_player_by_number(id); break; + case OBJTYPE_GAME: + return &game; + break; default: break; } @@ -1255,6 +1269,26 @@ static struct propval *objbind_get_value_from_object(struct objbind *ob, goto FAILED; break; } + + } else if (objtype == OBJTYPE_GAME) { + struct civ_game *pgame = objbind_get_object(ob); + + if (pgame == NULL) { + goto FAILED; + } + + switch (propid) { + case OPID_GAME_YEAR: + pv->data.v_int = pgame->info.year; + break; + default: + freelog(LOG_ERROR, "Unhandled request for value of property %d " + "(%s) from object of type \"%s\" in " + "objbind_get_value_from_object().", + propid, objprop_get_name(op), objtype_get_name(objtype)); + goto FAILED; + break; + } } else { goto FAILED; } @@ -1346,6 +1380,25 @@ static bool objbind_get_allowed_value_span(struct objbind *ob, ok = FALSE; break; } + + } else if (objtype == OBJTYPE_GAME) { + + switch (propid) { + case OPID_GAME_YEAR: + min = -30000; + max = 30000; + step = 1; + big_step = 25; + break; + default: + freelog(LOG_ERROR, "Unhandled request for value range of " + "property %d (%s) from object of type \"%s\" in " + "objbind_get_allowed_value_span().", + propid, objprop_get_name(op), objtype_get_name(objtype)); + ok = FALSE; + break; + } + } else { ok = FALSE; } @@ -1620,6 +1673,16 @@ static void objbind_pack_current_values(struct objbind *ob, } advance_index_iterate_end; /* TODO: Set more packet fields. */ + } else if (objtype == OBJTYPE_GAME) { + struct packet_edit_game *packet = pd.game; + struct civ_game *pgame = objbind_get_object(ob); + + if (!pgame) { + return; + } + + packet->year = pgame->info.year; + /* TODO: Set more packet fields. */ } } @@ -1744,6 +1807,21 @@ static void objbind_pack_modified_value(struct objbind *ob, propid, objprop_get_name(op), objtype_get_name(objtype)); break; } + + } else if (objtype == OBJTYPE_GAME) { + struct packet_edit_game *packet = pd.game; + + switch (propid) { + case OPID_GAME_YEAR: + packet->year = pv->data.v_int; + break; + default: + freelog(LOG_ERROR, "Unhandled request to pack value of " + "property %d (%s) from object of type \"%s\" in " + "objbind_pack_modified_value().", + propid, objprop_get_name(op), objtype_get_name(objtype)); + break; + } } } @@ -2062,6 +2140,7 @@ static void objprop_setup_widget(struct objprop *op) break; case OPID_CITY_SIZE: + case OPID_GAME_YEAR: spin = gtk_spin_button_new_with_range(0.0, 100.0, 1.0); g_signal_connect(spin, "value-changed", G_CALLBACK(objprop_widget_spin_button_changed), op); @@ -2224,6 +2303,7 @@ static void objprop_refresh_widget(struct objprop *op, break; case OPID_CITY_SIZE: + case OPID_GAME_YEAR: spin = objprop_get_child_widget(op, "spin"); if (pv) { disable_widget_callback(spin, @@ -3030,6 +3110,11 @@ static void property_page_setup_objprops(struct property_page *pp) | OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_INVENTIONS_ARRAY); break; + case OBJTYPE_GAME: + ADDPROP(OPID_GAME_YEAR, _("Year"), OPF_IN_LISTVIEW + | OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_INT); + break; + default: break; } @@ -3842,6 +3927,9 @@ static union packetdata property_page_new_packet(struct property_page *pp) case OBJTYPE_PLAYER: packet.player = fc_calloc(1, sizeof(*packet.player)); break; + case OBJTYPE_GAME: + packet.game = fc_calloc(1, sizeof(*packet.game)); + break; default: break; } @@ -3872,6 +3960,9 @@ static void property_page_send_packet(struct property_page *pp, case OBJTYPE_PLAYER: send_packet_edit_player(&client.conn, packet.player); break; + case OBJTYPE_GAME: + send_packet_edit_game(&client.conn, packet.game); + break; default: break; } @@ -4327,19 +4418,17 @@ void property_editor_clear(struct property_editor *pe) } /**************************************************************************** - Clear the player property page, load the current game players into it, and - make it the current shown notebook page. + Clear and load objects into the property page corresponding to the given + object type. Also, make it the current shown notebook page. ****************************************************************************/ -void property_editor_reload_players(struct property_editor *pe) +void property_editor_reload(struct property_editor *pe, int objtype) { - int objtype; struct property_page *pp; if (!pe) { return; } - objtype = OBJTYPE_PLAYER; pp = pe->property_pages[objtype]; if (!pp) { return; @@ -4347,9 +4436,18 @@ void property_editor_reload_players(struct property_editor *pe) property_page_clear_objbinds(pp); - players_iterate(pplayer) { - property_page_add_objbind(pp, pplayer); - } players_iterate_end; + switch (objtype) { + case OBJTYPE_PLAYER: + players_iterate(pplayer) { + property_page_add_objbind(pp, pplayer); + } players_iterate_end; + break; + case OBJTYPE_GAME: + property_page_add_objbind(pp, &game); + break; + default: + break; + } property_page_fill_widgets(pp); gtk_notebook_set_current_page(GTK_NOTEBOOK(pe->notebook), objtype); diff --git a/client/gui-gtk-2.0/editprop.h b/client/gui-gtk-2.0/editprop.h index 5910c8a..4a50721 100644 --- a/client/gui-gtk-2.0/editprop.h +++ b/client/gui-gtk-2.0/editprop.h @@ -21,7 +21,7 @@ struct property_editor; void property_editor_clear(struct property_editor *pe); void property_editor_load_tiles(struct property_editor *pe, const struct tile_list *tiles); -void property_editor_reload_players(struct property_editor *pe); +void property_editor_reload(struct property_editor *pe, int objtype); void property_editor_popup(struct property_editor *pe); void property_editor_popdown(struct property_editor *pe); void property_editor_handle_object_changed(struct property_editor *pe, diff --git a/client/packhand.c b/client/packhand.c index 9b24389..b5a180d 100644 --- a/client/packhand.c +++ b/client/packhand.c @@ -1613,6 +1613,12 @@ void handle_game_info(struct packet_game_info *pinfo) if (update_aifill_button) { update_start_page(); } + + if (can_client_change_view()) { + update_info_label(); + } + + editgui_notify_object_changed(OBJTYPE_GAME, 1, FALSE); } /************************************************************************** diff --git a/common/game.h b/common/game.h index ba18102..d05ae96 100644 --- a/common/game.h +++ b/common/game.h @@ -168,8 +168,8 @@ bool setting_class_is_changeable(enum sset_class class); #define GAME_DEFAULT_ANGRYCITIZEN TRUE #define GAME_DEFAULT_END_YEAR 5000 -#define GAME_MIN_END_YEAR GAME_START_YEAR -#define GAME_MAX_END_YEAR 5000 +#define GAME_MIN_END_YEAR -32768 +#define GAME_MAX_END_YEAR 32767 #define GAME_DEFAULT_MIN_PLAYERS 1 #define GAME_MIN_MIN_PLAYERS 0 diff --git a/common/packets.def b/common/packets.def index 8cdbe0e..a0e0f45 100644 --- a/common/packets.def +++ b/common/packets.def @@ -1593,10 +1593,14 @@ PACKET_EDIT_PLAYER=168;cs,handle-per-conn,lsend BOOL ai; end +PACKET_EDIT_GAME=169;cs,handle-per-conn,handle-via-packet + YEAR year; +end + /* Always keep this as the last edit type packet, * so that the test in server/srv_main.c +1203 * is easy to write. */ -PACKET_EDIT_PLAYER_VISION=169;cs,handle-per-conn,dsend +PACKET_EDIT_PLAYER_VISION=170;cs,handle-per-conn,dsend PLAYER player; COORD x, y; BOOL known; diff --git a/server/edithand.c b/server/edithand.c index e6f7e6f..f87772e 100644 --- a/server/edithand.c +++ b/server/edithand.c @@ -1111,3 +1111,38 @@ void handle_edit_startpos(struct connection *pc, int x, int y, send_tile_info(NULL, ptile, FALSE); } } + +/**************************************************************************** + Handle edit requests to the main game data structure. +****************************************************************************/ +void handle_edit_game(struct connection *pc, + struct packet_edit_game *packet) +{ + bool changed = FALSE; + + if (!can_conn_edit(pc)) { + notify_conn(pc->self, NULL, E_BAD_COMMAND, + _("You are not allowed to edit.")); + return; + } + + if (packet->year != game.info.year) { + + /* 'year' is stored in a signed short. */ + const short min_year = -30000, max_year = 30000; + + if (!(min_year <= packet->year && packet->year <= max_year)) { + notify_conn(pc->self, NULL, E_BAD_COMMAND, + _("Cannot set invalid game year %d. Valid year range " + "is from %d to %d."), + packet->year, min_year, max_year); + } else { + game.info.year = packet->year; + changed = TRUE; + } + } + + if (changed) { + send_game_info(NULL); + } +}
_______________________________________________ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev