/** * @brief Buys the given UGV * @param[in] ugv The ugv template of the UGV to buy * @param[out] base Base to buy at * @return @c true if the ugv could get bought, @c false otherwise * @todo Implement this correctly once we have UGV */ bool BS_BuyUGV (const ugv_t* ugv, base_t* base) { const objDef_t* ugvWeapon; if (!ugv) cgi->Com_Error(ERR_DROP, "BS_BuyUGV: Called on nullptr UGV!"); if (!base) cgi->Com_Error(ERR_DROP, "BS_BuyUGV: Called on nullptr base!"); ugvWeapon = INVSH_GetItemByID(ugv->weapon); if (!ugvWeapon) cgi->Com_Error(ERR_DROP, "BS_BuyItem_f: Could not get weapon '%s' for ugv/tank '%s'.", ugv->weapon, ugv->id); if (ccs.credits < ugv->price) return false; if (E_CountUnhiredRobotsByType(ugv) <= 0) return false; if (BS_GetItemOnMarket(ugvWeapon) <= 0) return false; if (CAP_GetFreeCapacity(base, CAP_ITEMS) < UGV_SIZE + ugvWeapon->size) return false; if (!E_HireRobot(base, ugv)) return false; BS_RemoveItemFromMarket(ugvWeapon, 1); CP_UpdateCredits(ccs.credits - ugv->price); B_AddToStorage(base, ugvWeapon, 1); return true; }
/** * @brief Buy items. * @param[in] base Pointer to the base where items are bought. * @param[in] item Pointer to the item to buy. * @param[in] number Number of items to buy. */ qboolean BS_CheckAndDoBuyItem (base_t* base, const objDef_t *item, int number) { int numItems; const int price = BS_GetItemBuyingPrice(item); const market_t *market = BS_GetMarket(); assert(base); /* you can't buy more items than there are on market */ numItems = min(number, market->numItems[item->idx]); /* you can't buy more items than you have credits for */ /** @todo Handle items with price 0 better */ if (price) numItems = min(numItems, ccs.credits / price); if (numItems <= 0) return qfalse; /* you can't buy more items than you have room for */ /** @todo Handle items with size 0 better */ if (item->size) numItems = min(numItems, (base->capacities[CAP_ITEMS].max - base->capacities[CAP_ITEMS].cur) / item->size); /* make sure that numItems is > 0 (can be negative because capacities.cur may be greater than * capacities.max if storage is disabled or if alien items have been collected on mission */ if (numItems <= 0) { UI_Popup(_("Not enough storage space"), _("You cannot buy this item.\nNot enough space in storage.\nBuild more storage facilities.")); return qfalse; } B_UpdateStorageAndCapacity(base, item, numItems, qfalse, qfalse); BS_RemoveItemFromMarket(item, numItems); CL_UpdateCredits(ccs.credits - price * numItems); return qtrue; }
/** * @brief Buys items from the market * @param[in] od pointer to the item (Object Definition record) * @param[out] base Base to buy at * @param[in ] count Number of items to buy * @return @c true if the ugv could get bought, @c false otherwise */ bool BS_BuyItem (const objDef_t* od, base_t* base, int count) { if (!od) cgi->Com_Error(ERR_DROP, "BS_BuyItem: Called on nullptr objDef!"); if (!base) cgi->Com_Error(ERR_DROP, "BS_BuyItem: Called on nullptr base!"); if (count <= 0) return false; if (!BS_IsOnMarket(od)) return false; if (ccs.credits < BS_GetItemBuyingPrice(od) * count) return false; if (BS_GetItemOnMarket(od) < count) return false; if (CAP_GetFreeCapacity(base, CAP_ITEMS) < od->size * count) return false; B_AddToStorage(base, od, count); BS_RemoveItemFromMarket(od, count); CP_UpdateCredits(ccs.credits - BS_GetItemBuyingPrice(od) * count); 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; } } }