// TRADER MENU SYSTEM
#library "TRADMENU"
#import "traderlist.acs"
#import "zt2functions.acs"
#include "zcommon.acs"

#define SWAP_DELAY					35

#define LIST_SIDE_WIDTH 256.0
#define LIST_SIDE_PADDING 48.0
#define LIST_SIDE_HEIGHT 32.0

#define HEADER_WIDTH				336.0
#define SIDETAB_WIDTH				168.0

#define TABLEFT_ID					1750
#define TABRIGHT_ID					1751
#define TAB_WIDTH 					168.0
#define TAB_HEIGHT					32.0

#define LID_BACKGROUND 				1100
#define LID_ITEMS 					1000
#define LID_TAGS					950
#define LID_TAGLABEL				900

#define LID_BACKGROUNDR 			1500
#define LID_ITEMSR 					1400
#define LID_TAGSR					1350
#define LID_TAGLABELR				1300

#define LID_BLACK					1800

#define LID_TOOLTIP					850
#define LID_TOOLTIPTEXT				800

#define LID_BUTTONS					1700

#define TOOLTIP_MINHEIGHT			256.0
#define TOOLTIP_WIDTH				336.0

#define PERKTAB_WIDTH				27.0
#define PERKTAB_HEIGHT				24.0
#define PERKTAB_PADDING				24.0

// Sell box
#define LEFTBOX_MINX 55.0 				// Left X
#define LEFTBOX_MAXX 230.0 			// Right X
#define LEFTBOX_MINY 83.0 				// Top Y
#define LEFTBOX_MAXY 544.0 			// Bottom Y

// Upgrade box
#define UPGRADEBOX_MINX 391.0 				// Left X
#define UPGRADEBOX_MAXX 744.0 			// Right X
#define UPGRADEBOX_MINY 83.0 				// Top Y
#define UPGRADEBOX_MAXY 464.0 			// Bottom Y

#define ALIGN_CENTER 0.4
#define ALIGN_CENTER_Y 0.0
#define ALIGN_LEFT 0.1
#define ALIGN_RIGHT 0.2

//===========================================
// PERK BUTTONS
//===========================================

#define PERK_IDBASE			5
#define PERK_XSTART			571.0				// Perk X
#define PERK_YSTART			52.0				// Perk Y

#define PERK_WIDTH			24.0				// How big a button is
#define PERK_HEIGHT			27.0				// How big a button is

#define TOTAL_PERKS			5

#define PD_DISPLAY			0
#define PD_ITEM				1
#define PD_ICON				2
#define PD_ICONBIG			3
#define PD_DESCRIPTION		4

str perkData[TOTAL_PERKS][5] = {
	{"Juggernaut", "Perk_Juggernaut", "TRADICO1", "TPRKSUPP", "\cKLock and load.\n\cJShotgun types designed for close range."},
	{"Commando", "Perk_Commando", "TRADICO2", "TPRKCOMM", "\cKSpray and pray.\n\cJWeapons designed for ranged or close combat."},
	{"Demolitionist","Perk_Demo", "TRADICO3", "TPRKDEMO", "\cKBoom boom.\n\cJExplosive weapons designed for splash combat."},
	{"Rifleman","Perk_Rifleman", "TRADICO4", "TPRKSHAR", "\cKHeadshot time.\n\cJSniper and pistol weapons designed for a mix."},
	{"Pyromaniac","Perk_Pyro", "TRADICO5", "TPRKFIRE", "\cKToasting time!\n\cJIncendiary weapons to burn enemies."},
};

#define PERKBUTTON_FRAMES	3
str perkButtonImages[PERKBUTTON_FRAMES] = {
	"PERKBUT1",
	"PERKBUT2",
	"PERKBUT3",
};

#define BUTTON_COUNTER 3
#define BUTTON_WIDTH 88.0
#define BUTTON_HEIGHT 32.0
str bottomButtons[BUTTON_COUNTER][5] = {
	{"RESTOCK1","RESTOCK2","Restock","Refills the ammo for all of your weapons.","ICONAMMO"},
	{"GETARMR1","GETARMR2","Get Armor","Grants a suit of armor for extra protection.","ICONARMR"},
	{"EXITMEN1","EXITMEN2","Exit Menu","Returns to regular Zombie Torrent 2 gameplay.","ICONEXIT"},
};

//===========================================

// Purchase box
#define RIGHTBOX_MINX 570.0
#define RIGHTBOX_MAXX 745.0
#define RIGHTBOX_MINY 83.0
#define RIGHTBOX_MAXY 544.0

// Left button
#define BUTTON1_MINX 246.0
#define BUTTON1_MAXX 332.0
#define BUTTON1_MINY 508.0
#define BUTTON1_MAXY 538.0

// Middle button
#define BUTTON2_MINX 360.0
#define BUTTON2_MAXX 445.0
#define BUTTON2_MINY 508.0
#define BUTTON2_MAXY 538.0

// Right button
#define BUTTON3_MINX 470.0
#define BUTTON3_MAXX 555.0
#define BUTTON3_MINY 508.0
#define BUTTON3_MAXY 538.0

// Left button - Cat2
#define CBUTTON1_MINX 426.0
#define CBUTTON1_MAXX 512.0
#define CBUTTON1_MINY 508.0
#define CBUTTON1_MAXY 538.0

// Middle button - Cat2
#define CBUTTON2_MINX 540.0
#define CBUTTON2_MAXX 625.0
#define CBUTTON2_MINY 508.0
#define CBUTTON2_MAXY 538.0

// Right button - Cat2
#define CBUTTON3_MINX 650.0
#define CBUTTON3_MAXX 736.0
#define CBUTTON3_MINY 508.0
#define CBUTTON3_MAXY 538.0

// Top Category Button
#define CATEGORY1_MINX 750.0
#define CATEGORY1_MAXX 782.0
#define CATEGORY1_MINY 453.0
#define CATEGORY1_MAXY 500.0

// Bottom Category Button
#define CATEGORY2_MINX 750.0
#define CATEGORY2_MAXX 782.0
#define CATEGORY2_MINY 500.0
#define CATEGORY2_MAXY 546.0

function int abs (int x)
{
    if (x < 0)
        return -x;

    return x;
}

// Returns fixed point value
function int floor(int fixedNumber)
{
	return fixedNumber & 0xFFFF0000;
}

// PUKED WHEN USING TRADER //
script 250 (int mode)
{
	switch (mode)
	{
		case 0:
		if (!CheckInventory("MenuActive"))
		{
		SetActorProperty(0,APROP_Invulnerable,1);
		SetPlayerProperty(0,1,4);
		SetPlayerProperty(0,1,1);
		SetPlayerProperty(0,1,7);
		GiveInventory("WepToApply",1);

		ACS_ExecuteAlways(701,0,0,0,0);
		GiveInventory("MenuActive",1);
		GiveInventory("MenuWeapon",1);
		SetWeapon("MenuWeapon");
		}
		break;

		case 1:
		SetActorProperty(0,APROP_Invulnerable,0);
		SetPlayerProperty(0,0,4);
		SetPlayerProperty(0,0,1);
		SetPlayerProperty(0,0,7);
		TakeInventory("MenuActive",1);
		TakeInventory("TraderCategory",2);
		TakeInventory("WepToApply",99);
		TakeInventory("MenuWeapon",1);
		break;
	}
}

#define LEVEL_DISCOUNT_AMOUNT		100

//=========================================================================
// WEAPON UPGRADES
//=========================================================================

#define SU_NAME				0
#define SU_SUFFIX			1
#define SU_ACTOR			2
#define SU_BUYPIC			3
#define SU_INFO				4
#define SU_PREVIEW			5

#define SHOP_UPGRADECOUNT 6

