| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : Commmando *
- * *
- * $Archive:: /Commando/Code/Commando/vendor.cpp $*
- * *
- * Author:: Patrick Smith *
- * *
- * $Modtime:: 1/28/02 11:17a $*
- * *
- * $Revision:: 23 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "vendor.h"
- #include "gameobjmanager.h"
- #include "playerdata.h"
- #include "soldier.h"
- #include "playertype.h"
- #include "combat.h"
- #include "powerup.h"
- #include "refinerygameobj.h"
- #include "vehiclefactorygameobj.h"
- #include "definitionmgr.h"
- #include "vehicle.h"
- #include "combatchunkid.h"
- #include "cnetwork.h"
- #include "purchaserequestevent.h"
- #include "purchasesettings.h"
- #include "teampurchasesettings.h"
- #include "weaponbag.h"
- #include "weapons.h"
- #include "purchaseresponseevent.h"
- ////////////////////////////////////////////////////////////////
- // Namespaces
- ////////////////////////////////////////////////////////////////
- using namespace BuildingConstants;
- ////////////////////////////////////////////////////////////////
- //
- // Purchase_Vehicle
- //
- ////////////////////////////////////////////////////////////////
- VendorClass::PURCHASE_ERROR
- VendorClass::Purchase_Vehicle
- (
- BaseControllerClass * base,
- SoldierGameObj * player,
- int cost,
- int vehicle_id
- )
- {
- PURCHASE_ERROR retval = PERR_NOT_IN_STOCK;
- //
- // Check to see if this vehicle is available to build
- //
- VehicleGameObjDef *definition = NULL;
- definition = (VehicleGameObjDef *)DefinitionMgrClass::Find_Definition (vehicle_id);
- if (definition != NULL) {
- PlayerDataClass *player_data = NULL;
- bool has_funds = true;
-
- //
- // Check to see if the player has sufficient funds to purchase the vehicle
- //
- if (player != NULL && player->Get_Player_Data () != NULL) {
- player_data = player->Get_Player_Data ();
- has_funds = (player_data->Get_Money () >= cost);
- }
- if (has_funds) {
- retval = PERR_NO_FACTORY;
- //
- // Find our vehicle factory
- //
- BuildingGameObj *building = base->Find_Building (TYPE_VEHICLE_FACTORY);
- if (building != NULL) {
- VehicleFactoryGameObj *factory = building->As_VehicleFactoryGameObj ();
- //
- // If we have a vehicle factory that isn't busy, then start building the vehicle
- //
- if (factory->Is_Available ()) {
- float time = 5.0F * base->Get_Operation_Time_Factor ();
- factory->Request_Vehicle (vehicle_id, time, player);
- retval = PERR_SUCCESS;
- //
- // If a player is purcahsing the vehicle, then debit
- // the player's account
- //
- if (player_data != NULL) {
- player_data->Purchase_Item (cost);
- }
- }
- }
- } else {
- retval = PERR_NO_FUNDS;
- }
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Purchase_Powerup
- //
- ////////////////////////////////////////////////////////////////
- VendorClass::PURCHASE_ERROR
- VendorClass::Purchase_Powerup
- (
- BaseControllerClass * base,
- SoldierGameObj * player,
- int cost,
- int powerup_id
- )
- {
- PURCHASE_ERROR retval = PERR_NO_FUNDS;
- //
- // Sanity check
- //
- if (player == NULL) {
- return retval;
- }
- //
- // Lookup the powerup's definition
- //
- DefinitionClass *definition = DefinitionMgrClass::Find_Definition (powerup_id);
- if (definition != NULL && definition->Get_Class_ID () == CLASSID_GAME_OBJECT_DEF_POWERUP) {
- PowerUpGameObjDef *powerup_def = reinterpret_cast<PowerUpGameObjDef *> (definition);
- //
- // If a player is purcahsing the powerup, then debit
- // the player's account
- //
- bool has_funds = false;
- PlayerDataClass *player_data = player->Get_Player_Data ();
- if (player_data != NULL) {
- //
- // Try to purchase the powerup
- //
- has_funds = player_data->Purchase_Item (cost);
- }
- //
- // If the player has the cash, then grant him the powerup
- //
- if (has_funds) {
- powerup_def->Grant (player);
- retval = PERR_SUCCESS;
- }
-
- } else {
- retval = PERR_NOT_IN_STOCK;
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Purchase_Character
- //
- ////////////////////////////////////////////////////////////////
- VendorClass::PURCHASE_ERROR
- VendorClass::Purchase_Character
- (
- BaseControllerClass * base,
- SoldierGameObj * player,
- int cost,
- int definition_id
- )
- {
- PURCHASE_ERROR retval = PERR_NO_FUNDS;
- //
- // Sanity check
- //
- if (player == NULL) {
- return retval;
- }
- //
- // Check to see if the player has sufficient funds to purchase the upgrade
- //
- PlayerDataClass *player_data = player->Get_Player_Data ();
- bool has_funds = (player_data->Get_Money () >= cost);
- if (has_funds) {
- retval = PERR_NO_FACTORY;
- //
- // Check to see if our soldier factory is operational
- //
- BuildingGameObj *building = base->Find_Building (TYPE_SOLDIER_FACTORY);
- if ((building != NULL && building->Is_Destroyed () == false) || cost == 0) {
-
- //
- // Lookup the new definition for the soldier
- //
- DefinitionClass *definition = DefinitionMgrClass::Find_Definition (definition_id);
- if (definition != NULL && definition->Get_Class_ID () == CLASSID_GAME_OBJECT_DEF_SOLDIER) {
-
- //
- // Upgrade the player
- //
- SoldierGameObjDef *soldier_def = reinterpret_cast<SoldierGameObjDef *> (definition);
- player->Re_Init (*soldier_def);
- player->Post_Re_Init();
- retval = PERR_SUCCESS;
- //
- // Debit the player's account
- //
- player_data->Purchase_Item (cost);
- }
- }
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Purchase_Powerup
- //
- ////////////////////////////////////////////////////////////////
- VendorClass::PURCHASE_ERROR
- VendorClass::Purchase_Item
- (
- SoldierGameObj * player,
- PURCHASE_TYPE type,
- int item_index,
- int alt_skin_index,
- bool is_from_server
- )
- {
- PURCHASE_ERROR retval = PERR_NO_FUNDS;
- //
- // Sanity check
- //
- if (player == NULL) {
- return retval;
- }
- if (CombatManager::I_Am_Server () == false) {
-
- //
- // Request this purchase from the server
- //
- cPurchaseRequestEvent *purchase_request = new cPurchaseRequestEvent;
- purchase_request->Init (type, item_index, alt_skin_index);
- //
- // Let the user know the operation is pending
- //
- retval = PERR_OPERATION_PENDING;
-
- } else {
- //
- // Determine which base controller to purchase from
- //
- BaseControllerClass *base = NULL;
- if (player->Get_Player_Type () == PLAYERTYPE_NOD) {
- base = BaseControllerClass::Find_Base ( PLAYERTYPE_NOD );
- } else {
- base = BaseControllerClass::Find_Base ( PLAYERTYPE_GDI );
- }
- //
- // Lookup information about this purchase
- //
- int cost = 0;
- int definition_id = 0;
- Get_Merchandise_Information (player, type, item_index, alt_skin_index, cost, definition_id);
- //
- // Cost is doubled if the base isn't powered
- //
- //if (base != NULL && base->Is_Base_Powered () == false) {
- if (type != TYPE_BEACON && base != NULL && base->Is_Base_Powered () == false) {
- cost = cost * 2;
- }
- if (type == TYPE_CHARACTER || type == TYPE_ENLISTED_CHARACTER || type == TYPE_SECRET_CHARACTER) {
- //
- // Purchase the character
- //
- retval = Purchase_Character (base, player, cost, definition_id);
- } else if (type == TYPE_VEHICLE || type == TYPE_SECRET_VEHICLE) {
-
- //
- // Purchase the vehicle
- //
- retval = Purchase_Vehicle (base, player, cost, definition_id);
- } else if (type == TYPE_BEACON) {
- //
- // Purchase the beacon powerup
- //
- retval = Purchase_Powerup (base, player, cost, definition_id);
- } else if (type == TYPE_SUPPLY) {
-
- //
- // Grant full health, armor and ammo
- //
- Grant_Supplies (player);
- retval = PERR_SUCCESS;
- }
- //
- // Send the response to the server locally as necessary
- //
- if (is_from_server) {
- cPurchaseResponseEvent *event = new cPurchaseResponseEvent;
- event->Init ((int)retval, cNetwork::Get_My_Id ());
- }
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Grant_Supplies
- //
- ////////////////////////////////////////////////////////////////
- void
- VendorClass::Grant_Supplies (SoldierGameObj *player)
- {
- //
- // Grant ammo
- //
- WeaponBagClass *weapon_bag = player->Get_Weapon_Bag ();
- for (int weapon_index = 0; weapon_index < weapon_bag->Get_Count (); weapon_index ++) {
- WeaponClass *weapon = weapon_bag->Peek_Weapon (weapon_index);
- if (weapon != NULL && weapon->Get_Definition ()->CanReceiveGenericCnCAmmo) {
- //
- // Restore full ammo
- //
- weapon->Set_Inventory_Rounds (weapon->Get_Definition ()->MaxInventoryRounds);
- weapon->Set_Clip_Rounds (weapon->Get_Definition ()->ClipSize);
- }
- }
- //
- // Grant full health and armor
- //
- DefenseObjectClass *defense_obj = player->Get_Defense_Object ();
- defense_obj->Set_Health (defense_obj->Get_Health_Max ());
- defense_obj->Set_Shield_Strength (defense_obj->Get_Shield_Strength_Max ());
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Get_Merchandise_Information
- //
- ////////////////////////////////////////////////////////////////
- void
- VendorClass::Get_Merchandise_Information
- (
- SoldierGameObj * player,
- PURCHASE_TYPE type,
- int item_index,
- int alt_skin_index,
- int & cost,
- int & definition_id
- )
- {
- //
- // Determine which team to use...
- //
- PurchaseSettingsDefClass::TEAM team = PurchaseSettingsDefClass::TEAM_GDI;
- if (player->Get_Player_Type () == PLAYERTYPE_NOD) {
- team = PurchaseSettingsDefClass::TEAM_NOD;
- }
- //
- // Lookup the definition
- //
- if (type == TYPE_CHARACTER || type == TYPE_VEHICLE) {
-
- //
- // Determine which purchase type to use
- //
- PurchaseSettingsDefClass::TYPE purchase_type = PurchaseSettingsDefClass::TYPE_CLASSES;
- if (type == TYPE_VEHICLE) {
- purchase_type = PurchaseSettingsDefClass::TYPE_VEHICLES;
- }
- //
- // Lookup the information from this purchase definition
- //
- PurchaseSettingsDefClass *definition = PurchaseSettingsDefClass::Find_Definition (purchase_type, team);
- if (definition != NULL) {
- cost = definition->Get_Cost (item_index);
- //
- // Either get the default skin or the alternate skin
- //
- if (alt_skin_index != -1) {
- definition_id = definition->Get_Alt_Definition (item_index, alt_skin_index);
- } else {
- definition_id = definition->Get_Definition (item_index);
- }
- }
- } else if (type == TYPE_SECRET_CHARACTER || type == TYPE_SECRET_VEHICLE) {
-
- //
- // Only allow cheats in non-laddered games!
- //
- if (The_Game()->IsLaddered.Is_False()) {
-
- //
- // Determine which purchase type to use
- //
- PurchaseSettingsDefClass::TYPE purchase_type = PurchaseSettingsDefClass::TYPE_SECRET_CLASSES;
- if (type == TYPE_SECRET_VEHICLE) {
- purchase_type = PurchaseSettingsDefClass::TYPE_SECRET_VEHICLES;
- }
- //
- // Lookup the information from this purchase definition
- //
- PurchaseSettingsDefClass *definition = PurchaseSettingsDefClass::Find_Definition (purchase_type, team);
- if (definition != NULL) {
- cost = definition->Get_Cost (item_index);
- definition_id = definition->Get_Definition (item_index);
- }
- }
-
- } else if (type == TYPE_ENLISTED_CHARACTER) {
- //
- // For enlisted characters, lookup the team purchase definition
- //
- cost = 0;
- TeamPurchaseSettingsDefClass *definition = TeamPurchaseSettingsDefClass::Get_Definition ((TeamPurchaseSettingsDefClass::TEAM)team);
- if (definition != NULL) {
- definition_id = definition->Get_Enlisted_Definition (item_index);
- }
- } else if (type == TYPE_BEACON) {
- //
- // For beacons, lookup the team purchase definition
- //
- TeamPurchaseSettingsDefClass *definition = TeamPurchaseSettingsDefClass::Get_Definition ((TeamPurchaseSettingsDefClass::TEAM)team);
- if (definition != NULL) {
- cost = definition->Get_Beacon_Cost ();
- definition_id = definition->Get_Beacon_Definition ();
- }
- }
- return ;
- }
|