mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
Added support for Russian city names and Items Fixed contract length exploit (hire merc for 2 weeks for the price of 1 day) Fixed insurance emails repeating when you choose "delete" but then say no Corrected UTF-8 to wide char translation on Windows platforms (Windows doesn't handle mbstowcs correctly) Moved UTF-8 to Wide Char translation for item descriptions and names so it happens at XML load time (fix bug that Russian has half the description space) Fix overflow when combining two items with high counts (such as 200-round boxes of ammo) Path AI fixes Fixed issues with non-interruptable animations causing infinite clock Fixed some issues with soldiers not reaching their plotted destination Fixed escorted players who were cowering, being unable to move after joining party Only allow militia to climb roofs if their orders allow them to move Fix bug where AI might climb the wrong roof on the way to the destination roof Allow AI who have gone outside their patrol grid, to return to the Grid git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@1702 3b4a5df2-a311-0410-b5c6-a8a6f20db521
1487 lines
36 KiB
C++
1487 lines
36 KiB
C++
#ifdef PRECOMPILEDHEADERS
|
|
#include "Tactical All.h"
|
|
#else
|
|
#include "Types.h"
|
|
#include "ArmsDealerInvInit.h"
|
|
#include "Item Types.h"
|
|
#include "Arms Dealer Init.h"
|
|
#include "DEbug.h"
|
|
#include "weapons.h"
|
|
#include "Campaign.h"
|
|
#include "GameSettings.h"
|
|
#include "AIInternals.h"
|
|
#include "LaptopSave.h"
|
|
#include "bobbyr.h"
|
|
#include "Random.h"
|
|
#include "Shopkeeper Interface.h"
|
|
#endif
|
|
|
|
|
|
extern INT8 gbSelectedArmsDealerID;
|
|
|
|
|
|
// This table controls the order items appear in inventory at BR's and dealers, and which kinds of items are sold used
|
|
ITEM_SORT_ENTRY DealerItemSortInfo[ ] =
|
|
{
|
|
// item class weapon class sold used?
|
|
{ IC_GUN, HANDGUNCLASS, TRUE },
|
|
{ IC_GUN, SHOTGUNCLASS, TRUE },
|
|
{ IC_GUN, SMGCLASS, TRUE },
|
|
{ IC_GUN, RIFLECLASS, TRUE },
|
|
{ IC_GUN, MGCLASS, FALSE },
|
|
{ IC_LAUNCHER, NOGUNCLASS, FALSE },
|
|
{ IC_AMMO, NOGUNCLASS, FALSE },
|
|
{ IC_GRENADE, NOGUNCLASS, FALSE },
|
|
{ IC_BOMB, NOGUNCLASS, FALSE },
|
|
{ IC_BLADE, NOGUNCLASS, FALSE },
|
|
{ IC_THROWING_KNIFE, NOGUNCLASS, FALSE },
|
|
{ IC_PUNCH, NOGUNCLASS, FALSE },
|
|
{ IC_ARMOUR, NOGUNCLASS, TRUE },
|
|
{ IC_FACE, NOGUNCLASS, TRUE },
|
|
{ IC_MEDKIT, NOGUNCLASS, FALSE },
|
|
{ IC_KIT, NOGUNCLASS, FALSE },
|
|
{ IC_MISC, NOGUNCLASS, TRUE },
|
|
{ IC_THROWN, NOGUNCLASS, FALSE },
|
|
{ IC_KEY, NOGUNCLASS, FALSE },
|
|
|
|
// marks end of list
|
|
{ IC_NONE, NOGUNCLASS, },
|
|
};
|
|
|
|
|
|
|
|
//
|
|
// Setup the inventory arrays for each of the arms dealers
|
|
//
|
|
// The arrays are composed of pairs of numbers
|
|
// The first is the item index
|
|
// The second is the amount of the items the dealer will try to keep in his inventory
|
|
|
|
|
|
//
|
|
// Tony ( Weapons only )
|
|
//
|
|
|
|
DEALER_POSSIBLE_INV gTonyInventory[MAXITEMS+1];// =
|
|
//{
|
|
// //Rare guns/ammo that Tony will buy although he won't ever sell them
|
|
// { ROCKET_RIFLE, 0 },
|
|
// { AUTO_ROCKET_RIFLE, 0 },
|
|
// { AUTOMAG_III, 0 },
|
|
//// { FLAMETHROWER, 0 },
|
|
//
|
|
//
|
|
// //Weapons
|
|
// { GLOCK_17, 1 }, /* Glock 17 */
|
|
// { GLOCK_18, 1 }, /* Glock 18 */
|
|
// { BERETTA_92F, 1 }, /* Beretta 92F */
|
|
// { BERETTA_93R, 1 }, /* Beretta 93R */
|
|
// { SW38, 1 }, /* .38 S&W Special */
|
|
// { BARRACUDA, 1 }, /* .357 Barracuda */
|
|
// { DESERTEAGLE, 1 }, /* .357 DesertEagle*/
|
|
// { M1911, 1 }, /* .45 M1911 */
|
|
// { MP5K, 1 }, /* H&K MP5K */
|
|
// { MAC10, 1 }, /* .45 MAC-10 */
|
|
//
|
|
// { THOMPSON, 1 }, /* Thompson M1A1 */
|
|
// { COMMANDO, 1 }, /* Colt Commando */
|
|
// { MP53, 1 }, /* H&K MP53 */
|
|
// { AKSU74, 1 }, /* AKSU-74 */
|
|
// { TYPE85, 1 }, /* Type-85 */
|
|
// { SKS, 1 }, /* SKS */
|
|
// { DRAGUNOV, 1 }, /* Dragunov */
|
|
// { M24, 1 }, /* M24 */
|
|
// { AUG, 1 }, /* Steyr AUG */
|
|
//
|
|
// { G41, 1 }, /* H&K G41 */
|
|
// { MINI14, 1 }, /* Ruger Mini-14 */
|
|
// { C7, 1 }, /* C-7 */
|
|
// { FAMAS, 1 }, /* FA-MAS */
|
|
// { AK74, 1 }, /* AK-74 */
|
|
// { AKM, 1 }, /* AKM */
|
|
// { M14, 1 }, /* M-14 */
|
|
// { G3A3, 1 }, /* H&K G3A3 */
|
|
// { FNFAL, 1 }, /* FN-FAL */
|
|
//
|
|
// { MINIMI, 1 },
|
|
// { RPK74, 1 },
|
|
// { HK21E, 1 },
|
|
//
|
|
// { M870, 1 }, /* Remington M870 */
|
|
// { SPAS15, 1 }, /* SPAS-15 */
|
|
//
|
|
// { GLAUNCHER, 1 }, /* grenade launcher*/
|
|
// { UNDER_GLAUNCHER, 1 }, /* underslung g.l. */
|
|
// { ROCKET_LAUNCHER, 1 }, /* rocket Launcher */
|
|
// { RPG7, 1 }, /* rpg 7*/
|
|
// { MORTAR, 1 },
|
|
//
|
|
// // SAP guns
|
|
// { G11, 1 },
|
|
// { CAWS, 1 },
|
|
// { P90, 1 },
|
|
//
|
|
// { DART_GUN, 1 },
|
|
//
|
|
// { M900, 1 },
|
|
// { M950, 1 },
|
|
// { M960, 1 },
|
|
// { MICRO_UZI, 1 },
|
|
// { ENFIELD, 1 },
|
|
// { TAR21, 1 },
|
|
// { PSG, 1 },
|
|
// { VAL_SILENT, 1 },
|
|
// { BARRETT, 1 },
|
|
// { MP5, 1 },
|
|
// { UMP45, 1 },
|
|
// { MP5SD, 1 },
|
|
// { MP5N, 1 },
|
|
// { FIVE7, 1 },
|
|
// { P7M8, 1 },
|
|
// { G36C, 1 },
|
|
// { G36K, 1 },
|
|
// { MSG90A1, 1 },
|
|
// { BENNELLI, 1 },
|
|
// { AK103, 1 },
|
|
//
|
|
// //Ammo
|
|
// { CLIP9_15, 8 },
|
|
// { CLIP9_30, 6 },
|
|
// { CLIP9_15_AP, 3 }, /* CLIP9_15_AP */
|
|
// { CLIP9_30_AP, 3 }, /* CLIP9_30_AP */
|
|
// { CLIP9_15_HP, 3 }, /* CLIP9_15_HP */
|
|
// { CLIP9_30_HP, 3 }, /* CLIP9_30_HP */
|
|
//
|
|
// { CLIP38_6, 10}, /* CLIP38_6 */
|
|
// { CLIP38_6_AP, 5 }, /* CLIP38_6_AP */
|
|
// { CLIP38_6_HP, 5 }, /* CLIP38_6_HP */
|
|
//
|
|
// { CLIP45_7, 6 }, /* CLIP45_7 */ // 70
|
|
//
|
|
// { CLIP45_30, 8 }, /* CLIP45_30 */
|
|
// { CLIP45_7_AP, 3 }, /* CLIP45_7_AP */
|
|
// { CLIP45_30_AP, 3 }, /* CLIP45_30_AP */
|
|
// { CLIP45_7_HP, 3 }, /* CLIP45_7_HP */
|
|
// { CLIP45_30_HP, 3 }, /* CLIP45_30_HP */
|
|
//
|
|
// { CLIP357_6, 6 }, /* CLIP357_6 */
|
|
// { CLIP357_9, 5 }, /* CLIP357_9 */
|
|
// { CLIP357_6_AP, 3 }, /* CLIP357_6_AP */
|
|
// { CLIP357_9_AP, 3 }, /* CLIP357_9_AP */
|
|
// { CLIP357_6_HP, 3 }, /* CLIP357_6_HP */ //80
|
|
// { CLIP357_9_HP, 3 }, /* CLIP357_9_HP */
|
|
//
|
|
// { CLIP545_30_AP, 6 }, /* CLIP545_30_AP */
|
|
// { CLIP545_30_HP, 3 }, /* CLIP545_30_HP */
|
|
//
|
|
// { CLIP556_30_AP, 6 }, /* CLIP556_30_AP */
|
|
// { CLIP556_30_HP, 3 }, /* CLIP556_30_HP */
|
|
//
|
|
// { CLIP762W_10_AP, 6 }, /* CLIP762W_10_AP */
|
|
// { CLIP762W_30_AP, 5 }, /* CLIP762W_30_AP */
|
|
// { CLIP762W_10_HP, 3 }, /* CLIP762W_10_HP */
|
|
// { CLIP762W_30_HP, 3 }, /* CLIP762W_30_HP */
|
|
//
|
|
// { CLIP762N_5_AP, 8 }, /* CLIP762N_5_AP */ //90
|
|
// { CLIP762N_20_AP, 5 }, /* CLIP762N_20_AP */
|
|
// { CLIP762N_5_HP, 3 }, /* CLIP762N_5_HP */
|
|
// { CLIP762N_20_HP, 3 }, /* CLIP762N_20_HP */
|
|
//
|
|
// { CLIP47_50_SAP, 5 }, /* CLIP47_50_SAP */
|
|
//
|
|
// { CLIP57_50_AP, 6 }, /* CLIP57_50_AP */
|
|
// { CLIP57_50_HP, 3 }, /* CLIP57_50_HP */
|
|
//
|
|
// { CLIP12G_7, 9 }, /* CLIP12G_7 */
|
|
// { CLIP12G_7_BUCKSHOT, 9 }, /* CLIP12G_7_BUCKSHOT */
|
|
//
|
|
// { CLIPCAWS_10_SAP, 5 }, /* CLIPCAWS_10_SAP */
|
|
// { CLIPCAWS_10_FLECH, 3 }, /* CLIPCAWS_10_FLECH */ //100
|
|
//
|
|
// { CLIPROCKET_AP, 3 },
|
|
// { CLIPROCKET_HE, 1 },
|
|
// { CLIPROCKET_HEAT, 1 },
|
|
//
|
|
// { CLIPDART_SLEEP, 5 },
|
|
//
|
|
// { CLIP50_11, 3 },
|
|
// { CLIP9H_20, 3 },
|
|
// { CLIP9_50, 4 },
|
|
// { CLIP9_50_AP, 3 },
|
|
// { CLIP9_50_HP, 2 },
|
|
// { DRUM545_75_AP, 3},
|
|
// { DRUM545_75_HP, 2 },
|
|
// { BELT556_200_AP, 3},
|
|
// { BELT556_200_HP, 2 },
|
|
// { BELT762N_100_AP, 3},
|
|
// { BELT762N_100_HP, 2 },
|
|
// { CLIP57_20_AP, 6 },
|
|
// { CLIP57_20_HP, 4 },
|
|
//// { CLIPFLAME, 5 },
|
|
//
|
|
// // "launchables" (New! From McCain!) - these are basically ammo
|
|
// { GL_HE_GRENADE, 2 },
|
|
// { GL_TEARGAS_GRENADE, 2 },
|
|
// { GL_STUN_GRENADE, 2 },
|
|
// { GL_SMOKE_GRENADE, 2 },
|
|
// { MORTAR_SHELL, 1 },
|
|
//
|
|
// // knives
|
|
// { COMBAT_KNIFE, 3 },
|
|
// { THROWING_KNIFE, 6 },
|
|
// { BRASS_KNUCKLES, 1 },
|
|
// { MACHETE, 1 },
|
|
//
|
|
// // attachments
|
|
// { SILENCER, 3 },
|
|
// { SNIPERSCOPE, 3 },
|
|
// { LASERSCOPE, 2 },
|
|
// { BIPOD, 3 },
|
|
// { DUCKBILL, 3 },
|
|
// { FLASH_SUPPRESSOR, 3 },
|
|
// { REFLEX_SCOPED, 3 },
|
|
// { REFLEX_UNSCOPED, 3 },
|
|
//
|
|
///*
|
|
// // grenades
|
|
// { STUN_GRENADE, 5 },
|
|
// { TEARGAS_GRENADE, 5 },
|
|
// { MUSTARD_GRENADE, 5 },
|
|
// { MINI_GRENADE, 5 },
|
|
// { HAND_GRENADE, 5 },
|
|
// { SMOKE_GRENADE, 5 },
|
|
//*/
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Devin ( Explosives )
|
|
//
|
|
DEALER_POSSIBLE_INV gDevinInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { STUN_GRENADE, 3 },
|
|
// { TEARGAS_GRENADE, 3 },
|
|
// { MUSTARD_GRENADE, 2 },
|
|
// { MINI_GRENADE, 3 },
|
|
// { HAND_GRENADE, 2 },
|
|
// { SMOKE_GRENADE, 3 },
|
|
//
|
|
// { GL_HE_GRENADE, 2 },
|
|
// { GL_TEARGAS_GRENADE, 2 },
|
|
// { GL_STUN_GRENADE, 2 },
|
|
// { GL_SMOKE_GRENADE, 2 },
|
|
// { MORTAR_SHELL, 1 },
|
|
// { RPG_HE_ROCKET, 2 },
|
|
// { RPG_AP_ROCKET, 2 },
|
|
// { RPG_FRAG_ROCKET, 2 },
|
|
//
|
|
// { CLIPROCKET_AP, 1 },
|
|
// { CLIPROCKET_HE, 1 },
|
|
// { CLIPROCKET_HEAT, 1 },
|
|
//
|
|
// { DETONATOR, 10},
|
|
// { REMDETONATOR, 5 },
|
|
// { REMOTEBOMBTRIGGER, 5 },
|
|
//
|
|
// { MINE, 6 },
|
|
// { RDX, 5 },
|
|
// { TNT, 5 },
|
|
// { C1, 4 },
|
|
// { HMX, 3 },
|
|
// { C4, 2 },
|
|
//
|
|
// { SHAPED_CHARGE, 5 },
|
|
//
|
|
//// { TRIP_FLARE, 2 },
|
|
//// { TRIP_KLAXON, 2 },
|
|
//
|
|
// { GLAUNCHER, 1 }, /* grenade launcher*/
|
|
// { UNDER_GLAUNCHER, 1 }, /* underslung g.l. */
|
|
// { ROCKET_LAUNCHER, 1 }, /* rocket Launcher */
|
|
// { RPG7, 1 }, /* rpg 7 */
|
|
// { MORTAR, 1 },
|
|
//
|
|
// { METALDETECTOR, 2 },
|
|
// { WIRECUTTERS, 1 },
|
|
// { DUCT_TAPE, 1 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Franz (Expensive pawn shop )
|
|
//
|
|
DEALER_POSSIBLE_INV gFranzInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { NIGHTGOGGLES, 3 },
|
|
//
|
|
// { LASERSCOPE, 3 },
|
|
// { METALDETECTOR, 2 },
|
|
// { EXTENDEDEAR, 2 },
|
|
//
|
|
// { DART_GUN, 1 },
|
|
//
|
|
// { KEVLAR_VEST, 1 },
|
|
// { KEVLAR_LEGGINGS, 1 },
|
|
// { KEVLAR_HELMET, 1 },
|
|
// { KEVLAR2_VEST, 1 },
|
|
// { SPECTRA_VEST, 1 },
|
|
// { SPECTRA_LEGGINGS, 1 },
|
|
// { SPECTRA_HELMET, 1 },
|
|
//
|
|
// { CERAMIC_PLATES, 1 },
|
|
//
|
|
// { CAMOUFLAGEKIT, 1 },
|
|
//
|
|
// { VIDEO_CAMERA, 1 }, // for robot quest
|
|
//
|
|
// { LAME_BOY, 1 },
|
|
// { FUMBLE_PAK, 1 },
|
|
//
|
|
// { GOLDWATCH, 1 },
|
|
// { GOLFCLUBS, 1 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Keith ( Cheap Pawn Shop )
|
|
//
|
|
DEALER_POSSIBLE_INV gKeithInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { FIRSTAIDKIT, 5 },
|
|
//
|
|
// // WARNING: Keith must not carry any guns, it would conflict with his story/quest
|
|
//
|
|
// { COMBAT_KNIFE, 2 },
|
|
// { THROWING_KNIFE, 3 },
|
|
// { BRASS_KNUCKLES, 1 },
|
|
// { MACHETE, 1 },
|
|
//
|
|
// { SUNGOGGLES, 3 },
|
|
// { FLAK_JACKET, 2 },
|
|
// { STEEL_HELMET, 3 },
|
|
// { LEATHER_JACKET, 1 },
|
|
//
|
|
// { CANTEEN, 5 },
|
|
// { CROWBAR, 1 },
|
|
// { JAR, 6 },
|
|
//
|
|
// { TOOLKIT, 1 },
|
|
// { GASMASK, 1 },
|
|
//
|
|
// { SILVER_PLATTER, 1 },
|
|
//
|
|
// { WALKMAN, 1 },
|
|
// { PORTABLETV, 1 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Sam ( Hardware )
|
|
//
|
|
DEALER_POSSIBLE_INV gSamInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { FIRSTAIDKIT, 3 },
|
|
//
|
|
// { LOCKSMITHKIT, 4 },
|
|
// { TOOLKIT, 3 },
|
|
//
|
|
// { CANTEEN, 5 },
|
|
//
|
|
// { CROWBAR, 3 },
|
|
// { WIRECUTTERS, 3 },
|
|
//
|
|
// { DUCKBILL, 3 },
|
|
// { JAR, 12},
|
|
// { BREAK_LIGHT, 12}, // flares
|
|
//
|
|
// { METALDETECTOR, 1 },
|
|
//
|
|
// { VIDEO_CAMERA, 1 },
|
|
//
|
|
// { QUICK_GLUE, 3 },
|
|
// { COPPER_WIRE, 5 },
|
|
// { BATTERIES, 10 },
|
|
//
|
|
// { CLIP9_15, 5 },
|
|
// { CLIP9_30, 5 },
|
|
// { CLIP38_6, 5 },
|
|
// { CLIP45_7, 5 },
|
|
// { CLIP45_30, 5 },
|
|
// { CLIP357_6, 5 },
|
|
// { CLIP357_9, 5 },
|
|
// { CLIP12G_7, 9 },
|
|
// { CLIP12G_7_BUCKSHOT, 9 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Jake ( Junk )
|
|
//
|
|
DEALER_POSSIBLE_INV gJakeInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { FIRSTAIDKIT, 4 },
|
|
// { MEDICKIT, 3 },
|
|
//
|
|
// { SW38, 1 },
|
|
// { CLIP38_6, 5 },
|
|
//
|
|
// { JAR, 3 },
|
|
// { CANTEEN, 2 },
|
|
// { BEER, 6 },
|
|
//
|
|
// { CROWBAR, 1 },
|
|
// { WIRECUTTERS, 1 },
|
|
//
|
|
// { COMBAT_KNIFE, 1 },
|
|
// { THROWING_KNIFE, 1 },
|
|
// { BRASS_KNUCKLES, 1 },
|
|
// { MACHETE, 1 },
|
|
//
|
|
// { BREAK_LIGHT, 5 }, // flares
|
|
//
|
|
// { BIPOD, 1 },
|
|
//
|
|
// { TSHIRT, 6 },
|
|
// { CIGARS, 3 },
|
|
// { PORNOS, 1 },
|
|
//
|
|
// { LOCKSMITHKIT, 1 },
|
|
//
|
|
// // "new" items, presumed unsafe for demo
|
|
// { TSHIRT_DEIDRANNA, 2 },
|
|
// { XRAY_BULB, 1 },
|
|
//
|
|
// // additional stuff possible in real game
|
|
// { GLOCK_17, 1 }, /* Glock 17 */
|
|
// { GLOCK_18, 1 }, /* Glock 18 */
|
|
// { BERETTA_92F, 1 }, /* Beretta 92F */
|
|
// { BERETTA_93R, 1 }, /* Beretta 93R */
|
|
// { BARRACUDA, 1 }, /* .357 Barracuda */
|
|
// { DESERTEAGLE, 1 }, /* .357 DesertEagle*/
|
|
// { M1911, 1 }, /* .45 M1911 */
|
|
//
|
|
// { DISCARDED_LAW, 1 },
|
|
//
|
|
// { STEEL_HELMET, 1 },
|
|
//
|
|
// { TOOLKIT, 1 },
|
|
//
|
|
// { WINE, 1 },
|
|
// { ALCOHOL, 1 },
|
|
//
|
|
// { GOLDWATCH, 1 },
|
|
// { GOLFCLUBS, 1 },
|
|
// { WALKMAN, 1 },
|
|
// { PORTABLETV, 1 },
|
|
//
|
|
// // stuff a real pawn shop wouldn't have, but it does make him a bit more useful
|
|
// { COMPOUND18, 1 },
|
|
// { CERAMIC_PLATES, 1 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
//
|
|
|
|
//
|
|
// Howard ( Pharmaceuticals )
|
|
//
|
|
DEALER_POSSIBLE_INV gHowardInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { FIRSTAIDKIT, 10},
|
|
// { MEDICKIT, 5 },
|
|
// { ADRENALINE_BOOSTER, 5 },
|
|
// { REGEN_BOOSTER, 5 },
|
|
//
|
|
// { ALCOHOL, 3 },
|
|
// { COMBAT_KNIFE, 2 },
|
|
//
|
|
// { CLIPDART_SLEEP, 5 },
|
|
//
|
|
// { CHEWING_GUM, 3 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Gabby ( Creature parts and Blood )
|
|
//
|
|
DEALER_POSSIBLE_INV gGabbyInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { JAR, 12 },
|
|
// { JAR_ELIXIR, 3 },
|
|
// // buys these, but can't supply them (player is the only source)
|
|
// { JAR_CREATURE_BLOOD, 0 },
|
|
// { JAR_QUEEN_CREATURE_BLOOD, 0 },
|
|
// { BLOODCAT_CLAWS, 0 },
|
|
// { BLOODCAT_TEETH, 0 },
|
|
// { BLOODCAT_PELT, 0 },
|
|
// { CREATURE_PART_CLAWS, 0 },
|
|
// { CREATURE_PART_FLESH, 0 },
|
|
// { CREATURE_PART_ORGAN, 0 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Frank ( Alcohol )
|
|
//
|
|
DEALER_POSSIBLE_INV gFrankInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { BEER, 12 },
|
|
// { WINE, 6 },
|
|
// { ALCOHOL, 9 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Elgin ( Alcohol )
|
|
//
|
|
DEALER_POSSIBLE_INV gElginInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { BEER, 12 },
|
|
// { WINE, 6 },
|
|
// { ALCOHOL, 9 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Manny ( Alcohol )
|
|
//
|
|
DEALER_POSSIBLE_INV gMannyInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { BEER, 12 },
|
|
// { WINE, 6 },
|
|
// { ALCOHOL, 9 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Herve Santos ( Alcohol )
|
|
//
|
|
DEALER_POSSIBLE_INV gHerveInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { BEER, 12 },
|
|
// { WINE, 6 },
|
|
// { ALCOHOL, 9 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Peter Santos ( Alcohol )
|
|
//
|
|
DEALER_POSSIBLE_INV gPeterInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { BEER, 12 },
|
|
// { WINE, 6 },
|
|
// { ALCOHOL, 9 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Alberto Santos ( Alcohol )
|
|
//
|
|
DEALER_POSSIBLE_INV gAlbertoInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { BEER, 12 },
|
|
// { WINE, 6 },
|
|
// { ALCOHOL, 9 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Carlo Santos ( Alcohol )
|
|
//
|
|
DEALER_POSSIBLE_INV gCarloInventory[MAXITEMS+1];// =
|
|
//{
|
|
// { BEER, 12 },
|
|
// { WINE, 6 },
|
|
// { ALCOHOL, 9 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Micky ( BUYS Animal / Creature parts )
|
|
//
|
|
|
|
DEALER_POSSIBLE_INV gMickyInventory[MAXITEMS+1];// =
|
|
//{
|
|
// // ONLY BUYS THIS STUFF, DOESN'T SELL IT
|
|
// { BLOODCAT_CLAWS, 0 },
|
|
// { BLOODCAT_TEETH, 0 },
|
|
// { BLOODCAT_PELT, 0 },
|
|
// { CREATURE_PART_CLAWS, 0 },
|
|
// { CREATURE_PART_FLESH, 0 },
|
|
// { CREATURE_PART_ORGAN, 0 },
|
|
// { JAR_QUEEN_CREATURE_BLOOD, 0 },
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
//
|
|
// Arnie ( Weapons REPAIR )
|
|
//
|
|
DEALER_POSSIBLE_INV gArnieInventory[MAXITEMS+1];// =
|
|
//{
|
|
// // NO INVENTORY
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
//
|
|
// Perko ( REPAIR)
|
|
//
|
|
DEALER_POSSIBLE_INV gPerkoInventory[MAXITEMS+1];// =
|
|
//{
|
|
// // NO INVENTORY
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
//
|
|
// Fredo ( Electronics REPAIR)
|
|
//
|
|
DEALER_POSSIBLE_INV gFredoInventory[MAXITEMS+1];// =
|
|
//{
|
|
// // NO INVENTORY
|
|
//
|
|
// { LAST_DEALER_ITEM, NO_DEALER_ITEM }, //Last One
|
|
//};
|
|
|
|
|
|
|
|
// prototypes
|
|
|
|
INT8 GetMaxItemAmount( DEALER_POSSIBLE_INV *pInv, UINT16 usItemIndex );
|
|
|
|
|
|
|
|
INT8 GetDealersMaxItemAmount( UINT8 ubDealerID, UINT16 usItemIndex )
|
|
{
|
|
switch( ubDealerID )
|
|
{
|
|
case ARMS_DEALER_TONY:
|
|
return( GetMaxItemAmount( gTonyInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_FRANK:
|
|
return( GetMaxItemAmount( gFrankInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_MICKY:
|
|
return( GetMaxItemAmount( gMickyInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_ARNIE:
|
|
return( GetMaxItemAmount( gArnieInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_PERKO:
|
|
return( GetMaxItemAmount( gPerkoInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_KEITH:
|
|
return( GetMaxItemAmount( gKeithInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_BAR_BRO_1:
|
|
return( GetMaxItemAmount( gHerveInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_BAR_BRO_2:
|
|
return( GetMaxItemAmount( gPeterInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_BAR_BRO_3:
|
|
return( GetMaxItemAmount( gAlbertoInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_BAR_BRO_4:
|
|
return( GetMaxItemAmount( gCarloInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_JAKE:
|
|
return( GetMaxItemAmount( gJakeInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_FRANZ:
|
|
return( GetMaxItemAmount( gFranzInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_HOWARD:
|
|
return( GetMaxItemAmount( gHowardInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_SAM:
|
|
return( GetMaxItemAmount( gSamInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_FREDO:
|
|
return( GetMaxItemAmount( gFredoInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_GABBY:
|
|
return( GetMaxItemAmount( gGabbyInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_DEVIN:
|
|
return( GetMaxItemAmount( gDevinInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_ELGIN:
|
|
return( GetMaxItemAmount( gElginInventory, usItemIndex ) );
|
|
break;
|
|
|
|
case ARMS_DEALER_MANNY:
|
|
return( GetMaxItemAmount( gMannyInventory, usItemIndex ) );
|
|
break;
|
|
|
|
default:
|
|
Assert( FALSE );
|
|
return( 0 );
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
INT8 GetMaxItemAmount( DEALER_POSSIBLE_INV *pInv, UINT16 usItemIndex )
|
|
{
|
|
UINT16 usCnt=0;
|
|
|
|
//loop through the array until a the LAST_DEALER_ITEM is hit
|
|
while( pInv[ usCnt ].sItemIndex != LAST_DEALER_ITEM )
|
|
{
|
|
//if this item is the one we want
|
|
if( pInv[ usCnt ].sItemIndex == usItemIndex )
|
|
return( pInv[ usCnt ].ubOptimalNumber );
|
|
|
|
// move to the next item
|
|
usCnt++;
|
|
}
|
|
|
|
return( NO_DEALER_ITEM );
|
|
}
|
|
|
|
|
|
DEALER_POSSIBLE_INV *GetPointerToDealersPossibleInventory( UINT8 ubArmsDealerID )
|
|
{
|
|
switch( ubArmsDealerID )
|
|
{
|
|
case ARMS_DEALER_TONY:
|
|
return( gTonyInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_FRANK:
|
|
return( gFrankInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_MICKY:
|
|
return( gMickyInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_ARNIE:
|
|
return( gArnieInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_PERKO:
|
|
return( gPerkoInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_KEITH:
|
|
return( gKeithInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_BAR_BRO_1:
|
|
return( gHerveInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_BAR_BRO_2:
|
|
return( gPeterInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_BAR_BRO_3:
|
|
return( gAlbertoInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_BAR_BRO_4:
|
|
return( gCarloInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_JAKE:
|
|
return( gJakeInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_FRANZ:
|
|
return( gFranzInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_HOWARD:
|
|
return( gHowardInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_SAM:
|
|
return( gSamInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_FREDO:
|
|
return( gFredoInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_GABBY:
|
|
return( gGabbyInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_DEVIN:
|
|
return( gDevinInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_ELGIN:
|
|
return( gElginInventory );
|
|
break;
|
|
|
|
case ARMS_DEALER_MANNY:
|
|
return( gMannyInventory );
|
|
break;
|
|
|
|
default:
|
|
return( NULL );
|
|
}
|
|
}
|
|
|
|
|
|
//Madd: added boolean fUsed
|
|
UINT8 GetCurrentSuitabilityForItem( INT8 bArmsDealer, UINT16 usItemIndex, BOOLEAN fUsed )
|
|
{
|
|
UINT8 ubItemCoolness;
|
|
UINT8 ubMinCoolness, ubMaxCoolness;
|
|
|
|
|
|
// item suitability varies with the player's maximum progress through the game. The farther he gets, the better items
|
|
// we make available. Weak items become more and more infrequent later in the game, although they never quite vanish.
|
|
|
|
// items illegal in this game are unsuitable [this checks guns vs. current GunSet!]
|
|
if (!ItemIsLegal( usItemIndex ))
|
|
{
|
|
return(ITEM_SUITABILITY_NONE);
|
|
}
|
|
|
|
// items normally not sold at shops are unsuitable
|
|
// if ( Item[ usItemIndex ].fFlags & ITEM_NOT_BUYABLE )
|
|
if ( Item[ usItemIndex ].notbuyable )
|
|
{
|
|
return(ITEM_SUITABILITY_NONE);
|
|
}
|
|
|
|
|
|
ubItemCoolness = Item[ usItemIndex ].ubCoolness;
|
|
|
|
if (ubItemCoolness == 0)
|
|
{
|
|
// items without a coolness rating can't be sold to the player by shopkeepers
|
|
return(ITEM_SUITABILITY_NONE);
|
|
}
|
|
|
|
// the following staple items are always deemed highly suitable regardless of player's progress:
|
|
//switch (usItemIndex)
|
|
//{
|
|
// case FIRSTAIDKIT:
|
|
// case MEDICKIT:
|
|
// case TOOLKIT:
|
|
// case LOCKSMITHKIT:
|
|
|
|
// case CANTEEN:
|
|
// case CROWBAR:
|
|
// case JAR:
|
|
// case JAR_ELIXIR:
|
|
// case JAR_CREATURE_BLOOD:
|
|
if ( Item[usItemIndex].medical || Item[usItemIndex].canteen || Item[usItemIndex].medicalkit || Item[usItemIndex].locksmithkit || Item[usItemIndex].toolkit || Item[usItemIndex].crowbar || Item[usItemIndex].jar )
|
|
return(ITEM_SUITABILITY_ALWAYS);
|
|
//}
|
|
|
|
|
|
// If it's not BobbyRay, Tony, or Devin
|
|
if ((bArmsDealer != -1) && (bArmsDealer != ARMS_DEALER_TONY) && (bArmsDealer != ARMS_DEALER_DEVIN))
|
|
{
|
|
// all the other dealers have very limited inventories, so their suitability remains constant at all times in game
|
|
return(ITEM_SUITABILITY_HIGH);
|
|
}
|
|
|
|
|
|
// figure out the appropriate range of coolness based on player's maximum progress so far
|
|
|
|
ubMinCoolness = HighestPlayerProgressPercentage() / 10;
|
|
ubMaxCoolness = ( HighestPlayerProgressPercentage() / 10 ) + 1;
|
|
|
|
if ( bArmsDealer == -1 )
|
|
ubMinCoolness = 1;
|
|
|
|
//Madd: Bobby Ray's will sell higher coolness stuff if it's used, and may also have a better selection at the start of the game, depending on selection
|
|
if ( bArmsDealer == -1 && gGameOptions.ubBobbyRay > BR_GOOD )
|
|
{
|
|
ubMaxCoolness += gGameOptions.ubBobbyRay - 1;
|
|
if (fUsed )
|
|
{
|
|
ubMaxCoolness += 1;
|
|
}
|
|
}
|
|
|
|
// Tony has the better stuff sooner (than Bobby R's)
|
|
if (bArmsDealer == ARMS_DEALER_TONY)
|
|
{
|
|
ubMinCoolness += 1;
|
|
ubMaxCoolness += 1;
|
|
}
|
|
else if (bArmsDealer == ARMS_DEALER_DEVIN)
|
|
{
|
|
// almost everything Devin sells is pretty cool (4+), so gotta apply a minimum or he'd have nothing early on
|
|
if ( ubMinCoolness < 3 )
|
|
{
|
|
ubMinCoolness = 3;
|
|
ubMaxCoolness = 4;
|
|
}
|
|
}
|
|
|
|
|
|
ubMinCoolness = max( 1, min( 9, ubMinCoolness ) );
|
|
ubMaxCoolness = max( 2, min( 10, ubMaxCoolness ) );
|
|
|
|
if ( bArmsDealer == -1 )
|
|
{
|
|
//Madd: BR's always sells ammo for its guns
|
|
if (Item[usItemIndex].usItemClass == IC_AMMO && ubItemCoolness <= ubMaxCoolness )
|
|
{
|
|
return(ITEM_SUITABILITY_ALWAYS);
|
|
}
|
|
}
|
|
|
|
// if item is too cool for current level of progress
|
|
if (ubItemCoolness > ubMaxCoolness)
|
|
{
|
|
return(ITEM_SUITABILITY_NONE);
|
|
}
|
|
|
|
// if item is exactly within the current coolness window
|
|
if ((ubItemCoolness >= ubMinCoolness) && (ubItemCoolness <= ubMaxCoolness))
|
|
{
|
|
return(ITEM_SUITABILITY_HIGH);
|
|
}
|
|
|
|
// if item is still relatively close to low end of the window
|
|
if ((ubItemCoolness + 2) >= ubMinCoolness)
|
|
{
|
|
return(ITEM_SUITABILITY_MEDIUM);
|
|
}
|
|
|
|
// item is way uncool for player's current progress, but it's still possible for it to make an appearance
|
|
return(ITEM_SUITABILITY_LOW);
|
|
}
|
|
|
|
|
|
|
|
UINT8 ChanceOfItemTransaction( INT8 bArmsDealer, UINT16 usItemIndex, BOOLEAN fDealerIsSelling, BOOLEAN fUsed )
|
|
{
|
|
UINT8 ubItemCoolness;
|
|
UINT8 ubChance = 0;
|
|
BOOLEAN fBobbyRay = FALSE;
|
|
|
|
|
|
// make sure dealers don't carry used items that they shouldn't
|
|
if ( fUsed && !fDealerIsSelling && !CanDealerItemBeSoldUsed( usItemIndex ) )
|
|
return( 0 );
|
|
|
|
|
|
if (bArmsDealer == -1)
|
|
{
|
|
// Bobby Ray has an easier time getting resupplied than the local dealers do
|
|
fBobbyRay = TRUE;
|
|
}
|
|
|
|
ubItemCoolness = Item[ usItemIndex ].ubCoolness;
|
|
|
|
switch (GetCurrentSuitabilityForItem( bArmsDealer, usItemIndex, fUsed ) )
|
|
{
|
|
case ITEM_SUITABILITY_NONE:
|
|
if (fDealerIsSelling)
|
|
{
|
|
// dealer always gets rid of stuff that is too advanced or inappropriate ASAP
|
|
ubChance = 100;
|
|
}
|
|
else // dealer is buying
|
|
{
|
|
// can't get these at all
|
|
ubChance = 0;
|
|
}
|
|
break;
|
|
|
|
case ITEM_SUITABILITY_LOW:
|
|
ubChance = (fBobbyRay) ? 25 : 15;
|
|
break;
|
|
|
|
case ITEM_SUITABILITY_MEDIUM:
|
|
ubChance = (fBobbyRay) ? 50 : 30;
|
|
break;
|
|
|
|
case ITEM_SUITABILITY_HIGH:
|
|
ubChance = (fBobbyRay) ? 75 : 50;
|
|
break;
|
|
|
|
case ITEM_SUITABILITY_ALWAYS:
|
|
if (fDealerIsSelling)
|
|
{
|
|
// sells just like suitability high
|
|
ubChance = 75;
|
|
}
|
|
else // dealer is buying
|
|
{
|
|
// dealer can always get a (re)supply of these
|
|
ubChance = 100;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
Assert(0);
|
|
break;
|
|
}
|
|
|
|
// Madd
|
|
if ( !fDealerIsSelling && fBobbyRay )
|
|
ubChance = min(100,gGameOptions.ubBobbyRay * ubChance);
|
|
|
|
// if there's any uncertainty
|
|
if ((ubChance > 0) && (ubChance < 100))
|
|
{
|
|
// cooler items sell faster
|
|
if (fDealerIsSelling)
|
|
{
|
|
ubChance += (5 * ubItemCoolness);
|
|
|
|
// ARM: New - keep stuff on the shelves longer
|
|
ubChance /= 2;
|
|
|
|
if ( fBobbyRay )
|
|
ubChance /= gGameOptions.ubBobbyRay;
|
|
}
|
|
|
|
// used items are traded more rarely
|
|
if (fUsed)
|
|
{
|
|
ubChance /= 2;
|
|
}
|
|
}
|
|
|
|
|
|
return(ubChance);
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN ItemTransactionOccurs( INT8 bArmsDealer, UINT16 usItemIndex, BOOLEAN fDealerIsSelling, BOOLEAN fUsed )
|
|
{
|
|
UINT8 ubChance;
|
|
INT16 sInventorySlot;
|
|
|
|
|
|
ubChance = ChanceOfItemTransaction( bArmsDealer, usItemIndex, fDealerIsSelling, fUsed );
|
|
|
|
// if the dealer is buying, and a chance exists (i.e. the item is "eligible")
|
|
if (!fDealerIsSelling && (ubChance > 0))
|
|
{
|
|
// mark it as such
|
|
if (bArmsDealer == -1)
|
|
{
|
|
if (fUsed)
|
|
{
|
|
sInventorySlot = GetInventorySlotForItem(LaptopSaveInfo.BobbyRayUsedInventory, usItemIndex, fUsed);
|
|
LaptopSaveInfo.BobbyRayUsedInventory[ sInventorySlot ].fPreviouslyEligible = TRUE;
|
|
}
|
|
else
|
|
{
|
|
sInventorySlot = GetInventorySlotForItem(LaptopSaveInfo.BobbyRayInventory, usItemIndex, fUsed);
|
|
LaptopSaveInfo.BobbyRayInventory [ sInventorySlot ].fPreviouslyEligible = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gArmsDealersInventory[ bArmsDealer ][ usItemIndex ].fPreviouslyEligible = TRUE;
|
|
}
|
|
}
|
|
|
|
// roll to see if a transaction occurs
|
|
if (Random(100) < ubChance)
|
|
{
|
|
return(TRUE);
|
|
}
|
|
else
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
UINT8 DetermineInitialInvItems( INT8 bArmsDealerID, UINT16 usItemIndex, UINT8 ubChances, BOOLEAN fUsed)
|
|
{
|
|
UINT8 ubNumBought;
|
|
UINT8 ubCnt;
|
|
|
|
// initial inventory is now rolled for one item at a time, instead of one type at a time, to improve variety
|
|
ubNumBought = 0;
|
|
for (ubCnt = 0; ubCnt < ubChances; ubCnt++)
|
|
{
|
|
if (ItemTransactionOccurs( bArmsDealerID, usItemIndex, DEALER_BUYING, fUsed))
|
|
{
|
|
ubNumBought++;
|
|
}
|
|
}
|
|
|
|
return( ubNumBought );
|
|
}
|
|
|
|
|
|
|
|
UINT8 HowManyItemsAreSold( INT8 bArmsDealerID, UINT16 usItemIndex, UINT8 ubNumInStock, BOOLEAN fUsed)
|
|
{
|
|
UINT8 ubNumSold;
|
|
UINT8 ubCnt;
|
|
|
|
// items are now virtually "sold" one at a time
|
|
ubNumSold = 0;
|
|
|
|
for (ubCnt = 0; ubCnt < ubNumInStock; ubCnt++)
|
|
{
|
|
if (ItemTransactionOccurs( bArmsDealerID, usItemIndex, DEALER_SELLING, fUsed))
|
|
{
|
|
ubNumSold++;
|
|
}
|
|
}
|
|
|
|
return( ubNumSold );
|
|
}
|
|
|
|
|
|
|
|
UINT8 HowManyItemsToReorder(UINT8 ubWanted, UINT8 ubStillHave)
|
|
{
|
|
UINT8 ubNumReordered;
|
|
DebugMsg(TOPIC_JA2, DBG_LEVEL_3,String("HowManyItemsToReorder: wanted = %d, still have = %d",ubWanted, ubStillHave));
|
|
|
|
Assert(ubStillHave <= ubWanted);
|
|
|
|
ubNumReordered = ubWanted - ubStillHave;
|
|
|
|
//randomize the amount. 33% of the time we add to it, 33% we subtract from it, rest leave it alone
|
|
switch (Random(3))
|
|
{
|
|
case 0:
|
|
ubNumReordered += ubNumReordered / 2;
|
|
break;
|
|
case 1:
|
|
ubNumReordered -= ubNumReordered / 2;
|
|
break;
|
|
}
|
|
|
|
DebugMsg(TOPIC_JA2, DBG_LEVEL_3,String("HowManyBRItemsToOrder: reordered = %d",ubNumReordered));
|
|
return(ubNumReordered);
|
|
}
|
|
|
|
|
|
|
|
int BobbyRayItemQsortCompare(const void *pArg1, const void *pArg2)
|
|
{
|
|
UINT16 usItem1Index;
|
|
UINT16 usItem2Index;
|
|
UINT8 ubItem1Quality;
|
|
UINT8 ubItem2Quality;
|
|
|
|
usItem1Index = ( ( STORE_INVENTORY * ) pArg1 ) -> usItemIndex;
|
|
usItem2Index = ( ( STORE_INVENTORY * ) pArg2 ) -> usItemIndex;
|
|
|
|
ubItem1Quality = ( ( STORE_INVENTORY * ) pArg1 ) -> ubItemQuality;
|
|
ubItem2Quality = ( ( STORE_INVENTORY * ) pArg2 ) -> ubItemQuality;
|
|
|
|
return( CompareItemsForSorting( usItem1Index, usItem2Index, ubItem1Quality, ubItem2Quality ) );
|
|
}
|
|
|
|
|
|
|
|
int ArmsDealerItemQsortCompare(const void *pArg1, const void *pArg2)
|
|
{
|
|
UINT16 usItem1Index;
|
|
UINT16 usItem2Index;
|
|
UINT8 ubItem1Quality;
|
|
UINT8 ubItem2Quality;
|
|
|
|
usItem1Index = ( ( INVENTORY_IN_SLOT * ) pArg1 ) -> sItemIndex;
|
|
usItem2Index = ( ( INVENTORY_IN_SLOT * ) pArg2 ) -> sItemIndex;
|
|
|
|
ubItem1Quality = ( ( INVENTORY_IN_SLOT * ) pArg1 ) -> ItemObject.ItemData.Generic.bStatus[ 0 ];
|
|
ubItem2Quality = ( ( INVENTORY_IN_SLOT * ) pArg2 ) -> ItemObject.ItemData.Generic.bStatus[ 0 ];
|
|
|
|
return( CompareItemsForSorting( usItem1Index, usItem2Index, ubItem1Quality, ubItem2Quality ) );
|
|
}
|
|
|
|
|
|
|
|
int RepairmanItemQsortCompare(const void *pArg1, const void *pArg2)
|
|
{
|
|
INVENTORY_IN_SLOT* pInvSlot1;
|
|
INVENTORY_IN_SLOT* pInvSlot2;
|
|
UINT32 uiRepairTime1;
|
|
UINT32 uiRepairTime2;
|
|
|
|
|
|
pInvSlot1 = ( INVENTORY_IN_SLOT * ) pArg1;
|
|
pInvSlot2 = ( INVENTORY_IN_SLOT * ) pArg2;
|
|
|
|
Assert( pInvSlot1->sSpecialItemElement != -1);
|
|
Assert( pInvSlot2->sSpecialItemElement != -1);
|
|
|
|
uiRepairTime1 = gArmsDealersInventory[ gbSelectedArmsDealerID ][ pInvSlot1->sItemIndex ].SpecialItem[ pInvSlot1->sSpecialItemElement ].uiRepairDoneTime;
|
|
uiRepairTime2 = gArmsDealersInventory[ gbSelectedArmsDealerID ][ pInvSlot2->sItemIndex ].SpecialItem[ pInvSlot2->sSpecialItemElement ].uiRepairDoneTime;
|
|
|
|
|
|
// lower reapir time first
|
|
if ( uiRepairTime1 < uiRepairTime2 )
|
|
{
|
|
return( -1 );
|
|
}
|
|
else
|
|
if ( uiRepairTime1 > uiRepairTime2 )
|
|
{
|
|
return( 1 );
|
|
}
|
|
else
|
|
{
|
|
return( 0 );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int CompareItemsForSorting( UINT16 usItem1Index, UINT16 usItem2Index, UINT8 ubItem1Quality, UINT8 ubItem2Quality )
|
|
{
|
|
UINT8 ubItem1Category;
|
|
UINT8 ubItem2Category;
|
|
//UINT16 usItem1Price;
|
|
//UINT16 usItem2Price;
|
|
//UINT8 ubItem1Coolness;
|
|
//UINT8 ubItem2Coolness;
|
|
|
|
ubItem1Category = GetDealerItemCategoryNumber( usItem1Index );
|
|
ubItem2Category = GetDealerItemCategoryNumber( usItem2Index );
|
|
|
|
// lower category first
|
|
if ( ubItem1Category < ubItem2Category )
|
|
{
|
|
return( -1 );
|
|
}
|
|
else
|
|
if ( ubItem1Category > ubItem2Category )
|
|
{
|
|
return( 1 );
|
|
}
|
|
else
|
|
{
|
|
// the same category
|
|
//if ( Item[ usItem1Index ].usItemClass == IC_AMMO && Item[ usItem2Index ].usItemClass == IC_AMMO )
|
|
//{
|
|
//UINT8 ubItem1Calibre;
|
|
//UINT8 ubItem2Calibre;
|
|
//UINT8 ubItem1MagSize;
|
|
//UINT8 ubItem2MagSize;
|
|
|
|
// AMMO is sorted by caliber first
|
|
//ubItem1Calibre = Magazine[ Item[ usItem1Index ].ubClassIndex ].ubCalibre;
|
|
//ubItem2Calibre = Magazine[ Item[ usItem2Index ].ubClassIndex ].ubCalibre;
|
|
//if ( ubItem1Calibre > ubItem2Calibre )
|
|
//{
|
|
// return( -1 );
|
|
//}
|
|
//else
|
|
//if ( ubItem1Calibre < ubItem2Calibre )
|
|
//{
|
|
// return( 1 );
|
|
//}
|
|
//// the same caliber - compare size of magazine, then fall out of if statement
|
|
//ubItem1MagSize = Magazine[ Item[ usItem1Index ].ubClassIndex ].ubMagSize;
|
|
//ubItem2MagSize = Magazine[ Item[ usItem2Index ].ubClassIndex ].ubMagSize;
|
|
//if ( ubItem1MagSize > ubItem2MagSize )
|
|
//{
|
|
// return( -1 );
|
|
//}
|
|
//else
|
|
//if ( ubItem1MagSize < ubItem2MagSize )
|
|
//{
|
|
// return( 1 );
|
|
//}
|
|
//}
|
|
//else
|
|
//{
|
|
// items other than ammo are compared on coolness first
|
|
//ubItem1Coolness = Item[ usItem1Index ].ubCoolness;
|
|
//ubItem2Coolness = Item[ usItem2Index ].ubCoolness;
|
|
|
|
//// higher coolness first
|
|
//if ( ubItem1Coolness > ubItem2Coolness )
|
|
//{
|
|
// return( -1 );
|
|
//}
|
|
//else
|
|
//if ( ubItem1Coolness < ubItem2Coolness )
|
|
//{
|
|
// return( 1 );
|
|
//}
|
|
//}
|
|
|
|
// the same coolness/caliber - compare base prices then
|
|
//usItem1Price = Item[ usItem1Index ].usPrice;
|
|
//usItem2Price = Item[ usItem2Index ].usPrice;
|
|
|
|
//// higher price first
|
|
//if ( usItem1Price > usItem2Price )
|
|
//{
|
|
// return( -1 );
|
|
//}
|
|
//else
|
|
//if ( usItem1Price < usItem2Price )
|
|
//{
|
|
// return( 1 );
|
|
//}
|
|
//else
|
|
//{
|
|
// the same price - compare item #s, then
|
|
|
|
//// lower index first
|
|
//if ( usItem1Index < usItem2Index )
|
|
//{
|
|
// return( -1 );
|
|
//}
|
|
//else
|
|
//if ( usItem1Index > usItem2Index )
|
|
//{
|
|
// return( 1 );
|
|
//}
|
|
|
|
//Madd: sort by name (for now at least):
|
|
if (_wcsicmp(Item[usItem1Index].szBRName,Item[usItem2Index].szBRName) < 0 )
|
|
return -1;
|
|
else if (_wcsicmp(Item[usItem1Index].szBRName,Item[usItem2Index].szBRName) > 0 )
|
|
return 1;
|
|
else
|
|
{
|
|
// same item type = compare item quality, then
|
|
|
|
// higher quality first
|
|
if ( ubItem1Quality > ubItem2Quality )
|
|
{
|
|
return( -1 );
|
|
}
|
|
else
|
|
if ( ubItem1Quality < ubItem2Quality )
|
|
{
|
|
return( 1 );
|
|
}
|
|
else
|
|
{
|
|
// identical items!
|
|
return( 0 );
|
|
}
|
|
}
|
|
//}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
UINT8 GetDealerItemCategoryNumber( UINT16 usItemIndex )
|
|
{
|
|
UINT32 uiItemClass;
|
|
UINT8 ubWeaponClass;
|
|
UINT8 ubCategory = 0;
|
|
|
|
|
|
uiItemClass = Item[ usItemIndex ].usItemClass;
|
|
|
|
if ( usItemIndex < MAXITEMS && IsWeapon(usItemIndex) )
|
|
{
|
|
ubWeaponClass = 0;// Madd: commented out so we can sort guns by name instead ... Weapon[ usItemIndex ].ubWeaponClass;
|
|
}
|
|
else
|
|
{
|
|
// not a weapon, so no weapon class, this won't be needed
|
|
ubWeaponClass = 0;
|
|
}
|
|
|
|
|
|
ubCategory = 0;
|
|
|
|
// search table until end-of-list marker is encountered
|
|
while ( DealerItemSortInfo[ ubCategory ].uiItemClass != IC_NONE )
|
|
{
|
|
if ( DealerItemSortInfo[ ubCategory ].uiItemClass == uiItemClass )
|
|
{
|
|
// if not a type of gun
|
|
if ( uiItemClass != IC_GUN )
|
|
{
|
|
// then we're found it
|
|
return ( ubCategory );
|
|
}
|
|
else
|
|
{
|
|
// for guns, must also match on weapon class
|
|
if ( DealerItemSortInfo[ ubCategory ].ubWeaponClass == ubWeaponClass )
|
|
{
|
|
// then we're found it
|
|
return ( ubCategory );
|
|
}
|
|
}
|
|
}
|
|
|
|
// check vs. next category in the list
|
|
ubCategory++;
|
|
}
|
|
|
|
// WANNE: commented the assert out, because we always get the assertion in debug mode!
|
|
// should never be trying to locate an item that's not covered in the table!
|
|
//Assert( FALSE );
|
|
return( 0 );
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN CanDealerItemBeSoldUsed( UINT16 usItemIndex )
|
|
{
|
|
// if ( !( Item[ usItemIndex ].fFlags & ITEM_DAMAGEABLE ) )
|
|
if ( !( Item[ usItemIndex ].damageable ) )
|
|
return(FALSE);
|
|
|
|
// certain items, although they're damagable, shouldn't be sold in a used condition
|
|
return( DealerItemSortInfo[ GetDealerItemCategoryNumber( usItemIndex ) ].fAllowUsed );
|
|
}
|