str ShopUpgrades[SHOP_UPGRADECOUNT][6] = {

		// STEN - SILENCER
		{
		"Silencer",
		"Silencer",
		"Sten MK II",
		"BUYPIC03",
		"Silencers are good for keeping your guns quiet.",
		"ZTSCREN2",
		},

		// LOBOTOMIZER - THERMAL SCOPE
		{
		"Thermal Scope",
		"Thermal",
		"Zed's Lobotomizer",
		"BUYPIC04",
		"Thermal scopes are good for seeing things in the dark.",
		"ZTSCREN3",
		},

		// PUMP SHOTGUN - DRAGON'S BREATH
		{
		"Dragon's Breath",
		"Dragon",
		"Pump Shotgun",
		"BUYPIC04",
		"Dragon's Breath Ammo is good for fucking enemies up.",
		"ZTSCREN4",
		},
		
		// M79 - INCENDIARY AMMO
		{
		"Incendiary Grenades",
		"Incendiary",
		"M79 Grenade Launcher",
		"BUYPIC04",
		"Incendiary grenades can cause dangerous, large fires from\na great distance. Especially shot from an M79.",
		"ZTSCREN5",
		},
		
		// M79 - INCENDIARY AMMO
		{
		"Buckshot Grenades",
		"Shotgun",
		"M79 Grenade Launcher",
		"BUYPIC04",
		"Buckshot grenades can be used to turn the M79 into a\nfull-on shotgun. Functions like a normal shotgun would.",
		"ZTSCREN6",
		},
		
		// ORDER PISTOL - EXPLOSIVE AMMO
		{
		"Explosive Ammo",
		"Explosive",
		"Order Pistol",
		"BUYPIC04",
		"A few magazines of explosive ammunition can go a\nlong way. Rigged especially for the Order Pistol.",
		"ZTSCREN7",
		},
};

#define SP_PRICE					0
#define SP_WEP						1

int ShopUpgradePrices[SHOP_UPGRADECOUNT] = { 
	400, 		// Silencer 			(Sten)
	600, 		// Thermal Scope 		(Lobotomizer)
	1000, 		// Dragon's Breath		(Pump Shotgun)
	1500,		// Incendiary Nades		(M79)
	1500,		// Shotgun nades		(M79)
	2500,		// Explosive Ammo		(Order Pistol)
};
str TradButImages[4] = { "TRADBUT1", "TRADBUT2", "TRADBUT3", "TRADBUT4" };
str BackgroundImages[2] = { "ZTTRADER", "ZTUPGRAD" };
str CategoryImages[3] = { "CATEG1", "CATEG3", "CATEG2" };

script 879 (void)
{
	Print(s:"availableWeapons is ",d:availableWeapons);
}

