コード例 #1
0
/**
 * @brief Function to trigger UFO Recovered event.
 * @note This function prepares related cvars for the recovery dialog.
 * @note Command to call this: cp_uforecovery_init.
 */
static void UR_DialogInit_f (void)
{
	char ufoID[MAX_VAR];
	const aircraft_t* ufoCraft;
	float cond = 1.0f;

	if (cgi->Cmd_Argc() < 2) {
		Com_Printf("Usage: %s <ufoID> [UFO-Condition]\n", cgi->Cmd_Argv(0));
		return;
	}

	Q_strncpyz(ufoID, cgi->Cmd_Argv(1), sizeof(ufoID));

	if (cgi->Cmd_Argc() >= 3)
		cond = atof(cgi->Cmd_Argv(2));

	ufoCraft = AIR_GetAircraft(ufoID);

	/* Fill ufoRecovery structure */
	OBJZERO(ufoRecovery);
	ufoRecovery.ufoTemplate = ufoCraft;
	ufoRecovery.condition = cond;
	ufoRecovery.sortedColumn = ORDER_NATION;

	if (ufoCraft) {
		if (cond < 1.0)
			cgi->Cvar_Set("mn_uforecovery_actualufo", _("\nSecured crashed %s (%.0f%%)\n"), UFO_GetName(ufoCraft), cond * 100);
		else
			cgi->Cvar_Set("mn_uforecovery_actualufo", _("\nSecured landed %s\n"), UFO_GetName(ufoCraft));

		cgi->UI_PushWindow("uforecovery");
	}
}
コード例 #2
0
/**
 * @brief Fills the UI with ufo yard data
 */
static void INS_FillUFOYardData_f (void)
{
	installation_t* ins;

	cgi->UI_ExecuteConfunc("ufolist_clear");
	if (cgi->Cmd_Argc() < 2 || atoi(cgi->Cmd_Argv(1)) < 0) {
		ins = INS_GetCurrentSelectedInstallation();
		if (!ins || ins->installationTemplate->type != INSTALLATION_UFOYARD)
			ins = INS_GetFirstUFOYard(false);
	} else {
		ins = INS_GetByIDX(atoi(cgi->Cmd_Argv(1)));
		if (!ins)
			Com_DPrintf(DEBUG_CLIENT, "Installation not founded (idx %i)\n", atoi(cgi->Cmd_Argv(1)));
	}

	if (ins) {
		const nation_t* nat = GEO_GetNation(ins->pos);
		const int timeToBuild = std::max(0, ins->installationTemplate->buildTime - (ccs.date.day - ins->buildStart));
		const char* buildTime = (timeToBuild > 0 && ins->installationStatus == INSTALLATION_UNDER_CONSTRUCTION) ? va(ngettext("%d day", "%d days", timeToBuild), timeToBuild) : "-";
		const int freeCap = std::max(0, ins->ufoCapacity.max - ins->ufoCapacity.cur);
		const char* nationName = nat ? _(nat->name) : "";

		cgi->UI_ExecuteConfunc("ufolist_addufoyard %d \"%s\" \"%s\" %d %d \"%s\"", ins->idx, ins->name, nationName, ins->ufoCapacity.max, freeCap, buildTime);

		US_Foreach(ufo) {
			if (ufo->installation != ins)
				continue;

			const char* ufoName = UFO_GetName(ufo->ufoTemplate);
			const char* condition = va(_("Condition: %3.0f%%"), ufo->condition * 100);
			const char* status = US_StoredUFOStatus(ufo);
			cgi->UI_ExecuteConfunc("ufolist_addufo %d \"%s\" \"%s\" \"%s\" \"%s\"", ufo->idx, ufoName, condition, ufo->ufoTemplate->model, status);
		}
	}
}
コード例 #3
0
/**
 * @brief Send Stored UFO data to the UI
 * @note it's called by 'ui_selectstoredufo' command with a parameter of the stored UFO IDX
 */
static void US_SelectStoredUfo_f (void)
{
	const storedUFO_t *ufo;

	if (cgi->Cmd_Argc() < 2 || (ufo = US_GetStoredUFOByIDX(atoi(cgi->Cmd_Argv(1)))) == nullptr) {
		cgi->UI_ExecuteConfunc("show_storedufo -");
		return;
	}

	const char *ufoName = UFO_GetName(ufo->ufoTemplate);
	const char *status = US_StoredUFOStatus(ufo);
	const char *eta;

	if (Q_streq(status, "transfering")) {
		date_t time = Date_Substract(ufo->arrive, ccs.date);
		eta = CP_SecondConvert(Date_DateToSeconds(&time));
	} else {
		eta = "-";
	}

	cgi->UI_ExecuteConfunc("show_storedufo %d \"%s\" %3.0f \"%s\" \"%s\" \"%s\" \"%s\"", ufo->idx, ufoName, ufo->condition * 100, ufo->ufoTemplate->model, status, eta, ufo->installation->name);
}
コード例 #4
0
/**
 * @brief Function to start UFO recovery process.
 * @note Command to call this: cp_uforecovery_store_start.
 */
