38#define CREATE_NEW_BASE_ID -1
48 const float prob =
frand();
50 if (
cgi->Cmd_Argc() < 4) {
51 cgi->Com_Printf(
"Usage: %s <probability> <baseID> <buildingType>\n",
cgi->Cmd_Argv(0));
66 if (prob < atof(
cgi->Cmd_Argv(1))) {
68 cgi->UI_PopWindow(
false);
81 if (
cgi->Cmd_Argc() < 2) {
82 cgi->Com_Printf(
"Usage: %s <baseID>\n",
cgi->Cmd_Argv(0));
85 baseID = atoi(
cgi->Cmd_Argv(1));
116 while (j <= baseCount && !
Q_streq(baseName,
ccs.bases[j].name)) {
119 }
while (
i++ <= baseCount && j <= baseCount);
124 cgi->Cvar_Set(
"mn_base_title",
"%s", baseName);
127 cgi->UI_PopWindow(
false);
148 baseName =
_(
"Base");
150 base =
B_Build(campaign,
ccs.newBasePos, baseName);
163 if (
ccs.campaignStats.basesBuilt == 1)
174 CP_Popup(
_(
"Notice"),
"%s",
_(
"Not enough credits to set up a new base."));
183 if (
cgi->Cmd_Argc() < 3) {
184 cgi->Com_Printf(
"Usage: %s <baseIDX> \"<new base name>\"\n",
cgi->Cmd_Argv(0));
189 cgi->Com_Printf(
"Invalid base idx: %s\n",
cgi->Cmd_Argv(1));
196 cgi->Cvar_Set(
"mn_base_title",
"%s", base->
name);
211 if (
cgi->Cmd_Argc() < 2) {
213 cgi->Com_Printf(
"Usage: %s <baseIDX>\n",
cgi->Cmd_Argv(0));
221 cgi->Com_Printf(
"Invalid base idx: %s\n",
cgi->Cmd_Argv(1));
231 cgi->UI_ExecuteConfunc(
"update_basebutton aircraft false \"%s\"",
_(
"Aircraft management and crew equipment"));
233 cgi->UI_ExecuteConfunc(
"update_basebutton aircraft true \"%s\"",
_(
"Buy or produce at least one aircraft first."));
235 cgi->UI_ExecuteConfunc(
"update_basebutton aircraft true \"%s\"",
_(
"No Hangar operating at this base."));
239 cgi->UI_ExecuteConfunc(
"update_basebutton buysell false \"%s\"",
_(
"Buy/Sell equipment, aircraft and UGV"));
241 cgi->UI_ExecuteConfunc(
"update_basebutton buysell true \"%s\"",
_(
"No Storage operating at this base."));
244 cgi->UI_ExecuteConfunc(
"update_basebutton transfer false \"%s\"",
_(
"Transfer equipment, vehicles, aliens and employees to other bases"));
246 cgi->UI_ExecuteConfunc(
"update_basebutton transfer true \"%s\"",
_(
"Build at least a second base to transfer equipment or personnel"));
249 cgi->UI_ExecuteConfunc(
"update_basebutton research false \"%s\"",
_(
"Research new technology"));
251 cgi->UI_ExecuteConfunc(
"update_basebutton research true \"%s\"",
_(
"No Laboratory operating at this base."));
254 cgi->UI_ExecuteConfunc(
"update_basebutton production false \"%s\"",
_(
"Produce equipment, aircraft and UGV"));
256 cgi->UI_ExecuteConfunc(
"update_basebutton production true \"%s\"",
_(
"No Workshop operating at this base."));
259 cgi->UI_ExecuteConfunc(
"update_basebutton hire false \"%s\"",
_(
"Hire or dismiss employees"));
261 cgi->UI_ExecuteConfunc(
"update_basebutton hire true \"%s\"",
_(
"No Living Quarters operating at this base."));
264 cgi->UI_ExecuteConfunc(
"update_basebutton containment false \"%s\"",
_(
"Manage captured aliens"));
266 cgi->UI_ExecuteConfunc(
"update_basebutton containment true \"%s\"",
_(
"No Containment operating at this base."));
269 cgi->UI_ExecuteConfunc(
"update_basebutton hospital false \"%s\"",
_(
"Treat wounded soldiers and perform implant surgery"));
271 cgi->UI_ExecuteConfunc(
"update_basebutton hospital true \"%s\"",
_(
"No Hospital operating at this in base."));
280 if (
cgi->Cmd_Argc() < 4) {
281 cgi->Com_Printf(
"Usage: %s <baseIDX> <column> <row> [confirmed]\n",
cgi->Cmd_Argv(0));
286 if (base ==
nullptr) {
287 cgi->Com_Printf(
"B_BuildingDestroy_f: Invalid base IDX: %s\n",
cgi->Cmd_Argv(1));
292 if (building ==
nullptr) {
293 cgi->Com_Printf(
"B_BuildingDestroy_f: No valid building at base %i, position (%s, %s)\n",
294 base->
idx,
cgi->Cmd_Argv(2),
cgi->Cmd_Argv(3));
298 if (
cgi->Cmd_Argc() == 5 &&
Q_streq(
cgi->Cmd_Argv(4),
"confirmed")) {
305 CP_Popup(
_(
"Notice"),
_(
"Base is under attack, you can't destroy buildings!"));
312 CP_Popup(
_(
"Destroy Entrance"),
_(
"You can't destroy the entrance of the base!"));
317 CP_Popup(
_(
"Notice"),
_(
"You can't destroy this building! It is the only connection to other buildings!"));
326 cgi->UI_PopupButton(
_(
"Destroy Alien Containment"),
_(
"If you destroy this building, you will also kill the aliens inside.\nAre you sure you want to destroy this building?"),
327 "ui_pop;ui_push aliencont;",
_(
"Containment"),
_(
"Go to the Alien Containment without destroying building"),
328 va(
"ui_pop;building_destroy %i %i %i confirmed;", base->
idx,
int(building->
pos[0]),
int(building->
pos[1])),
_(
"Destroy"),
_(
"Destroy the building"),
329 hasMoreBases ?
"ui_pop;ui_push transfer;" :
nullptr, hasMoreBases ?
_(
"Transfer") :
nullptr,
330 _(
"Go to transfer menu without destroying the building"));
337 cgi->UI_PopupButton(
_(
"Destroy Hangar"),
_(
"If you destroy this hangar, you will also destroy the aircraft inside.\nAre you sure you want to destroy this building?"),
338 "ui_pop;ui_push aircraft_equip;aircraft_select;",
_(
"Go to hangar"),
_(
"Go to hangar without destroying building"),
339 va(
"ui_pop;building_destroy %i %i %i confirmed;", base->
idx,
int(building->
pos[0]),
int(building->
pos[1])),
_(
"Destroy"),
_(
"Destroy the building"),
340 hasMoreBases ?
"ui_pop;ui_push transfer;" :
nullptr, hasMoreBases ?
_(
"Transfer") :
nullptr,
341 _(
"Go to transfer menu without destroying the building"));
347 cgi->UI_PopupButton(
_(
"Destroy Quarter"),
_(
"If you destroy this Quarters, every employee inside will be killed.\nAre you sure you want to destroy this building?"),
348 "ui_pop;ui_push employees;employee_list 0;",
_(
"Dismiss"),
_(
"Go to hiring menu without destroying building"),
349 va(
"ui_pop;building_destroy %i %i %i confirmed;", base->
idx,
int(building->
pos[0]),
int(building->
pos[1])),
_(
"Destroy"),
_(
"Destroy the building"),
350 hasMoreBases ?
"ui_pop;ui_push transfer;" :
nullptr, hasMoreBases ?
_(
"Transfer") :
nullptr,
351 _(
"Go to transfer menu without destroying the building"));
357 cgi->UI_PopupButton(
_(
"Destroy Storage"),
_(
"If you destroy this Storage, every items inside will be destroyed.\nAre you sure you want to destroy this building?"),
358 "ui_pop;ui_push market;buy_type *mn_itemtype",
_(
"Go to storage"),
_(
"Go to buy/sell menu without destroying building"),
359 va(
"ui_pop;building_destroy %i %i %i confirmed;", base->
idx,
int(building->
pos[0]),
int(building->
pos[1])),
_(
"Destroy"),
_(
"Destroy the building"),
360 hasMoreBases ?
"ui_pop;ui_push transfer;" :
nullptr, hasMoreBases ?
_(
"Transfer") :
nullptr,
361 _(
"Go to transfer menu without destroying the building"));
370 cgi->UI_PopupButton(
_(
"Destroy building"),
_(
"Are you sure you want to destroy this building?"),
371 nullptr,
nullptr,
nullptr,
372 va(
"ui_pop;building_destroy %i %i %i confirmed;", base->
idx,
int(building->
pos[0]),
int(building->
pos[1])),
_(
"Destroy"),
_(
"Destroy the building"),
373 nullptr,
nullptr,
nullptr);
384 if (
cgi->Cmd_Argc() < 2) {
385 cgi->Com_Printf(
"Usage: %s <baseIDX>\n",
cgi->Cmd_Argv(0));
389 if (base ==
nullptr) {
390 cgi->Com_Printf(
"B_AssembleMap_f: Invalid base IDX: %s\n",
cgi->Cmd_Argv(1));
396 B_AssembleMap(maps,
sizeof(maps), coords,
sizeof(coords), base);
397 cgi->Cbuf_AddText(
"map %s \"%s\" \"%s\"\n", (
GEO_IsNight(base->
pos) ?
"night" :
"day"), maps, coords);
406 if (!
cgi->Com_ServerState()) {
407 cgi->Com_Printf(
"Load the base map before you try to use this function\n");
411 cgi->Cmd_ExecuteString(
"camsetangles %i %i", 60, 90);
412 cgi->Cvar_SetValue(
"r_isometric", 1);
414 cgi->Cvar_SetValue(
"cl_worldlevel", 1);
415 cgi->UI_PushWindow(
"hud_nohud");
417 cgi->Cmd_ExecuteString(
"toggleconsole");
418 cgi->Cmd_ExecuteString(
"r_screenshot tga");
426 if (
cgi->Cmd_Argc() < 3) {
427 cgi->Com_Printf(
"Usage: %s <baseIDX> <buildingID>\n",
cgi->Cmd_Argv(0));
432 cgi->Com_Printf(
"Invalid base idx\n");
437 cgi->Com_Printf(
"Invalid building id\n");
441 cgi->UI_ExecuteConfunc(
"show_buildinginfo %s \"%s\" \"%s\" %i %i %i \"%s\" \"%s\"",
462 if (
cgi->Cmd_Argc() < 2) {
463 cgi->Com_Printf(
"Usage: %s <baseID>\n",
cgi->Cmd_Argv(0));
470 for (
int i = 0;
i <
ccs.numBuildingTemplates;
i++) {
487 assert(building->
tpl);
490 cgi->UI_ExecuteConfunc(
"show_building \"%s\" \"%s\" %i %i %i %i %i %i %i",
_(building->
name),
492 building->
tpl->maxCount,
int(building->
size[0]),
int(building->
size[1]));
501 if (
cgi->Cmd_Argc() < 2) {
505 const int baseIdx = atoi(
cgi->Cmd_Argv(1));
511 for (
int baseRow = 0; baseRow <
BASE_SIZE; baseRow++) {
512 for (
int baseCol = 0; baseCol <
BASE_SIZE; baseCol++) {
515 cgi->UI_ExecuteConfunc(
"base_building_add %d %d %d %d \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
516 baseCol, baseRow, 1, 1,
"",
"",
"base/invalid",
_(
"Blocked tile"),
"");
519 if (building ==
nullptr) {
520 cgi->UI_ExecuteConfunc(
"base_building_add %d %d %d %d \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
521 baseCol, baseRow, 1, 1,
"",
"",
"base/grid",
_(
"Free tile"),
"");
524 if (building->
pos[0] != baseCol || building->
pos[1] != baseRow)
526 cgi->UI_ExecuteConfunc(
"base_building_add %d %d %d %d \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
527 baseCol, baseRow,
int(building->
size[0]),
int(building->
size[1]),
541 if (
cgi->Cmd_Argc() < 4) {
542 cgi->Com_Printf(
"Usage: %s <baseIDX> <column> <row>\n",
cgi->Cmd_Argv(0));
547 if (base ==
nullptr) {
548 cgi->Com_Printf(
"B_BuildingOpenAfterClick_f: Invalid base IDX: %s\n",
cgi->Cmd_Argv(1));
553 if (building ==
nullptr) {
554 cgi->Com_Printf(
"B_BuildingOpenAfterClick_f: No valid building at base %i, position (%s, %s)\n",
555 base->
idx,
cgi->Cmd_Argv(2),
cgi->Cmd_Argv(3));
567 cgi->UI_PushWindow(
"research");
573 cgi->Cmd_ExecuteString(
"ui_push hospital %d", base->
idx);
579 cgi->UI_PushWindow(
"aliencont");
585 cgi->UI_PushWindow(
"employees");
591 cgi->UI_PushWindow(
"production");
597 cgi->UI_PushWindow(
"basedefence");
604 cgi->UI_PushWindow(
"aircraft_equip");
606 cgi->UI_PushWindow(
"buyaircraft");
609 CP_Popup(
_(
"Note"),
_(
"No aircraft in this base - You first have to purchase or transfer an aircraft\n"));
611 CP_Popup(
_(
"Note"),
_(
"No aircraft in this base - You first have to purchase an aircraft\n"));
616 cgi->UI_PushWindow(
"market");
634 if (
cgi->Cmd_Argc() < 5) {
635 cgi->Com_Printf(
"Usage: %s <baseIDX> <buildingID> <column> <row>\n",
cgi->Cmd_Argv(0));
641 cgi->Com_Printf(
"Invalid base idx\n");
647 cgi->Com_Printf(
"Invalid building id\n");
651 const int column = atoi(
cgi->Cmd_Argv(3));
652 const int row = atoi(
cgi->Cmd_Argv(4));
654 cgi->Com_Printf(
"Invalid building position (%s, %s)\n",
cgi->Cmd_Argv(3),
cgi->Cmd_Argv(4));
659 cgi->Com_Printf(
"Building doesn't fit position (%s, %s), size (%d, %d)\n",
660 cgi->Cmd_Argv(3),
cgi->Cmd_Argv(4),
int(building->
size[0]),
int(building->
size[1]));
665 CP_Popup(
_(
"Notice"),
_(
"Not enough credits to build this\n"));
670 cgi->S_StartLocalSample(
"geoscape/build-place", 1.0f);
671 cgi->Cmd_ExecuteString(
"ui_push bases %d", base->
idx);
677 {
"basemapshot",
B_MakeBaseMapShot_f,
"Command to make a screenshot for the baseview with the correct angles"},
678 {
"mn_base_select",
B_SelectBase_f,
"Select a founded base by index"},
683 {
"base_assemble",
B_AssembleMap_f,
"Called to assemble the current selected base"},
684 {
"building_destroy",
B_BuildingDestroy_f,
"Function to destroy a building (select via right click in baseview first)"},
687 {
"ui_list_buildings",
B_ListBuildings_f,
"Lists buildings built or can be built on a base and their capacities"},
688 {
"ui_show_buildinginfo",
B_FillBuildingInfo_f,
"Opens the building information window in construction mode"},
691 {
nullptr,
nullptr,
nullptr}
697 mn_base_title =
cgi->Cvar_Get(
"mn_base_title",
"", 0,
"The title of the current base");
698 cgi->Cvar_Set(
"mn_base_cost",
_(
"%i c"),
ccs.curCampaign->basecost);
710 cgi->Cvar_Delete(
"mn_base_max");
711 cgi->Cvar_Delete(
"mn_base_cost");
712 cgi->Cvar_Delete(
"mn_base_title");
713 cgi->Cvar_Delete(
"mn_base_count");
Alien containment class header.
Share stuff between the different cgame implementations.
bool AIR_AircraftAllowed(const base_t *base)
Returns true if the current base is able to handle aircraft.
bool AIR_BaseHasAircraft(const base_t *base)
Checks whether there is any aircraft assigned to the given base.
bool AC_ContainmentAllowed(const base_t *base)
Returns true if the current base is able to handle captured aliens.
bool B_BuildingDestroy(building_t *building)
Removes a building from the given base.
building_t * B_BuildBuilding(base_t *base, const building_t *buildingTemplate, int col, int row)
Build a new building to the base.
baseCapacities_t B_GetCapacityFromBuildingType(buildingType_t type)
Get the capacity associated to a building type.
base_t * B_GetFoundedBaseByIDX(int baseIdx)
Array bound check for the base index.
bool B_AssembleMap(char *maps, size_t mapsLength, char *coords, size_t coordsLength, const base_t *base)
Perform the base assembling in case of an alien attack.
void B_SelectBase(const base_t *base)
Select and opens a base.
int B_GetCount(void)
Returns the count of founded bases.
base_t * B_GetCurrentSelectedBase(void)
returns the currently selected base
base_t * B_GetBaseByIDX(int baseIdx)
Array bound check for the base index. Will also return unfounded bases as long as the index is in the...
bool B_IsBuildingDestroyable(const building_t *building)
Returns if a base building is destroyable.
void B_SetName(base_t *base, const char *name)
Set the base name.
void B_Destroy(base_t *base)
Destroy a base.
int B_GetNumberOfBuildingsInBaseByTemplate(const base_t *base, const building_t *tpl)
Counts the number of buildings of a particular type in a base.
bool B_GetBuildingStatus(const base_t *const base, const buildingType_t buildingType)
Get the status associated to a building.
base_t * B_Build(const campaign_t *campaign, const vec2_t pos, const char *name, bool fillBase)
Build new base, uses template for the first base.
void B_SetUpFirstBase(const campaign_t *campaign, base_t *base)
Setup aircraft and equipment for first base. Uses the campaign scriptable equipmentlist.
Header for base management related stuff.
#define B_IsTileBlocked(base, x, y)
bool PR_ProductionAllowed(const base_t *base)
Returns true if the current base is able to produce items.
#define B_GetBuildingAt(base, x, y)
bool E_HireAllowed(const base_t *base)
Returns true if the current base is able to handle employees.
bool RS_ResearchAllowed(const base_t *base)
Returns true if the current base is able to handle research.
#define B_IsUnderAttack(base)
bool HOS_HospitalAllowed(const base_t *base)
Returns true if you can enter in the hospital.
bool BS_BuySellAllowed(const base_t *base)
Returns true if you can buy or sell equipment.
static void B_BuildingOpenAfterClick_f(void)
Opens menu on clicking a building in Baseview.
void B_InitCallbacks(void)
static void B_BuildingDestroy_f(void)
Destroy a base building.
static void B_ListBuildings_f(void)
Update the facilities list.
void B_ShutdownCallbacks(void)
static void B_BaseInit_f(void)
Initialises base.
static cvar_t * mn_base_title
static void B_BuildBase_f(void)
Constructs a new base.
static void B_ChangeBaseName_f(void)
Creates console command to change the name of a base.
#define CREATE_NEW_BASE_ID
Used from menu scripts as parameter for mn_base_select.
static void B_SetBaseTitle_f(void)
Sets the title of the base to a cvar to prepare the rename menu.
static void B_MakeBaseMapShot_f(void)
Makes a mapshot - called by basemapshot script command.
static void B_Destroy_AntimaterStorage_f(void)
onDestroy Callback for Antimatter Storage
static void B_AssembleMap_f(void)
Builds a base map for tactical combat.
static void B_SelectBase_f(void)
Called when a base is opened or a new base is created on geoscape. For a new base the baseID is -1.
static void B_FillBuildingInfo_f(void)
Script function for clicking the building list text field.
static void B_FillMap_f(void)
Lists building tiles for the Basescape UI.
static void B_BuildBuilding_f(void)
Build a base building.
static const cmdList_t baseCallbacks[]
Header file for menu related console command callbacks.
building_t * B_GetBuildingTemplateSilent(const char *buildingName)
Returns the building in the global building-types list that has the unique name buildingID.
bool B_IsBuildingBuiltUp(const building_t *building)
Returns if a building is fully buildt up.
float B_GetConstructionTimeRemain(const building_t *building)
Returns the time remaining time of a building construction.
bool CP_CheckCredits(int costs)
Checks whether you have enough credits for something.
void CP_UpdateCredits(int credits)
Sets credits and update mn_credits cvar.
Header file for single player campaign control.
const cgame_import_t * cgi
void CAP_RemoveAntimatterExceedingCapacity(base_t *base)
Remove exceeding antimatter if an antimatter tank has been destroyed.
int CAP_GetFreeCapacity(const base_t *base, baseCapacities_t capacityType)
Returns the free capacity of a type.
#define CAP_GetCurrent(base, capacity)
baseCapacities_t
All possible capacities in base.
#define CAP_GetMax(base, capacity)
#define CAP_Get(base, capacity)
Capacity macros.
bool GEO_IsNight(const vec2_t pos)
Check whether given position is Day or Night.
nation_t * GEO_GetNation(const vec2_t pos)
Translate nation map color to nation.
void GEO_SetOverlay(const char *overlayID, int status)
Turn overlay on/off.
bool GEO_IsRadarOverlayActivated(void)
Header for Geoscape management.
uiMessageListNodeMessage_t * MS_AddNewMessage(const char *title, const char *text, messageType_t type, technology_t *pedia, bool popup, bool playSound)
Adds a new message to message stack.
char cp_messageBuffer[MAX_MESSAGE_TEXT]
bool RS_IsResearched_ptr(const technology_t *tech)
Checks whether an item is already researched.
void CP_GameTimeStop(void)
Stop game time speed.
Campaign geoscape time header.
void UP_OpenWith(const char *techID)
Opens the UFOpaedia from everywhere with the entry given through name.
#define ngettext(x, y, cnt)
float frand(void)
Return random values between 0 and 1.
bool Com_IsValidName(const char *input)
Checks whether the given input string is allowed to be used as a user-given name string for aircraft,...
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
A base with all it's data.
A building with all it's data.
const struct building_s * dependsBuilding
buildingType_t buildingType
buildingStatus_t buildingStatus
struct technology_s * tech
Store capacities in base.
This is a cvar definition. Cvars can be user modified and used in our menus e.g.