// Actual menu script
script 701 (void) CLIENTSIDE
{

	int cursor;
	int mouse_x;
	int mousex_var;
	int mouse_y;
	int mousey_var;
	int buttons;
	int wait;
	int IsSelling;
	int IsBuying;
	int colortodraw;
	int buttonimg;
	int IsUpgrading;
	int weptoapply;
	int buttonHover;
	int tabHover;
	int topTabHover;
	
	int swapper;
	int showMoney;
	
	// BUY MODE: Perk filter
	// UPGRADE MODE: Selected weapon
	int currentTab = 0;
	int currentTabHover = -1;
	
	int discountAmount = 0;

	int tradercategory;
	
	int listY;

	str moneycolor;
	str itemColor;

	moneycolor = "\cJ$";

	buttons = GetPlayerInput(-1, INPUT_BUTTONS);

	wait=CheckInventory("Waiting");
	colortodraw = CR_BLACK;

	int hover;

	cursor=CheckInventory("MenuCursor");
	mouse_x = CheckInventory("MouseX");
	mouse_y = CheckInventory("MouseY");
	
	LocalAmbientSound("trader/hello",128);

	int categoryicon;
	
	// SELECTION
	int selectUpper = 0;
	int selectUpperR = 0;
	
	// Probably not even used
	int selectLower = 1;
	
	int listCounter = 0;
	
	int shadWidth;

	while (CheckInventory("MenuActive") )
	{
			swapper ++;
			
			if (swapper >= SWAP_DELAY)
			{
				swapper = 0;
				
				if (showMoney)
					showMoney = 0;
				else
					showMoney = 1;
			}
			
			// Perk discount
			discountAmount = LEVEL_DISCOUNT_AMOUNT*CheckInventory("PerkLevel");

			shadWidth = GetCVar("vid_defwidth") / 256;

			SetFont("BLAKNESS");
			for (int l=0; l<shadWidth; l++)
			{
			// HudMessage(s:"a"; HUDMSG_PLAIN, LID_BLACK+l, CR_WHITE, 0.1, 0.1, 0.0);
			HMUSRedux(512.0*l,0.0,"a",0,0,LID_BLACK+l,0.0,1);
			}
			
			SetHudSize(GetCVar("vid_defwidth"),GetCVar("vid_defheight"),1);
			
			// Do menu item shit
			cursor=0;

			//TakeInventory("MouseX",800);
			//TakeInventory("MouseY",800);

			buttons = GetPlayerInput(-1, INPUT_BUTTONS);
			
			//- - - - - - - - - - - - - - 
			//
			// B O T T O M   B U T T O N S
			//
			//- - - - - - - - - - - - - - 
			
			int bWidth = FixedDiv(GetCVar("vid_defwidth")*1.0,(BUTTON_COUNTER+1)*1.0); 
			int buttonX;
			int buttonY;
			int bWidthTwo = FixedDiv(BUTTON_WIDTH,2.0);
			
			buttonHover = -1;
			
			for (int bb=0; bb<BUTTON_COUNTER; bb++)
			{
				//HMUSRedux(FixedMul(bWidth,(bb+1)*1.0),64.0,"a",1,2,LID_BUTTONS+bb,2.0,1);
				buttonX = FixedMul(bWidth,(bb+1)*1.0);
				buttonY = (GetCVar("vid_defheight")*1.0)-16.0;
					
				if (CursorIsOverX(buttonX-bWidthTwo,buttonX+bWidthTwo) && CursorIsOverY(buttonY-BUTTON_HEIGHT,buttonY))
				{
					buttonHover = bb;
					SetFont(bottomButtons[bb][1]);
				}
				else
					SetFont(bottomButtons[bb][0]);
					
				HMUSRedux(buttonX,buttonY,"a",1,2,LID_BUTTONS+bb,2.0,1);
			}
			
			int centerX = FixedDiv(GetCVar("vid_defwidth")*1.0,2.0);
			int centerY = FixedDiv(GetCVar("vid_defheight")*1.0,2.0);
			
			//- - - - - - - - - - - - - - 
			//
			// T O P   T A B S
			//
			//- - - - - - - - - - - - - - 
			
			int tabWidthTwo = FixedDiv(TAB_WIDTH,2.0);
			topTabHover = -1;
			
			// -- LEFT TAB --
			if (CursorIsOverX(centerX-TAB_WIDTH,centerX) && CursorIsOverY(26.0,26.0+TAB_HEIGHT))
			{
				SetFont("FIRETAB2");
				topTabHover = 0;
			}
			else
			{
				if (CheckInventory("TraderCategory") == 0)
					SetFont("FIRETAB3");
				else
					SetFont("FIRETAB1");
			}
			
			HMUSRedux(centerX-tabWidthTwo,26.0,"a",1,0,TABLEFT_ID,1.0,1);
			
			// -- RIGHT TAB --
			if (CursorIsOverX(centerX,centerX+TAB_WIDTH) && CursorIsOverY(26.0,26.0+TAB_HEIGHT))
			{
				SetFont("UPGRTAB2");
				topTabHover = 1;
			}
			else
			{
				if (CheckInventory("TraderCategory") == 1)
					SetFont("UPGRTAB3");
				else
					SetFont("UPGRTAB1");
			}
			
			HMUSRedux(centerX+tabWidthTwo,26.0,"a",1,0,TABRIGHT_ID,1.0,1);

			///////////////////////////////////////////////////////////////////////
			// -- CONTROL THE MENU BASED ON THE CATEGORY ITEM -- //
			///////////////////////////////////////////////////////////////////////
			// HMUSRedux (int xoffset, int yoffset, str text, int alignx, int aligny, int id, int showtime, int side)
			
			// How big is our selection range? 5 for testing
			//int selectRange = 5;
			
			int selectRange = 0;
			int priceX = 0;
			int exclude = 0;
			
			int listLeftX;
			int listRightX;
			
			/*
			// Draw the header
			if (showMoney)
			{
				SetFont("BIGFONT");
				HMUSRedux(centerX,13.0,StrParam(s:"\cJYou have: $",d:CheckInventory("Money")),1,1,LID_BACKGROUND-2,5.0,1);
				SetFont("TSIDE5");
			}
			else
			{
				HMUSRedux(centerX,0.0,"",1,0,LID_BACKGROUND-2,5.0,1);
				SetFont("TSIDE4");
			}	
			*/
			
			SetFont("TSIDE4");
			HMUSRedux(centerX,0.0,"a",1,0,LID_BACKGROUND-1,5.0,1);
			
			// Draw left and right info boxes
			SetFont("SIDETAB1");
			HMUSRedux(centerX - FixedDiv(HEADER_WIDTH,2.0) - SIDETAB_WIDTH,0.0,"a",0,0,LID_BACKGROUND-2,5.0,1);
			SetFont("SIDETAB2");
			HMUSRedux(centerX + FixedDiv(HEADER_WIDTH,2.0),0.0,"a",0,0,LID_BACKGROUND-3,5.0,1);
			
			SetFont("BIGFONT");
			// YOU HAVE AND TIME
			// CALCULATE SHIT
			// it_tradertime = CheckInventory("HUDDummy_Trader");
			int timeMinutes = GetMinutes();
			int timeSeconds = GetSeconds();
			
			HMUSRedux(centerX - FixedDiv(HEADER_WIDTH,2.0) - 8.0,13.0,StrParam(s:"\cJ$",d:CheckInventory("Money")),2,1,LID_BACKGROUND-4,5.0,1);
			HMUSRedux(centerX + FixedDiv(HEADER_WIDTH,2.0) + 8.0,13.0,StrParam(s:timeMinutes,s:":",s:timeSeconds),0,1,LID_BACKGROUND-5,5.0,1);
			
			SetFont("SMALLFONT");
			
			// -- L E F T   A N D   R I G H T   L I S T S --
			int listSideHeight = FixedDiv(GetCVar("vid_defheight")*1.0,LIST_SIDE_HEIGHT) - 2.0;
			int listStartY = centerY - FixedDiv(FixedMul(LIST_SIDE_HEIGHT,listSideHeight),2.0) + 40.0;
			int listLeftY = centerY;
					
			int listWidthTwo = FixedDiv(LIST_SIDE_WIDTH,2.0);
			
			int listLeftMSGX = listLeftX - (FixedDiv(LIST_SIDE_WIDTH,2.0) - 16.0);
			int listRightMSGX = listRightX - (FixedDiv(LIST_SIDE_WIDTH,2.0) - 16.0);
					
			listSideHeight = listSideHeight-3.0;
					
			selectRange = listSideHeight >> 16;
			
			int q = 0.0;
			int successes = -1;
			
			//- - - - - - - - - - - - - - 
			//
			// S E L L   L I S T
			//
			//- - - - - - - - - - - - - - 
					listLeftX = FixedDiv(LIST_SIDE_WIDTH,2.0) + LIST_SIDE_PADDING;
					
					listCounter = 0;
					// Background
					for (q=0.0; q<listSideHeight; q+= 1.0)
					{
						HMUSRedux(listLeftX,listStartY,"",0,1,LID_ITEMS+(q >> 16),5.0,1);
						HMUSRedux(listLeftX,listStartY,"",0,1,LID_TAGS+(q >> 16),5.0,1);
						HMUSRedux(listLeftX,listStartY,"",0,1,LID_TAGLABEL+(q >> 16),5.0,1);
						
						if (q==0.0)
							SetFont("TSIDE1");
						else if (q >= listSideHeight-1.0)
							SetFont("TSIDE2");
						else
							SetFont("TSIDE3");
							
						HMUSRedux(listLeftX,listStartY+FixedMul(LIST_SIDE_HEIGHT,q),"a",1,1,LID_BACKGROUND+listCounter,5.0,1);
						
						// Draw sell pic?
						if (q >= listSideHeight-1.0)
						{
							if (CheckInventory("TraderCategory") <= 0)
								SetFont("TSINSELL");
							else
								SetFont("TSINOWND");
							HMUSRedux(listLeftX-FixedDiv(LIST_SIDE_WIDTH,2.0),listStartY+FixedMul(LIST_SIDE_HEIGHT,q+1.0),"a",0,1,LID_BACKGROUND+listCounter+1,5.0,1);
						}
						
						SetFont("SMALLFONT");
						
						listCounter ++;
					}
					
					SetFont("LADYDETH");
					listCounter = 0;
					cursor = -1;
					
					// Items
					for (q=selectUpper; q<500; q++)
					{
						exclude = 0;
						
						HMUSRedux(listLeftMSGX,listStartY+FixedMul(LIST_SIDE_HEIGHT,listCounter*1.0),"",0,1,LID_ITEMS+listCounter,5.0,1);
						
						if (q < 0)
							continue;
							
						if (q >= availableWeapons || listCounter >= selectRange-1)
							break;
							
						// Exclude this item from the list?
						if (traderHidden[q] || (!CheckInventory(traderActorName[q]) && !CheckInventory(traderDualVariant[q])))
							exclude = 1;
							
						if (!exclude)
						{
							// ARE WE MOUSING OVER THIS ITEM?
							listY = listStartY+8.0+FixedMul(LIST_SIDE_HEIGHT,listCounter*1.0);
							
							if (OptionHovered(listY,listLeftX))
								cursor = q;
								
							// -- IS THIS ITEM SELECTED? --
							if (cursor == q && OptionHovered(listY,listLeftX))
							{
								itemColor = "\cK";
							}
							else
							{
								// Check to see if we own this item
								if (CheckInventory(traderActorName[q]) || CheckInventory(traderDualVariant[q]))
									itemColor = "\cJ";
								else
									itemColor = "\cM";
							}
								
							// Draw the display name
							SetFont("LADYDETH");
							HMUSRedux(listLeftMSGX,listY,StrParam(s:itemColor,s:GetWepName(q,0)),0,1,LID_ITEMS+listCounter,5.0,1);
							
							priceX = listLeftX+(FixedDiv(LIST_SIDE_WIDTH,2.0) - 2.0);
							
							// Draw the appropriate price tag
							SetFont("PRICETAG");
							HMUSRedux(priceX,listY,"a",0,1,LID_TAGS+listCounter,5.0,1);
							
							// Draw the label
							SetFont("PRICFONT");
							HMUSRedux(priceX+4.0,listY,StrParam(s:"\cM$",d:traderPrice[q]),0,1,LID_TAGLABEL+listCounter,5.0,1);
							
							listCounter ++;
						}
					}
			
			// -- DRAW LISTS --
			switch (CheckInventory("TraderCategory"))
			{
				//--================================================================
				// - - B U Y I N G   W E A P O N S - -
				//--================================================================
				case 0:
	
				//- - - - - - - - - - - - - - 
				//
				// B U Y   L I S T
				//
				//- - - - - - - - - - - - - - 
					listRightX = (GetCVar("vid_defwidth")*1.0) - (FixedDiv(LIST_SIDE_WIDTH,2.0) + LIST_SIDE_PADDING);
					
					listCounter = 0;
					// Background
					for (q=0.0; q<listSideHeight; q+= 1.0)
					{
						HMUSRedux(listRightX,listStartY,"",0,1,LID_ITEMSR+(q >> 16),5.0,1);
						HMUSRedux(listRightX,listStartY,"",0,1,LID_TAGSR+(q >> 16),5.0,1);
						HMUSRedux(listRightX,listStartY,"",0,1,LID_TAGLABELR+(q >> 16),5.0,1);
						
						if (q==0.0)
							SetFont("TSIDE1");
						else if (q >= listSideHeight-1.0)
							SetFont("TSIDE2");
						else
							SetFont("TSIDE3");
							
						HMUSRedux(listRightX,listStartY+FixedMul(LIST_SIDE_HEIGHT,q),"a",1,1,LID_BACKGROUNDR+listCounter,5.0,1);
						
						// Draw buy pic?
						if (q >= listSideHeight-1.0)
						{
							SetFont("TSINBUY");
							HMUSRedux(listRightX+FixedDiv(LIST_SIDE_WIDTH,2.0),listStartY+FixedMul(LIST_SIDE_HEIGHT,q+1.0),"a",2,1,LID_BACKGROUNDR+listCounter+1,5.0,1);
						}
						
						SetFont("SMALLFONT");
						
						listCounter ++;
					}		
					SetFont("LADYDETH");
					
					listCounter = 0;
					successes = -1;
					// Items
					for (q=0; q<750; q++)
					{
						exclude = 0;
						
						HMUSRedux(listRightMSGX,listStartY+FixedMul(LIST_SIDE_HEIGHT,listCounter*1.0),"",0,1,LID_ITEMSR+listCounter,5.0,1);
						
						if (q < 0)
							continue;
							
						if (q >= availableWeapons || listCounter >= selectRange-1)
							break;
							
						// Only exclude if we're in the wrong tab
						if (perkData[currentTab][PD_ITEM] != traderDiscountActor[q] || traderHidden[q])
							exclude = 1;
							
						if (!exclude)
						{
							successes ++;
							
							if (successes >= selectUpperR)
							{
							// ARE WE MOUSING OVER THIS ITEM?
							listY = listStartY+8.0+FixedMul(LIST_SIDE_HEIGHT,listCounter*1.0);
							
							if (OptionHovered(listY,listRightX))
								cursor = q;
								
							// -- IS THIS ITEM SELECTED? --
							if (cursor == q && OptionHovered(listY,listRightX))
							{
								itemColor = "\cK";
							}
							else
							{
								// Check to see if we can afford this item
								if (CheckInventory("Money") >= traderPrice[q])
									itemColor = "\cJ";
								else
									itemColor = "\cM";
							}
								
							// Draw the display name
							SetFont("LADYDETH");
							HMUSRedux(listRightMSGX,listY,StrParam(s:itemColor,s:GetWepName(q,1)),0,1,LID_ITEMSR+listCounter,5.0,1);
							
							priceX = listRightX - (FixedDiv(LIST_SIDE_WIDTH,2.0) - 2.0);
							
							// Draw the appropriate price tag
							SetFont("PRICETG2");
							HMUSRedux(priceX,listY,"a",2,1,LID_TAGSR+q,5.0,1);
							
							// Draw the label
							SetFont("PRICFONT");
							HMUSRedux(priceX-4.0,listY,StrParam(s:"\cM$",d:GetWeaponPrice(q)),2,1,LID_TAGLABELR+listCounter,5.0,1);
							
							listCounter ++;
							}
						}
					}
					
			
			
				//- - - - - - - - - - - - - - 
				//
				// P E R K   T A B S
				//
				//- - - - - - - - - - - - - - 
				//currentTab = -1;
				currentTabHover = -1;
				int perkY;
				
					for (int tq=0; tq<TOTAL_PERKS; tq++)
					{
						perkY = listStartY+16.0+FixedMul(tq*1.0,PERKTAB_HEIGHT+PERKTAB_PADDING);
						// Draw the button first
						// HOVERING OVER THIS BUTTON
						if (CursorIsOverX(listRightX+listWidthTwo,listRightX+listWidthTwo+PERKTAB_WIDTH) && CursorIsOverY(perkY-PERKTAB_HEIGHT,perkY))
						{
							SetFont("PERKBUT3");
							currentTabHover = tq;
						}
						// Not hovering
						else
						{
							if (currentTab == tq)
								SetFont("PERKBUT2");
							else
								SetFont("PERKBUT1");
						}
						HMUSRedux(listRightX+listWidthTwo,perkY,"a",0,2,PERK_IDBASE+(2*((TOTAL_PERKS-tq)+1)),2.0,1);
						SetFont(perkData[tq][PD_ICON]);
						HMUSRedux(listRightX+listWidthTwo,perkY,"a",0,2,PERK_IDBASE+(2*((TOTAL_PERKS-tq)+1))-1,2.0,1);
					}
			
				break;
				
				//--================================================================
				// - - B U Y I N G   U P G R A D E S = -
				//--================================================================
				case 1:
					//- - - - - - - - - - - - - - 
					//
					// U P G R A D E   L I S T
					//
					//- - - - - - - - - - - - - - 
					listRightX = (GetCVar("vid_defwidth")*1.0) - (FixedDiv(LIST_SIDE_WIDTH,2.0) + LIST_SIDE_PADDING);
					
					listCounter = 0;
					// Background
					for (q=0.0; q<listSideHeight; q+= 1.0)
					{
						HMUSRedux(listRightX,listStartY,"",0,1,LID_ITEMSR+(q >> 16),5.0,1);
						HMUSRedux(listRightX,listStartY,"",0,1,LID_TAGSR+(q >> 16),5.0,1);
						HMUSRedux(listRightX,listStartY,"",0,1,LID_TAGLABELR+(q >> 16),5.0,1);
						
						if (q==0.0)
							SetFont("TSIDE1");
						else if (q >= listSideHeight-1.0)
							SetFont("TSIDE2");
						else
							SetFont("TSIDE3");
							
						HMUSRedux(listRightX,listStartY+FixedMul(LIST_SIDE_HEIGHT,q),"a",1,1,LID_BACKGROUNDR+listCounter,5.0,1);
						
						// Draw buy pic?
						if (q >= listSideHeight-1.0)
						{
							SetFont("TSINUPGR");
							HMUSRedux(listRightX+FixedDiv(LIST_SIDE_WIDTH,2.0),listStartY+FixedMul(LIST_SIDE_HEIGHT,q+1.0),"a",2,1,LID_BACKGROUNDR+listCounter+1,5.0,1);
						}
						
						SetFont("SMALLFONT");
						
						listCounter ++;
					}
					
					SetFont("LADYDETH");
					
					listCounter = 0;
					successes = -1;
					// Items
					for (q=0; q<750; q++)
					{
						exclude = 0;
						
						HMUSRedux(listRightMSGX,listStartY+FixedMul(LIST_SIDE_HEIGHT,listCounter*1.0),"",0,1,LID_ITEMSR+listCounter,5.0,1);
						
						if (q < 0)
							continue;
							
						if (q >= SHOP_UPGRADECOUNT || listCounter >= selectRange-1)
							break;
							
						// Only exclude if we're in the wrong tab
						if (ShopUpgrades[q][SU_ACTOR] != traderActorName[currentTab])
							exclude = 1;
							
						if (!exclude)
						{
							successes ++;
							
							if (successes >= selectUpperR)
							{
							// ARE WE MOUSING OVER THIS ITEM?
							listY = listStartY+8.0+FixedMul(LIST_SIDE_HEIGHT,listCounter*1.0);
							
							if (OptionHovered(listY,listRightX))
								cursor = q;
								
							// -- IS THIS ITEM SELECTED? --
							if (cursor == q && OptionHovered(listY,listRightX))
							{
								itemColor = "\cK";
							}
							else
							{
								// Check to see if we can afford this item
								if (CheckInventory("Money") >= ShopUpgradePrices[q])
									itemColor = "\cJ";
								else
									itemColor = "\cM";
							}
								
							// Draw the display name
							SetFont("LADYDETH");
							HMUSRedux(listRightMSGX,listY,StrParam(s:itemColor,s:ShopUpgrades[q][SU_NAME]),0,1,LID_ITEMSR+listCounter,5.0,1);
							
							priceX = listRightX - (FixedDiv(LIST_SIDE_WIDTH,2.0) - 2.0);
							
							// Draw the appropriate price tag
							SetFont("PRICETG2");
							HMUSRedux(priceX,listY,"a",2,1,LID_TAGSR+q,5.0,1);
							
							// Draw the label
							SetFont("PRICFONT");
							HMUSRedux(priceX-4.0,listY,StrParam(s:"\cM$",d:ShopUpgradePrices[q]),2,1,LID_TAGLABELR+listCounter,5.0,1);
							
							listCounter ++;
							}
						}
					}
				break;
			}
			// End switch
			
			//- - - - - - - - - - - - - - 
			//
			// M A I N   T O O L T I P
			// If you're using less than 1024x768 then you're a cunt who
			// lives in the stone age, this won't look right at all
			//
			//- - - - - - - - - - - - - - 
			
			// Main thing is 75% of the list size
			//int mainHeight = FixedMul( FixedMul(listSideHeight,LIST_SIDE_HEIGHT) , 0.75 );
			
			// Main height shouldn't really be dynamically scaled, it's a tooltip
			int mainHeight = FixedMul(LIST_SIDE_HEIGHT,12.0);
			
			// Mousing over a perk tab
			if (currentTabHover > -1)
				mainHeight = FixedMul(LIST_SIDE_HEIGHT,8.0);
			// Mousing over a button
			if (buttonHover > -1)
					mainHeight = FixedMul(LIST_SIDE_HEIGHT,7.0);
				
			int tooltipX;
			
			if (GetMouseX() < centerX)
				tooltipX = GetMouseX() + FixedDiv(TOOLTIP_WIDTH,2.0) + 32.0;
			else
				tooltipX = GetMouseX() - (FixedDiv(TOOLTIP_WIDTH,2.0) + 32.0);
			
			int tooltipY;
			
			// Bottom-up
			if (GetMouseY() >= (GetCVar("vid_defheight")*1.0) - FixedDiv(mainHeight,2.0))
				tooltipY = GetMouseY() - mainHeight - 16.0;
			// Top-down
			else if (GetMouseY() <= FixedDiv(mainHeight,2.0))
				tooltipY = GetMouseY() + 16.0;
			// Centered
			else
				tooltipY = GetMouseY() - FixedDiv(mainHeight,2.0);
			

			int cc = 0;
			// Give some space for the header
			int mainY = 96.0;
			int ff=0;
			
			int showTip = 0;
			
			if (cursor >= 0 || currentTabHover > -1 || buttonHover > -1)
				showTip = 1;
				
			if (showTip)
			{
				for (ff=0.0; ff<mainHeight; ff += LIST_SIDE_HEIGHT)
				{
						if (ff == 0)
							SetFont("INFOBOX1");
						else if (ff >= mainHeight-LIST_SIDE_HEIGHT)
							SetFont("INFOBOX3");
						else
							SetFont("INFOBOX2");
							
						HMUSRedux(tooltipX,tooltipY+ff,"a",1,1,LID_TOOLTIP+cc,1.0,1);
						cc ++;
				}
			}
			
			for (ff=0.0; ff<mainHeight; ff += LIST_SIDE_HEIGHT)
			{
					HMUSRedux(tooltipX,tooltipY+ff,"",1,1,LID_TOOLTIP+cc,1.0,1);
					cc ++;
			}
			for (int fg=0; fg<10; fg++)
					HMUSRedux(tooltipX+241.0,tooltipY + 120.0,"",1,1,LID_TOOLTIPTEXT+fg,1.0,1);
			
			// Show a tooltip for an item in a list
			if (cursor >= 0)
			{
				str nameString;
				
				if (CheckInventory("TraderCategory") <= 0 || (CheckInventory("TraderCategory") == 1 && ListHovered(listLeftX)))
				{
					// -- WEAPON IMAGE --
					SetFont(traderBuyPicture[cursor]);
					HMUSRedux(tooltipX,tooltipY + 120.0,"a",0,0,LID_TOOLTIPTEXT,1.0,1);
					
					// -- WEAPON NAME --
					if (ListHovered(listRightX))
						nameString = StrParam(s:GetWepName(cursor,1));
					else
						nameString = StrParam(s:GetWepName(cursor,0));
					
					SetFont("BIGFONT");
					HMUSRedux(tooltipX+2.0,tooltipY + 200.0 + 2.0,StrParam(s:"\cM",s:nameString),1,1,LID_TOOLTIPTEXT+2,1.0,1);
					HMUSRedux(tooltipX,tooltipY + 200.0,StrParam(s:"\cJ",s:nameString),1,1,LID_TOOLTIPTEXT+1,1.0,1);
					
					// -- WEAPON DESCRIPTION
					SetFont("SMALLFONT");
					HMUSRedux(tooltipX,tooltipY + 245.0,StrParam(s:"\cJ",s:traderDescription[cursor]),1,0,LID_TOOLTIPTEXT+3,1.0,1);
					
					// -- WEAPON PRICE
					SetFont("BIGFONT");
					HMUSRedux(tooltipX+2.0,tooltipY + 225.0 + 2.0,StrParam(s:"\cM$",d:GetWeaponPrice(cursor)),1,1,LID_TOOLTIPTEXT+5,1.0,1);
					HMUSRedux(tooltipX,tooltipY + 225.0,StrParam(s:"\cD$",d:GetWeaponPrice(cursor)),1,1,LID_TOOLTIPTEXT+4,1.0,1);
				}
				
				// Show upgrade info
				else if (CheckInventory("TraderCategory") == 1 && ListHovered(listRightX))
				{
					// -- WEAPON IMAGE --
					SetFont(ShopUpgrades[cursor][SU_PREVIEW]);
					HMUSRedux(tooltipX,tooltipY + 120.0,"a",0,0,LID_TOOLTIPTEXT,1.0,1);
					
					// -- WEAPON NAME --
					nameString = StrParam(s:ShopUpgrades[cursor][SU_NAME]);
					
					SetFont("BIGFONT");
					HMUSRedux(tooltipX+2.0,tooltipY + 250.0 + 2.0,StrParam(s:"\cM",s:nameString),1,1,LID_TOOLTIPTEXT+2,1.0,1);
					HMUSRedux(tooltipX,tooltipY + 250.0,StrParam(s:"\cJ",s:nameString),1,1,LID_TOOLTIPTEXT+1,1.0,1);
					
					// -- WEAPON DESCRIPTION
					SetFont("SMALLFONT");
					HMUSRedux(tooltipX,tooltipY + 295.0,StrParam(s:"\cJ",s:ShopUpgrades[cursor][SU_INFO]),1,0,LID_TOOLTIPTEXT+3,1.0,1);
					
					// -- WEAPON PRICE
					SetFont("BIGFONT");
					HMUSRedux(tooltipX+2.0,tooltipY + 275.0 + 2.0,StrParam(s:"\cM$",d:ShopUpgradePrices[cursor]),1,1,LID_TOOLTIPTEXT+5,1.0,1);
					HMUSRedux(tooltipX,tooltipY + 275.0,StrParam(s:"\cD$",d:ShopUpgradePrices[cursor]),1,1,LID_TOOLTIPTEXT+4,1.0,1);
				}
			}
			// Perk tab image
			else if (currentTabHover > -1)
			{		
				// PERK NAME
				SetFont("BIGFONT");
				HMUSRedux(tooltipX+2.0,tooltipY + 160.0 + 2.0,StrParam(s:"\cM",s:perkData[currentTabHover][PD_DISPLAY]),1,1,LID_TOOLTIPTEXT+2,1.0,1);
				HMUSRedux(tooltipX,tooltipY + 160.0,StrParam(s:"\cJ",s:perkData[currentTabHover][PD_DISPLAY]),1,1,LID_TOOLTIPTEXT+1,1.0,1);
				
				// -- PERK IMAGE --
				SetFont(perkData[currentTabHover][PD_ICONBIG]);
				HMUSRedux(tooltipX,tooltipY + 80.0,"a",0,0,LID_TOOLTIPTEXT,1.0,1);
				
				// -- WEAPON DESCRIPTION
				SetFont("SMALLFONT");
				HMUSRedux(tooltipX,tooltipY + 190.0,perkData[currentTabHover][PD_DESCRIPTION],1,0,LID_TOOLTIPTEXT+3,1.0,1);
			}
			// Button tooltip
			else if (buttonHover > -1)
			{		
				// PERK NAME
				SetFont("BIGFONT");
				HMUSRedux(tooltipX+2.0,tooltipY + 160.0 + 2.0,StrParam(s:"\cM",s:bottomButtons[buttonHover][2]),1,1,LID_TOOLTIPTEXT+2,1.0,1);
				HMUSRedux(tooltipX,tooltipY + 160.0,StrParam(s:"\cJ",s:bottomButtons[buttonHover][2]),1,1,LID_TOOLTIPTEXT+1,1.0,1);
				
				// -- PERK IMAGE --
				SetFont(bottomButtons[buttonHover][4]);
				HMUSRedux(tooltipX,tooltipY + 80.0,"a",0,0,LID_TOOLTIPTEXT,1.0,1);
				
				// -- WEAPON DESCRIPTION
				SetFont("SMALLFONT");
				HMUSRedux(tooltipX,tooltipY + 180.0,bottomButtons[buttonHover][3],1,0,LID_TOOLTIPTEXT+3,1.0,1);
			}
			
			// -- OTHER SHIT --

			RedrawCursor();

			if (wait == 0)
			{
				if (buttons & BT_MOVERIGHT && CheckInventory("TraderCategory") > 0)
				{
					LocalAmbientSound("menu/change",127);
					GiveInventory("WepToApply",1);
				}
				
				else if (buttons & BT_BACK)
				{
					if (ListHovered(listLeftX))
					{
						if (selectUpper + selectRange < availableWeapons)
						{
						selectUpper ++;
						LocalAmbientSound("menu/change",127);
						}
					}
					
					if (ListHovered(listRightX))
					{
						if (selectUpperR + selectRange < availableWeapons)
						{
						selectUpperR ++;
						LocalAmbientSound("menu/change",127);
						}
					}
				}
					
				else if (buttons & BT_FORWARD)
				{
					if (ListHovered(listLeftX))
					{
						if (selectUpper > 0)
						{
						selectUpper --;
						LocalAmbientSound("menu/change",127);
						}
					}
					if (ListHovered(listRightX))
					{
						if (selectUpperR > 0)
						{
						selectUpperR --;
						LocalAmbientSound("menu/change",127);
						}
					}
				}
				
				// WE CLICKED SOMETHING
				else if (buttons & BT_ATTACK)
				{
					//TakeInventory("PendingClick");
					LocalAmbientSound("sten/fire",127);

					SetFont("SMALLFONT");
					//====================================================================
					// SELL A WEAPON
					//====================================================================
					if (ListHovered(listLeftX))
					{
						// -- BUY MODE -- 
						if (CheckInventory("TraderCategory") <= 0)
						{
							int SSchecker = traderActorName[cursor];
							int sellName = traderDisplayName[cursor];
							
							if (traderDualVariant[cursor] != "None")
							{
								// See if we've got the dual version
								if (CheckInventory(traderDualVariant[cursor]))
								{
									if (traderDualName[cursor] == "DEFAULT")
										sellName = StrParam(s:"Dual ",s:traderDisplayName[cursor],s:"s");
									else
										sellName = traderDualName[cursor];
										
									SSchecker = traderDualVariant[cursor];
								}
								else
									SSchecker = traderSingleVariant[cursor];
							}
							
							if (CheckInventory(SSchecker))
							{
								TraderLog(StrParam(s:"You sold your ",s:sellName,s:" and got $",d:traderPrice[cursor],s:" in return!"));
								RequestScriptPuke(702,StrLen(traderDisplayName[cursor]),11,traderPrice[cursor]);
							}
							else
								TraderLog(StrParam(s:"You don't have this item!"));
						}
						else
							currentTab = cursor;
					}

					//====================================================================
					// PURCHASE A WEAPON
					//====================================================================
					else if (ListHovered(listRightX) && CheckInventory("TraderCategory") == 0)
					{
						// Figure out our discount
						// discountAmount
						int subDiscount = GetWeaponPrice(cursor);
						int showName = StrParam(s:"a ",s:traderDisplayName[cursor]);
						int itemChecker2 = traderActorName[cursor];
						
						if (traderDualVariant[cursor] != "None")
						{
							if (CheckInventory(traderSingleVariant[cursor]))
								itemChecker2 = traderDualVariant[cursor];
						}
						
						// IF WE DON'T HAVE THE WEAPON
						if (!CheckInventory(itemChecker2))
						{
							// IF WE HAVE ENOUGH MONEY
							if (CheckInventory("Money") >= traderPrice[cursor])
							{
							RequestScriptPuke(702,StrLen(traderDisplayName[cursor]),10,traderPrice[cursor]);								
							TraderLog(StrParam(s:"You bought a ",s:showName,s:" for $",d:subDiscount,s:"!"));							
							}
							else
							{
							TraderLog(StrParam(s:"You don't have enough money!"));
							}
						}
						else
						{
						TraderLog(StrParam(s:"You already have this item!"));
						}
						
						//============================================
					}
					//===========================================================================
					// 
					// UPGRADE PURCHASING
					//
					//===========================================================================
					else if (ListHovered(listRightX) && CheckInventory("TraderCategory") == 1)
					{
								//===========================================================================
								// If we have the weapon in our inventory
								//===========================================================================
								if (CheckInventory(ShopUpgrades[cursor][SU_ACTOR]))
								{
									// ===========================================================================
									// If we don't already have the (silencer) attachment
									// ===========================================================================
									if (!CheckInventory(StrParam(s:traderActorName[currentTab],s:" ",s:ShopUpgrades[cursor][SU_SUFFIX])))
									{
											// ===========================================================================
											// If we have enough money
											// ===========================================================================
											if (CheckInventory("Money") >= ShopUpgradePrices[cursor])
											{
												RequestScriptPuke(702,StrLen(ShopUpgrades[cursor][SU_NAME]),5000 + StrLen(traderDisplayName[currentTab]),ShopUpgradePrices[cursor]);				
												TraderLog(StrParam(s:"\cJYou bought the \cK",s:ShopUpgrades[cursor][SU_NAME],s:" \cJupgrade."));
											}
											// ===========================================================================
											// Not enough money
											// ===========================================================================
											else
											{
												TraderLog(StrParam(s:"You do not have enough money for this modification."));
											}
									}
									// ===========================================================================
									// Already have the upgrade
									// ===========================================================================
									else
									{
										TraderLog(StrParam(s:"You have already applied that modification to this weapon."));
									}
								}
								// ===========================================================================
								// Not compatible
								// ===========================================================================
								else
								{
								TraderLog(StrParam(s:"You do not own this weapon!"));
								}
					}
					//===========================================================================

					// IF WE CLICK ON THE BUTTONS
					else
					{
						// IF WE CLICK ONE OF THE THREE BUTTONS
						if (buttonHover == 0)
						{
							if (CheckInventory("Money") >= 500)
							{
								RequestScriptPuke(703,2,0,0);
								TraderLog(StrParam(s:"You bought some ammo for $500."));
							}
							else
							{
								TraderLog(StrParam(s:"You don't have enough."));
							}
						}
						else if (buttonHover == 1)
						{
							if (CheckInventory("Money") >= 200)
							{
								RequestScriptPuke(703,1,0,0);
								
								TraderLog(StrParam(s:"You bought some armor for $200."));
							}
							else
							{
								TraderLog(StrParam(s:"You don't have enough."));
							}
						}
						else if (buttonHover == 2)
						{
							RequestScriptPuke(703,0,0,0);
						}
						
						// IF WE ARE USING TRADER CATEGORIES
						if (categoryicon == 1)
						{
							TakeInventory("TraderCategory",2);
							ClearMainTraderMessages();
						}
						else if (categoryicon==2)
						{
							GiveInventory("TraderCategory",1);
							ClearMainTraderMessages();
						}
						
						// CHECK TO SEE IF WE'RE OVER A PERK BUTTON
						if (currentTabHover > -1)
							currentTab = currentTabHover;
							
						// MAIN TAB
						if (topTabHover > -1)
						{
							TakeInventory("TraderCategory",55);
							
							ClearMainTraderMessages();
							currentTab = 0;
							
							GiveInventory("TraderCategory",topTabHover);
						}
					}

				}
				// REDRAW CURSOR
			}

			 GiveInventory("Waiting",1);
			 wait++;

			 if (buttons & BT_ATTACK && wait > 10)
			{
				TakeInventory("Waiting",200);
				wait=0;
			}

			if (buttons & BT_MOVELEFT && wait > 3)
			{
				TakeInventory("Waiting",200);
				wait=0;
			}

			if (buttons & BT_MOVERIGHT && wait > 3)
			{
				TakeInventory("Waiting",200);
				wait=0;
			}
			
			if (buttons & BT_FORWARD && wait > 3)
			{
				TakeInventory("Waiting",200);
				wait=0;
			}
			
			if (buttons & BT_BACK && wait > 3)
			{
				TakeInventory("Waiting",200);
				wait=0;
			}

			if (GetCVar ("cl_zombiedebugger") == 1)
			{
			Setfont("SMALLFONT");
			print(s:"Wait is ",d:wait,s:"\nCursor pos: ",d:GetMouseX(),s:" ; ",d:GetMouseY(),s:"\nCursor is ",d:cursor,s:"\nSelling: ",d:IsSelling);
			}

			delay(1);
		}

		// Clear all hud messages
		ClearTraderMessages();
}

