/**************************************************************************** Adds focus units to given battlegroup (or removes unit from battlegoup if battlegroup is the same that unit has). ****************************************************************************/ void add_unit_to_battlegroup(int battlegroup) { if (NULL != client.conn.playing && can_client_issue_orders()) { struct unit *punit; punit = head_of_units_in_focus(); if (punit && punit->battlegroup == battlegroup) { /* If top unit already in the same battlegroup, detach it */ unit_change_battlegroup(punit, BATTLEGROUP_NONE); refresh_unit_mapcanvas(punit, punit->tile, TRUE, FALSE); } else { key_unit_assign_battlegroup(battlegroup, TRUE); } } }
/************************************************************************** Called when the tileset is changed to reset unit pixmaps. **************************************************************************/ void reset_unit_below_pixmaps(void) { long i; for (i = 0; i < num_units_below; i++) { XFreePixmap(display, unit_below_pixmap[i]); } xaw_set_bitmap(more_arrow_label, None); fill_unit_below_pixmaps(); set_unit_icons_more_arrow(FALSE); if (get_num_units_in_focus() == 1) { set_unit_icon(-1, head_of_units_in_focus()); } else { set_unit_icon(-1, NULL); } update_unit_pix_label(get_units_in_focus()); }
// TODO: Support irrigation modes JNIEXPORT jbyteArray JNICALL Java_net_hackcasual_freeciv_NativeHarness_getAvailableCommandsForActiveUnit (JNIEnv * env, jobject obj) { struct unit * pUnit; char availCommands[COM_UNIT_LAST]; int commandCount = 0; pUnit = head_of_units_in_focus(); if (pUnit) { struct tile *pTile = pUnit->tile; struct city *pCity = tile_city(pTile); struct terrain *pTerrain = tile_terrain(pTile); struct base_type *pbase; struct unit_list *punits = get_units_in_focus(); if (can_unit_build_city(pUnit)) { availCommands[commandCount++] = COM_BUILD_CITY; } if (can_unit_do_activity(pUnit, ACTIVITY_GOTO)) { availCommands[commandCount++] = COM_GO_TO; availCommands[commandCount++] = COM_GO_TO_CITY; } if (can_unit_do_activity(pUnit, ACTIVITY_SENTRY)) { availCommands[commandCount++] = COM_SENTRY; } if (can_unit_do_activity(pUnit, ACTIVITY_FORTIFYING)) { availCommands[commandCount++] = COM_FORTIFY; } if (can_unit_do_activity(pUnit, ACTIVITY_EXPLORE)) { availCommands[commandCount++] = COM_EXPLORE; } availCommands[commandCount++] = COM_DISBAND; if (can_unit_do_activity(pUnit, ACTIVITY_ROAD) || can_unit_do_activity(pUnit, ACTIVITY_RAILROAD)) { availCommands[commandCount++] = COM_ROAD; } if (can_unit_do_activity(pUnit, ACTIVITY_IRRIGATE)) { availCommands[commandCount++] = COM_IRRIGATION; } if (can_unit_do_autosettlers(pUnit)) { availCommands[commandCount++] = COM_AUTO_WORKER; } if (can_unit_do_connect(pUnit, ACTIVITY_IRRIGATE)) { availCommands[commandCount++] = COM_CONNECT_IRRIGATION; } if (can_unit_do_connect(pUnit, ACTIVITY_ROAD)) { availCommands[commandCount++] = COM_CONNECT_ROAD; } if (can_unit_do_connect(pUnit, ACTIVITY_RAILROAD)) { availCommands[commandCount++] = COM_CONNECT_RAILROAD; } availCommands[commandCount++] = COM_WAIT; if (unit_can_help_build_wonder_here(pUnit)) { availCommands[commandCount++] = COM_BUILD_WONDER; } if (unit_can_est_trade_route_here(pUnit)) { availCommands[commandCount++] = COM_TRADE_ROUTE; } if (can_unit_do_activity(pUnit, ACTIVITY_MINE)) { availCommands[commandCount++] = COM_MINE; } if (can_unit_do_activity(pUnit, ACTIVITY_TRANSFORM)) { availCommands[commandCount++] = COM_TRANSFORM; } pbase = get_base_by_gui_type(BASE_GUI_FORTRESS, pUnit, pUnit->tile); if (!pCity && pbase) { availCommands[commandCount++] = COM_FORTRESS; } pbase = get_base_by_gui_type(BASE_GUI_AIRBASE, pUnit, pUnit->tile); if (!pCity && pbase) { availCommands[commandCount++] = COM_AIRBASE; } if (can_unit_do_activity(pUnit, ACTIVITY_POLLUTION)) { availCommands[commandCount++] = COM_POLLUTION; } if (can_unit_do_activity(pUnit, ACTIVITY_FALLOUT)) { availCommands[commandCount++] = COM_FALLOUT; } if (can_unit_paradrop(pUnit)) { availCommands[commandCount++] = COM_PARADROP; } if (can_unit_do_activity(pUnit, ACTIVITY_PILLAGE)) { availCommands[commandCount++] = COM_FALLOUT; } if (pCity && can_unit_change_homecity(pUnit) && pCity->id != pUnit->homecity) { availCommands[commandCount++] = COM_HOMECITY; } if (pUnit->occupy && get_transporter_occupancy(pUnit) > 0) { availCommands[commandCount++] = COM_UNLOAD_TRANSPORT; } if (units_can_load(punits)) { availCommands[commandCount++] = COM_LOAD; } if (units_can_unload(punits)) { availCommands[commandCount++] = COM_UNLOAD; } if (pCity && pCity->airlift) { availCommands[commandCount++] = COM_AIRLIFT; } if (pCity && can_upgrade_unittype(client.conn.playing, unit_type(pUnit))) { availCommands[commandCount++] = COM_UPGRADE; } if (diplomat_can_do_action(pUnit, DIPLOMAT_ANY_ACTION, pUnit->tile)) { availCommands[commandCount++] = COM_DIPLOMAT; } if (unit_has_type_flag(pUnit, F_NUCLEAR)) { availCommands[commandCount++] = COM_NUKE; } } jbyteArray commands; commands = (*env)->NewByteArray(env, commandCount); (*env)->SetByteArrayRegion(env, commands, 0, commandCount, (jbyte *)availCommands); return commands; }
/************************************************************************** ... **************************************************************************/ static int unit_order_callback(struct widget *pOrder_Widget) { if (Main.event.button.button == SDL_BUTTON_LEFT) { struct unit *pUnit = head_of_units_in_focus(); set_wstate(pOrder_Widget, FC_WS_SELLECTED); pSellected_Widget = pOrder_Widget; if (!pUnit) { return -1; } switch (pOrder_Widget->ID) { case ID_UNIT_ORDER_BUILD_CITY: /* Enable the button for adding to a city in all cases, so we get an eventual error message from the server if we try. */ key_unit_build_city(); break; case ID_UNIT_ORDER_BUILD_WONDER: key_unit_build_wonder(); break; case ID_UNIT_ORDER_ROAD: key_unit_road(); break; case ID_UNIT_ORDER_TRADE_ROUTE: key_unit_trade_route(); break; case ID_UNIT_ORDER_IRRIGATE: key_unit_irrigate(); break; case ID_UNIT_ORDER_MINE: key_unit_mine(); break; case ID_UNIT_ORDER_TRANSFORM: key_unit_transform(); break; case ID_UNIT_ORDER_FORTRESS: key_unit_fortress(); break; case ID_UNIT_ORDER_FORTIFY: key_unit_fortify(); break; case ID_UNIT_ORDER_AIRBASE: key_unit_airbase(); break; case ID_UNIT_ORDER_POLLUTION: key_unit_pollution(); break; case ID_UNIT_ORDER_PARADROP: key_unit_paradrop(); break; case ID_UNIT_ORDER_FALLOUT: key_unit_fallout(); break; case ID_UNIT_ORDER_SENTRY: key_unit_sentry(); break; case ID_UNIT_ORDER_PILLAGE: key_unit_pillage(); break; case ID_UNIT_ORDER_HOMECITY: key_unit_homecity(); break; case ID_UNIT_ORDER_UNLOAD_TRANSPORTER: key_unit_unload_all(); break; case ID_UNIT_ORDER_LOAD: unit_list_iterate(get_units_in_focus(), punit) { request_unit_load(punit, NULL); } unit_list_iterate_end; break; case ID_UNIT_ORDER_UNLOAD: unit_list_iterate(get_units_in_focus(), punit) { request_unit_unload(punit); } unit_list_iterate_end; break; case ID_UNIT_ORDER_WAKEUP_OTHERS: key_unit_wakeup_others(); break; case ID_UNIT_ORDER_AUTO_SETTLER: unit_list_iterate(get_units_in_focus(), punit) { request_unit_autosettlers(punit); } unit_list_iterate_end;
/************************************************************************** Main handler for key presses **************************************************************************/ static Uint16 main_key_down_handler(SDL_keysym Key, void *pData) { static struct widget *pWidget; if ((pWidget = find_next_widget_for_key(NULL, Key)) != NULL) { return widget_pressed_action(pWidget); } else { if (Key.sym == SDLK_TAB) { /* input */ popup_input_line(); } else { if (map_event_handler(Key) && C_S_RUNNING == client_state()) { switch (Key.sym) { case SDLK_RETURN: case SDLK_KP_ENTER: if (LSHIFT || RSHIFT) { disable_focus_animation(); key_end_turn(); } else { struct unit *pUnit; struct city *pCity; if (NULL != (pUnit = head_of_units_in_focus()) && (pCity = tile_city(unit_tile(pUnit))) != NULL && city_owner(pCity) == client.conn.playing) { popup_city_dialog(pCity); } } return ID_ERROR; case SDLK_F2: units_report_dialog_popup(FALSE); return ID_ERROR; case SDLK_F4: city_report_dialog_popup(FALSE); return ID_ERROR; case SDLK_F7: send_report_request(REPORT_WONDERS_OF_THE_WORLD); return ID_ERROR; case SDLK_F8: send_report_request(REPORT_TOP_5_CITIES); return ID_ERROR; case SDLK_F9: if (meswin_dialog_is_open()) { meswin_dialog_popdown(); } else { meswin_dialog_popup(TRUE); } flush_dirty(); return ID_ERROR; case SDLK_F11: send_report_request(REPORT_DEMOGRAPHIC); return ID_ERROR; case SDLK_F12: popup_spaceship_dialog(client.conn.playing); return ID_ERROR; default: return ID_ERROR; } } } } return ID_ERROR; }
/**************************************************************** Pops-up the Spy sabotage dialog, upon return of list of available improvements requested by the above function. *****************************************************************/ void popup_sabotage_dialog(struct city *pCity) { struct widget *pWindow = NULL, *pBuf = NULL , *pLast = NULL; struct CONTAINER *pCont; struct unit *pUnit = head_of_units_in_focus(); SDL_String16 *pStr; SDL_Rect area, area2; int n, w = 0, h, imp_h = 0; if (pDiplomat_Dlg || !pUnit || !unit_has_type_flag(pUnit, F_SPY)) { return; } is_unit_move_blocked = TRUE; pDiplomat_Dlg = fc_calloc(1, sizeof(struct diplomat_dialog)); pDiplomat_Dlg->diplomat_id = pUnit->id; pDiplomat_Dlg->diplomat_target_id = pCity->id; pDiplomat_Dlg->pdialog = fc_calloc(1, sizeof(struct ADVANCED_DLG)); pCont = fc_calloc(1, sizeof(struct CONTAINER)); pCont->id0 = pCity->id; pCont->id1 = pUnit->id;/* spy id */ pStr = create_str16_from_char(_("Select Improvement to Sabotage") , adj_font(12)); pStr->style |= TTF_STYLE_BOLD; pWindow = create_window_skeleton(NULL, pStr, 0); pWindow->action = diplomat_dlg_window_callback; set_wstate(pWindow, FC_WS_NORMAL); add_to_gui_list(ID_TERRAIN_ADV_DLG_WINDOW, pWindow); pDiplomat_Dlg->pdialog->pEndWidgetList = pWindow; area = pWindow->area; area.h = MAX(area.h, adj_size(2)); /* ---------- */ /* exit button */ pBuf = create_themeicon(pTheme->Small_CANCEL_Icon, pWindow->dst, WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND); pBuf->info_label = create_str16_from_char(_("Close Dialog (Esc)"), adj_font(12)); area.w += pBuf->size.w + adj_size(10); pBuf->action = diplomat_close_callback; set_wstate(pBuf, FC_WS_NORMAL); pBuf->key = SDLK_ESCAPE; add_to_gui_list(ID_TERRAIN_ADV_DLG_EXIT_BUTTON, pBuf); /* ---------- */ create_active_iconlabel(pBuf, pWindow->dst, pStr, _("City Production"), sabotage_impr_callback); pBuf->data.cont = pCont; set_wstate(pBuf, FC_WS_NORMAL); set_wflag(pBuf, WF_FREE_DATA); add_to_gui_list(MAX_ID - 1000, pBuf); area.w = MAX(area.w, pBuf->size.w); area.h += pBuf->size.h; /* separator */ pBuf = create_iconlabel(NULL, pWindow->dst, NULL, WF_FREE_THEME); add_to_gui_list(ID_SEPARATOR, pBuf); area.h += pBuf->next->size.h; /* ------------------ */ n = 0; city_built_iterate(pCity, pImprove) { if (pImprove->sabotage > 0) { create_active_iconlabel(pBuf, pWindow->dst, pStr, (char *) city_improvement_name_translation(pCity, pImprove), sabotage_impr_callback); pBuf->data.cont = pCont; set_wstate(pBuf , FC_WS_NORMAL); add_to_gui_list(MAX_ID - improvement_number(pImprove), pBuf); area.w = MAX(area.w , pBuf->size.w); imp_h += pBuf->size.h; if (!pDiplomat_Dlg->pdialog->pEndActiveWidgetList) { pDiplomat_Dlg->pdialog->pEndActiveWidgetList = pBuf; } if (improvement_number(pImprove) > 9) { set_wflag(pBuf, WF_HIDDEN); } n++; /* ----------- */ } } city_built_iterate_end; pDiplomat_Dlg->pdialog->pBeginActiveWidgetList = pBuf; if (n > 0) { /* separator */ pBuf = create_iconlabel(NULL, pWindow->dst, NULL, WF_FREE_THEME); add_to_gui_list(ID_SEPARATOR, pBuf); area.h += pBuf->next->size.h; /* ------------------ */ } create_active_iconlabel(pBuf, pWindow->dst, pStr, _("At Spy's Discretion"), sabotage_impr_callback); pBuf->data.cont = pCont; set_wstate(pBuf, FC_WS_NORMAL); add_to_gui_list(MAX_ID - B_LAST, pBuf); area.w = MAX(area.w, pBuf->size.w); area.h += pBuf->size.h; /* ----------- */ pLast = pBuf; pDiplomat_Dlg->pdialog->pBeginWidgetList = pLast; pDiplomat_Dlg->pdialog->pActiveWidgetList = pDiplomat_Dlg->pdialog->pEndActiveWidgetList; /* ---------- */ if (n > 10) { imp_h = 10 * pBuf->size.h; n = create_vertical_scrollbar(pDiplomat_Dlg->pdialog, 1, 10, TRUE, TRUE); area.w += n; } /* ---------- */ area.h += imp_h; resize_window(pWindow, NULL, NULL, (pWindow->size.w - pWindow->area.w) + area.w, (pWindow->size.h - pWindow->area.h) + area.h); area = pWindow->area; auto_center_on_focus_unit(); put_window_near_map_tile(pWindow, pWindow->size.w, pWindow->size.h, pUnit->tile); w = area.w; if (pDiplomat_Dlg->pdialog->pScroll) { w -= n; imp_h = pBuf->size.w; } else { imp_h = 0; } /* exit button */ pBuf = pWindow->prev; pBuf->size.x = area.x + area.w - pBuf->size.w - 1; pBuf->size.y = pWindow->size.y + adj_size(2); /* Production sabotage */ pBuf = pBuf->prev; pBuf->size.x = area.x; pBuf->size.y = area.y + 1; pBuf->size.w = w; h = pBuf->size.h; area2.x = adj_size(10); area2.h = adj_size(2); pBuf = pBuf->prev; while(pBuf) { if (pBuf == pDiplomat_Dlg->pdialog->pEndActiveWidgetList) { w -= imp_h; } pBuf->size.w = w; pBuf->size.x = pBuf->next->size.x; pBuf->size.y = pBuf->next->size.y + pBuf->next->size.h; if (pBuf->ID == ID_SEPARATOR) { FREESURFACE(pBuf->theme); pBuf->size.h = h; pBuf->theme = create_surf(w, h, SDL_SWSURFACE); area2.y = pBuf->size.h / 2 - 1; area2.w = pBuf->size.w - adj_size(20); SDL_FillRect(pBuf->theme , &area2, map_rgba(pBuf->theme->format, *get_game_colorRGB(COLOR_THEME_SABOTAGEDLG_SEPARATOR))); } if (pBuf == pLast) { break; } pBuf = pBuf->prev; } if (pDiplomat_Dlg->pdialog->pScroll) { setup_vertical_scrollbar_area(pDiplomat_Dlg->pdialog->pScroll, area.x + area.w, pDiplomat_Dlg->pdialog->pEndActiveWidgetList->size.y, area.y - pDiplomat_Dlg->pdialog->pEndActiveWidgetList->size.y + area.h, TRUE); } /* -------------------- */ /* redraw */ redraw_group(pDiplomat_Dlg->pdialog->pBeginWidgetList, pWindow, 0); widget_flush(pWindow); }
/************************************************************************** Popup a dialog asking a diplomatic unit if it wishes to bribe the given enemy unit. **************************************************************************/ void popup_bribe_dialog(struct unit *pUnit, int cost) { struct widget *pWindow = NULL, *pBuf = NULL; SDL_String16 *pStr; struct unit *pDiplomatUnit; char tBuf[255], cBuf[255]; bool exit = FALSE; SDL_Rect area; if (pBribe_Dlg) { return; } /* ugly hack */ pDiplomatUnit = head_of_units_in_focus(); if (!pDiplomatUnit || !is_diplomat_unit(pDiplomatUnit)) { return; } is_unit_move_blocked = TRUE; pBribe_Dlg = fc_calloc(1, sizeof(struct small_diplomat_dialog)); pBribe_Dlg->diplomat_id = pDiplomatUnit->id; pBribe_Dlg->diplomat_target_id = pUnit->id; pBribe_Dlg->pdialog = fc_calloc(1, sizeof(struct SMALL_DLG)); fc_snprintf(tBuf, ARRAY_SIZE(tBuf), PL_("Treasury contains %d gold.", "Treasury contains %d gold.", client_player()->economic.gold), client_player()->economic.gold); /* window */ pStr = create_str16_from_char(_("Bribe Enemy Unit"), adj_font(12)); pStr->style |= TTF_STYLE_BOLD; pWindow = create_window_skeleton(NULL, pStr, 0); pWindow->action = bribe_dlg_window_callback; set_wstate(pWindow, FC_WS_NORMAL); add_to_gui_list(ID_BRIBE_DLG_WINDOW, pWindow); pBribe_Dlg->pdialog->pEndWidgetList = pWindow; area = pWindow->area; area.w = MAX(area.w, adj_size(8)); area.h = MAX(area.h, adj_size(2)); if (cost <= client_player()->economic.gold) { fc_snprintf(cBuf, sizeof(cBuf), /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */ PL_("Bribe unit for %d gold?\n%s", "Bribe unit for %d gold?\n%s", cost), cost, tBuf); create_active_iconlabel(pBuf, pWindow->dst, pStr, cBuf, NULL); add_to_gui_list(ID_LABEL, pBuf); area.w = MAX(area.w, pBuf->size.w); area.h += pBuf->size.h; /*------------*/ create_active_iconlabel(pBuf, pWindow->dst, pStr, _("Yes"), diplomat_bribe_yes_callback); pBuf->data.unit = pUnit; set_wstate(pBuf, FC_WS_NORMAL); add_to_gui_list(MAX_ID - pDiplomatUnit->id, pBuf); area.w = MAX(area.w, pBuf->size.w); area.h += pBuf->size.h; /* ------- */ create_active_iconlabel(pBuf, pWindow->dst, pStr, _("No") , exit_bribe_dlg_callback); set_wstate(pBuf , FC_WS_NORMAL); pBuf->key = SDLK_ESCAPE; add_to_gui_list(ID_LABEL, pBuf); area.w = MAX(area.w, pBuf->size.w); area.h += pBuf->size.h; } else { /* exit button */ pBuf = create_themeicon(pTheme->Small_CANCEL_Icon, pWindow->dst, WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND); pBuf->info_label = create_str16_from_char(_("Close Dialog (Esc)"), adj_font(12)); area.w += pBuf->size.w + adj_size(10); pBuf->action = exit_bribe_dlg_callback; set_wstate(pBuf, FC_WS_NORMAL); pBuf->key = SDLK_ESCAPE; add_to_gui_list(ID_BRIBE_DLG_EXIT_BUTTON, pBuf); exit = TRUE; /* --------------- */ fc_snprintf(cBuf, sizeof(cBuf), /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */ PL_("Bribing the unit costs %d gold.\n%s", "Bribing the unit costs %d gold.\n%s", cost), cost, tBuf); create_active_iconlabel(pBuf, pWindow->dst, pStr, cBuf, NULL); add_to_gui_list(ID_LABEL, pBuf); area.w = MAX(area.w, pBuf->size.w); area.h += pBuf->size.h; /*------------*/ create_active_iconlabel(pBuf, pWindow->dst, pStr, _("Traitors Demand Too Much!"), NULL); add_to_gui_list(ID_LABEL, pBuf); area.w = MAX(area.w, pBuf->size.w); area.h += pBuf->size.h; } pBribe_Dlg->pdialog->pBeginWidgetList = pBuf; /* setup window size and start position */ resize_window(pWindow, NULL, NULL, (pWindow->size.w - pWindow->area.w) + area.w, (pWindow->size.h - pWindow->area.h) + area.h); area = pWindow->area; auto_center_on_focus_unit(); put_window_near_map_tile(pWindow, pWindow->size.w, pWindow->size.h, pDiplomatUnit->tile); /* setup widget size and start position */ pBuf = pWindow; if (exit) {/* exit button */ pBuf = pBuf->prev; pBuf->size.x = area.x + area.w - pBuf->size.w - 1; pBuf->size.y = pWindow->size.y + adj_size(2); } pBuf = pBuf->prev; setup_vertical_widgets_position(1, area.x, area.y + 1, area.w, 0, pBribe_Dlg->pdialog->pBeginWidgetList, pBuf); /* --------------------- */ /* redraw */ redraw_group(pBribe_Dlg->pdialog->pBeginWidgetList, pWindow, 0); widget_flush(pWindow); }