/** * @brief Buys an aircraft * @param[in] aircraftTemplate The aircraft template to buy * @param[out] base Base to buy at * @return @c true if the aircraft could get bought, @c false otherwise */ bool BS_BuyAircraft (const aircraft_t* aircraftTemplate, base_t* base) { if (!base) cgi->Com_Error(ERR_DROP, "BS_BuyAircraft: No base given."); if (!aircraftTemplate) cgi->Com_Error(ERR_DROP, "BS_BuyAircraft: No aircraft template given."); int price = BS_GetAircraftBuyingPrice(aircraftTemplate); if (ccs.credits < price) return false; /* Hangar capacities are being updated in AIR_NewAircraft().*/ BS_RemoveAircraftFromMarket(aircraftTemplate, 1); CP_UpdateCredits(ccs.credits - price); AIR_NewAircraft(base, aircraftTemplate); return true; }
/** * @brief make number of items change every day. * @sa CP_CampaignRun * @sa daily called * @note This function makes items number on market slowly reach the asymptotic number of items defined in equipment.ufo * If an item has just been researched, it's not available on market until RESEARCH_LIMIT_DELAY days is reached. */ void CP_CampaignRunMarket (campaign_t* campaign) { int i; const float TYPICAL_TIME = 10.f; /**< Number of days to reach the asymptotic number of items */ const int RESEARCH_LIMIT_DELAY = 30; /**< Numbers of days after end of research to wait in order to have * items added on market */ market_t* market = BS_GetMarket(); assert(campaign->marketDef); assert(campaign->asymptoticMarketDef); for (i = 0; i < cgi->csi->numODs; i++) { const objDef_t* od = INVSH_GetItemByIDX(i); const technology_t* tech = RS_GetTechForItem(od); int asymptoticNumber; if (RS_IsResearched_ptr(tech) && (campaign->marketDef->numItems[i] != 0 || ccs.date.day > tech->researchedDate.day + RESEARCH_LIMIT_DELAY)) { /* if items are researched for more than RESEARCH_LIMIT_DELAY or was on the initial market, * there number tend to the value defined in equipment.ufo. * This value is the asymptotic value if it is not 0, or initial value else */ asymptoticNumber = campaign->asymptoticMarketDef->numItems[i] ? campaign->asymptoticMarketDef->numItems[i] : campaign->marketDef->numItems[i]; } else { /* items that have just been researched don't appear on market, but they can disappear */ asymptoticNumber = 0; } /* Store the evolution of the market in currentEvolution */ market->currentEvolutionItems[i] += (asymptoticNumber - market->numItems[i]) / TYPICAL_TIME; /* Check if new items appeared or disappeared on market */ if (fabs(market->currentEvolutionItems[i]) >= 1.0f) { const int num = (int)(market->currentEvolutionItems[i]); if (num >= 0) BS_AddItemToMarket(od, num); else BS_RemoveItemFromMarket(od, -num); market->currentEvolutionItems[i] -= num; } } for (i = 0; i < AIRCRAFTTYPE_MAX; i++) { const humanAircraftType_t type = (humanAircraftType_t)i; const char* aircraftID = cgi->Com_DropShipTypeToShortName(type); const aircraft_t* aircraft = AIR_GetAircraft(aircraftID); const technology_t* tech = aircraft->tech; int asymptoticNumber; if (RS_IsResearched_ptr(tech) && (campaign->marketDef->numAircraft[i] != 0 || ccs.date.day > tech->researchedDate.day + RESEARCH_LIMIT_DELAY)) { /* if aircraft is researched for more than RESEARCH_LIMIT_DELAY or was on the initial market, * there number tend to the value defined in equipment.ufo. * This value is the asymptotic value if it is not 0, or initial value else */ asymptoticNumber = campaign->asymptoticMarketDef->numAircraft[i] ? campaign->asymptoticMarketDef->numAircraft[i] : campaign->marketDef->numAircraft[i]; } else { /* items that have just been researched don't appear on market, but they can disappear */ asymptoticNumber = 0; } /* Store the evolution of the market in currentEvolution */ market->currentEvolutionAircraft[i] += (asymptoticNumber - market->numAircraft[i]) / TYPICAL_TIME; /* Check if new items appeared or disappeared on market */ if (fabs(market->currentEvolutionAircraft[i]) >= 1.0f) { const int num = (int)(market->currentEvolutionAircraft[i]); if (num >= 0) BS_AddAircraftToMarket(aircraft, num); else BS_RemoveAircraftFromMarket(aircraft, -num); market->currentEvolutionAircraft[i] -= num; } } }
/** * @brief Buys aircraft or craftitem. * @sa BS_SellAircraft_f */ static void BS_BuyAircraft_f (void) { int num; const aircraft_t *aircraftTemplate; base_t *base = B_GetCurrentSelectedBase(); if (Cmd_Argc() < 2) { Com_Printf("Usage: %s <num>\n", Cmd_Argv(0)); return; } if (!base) return; num = atoi(Cmd_Argv(1)); if (num < 0 || num >= buyList.length) return; if (buyCat == FILTER_AIRCRAFT) { int freeSpace; if (!B_GetBuildingStatus(base, B_COMMAND)) { CP_Popup(_("Note"), _("No command centre in this base.\nHangars are not functional.\n")); return; } /* We cannot buy aircraft if there is no power in our base. */ if (!B_GetBuildingStatus(base, B_POWER)) { CP_Popup(_("Note"), _("No power supplies in this base.\nHangars are not functional.")); return; } /* We cannot buy aircraft without any hangar. */ if (!AIR_AircraftAllowed(base)) { CP_Popup(_("Note"), _("Build a hangar first.")); return; } aircraftTemplate = buyList.l[num].aircraft; freeSpace = AIR_CalculateHangarStorage(aircraftTemplate, base, 0); /* Check free space in hangars. */ if (freeSpace < 0) { Com_Printf("BS_BuyAircraft_f: something bad happened, AIR_CalculateHangarStorage returned -1!\n"); return; } if (freeSpace == 0) { CP_Popup(_("Notice"), _("You cannot buy this aircraft.\nNot enough space in hangars.\n")); return; } else { const int price = BS_GetAircraftBuyingPrice(aircraftTemplate); if (ccs.credits < price) { CP_Popup(_("Notice"), _("You cannot buy this aircraft.\nNot enough credits.\n")); return; } else { /* Hangar capacities are being updated in AIR_NewAircraft().*/ BS_RemoveAircraftFromMarket(aircraftTemplate, 1); CP_UpdateCredits(ccs.credits - price); AIR_NewAircraft(base, aircraftTemplate); Cmd_ExecuteString(va("buy_type %s", INV_GetFilterType(FILTER_AIRCRAFT))); } } } }