static void UR_DialogStartStore_f (void)
{
	installation_t *installation = nullptr;
	int idx;
	int count = 0;
	date_t date;

	if (cgi->Cmd_Argc() < 2) {
		Com_Printf("Usage: %s <installationIDX>\n", cgi->Cmd_Argv(0));
		return;
	}

	idx = atoi(cgi->Cmd_Argv(1));

	INS_Foreach(i) {
		if (i->ufoCapacity.max <= 0 || i->ufoCapacity.max <= i->ufoCapacity.cur)
			continue;

		if (count == idx) {
			installation = i;
			break;
		}
		count++;
	}

	if (!installation)
		return;

	Com_sprintf(cp_messageBuffer, lengthof(cp_messageBuffer), _("Recovered %s from the battlefield. UFO is being transported to %s."),
			UFO_GetName(ufoRecovery.ufoTemplate), installation->name);
	MS_AddNewMessage(_("UFO Recovery"), cp_messageBuffer);
	date = ccs.date;
	date.day += (int) RECOVERY_DELAY;

	US_StoreUFO(ufoRecovery.ufoTemplate, installation, date, ufoRecovery.condition);
	UR_DialogRecoveryDone();
}
コード例 #5
0
/**
 * @brief Fills the battery list, descriptions, and weapons in slots
 * of the basedefence equip menu
 */