function void TraderLog (str LogMessage)
{
	SetHudSize(0,0,1);
	SetFont("BIGFONT");
    HudMessage(s:"\cJ",s:LogMessage; 1, 32, CR_WHITE, 0.5,0.96, 2.0,0.25);
	SetHudSize(800,600,1);
}

function void ClearTraderMessages (void)
{
	for (int k=0; k<=availableWeapons; k++)
		{
			HudMessage(s:""; HUDMSG_PLAIN, 300+k, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, 400+k, CR_WHITE, 0, 0, 0);
		}

		HudMessage(s:""; HUDMSG_PLAIN, 4, CR_WHITE, 0, 0, 0);

		HudMessage(s:""; HUDMSG_PLAIN, 618, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 619, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 620, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 470, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 471, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 472, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 473, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 474, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 250, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; 1, 32, CR_WHITE, 0.5,0.95, 2.0,0.25);
		HudMessage(s:""; HUDMSG_PLAIN, 450, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 1200, CR_WHITE, 0.0, 0.0, 0.0);
		
		for (int qq=0; qq<TOTAL_PERKS; qq++)
		{
		HudMessage(s:""; HUDMSG_PLAIN, (PERK_IDBASE*2)+qq, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, PERK_IDBASE+qq, CR_WHITE, 0, 0, 0);
		}
		
		// Clear the lists
		for (int pp=0; pp<100; pp++)
		{
			HudMessage(s:""; HUDMSG_PLAIN, LID_BACKGROUND+pp, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, LID_ITEMS+pp, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, LID_TAGS+pp, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, LID_TAGLABEL+pp, CR_WHITE, 0, 0, 0);
			
			HudMessage(s:""; HUDMSG_PLAIN, LID_BACKGROUNDR+pp, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, LID_ITEMSR+pp, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, LID_TAGSR+pp, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, LID_TAGLABELR+pp, CR_WHITE, 0, 0, 0);
		}
		
		ClearBlack();
		ClearMainTraderMessages();
}

