示例#1
0
/**
 * @brief Choose Base that will be attacked
 * @return Pointer to the base, NULL if no base set
 * @note Base attack mission -- Stage 1
 */
static base_t *CP_BaseAttackChooseBase (void)
{
	float randomNumber;
	float sum = 0.0f;
	base_t *base = NULL;

	/* Choose randomly a base depending on alienInterest values for those bases */
	while ((base = B_GetNext(base)) != NULL)
		sum += base->alienInterest;
	randomNumber = frand() * sum;
	while ((base = B_GetNext(base)) != NULL) {
		randomNumber -= base->alienInterest;
		if (randomNumber < 0)
			break;
	}

	/* Make sure we have a base */
	assert(base && (randomNumber < 0));

	/* base is already under attack */
	if (B_IsUnderAttack(base))
		return NULL;
	/* base not (yet) working */
	if (!B_GetBuildingStatus(base, B_COMMAND))
		return NULL;

	return base;
}
示例#2
0
/**
 * @brief Run base defences.
 * @param[in] dt Time elapsed since last call of this function.
 */
void AIRFIGHT_CampaignRunBaseDefence (int dt)
{
	base_t* base;

	base = nullptr;
	while ((base = B_GetNext(base)) != nullptr) {
		int idx;

		if (B_IsUnderAttack(base))
			continue;

		for (idx = 0; idx < base->numBatteries; idx++) {
			baseWeapon_t* battery = &base->batteries[idx];
			aircraftSlot_t* slot = &battery->slot;
			if (slot->delayNextShot > 0)
				slot->delayNextShot -= dt;
			if (slot->ammoLeft <= 0)
				AII_ReloadWeapon(slot);
		}

		for (idx = 0; idx < base->numLasers; idx++) {
			baseWeapon_t* battery = &base->lasers[idx];
			aircraftSlot_t* slot = &battery->slot;
			if (slot->delayNextShot > 0)
				slot->delayNextShot -= dt;
			if (slot->ammoLeft <= 0)
				AII_ReloadWeapon(slot);
		}

		if (AII_BaseCanShoot(base)) {
			if (B_GetBuildingStatus(base, B_DEFENCE_MISSILE))
				AIRFIGHT_BaseShoot(base, base->batteries, base->numBatteries);
			if (B_GetBuildingStatus(base, B_DEFENCE_LASER))
				AIRFIGHT_BaseShoot(base, base->lasers, base->numLasers);
		}
	}

	INS_Foreach(installation) {
		if (installation->installationStatus != INSTALLATION_WORKING)
			continue;

		if (installation->installationTemplate->maxBatteries <= 0)
			continue;

		for (int idx = 0; idx < installation->installationTemplate->maxBatteries; idx++) {
			baseWeapon_t* battery = &installation->batteries[idx];
			aircraftSlot_t* slot = &battery->slot;
			if (slot->delayNextShot > 0)
				slot->delayNextShot -= dt;
			if (slot->ammoLeft <= 0)
				AII_ReloadWeapon(slot);
		}

		if (AII_InstallationCanShoot(installation)) {
			AIRFIGHT_InstallationShoot(installation, installation->batteries, installation->installationTemplate->maxBatteries);
		}
	}
}
示例#3
0
/**
 * @brief Returns true if you can buy or sell equipment
 * @param[in] base Pointer to base to check on
 * @sa B_BaseInit_f
 */
bool BS_BuySellAllowed (const base_t* base)
{
	return !B_IsUnderAttack(base) && B_GetBuildingStatus(base, B_STORAGE);
}
示例#4
0
/**
 * @brief Returns true if the current base is able to produce items
 * @param[in] base Pointer to the base.
 * @sa B_BaseInit_f
 */