static void BDEF_BaseDefenceMenuUpdate_f (void)
{
	char type[MAX_VAR];
	base_t* base = B_GetCurrentSelectedBase();
	installation_t* installation = INS_GetCurrentSelectedInstallation();
	aircraftItemType_t bdefType;
	linkedList_t* slotList = nullptr;
	const bool missileResearched = RS_IsResearched_ptr(RS_GetTechByID("rs_building_missile"));
	const bool laserResearched = RS_IsResearched_ptr(RS_GetTechByID("rs_building_laser"));

	if (cgi->Cmd_Argc() != 2)
		type[0] = '\0';
	else
		Q_strncpyz(type, cgi->Cmd_Argv(1), sizeof(type));

	/* don't let old links appear on this menu */
	cgi->UI_ResetData(TEXT_BASEDEFENCE_LIST);
	cgi->UI_ResetData(TEXT_LIST);
	cgi->UI_ResetData(TEXT_ITEMDESCRIPTION);

	/* base or installation should not be nullptr because we are in the menu of this base or installation */
	if (!base && !installation)
		return;

	/* base and installation should not both be set. This function requires one or the other set. */
	if (base && installation) {
		Sys_Error("BDEF_BaseDefenceMenuUpdate_f: Both the base and installation are set");
		return;
	}

	cgi->Cvar_Set("mn_target", _("None"));
	cgi->UI_ExecuteConfunc("setautofire disable");
	if (installation) {
		/* Every slot aims the same target */
		if (installation->numBatteries) {
			cgi->UI_ExecuteConfunc("setautofire %i", installation->batteries[0].autofire);

			if (installation->batteries[0].target)
				cgi->Cvar_Set("mn_target", "%s", UFO_GetName(installation->batteries[0].target));
		}
	} else if (base) {
		bool autofire = false;
		/* Every slot aims the same target */
		if (base->numBatteries) {
			autofire |= base->batteries[0].autofire;
			if (base->batteries[0].target)
				cgi->Cvar_Set("mn_target", "%s", UFO_GetName(base->batteries[0].target));
		}
		if (base->numLasers) {
			autofire |= base->lasers[0].autofire;
			if (base->lasers[0].target && !base->batteries[0].target)
				cgi->Cvar_Set("mn_target", "%s", UFO_GetName(base->lasers[0].target));
		}
		if (base->numBatteries || base->numLasers)
			cgi->UI_ExecuteConfunc("setautofire %i", autofire);
	}

	/* Check if we can change to laser or missile */
	if (base) {
		cgi->UI_ExecuteConfunc("set_defencetypes %s %s",
				(!missileResearched) ? "na" : (base && base->numBatteries > 0) ? "enable" : "disable",
				(!laserResearched) ? "na" : (base && base->numLasers > 0) ? "enable" : "disable");
	} else if (installation) {
		cgi->UI_ExecuteConfunc("set_defencetypes %s %s",
				(!missileResearched) ? "na" : (installation && installation->installationStatus == INSTALLATION_WORKING
						&& installation->numBatteries > 0) ? "enable" : "disable", "na");
	}

	if (Q_streq(type, "missile"))
		bdefType = AC_ITEM_BASE_MISSILE;
	else if (Q_streq(type, "laser"))
		bdefType = AC_ITEM_BASE_LASER;
	else	/* info page */
		return;

	/* Check that the base or installation has at least 1 battery */
	if (base) {
		if (base->numBatteries + base->numLasers < 1) {
			Com_Printf("BDEF_BaseDefenceMenuUpdate_f: there is no defence battery in this base: you shouldn't be in this function.\n");
			return;
		}
	} else if (installation) {
		if (installation->installationStatus != INSTALLATION_WORKING) {
			Com_Printf("BDEF_BaseDefenceMenuUpdate_f: installation isn't working: you shouldn't be in this function.\n");
			return;
		} else if (installation->installationTemplate->maxBatteries < 1) {
			Com_Printf("BDEF_BaseDefenceMenuUpdate_f: there is no defence battery in this installation: you shouldn't be in this function.\n");
			return;
		}
	}

	if (installation) {
		/* we are in the installation defence menu */
		if (installation->installationTemplate->maxBatteries == 0) {
			cgi->LIST_AddString(&slotList, _("No defence of this type in this installation"));
		} else {
			BDEF_FillSlotList(installation->batteries, installation->installationTemplate->maxBatteries, &slotList);
		}
	} else if (bdefType == AC_ITEM_BASE_MISSILE) {
		/* we are in the base defence menu for missile */
		if (base->numBatteries == 0) {
			cgi->LIST_AddString(&slotList, _("No defence of this type in this base"));
		} else {
			BDEF_FillSlotList(base->batteries, base->numActiveBatteries, &slotList);
		}
	} else if (bdefType == AC_ITEM_BASE_LASER) {
		/* we are in the base defence menu for laser */
		if (base->numLasers == 0) {
			cgi->LIST_AddString(&slotList, _("No defence of this type in this base"));
		} else {
			BDEF_FillSlotList(base->lasers, base->numActiveLasers, &slotList);
		}
	} else {
		Com_Printf("BDEF_BaseDefenceMenuUpdate_f: unknown bdefType.\n");
		return;
	}
	cgi->UI_RegisterLinkedListText(TEXT_BASEDEFENCE_LIST, slotList);
}
コード例 #6
0
/**
 * @brief Function to start UFO selling process.
 * @note Command to call this: cp_uforecovery_sell_start.
 */
static void UR_DialogStartSell_f (void)
{
	int price = -1;
	const nation_t *nation;
	int i;

	if (!ufoRecovery.nation)
		return;

	nation = ufoRecovery.nation;

	i = UR_DialogGetCurrentNationIndex();
	price = ufoRecovery.ufoNations[i].price;

	assert(price >= 0);
#if 0
	if (ufoRecovery.selectedStorage) {
		Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("Sold previously recovered %s from %s to nation %s, gained %i credits."), UFO_TypeToName(
				ufoRecovery.selectedStorage->ufoTemplate->ufotype), ufoRecovery.selectedStorage->base->name, _(nation->name), price);
	} else
#endif
	{
		Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("Recovered %s from the battlefield. UFO sold to nation %s, gained %i credits."), UFO_GetName(ufoRecovery.ufoTemplate), _(nation->name), price);
	}
	MS_AddNewMessage(_("UFO Recovery"), cp_messageBuffer);
	CP_UpdateCredits(ccs.credits + price);

	/* update nation happiness */
	for (i = 0; i < ccs.numNations; i++) {
		nation_t *nat = NAT_GetNationByIDX(i);
		float ufoHappiness;

		assert(nat);
		if (nat == nation)
			/* nation is happy because it got the UFO */
			ufoHappiness = HAPPINESS_UFO_SALE_GAIN;
		else
			/* nation is unhappy because it wanted the UFO */
			ufoHappiness = HAPPINESS_UFO_SALE_LOSS;

		NAT_SetHappiness(ccs.curCampaign->minhappiness, nat, nat->stats[0].happiness + ufoHappiness);
	}

	/* UFO recovery process is done, disable buttons. */
	UR_DialogRecoveryDone();
}
コード例 #7
0
ファイル: cp_ufo.cpp プロジェクト: nicogiraldi/ufoai
/**
 * @brief Check events for UFOs: Appears or disappears on radars
 * @return true if any new ufo was detected during this iteration, false otherwise
 */