function void ClearBlack(void)
{
	for (int n=0; n<15; n++)
	{
		HudMessage(s:""; HUDMSG_PLAIN, LID_BLACK+n, CR_WHITE, 0, 0, 0);
	}
}

// Just clears some of the essential shit
function void ClearMainTraderMessages (void)
{
	for (int k=0; k<=availableWeapons; k++)
		{
			HudMessage(s:""; HUDMSG_PLAIN, 300+k, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, 400+k, CR_WHITE, 0, 0, 0);
		}


		HudMessage(s:""; HUDMSG_PLAIN, 4, CR_WHITE, 0, 0, 0);
		
		HudMessage(s:""; HUDMSG_PLAIN, 618, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 470, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 471, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 472, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 473, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 474, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, 450, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; 1, 32, CR_WHITE, 0.5,0.95, 2.0,0.25);
		
		for (int qq=0; qq<TOTAL_PERKS; qq++)
		{
		HudMessage(s:""; HUDMSG_PLAIN, (PERK_IDBASE*2)+qq, CR_WHITE, 0, 0, 0);
		HudMessage(s:""; HUDMSG_PLAIN, PERK_IDBASE+qq, CR_WHITE, 0, 0, 0);
		}
		
		int pp;
		
		// Clear the lists
		for (pp=0; pp<100; pp++)
		{
			HudMessage(s:""; HUDMSG_PLAIN, LID_BACKGROUND+pp, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, LID_ITEMS+pp, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, LID_TAGS+pp, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, LID_TAGLABEL+pp, CR_WHITE, 0, 0, 0);
			
			HudMessage(s:""; HUDMSG_PLAIN, LID_BACKGROUNDR+pp, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, LID_ITEMSR+pp, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, LID_TAGSR+pp, CR_WHITE, 0, 0, 0);
			HudMessage(s:""; HUDMSG_PLAIN, LID_TAGLABELR+pp, CR_WHITE, 0, 0, 0);
			
			if (pp < 50)
			HudMessage(s:""; HUDMSG_PLAIN, PERK_IDBASE+pp, CR_WHITE, 0, 0, 0);
		}
}