bool PR_ProductionAllowed (const base_t* base)
{
	assert(base);
	return !B_IsUnderAttack(base) && B_GetBuildingStatus(base, B_WORKSHOP) && E_CountHired(base, EMPL_WORKER) > 0;
}
/**
 * @brief Checks why a button in base menu is disabled, and create a popup to inform player
 */
static void B_CheckBuildingStatusForMenu_f (void)
{
	int num;
	const char *buildingID;
	const building_t *building;
	const base_t *base = B_GetCurrentSelectedBase();

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

	buildingID = cgi->Cmd_Argv(1);
	building = B_GetBuildingTemplate(buildingID);

	if (!building || !base)
		return;

	/* Maybe base is under attack ? */
	if (B_IsUnderAttack(base)) {
		CP_Popup(_("Notice"), _("Base is under attack, you can't access this building !"));
		return;
	}

	if (building->buildingType == B_HANGAR) {
		/* this is an exception because you must have a small or large hangar to enter aircraft menu */
		CP_Popup(_("Notice"), _("You need at least one Hangar (and its dependencies) to use aircraft."));
		return;
	}

	num = B_GetNumberOfBuildingsInBaseByBuildingType(base, building->buildingType);
	if (num > 0) {
		int numUnderConstruction;
		/* maybe all buildings of this type are under construction ? */
		B_CheckBuildingTypeStatus(base, building->buildingType, B_STATUS_UNDER_CONSTRUCTION, &numUnderConstruction);
		if (numUnderConstruction == num) {
			int minDay = 99999;
			building_t *b = NULL;

			while ((b = B_GetNextBuildingByType(base, b, building->buildingType))) {
				if (b->buildingStatus == B_STATUS_UNDER_CONSTRUCTION) {
					const float remaining = B_GetConstructionTimeRemain(b);
					minDay = std::min(minDay, (int)std::max(0.0f, remaining));
				}
			}

			CP_Popup(_("Notice"), ngettext("Construction of building will be over in %i day.\nPlease wait to enter.", "Construction of building will be over in %i days.\nPlease wait to enter.",
					minDay), minDay);
			return;
		}

		if (!B_CheckBuildingDependencesStatus(building)) {
			const building_t *dependenceBuilding = building->dependsBuilding;
			assert(building->dependsBuilding);
			if (B_GetNumberOfBuildingsInBaseByBuildingType(base, dependenceBuilding->buildingType) <= 0) {
				/* the dependence of the building is not built */
				CP_Popup(_("Notice"), _("You need a building %s to make building %s functional."), _(dependenceBuilding->name), _(building->name));
				return;
			} else {
				/* maybe the dependence of the building is under construction
				 * note that we can't use B_STATUS_UNDER_CONSTRUCTION here, because this value
				 * is not use for every building (for exemple Command Centre) */
				building_t *b = NULL;

				while ((b = B_GetNextBuildingByType(base, b, dependenceBuilding->buildingType))) {
					if (!B_IsBuildingBuiltUp(b)) {
						CP_Popup(_("Notice"), _("Building %s is not finished yet, and is needed to use building %s."),
								_(dependenceBuilding->name), _(building->name));
						return;
					}
				}
				/* the dependence is built but doesn't work - must be because of their dependendes */
				CP_Popup(_("Notice"), _("Make sure that the dependencies of building %s (%s) are operational, so that building %s may be used."),
						_(dependenceBuilding->name), _(dependenceBuilding->dependsBuilding->name), _(building->name));
				return;
			}
		}
		/* all buildings are OK: employees must be missing */
		if (building->buildingType == B_WORKSHOP && E_CountHired(base, EMPL_WORKER) <= 0) {
			CP_Popup(_("Notice"), _("You need to recruit %s to use building %s."),
					E_GetEmployeeString(EMPL_WORKER, 2), _(building->name));
			return;
		} else if (building->buildingType == B_LAB && E_CountHired(base, EMPL_SCIENTIST) <= 0) {
			CP_Popup(_("Notice"), _("You need to recruit %s to use building %s."),
					E_GetEmployeeString(EMPL_SCIENTIST, 2), _(building->name));
			return;
		}
	} else {
		CP_Popup(_("Notice"), _("Build a %s first."), _(building->name));
		return;
	}
}
/**
 * @brief Mark a building for destruction - you only have to confirm it now
 * @param[in] building Pointer to the base to destroy
 */