bool UFO_CampaignCheckEvents (void)
{
	bool newDetection;
	aircraft_t* ufo;

	newDetection = false;

	/* For each ufo in geoscape */
	ufo = nullptr;
	while ((ufo = UFO_GetNext(ufo)) != nullptr) {
		char detectedBy[MAX_VAR] = "";
		float minDistance = -1;
		/* detected tells us whether or not a UFO is detected NOW, whereas ufo->detected tells
		 * us whether or not the UFO was detected PREVIOUSLY. */
		bool detected = false;
		base_t* base;

		/* don't update UFO status id UFO is landed or crashed */
		if (ufo->landed)
			continue;

		/* note: We can't exit these loops as soon as we found the UFO detected
		 * RADAR_CheckUFOSensored registers the UFO in every radars' detection list
		 * which detect it */

		/* Check if UFO is detected by an aircraft */
		AIR_Foreach(aircraft) {
			if (!AIR_IsAircraftOnGeoscape(aircraft))
				continue;
			/* maybe the ufo is already detected, don't reset it */
			if (RADAR_CheckUFOSensored(&aircraft->radar, aircraft->pos, ufo, detected | ufo->detected)) {
				const int distance = GetDistanceOnGlobe(aircraft->pos, ufo->pos);
				detected = true;
				if (minDistance < 0 || minDistance > distance) {
					minDistance = distance;
					Q_strncpyz(detectedBy, aircraft->name, sizeof(detectedBy));
				}
			}
		}

		/* Check if UFO is detected by a base */
		base = nullptr;
		while ((base = B_GetNext(base)) != nullptr) {
			if (!B_GetBuildingStatus(base, B_POWER))
				continue;

			/* maybe the ufo is already detected, don't reset it */
			if (RADAR_CheckUFOSensored(&base->radar, base->pos, ufo, detected | ufo->detected)) {
				const int distance = GetDistanceOnGlobe(base->pos, ufo->pos);
				detected = true;
				if (minDistance < 0 || minDistance > distance) {
					minDistance = distance;
					Q_strncpyz(detectedBy, base->name, sizeof(detectedBy));
				}
			}

		}

		/* Check if UFO is detected by a radartower */
		INS_Foreach(installation) {
			/* maybe the ufo is already detected, don't reset it */
			if (RADAR_CheckUFOSensored(&installation->radar, installation->pos, ufo, detected | ufo->detected)) {
				const int distance = GetDistanceOnGlobe(installation->pos, ufo->pos);
				detected = true;
				if (minDistance < 0 || minDistance > distance) {
					minDistance = distance;
					Q_strncpyz(detectedBy, installation->name, sizeof(detectedBy));
				}
			}
		}

		/* Check if ufo appears or disappears on radar */
		if (detected != ufo->detected) {
			if (detected) {
				UFO_DetectNewUFO(ufo);
				/* if UFO is aiming a PHALANX aircraft, warn player */
				if (ufo->aircraftTarget) {
					/* stop time and notify */
					MSO_CheckAddNewMessage(NT_UFO_ATTACKING, _("Notice"), va(_("%s is flying toward %s"), UFO_GetName(ufo), ufo->aircraftTarget->name));
					/** @todo present a popup with possible orders like: return to base, attack the ufo, try to flee the rockets
					 * @sa UFO_SearchAircraftTarget */
				} else {
					MSO_CheckAddNewMessage(NT_UFO_SPOTTED, _("Notice"), va(_("Our radar detected %s near %s"), UFO_GetName(ufo), detectedBy), MSG_UFOSPOTTED);
				}
				newDetection = true;
			} else if (!detected) {
				MSO_CheckAddNewMessage(NT_UFO_SIGNAL_LOST, _("Notice"), va(_("Our radar has lost the tracking on %s"), UFO_GetName(ufo)), MSG_UFOLOST);
				/* Make this UFO undetected */
				ufo->detected = false;
				/* Notify that ufo disappeared */
				AIR_AircraftsUFODisappear(ufo);
				GEO_NotifyUFODisappear(ufo);

				/* Deactivate Radar overlay */
				RADAR_DeactivateRadarOverlay();
			}
		}
	}
	return newDetection;
}