function void RedrawCursor (void)
{
	// Do nothing
}

function int CursorIsOverX (int minx, int maxx)
{
	int cursor_xpos;
	int value;
	cursor_xpos = CheckInventory("MouseX") * 1.0;


	if (cursor_xpos > minx && cursor_xpos < maxx)
		value = 1;
	else
		value = 0;

	return value;
}

function int CursorIsOverY (int miny, int maxy)
{
	int value;
	int cursor_ypos;
	cursor_ypos = CheckInventory("MouseY") * 1.0;

	if (cursor_ypos > miny && cursor_ypos < maxy)
		value = 1;
	else
		value = 0;

	return value;
}

function int OptionHovered(int startY, int startX)
{
	int widthTwo = FixedDiv(LIST_SIDE_WIDTH,2.0);
	int returner = 0;
	
	if (CursorIsOverY(startY-14.0,startY+14.0) && CursorIsOverX(startX-widthTwo,startX+widthTwo))
		returner = 1;
		
	return returner;
}

// -- FIGURE OUT WHETHER OR NOT WE'RE HOVERING OVER A LIST
function int ListHovered(int xPos)
{
	int returner = 0;
	int widthTwo = FixedDiv(LIST_SIDE_WIDTH,2.0);
	
	if (CursorIsOverX(xPos-widthTwo,xPos+widthTwo))
		returner = 1;
		
	return returner;
}