static void B_MarkBuildingDestroy (building_t* building)
{
	baseCapacities_t cap;
	base_t *base = building->base;

	/* you can't destroy buildings if base is under attack */
	if (B_IsUnderAttack(base)) {
		CP_Popup(_("Notice"), _("Base is under attack, you can't destroy buildings!"));
		return;
	}

	cap = B_GetCapacityFromBuildingType(building->buildingType);
	/* store the pointer to the building you wanna destroy */
	base->buildingCurrent = building;

	/** @todo: make base destroyable by destroying entrance */
	if (building->buildingType == B_ENTRANCE) {
		CP_Popup(_("Destroy Entrance"), _("You can't destroy the entrance of the base!"));
		return;
	}

	if (!B_IsBuildingDestroyable(building)) {
			CP_Popup(_("Notice"), _("You can't destroy this building! It is the only connection to other buildings!"));
			return;
	}

	if (building->buildingStatus == B_STATUS_WORKING) {
		const bool hasMoreBases = B_GetCount() > 1;
		switch (building->buildingType) {
		case B_HANGAR:
		case B_SMALL_HANGAR:
			if (CAP_GetFreeCapacity(base, cap) <= 0) {
				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?"),
					"ui_pop;ui_push aircraft;aircraft_select;", _("Go to hangar"), _("Go to hangar without destroying building"),
					va("building_destroy %i %i confirmed; ui_pop;", base->idx, building->idx), _("Destroy"), _("Destroy the building"),
					hasMoreBases ? "ui_pop;ui_push transfer;" : NULL, hasMoreBases ? _("Transfer") : NULL,
					_("Go to transfer menu without destroying the building"));
				return;
			}
			break;
		case B_QUARTERS:
			if (CAP_GetFreeCapacity(base, cap) < building->capacity) {
				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?"),
					"ui_pop;ui_push employees;employee_list 0;", _("Dismiss"), _("Go to hiring menu without destroying building"),
					va("building_destroy %i %i confirmed; ui_pop;", base->idx, building->idx), _("Destroy"), _("Destroy the building"),
					hasMoreBases ? "ui_pop;ui_push transfer;" : NULL, hasMoreBases ? _("Transfer") : NULL,
					_("Go to transfer menu without destroying the building"));
				return;
			}
			break;
		case B_STORAGE:
			if (CAP_GetFreeCapacity(base, cap) < building->capacity) {
				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?"),
					"ui_pop;ui_push market;buy_type *mn_itemtype", _("Go to storage"), _("Go to buy/sell menu without destroying building"),
					va("building_destroy %i %i confirmed; ui_pop;", base->idx, building->idx), _("Destroy"), _("Destroy the building"),
					hasMoreBases ? "ui_pop;ui_push transfer;" : NULL, hasMoreBases ? _("Transfer") : NULL,
					_("Go to transfer menu without destroying the building"));
				return;
			}
			break;
		default:
			break;
		}
	}

	cgi->UI_PopupButton(_("Destroy building"), _("Are you sure you want to destroy this building?"),
		NULL, NULL, NULL,
		va("building_destroy %i %i confirmed; ui_pop;", base->idx, building->idx), _("Destroy"), _("Destroy the building"),
		NULL, NULL, NULL);
}
示例#7
0
/**
 * @brief Returns true if you can enter in the hospital
 * @sa B_BaseInit_f
 */
bool HOS_HospitalAllowed (const base_t* base)
{
	return !B_IsUnderAttack(base) && B_GetBuildingStatus(base, B_HOSPITAL);
}