function int GetMouseX (void)
{
	int pos;

	pos = CheckInventory("MouseX")*1.0;
	return pos;
}

function int GetMouseY (void)
{
	int pos;

	pos = CheckInventory("MouseY")*1.0;
	return pos;
}

// Get the proper name for this individual item
function str GetWepName(int curcur, int isBuying)
{
	str returner = "DULL GUN";
	
	if (traderDualVariant[curcur] != "None")
	{
		// Are we buying or selling?
		if (isBuying)
		{
			// Yes, show the dual name
			if (CheckInventory(traderActorName[curcur]) || CheckInventory(traderDualVariant[curcur]))
			{
				// Does the weapon use the default dualies formula?
				if (traderDualName[curcur] == "DEFAULT")
					returner = StrParam(s:"Dual ",s:traderDisplayName[curcur],s:"s");
				else
					returner = traderDualName[curcur];
			}
			// No, show the single name
			else
				returner = traderDisplayName[curcur];
		}
		
		// Selling
		else
		{
			if (CheckInventory(traderDualVariant[curcur]))
			{
				// Does the weapon use the default dualies formula?
				if (traderDualName[curcur] == "DEFAULT")
					returner = StrParam(s:"Dual ",s:traderDisplayName[curcur],s:"s");
				else
					returner = traderDualName[curcur];
			}
			else
				returner = traderDisplayName[curcur];
		}
	}
	else
		returner = traderDisplayName[curcur];
	
	return returner;
}

// Get the price of a weapon with discount
function int GetWeaponPrice(int wepNumber)
{
	int returner;
	int discounter;
	
	returner = traderPrice[wepNumber];
	discounter = LEVEL_DISCOUNT_AMOUNT * CheckInventory("PerkLevel");
	
	if (CheckInventory(traderDiscountActor[wepNumber]))
	{
	returner = returner - discounter;
	if (returner < 5)
		returner = 5;
	}
		
	return returner;
}

function str GetMinutes(void)
{
	str returner = "";
	int minutes;
	
	// Split the trader text into minutes
	minutes = floor(FixedDiv(CheckInventory("HUDDummy_Trader")*1.0,60.0));
	if (minutes < 10.0)
		returner = StrParam(s:"0",f:minutes);
	else
		returner = StrParam(f:minutes);
		
	return returner;
}

function str GetSeconds(void)
{
	int seconds;
	
	str returner = "";
	// Split the trader text into seconds
	seconds = CheckInventory("HUDDummy_Trader") % 60;
	if (seconds < 10)
		returner = StrParam(s:"0",d:seconds);
	else
		returner = StrParam(d:seconds);
			
	return returner;
}

/*
// --================================================--
// -- S E N D   C A L L S --
// Sends "calls" from the server to the client, act in transporting
// important variables
//
// cNum is composed of the item in the list and a case
// 173 = Item 17, case 3 
//
// STRINGS:
// 0 - traderDisplayName
// 0 - traderActorName
// 0 - traderBuyPicture
//
// 1 - traderDescription
// 1 - traderWeaponType
// 1 - traderAttachName
//
// 2 - traderDiscountActor
// 2 - traderDualVariant
// 2 - traderSingleVariant
//
// 3 - traderDualName
//
// INTS:
// 0 - traderPrice
// 0 - traderIsDualies
// 0 - traderIsHidden
// --================================================--

// STRINGS ONLY, SCRIPT 702
function void SendCallStrings(int cNum, str argOne, str argTwo, str argThree)
{
	ACS_ExecuteWithResult(702,cNum,argOne,argTwo,argThree);
}

// INTS ONLY, SCRIPT 703
function void SendCallInts(int cNum, int argOne, int argTwo, int argThree)
{
	ACS_ExecuteWithResult(703,cNum,argOne,argTwo,argThree);
}

// Server -> Client
script 702 (int cNum, str argOne, str argTwo, str argThree) CLIENTSIDE
{
	// Divide by 10 and get the list number
	int listNum = floor(cNum/10);
	// Now subtract the real number from this to get our call
	int callNum = cNum - (listNum*10);
	
	// Do different things based on different calls
	switch (callNum)
	{
		case 0:
			traderDisplayName[listNum] = argOne;
			traderActorName[listNum] = argTwo;
			traderBuyPicture[listNum] = argThree;
		break;
		
		case 1:
			traderDescription[listNum] = argOne;
			traderWeaponType[listNum] = argTwo;
			traderAttachName[listNum] = argThree;
		break;
		
		case 2:
			traderDiscountActor[listNum] = argOne;
			traderDualVariant[listNum] = argTwo;
			traderSingleVariant[listNum] = argThree;
		break;
		
		case 3:
			traderDualName[listNum] = argOne;
		break;
	}
}

// Server -> Client
script 703 (int cNum, int argOne, int argTwo, int argThree) CLIENTSIDE
{
	// Divide by 10 and get the list number
	int listNum = floor(cNum/10);
	// Now subtract the real number from this to get our call
	int callNum = cNum - (listNum*10);
	
	// Do different things based on different calls
	switch (callNum)
	{
		case 0:
			traderPrice[listNum] = argOne;
			traderIsDualies[listNum] = argTwo;
			traderHidden[listNum] = argThree;
		break;
	}
}
*/

// Client -> Server
// Gives the player an inventory item that says they need clicking
// Also gives specialized inventory items that click at a certain spot
/*
script 702 (int clickX, int clickY) NET
{
	TakeInventory("ServerClickX",9999);
	TakeInventory("ServerClickY",9999);
	
	GiveInventory("ServerClickX",clickX);
	GiveInventory("ServerClickY",clickY);
	
	// Tell the server that we sent a click request
	GiveInventory("PendingClick",1);
}
*/

// Client -> Server
// Handles purchasing a weapon or upgrade
//
// stringRequire - The length of the weapon name
// mody - Buy or Sell?
// umode - Weapon or upgrade
// amount - Amount of money to give or take
script 702 (int stringRequire, int combiner, int amount) NET
{
	int l;
	
	str itemName = "";
	int itemNumber = -1;
	int wepNumber = -1;
	
	// 10 IS BUY, 20 IS SELL
	// 11 IS WEAPON, 12 IS UPGRADE
	int mody = 0;
	int umode = 0;
	
	int foundWeapon = 0;
	
	// FIGURE OUT BUY AND JUNK
	if (combiner == 10 || combiner == 11) {mody = 0;}
	
	// A combiner of 5000 or above means we're upgrading
	if (combiner < 5000) {umode = 0;}
	else {umode = 1;}
	
	// -- FIRST AND FOREMOST, FIND THE NAME OF THE ITEM --
	if (umode == 0)
	{
		for (l=0; l<availableWeapons; l++)
		{
			// Does this weapon match?
			if (StrLen(traderDisplayName[l]) == stringRequire && traderPrice[l] == amount && !foundWeapon)
			{
				itemNumber = l;
				foundWeapon = 1;
			}
		}
	}
	// -- If we're upgrading then the length is blah-5000
	else
	{
		// -- FIRST FIGURE OUT OUR UPGRADE
		for (l=0; l<SHOP_UPGRADECOUNT; l++)
		{
			// Does this weapon match?
			if (StrLen(ShopUpgrades[l][SU_NAME]) == stringRequire && ShopUpgradePrices[l] == amount && !foundWeapon)
			{
				itemNumber = l;
				foundWeapon = 1;
			}
		}
		
		foundWeapon = 0;
		// -- NEXT FIGURE OUT THE WEAPON THAT BELONGS TO IT
		for (l=0; l<availableWeapons; l++)
		{
			// Does this weapon match?
			if (ShopUpgrades[itemNumber][SU_ACTOR] == traderActorName[l] && !foundWeapon)
			{
				wepNumber = l;
				foundWeapon = 1;
			}
		}
	}
	
	// -- WE HAVE THE NUMBER OF THE ITEM THAT WE WANT, NOW ACTUALLY DO SOME STUFF WITH IT
	if (itemNumber != -1)
	{
		PrintBold(s:"Length: ",d:stringRequire,s:"\nPrice: ",d:amount,s:"\nCombiner: ",d:combiner,s:"\nFinal Number: ",d:itemNumber);
	// First, are we getting a weapon or an upgrade?
	if (umode == 0)
	{
		// -- IF WE'RE BUYING --
		if (mody == 0)
		{
			TakeInventory("Money",amount);
			
			//============================================
			// DUALIES EXCEPTION
			//============================================
			if (traderDualVariant[itemNumber] != "None")
			{
				if (CheckInventory(traderSingleVariant[itemNumber]))
				{
					GiveInventory(traderDualVariant[itemNumber],1);
					TakeInventory(traderActorName[itemNumber],1);
				}
									
				else
					GiveInventory(traderActorName[itemNumber],1);
			}
			else
				GiveInventory(traderActorName[itemNumber],1);
		}
		// -- IF WE'RE SELLING -- 
		else if (mody == 1)
		{
			GiveInventory("Money",amount);
			TakeInventory(traderActorName[itemNumber],1);
			
			// -- DUALIES EXCEPTION
			if (traderSingleVariant[itemNumber] != "None")
			{
				if (CheckInventory(traderDualVariant[itemNumber]))
				{
					TakeInventory(traderDualVariant[itemNumber],1);
					GiveInventory(traderSingleVariant[itemNumber],1);
				}
				else
				{
					TakeInventory(traderSingleVariant[itemNumber],1);
				}
			}
			else
				TakeInventory(traderActorName[itemNumber],1);
		}
	}
	// Upgrade mode
	else if (umode == 1)
	{
			TakeInventory("Money",amount);
			GiveInventory(StrParam(s:traderActorName[wepNumber],s:" ",s:ShopUpgrades[itemNumber][SU_SUFFIX]), 1);
	}
	}
}

// Exit the trader menu, armor, all that fun stuff
script 703 (int casing, int mode) NET
{
	// Exit
	if (mode == 0)
	{
		SetActorProperty(0,APROP_Invulnerable,0);
		SetPlayerProperty(0,0,4);
		SetPlayerProperty(0,0,1);
		SetPlayerProperty(0,0,7);
		TakeInventory("MenuActive",1);
		TakeInventory("TraderCategory",2);
		TakeInventory("WepToApply",99);
		TakeInventory("MenuWeapon",1);
	}
	
	// Armor
	else if (mode == 1)
	{
		TakeInventory("Money",200);
		GiveInventory("GreenArmor",1);
	}
	
	// Ammo
	else if (mode == 2)
	{
		TakeInventory("Money",500);
		
		for (int l=0; l<5; l++)
		{
		GiveInventory("Backpack",20);
		delay(1);
		}
	}
}

// Kicked out
script 704 (void)
{
	TakeInventory("MenuActive",1);
	TakeInventory("MenuWeapon",1);
	SetActorProperty(0,APROP_Invulnerable,0);
	SetPlayerProperty(0,0,4);
	SetPlayerProperty(0,0,1);
	SetPlayerProperty(0,0,7);
	ACS_ExecuteAlways(705,0,0,0,0);
}

script 705 (void) CLIENTSIDE
{
	TakeInventory("MenuActive",1);
	TakeInventory("TraderCategory",2);
	TakeInventory("WepToApply",99);
}