--[[Design thoughts (subjective)
Roguelikes in games typicallly follow a standard loop of progressing through a level
giving the players power spikes and maintaining survival as the winning condition
There are some parallels that can be applied to typical MvM (forgoing death as a lose condition),
or you can choose to opt for a total gamemode replacement

Some games to take inspiration from:
	Risk of Rain 2
	Vampire Survivors (and heavily inspired Holocure, 20 Minutes Til Dawn)
	Hades
	The Binding of Issac
	Enter The Gungeon

The most important thing to consider is how much control you want to give the players in terms of progression
Currently this is done by the number of upgrades and rerolls given, but you can also come up with other methods
Such as introducing another currency, or keeping the regular upgrade menu, or limiting which upgrades appear
until a certain wave, or perhaps even introducing a "refund and craft upgrade system"
Any mechanic you can think is possible in lua

Some features I wanted to implement but got lazy:
	Picking upgrades from RNG based on what loadout you have
	Using ItemAttributes instead of CharacterAttributes
	Some sort of sensible refund/respec that isn't completely overpowered
	Possible form of "weighted RNG" to allow RNG manipulation and more nuanced upgrading choices

"Style2" refers to the upgrade menu being rerolled after every purchase, 
there should be no duplicate upgrades in the shop so as not to waste slots
Think Vampire Survivors/Hades

"Style1" was when the upgrade menu behaved more similar to the regular shop, 
you could buy any choice of upgrades and it only rerolled on wave end
]]

--[[Global variables 
MenuCapacity - How many upgrades can be stored in the menu, keep as integer
	Note that the sourcemod menu has a 512 byte limit, try to keep names/descriptions short
	Byte limit as opposed to a character limit means that inserting unicode characters which contain more than 1 byte
	will use up more of the limit
	
	You can use special characters like \n in sourcemod menus
	
	If you go above 7 selections (6+1 reroll selections) the sourcemod menu will display the Next and Previous buttons
	Personally I find this to be a bit clunky so I would stick with using a MenuCapacity of 6, 7 if you want to
	prevent accidental rerolls
	
TotalUpgradePoints - Determines the starting amount of upgrade points on wave 1, and for any late joiners, keep as integer

TotalRerollPoints - Determines the starting amount of upgrade points on wave 1, and for any late joiners, keep as integer]]

MenuCapacity = 5
TotalUpgradePoints = 666
TotalRerollPoints = 666
TotalAvailableEpic = 3


--[[AllShops is a table that controls what upgrades are shown to players, based on what class they are
	Note that it uses the game's interal reference for classes, which is different from their class selection screen order
	
	Each class can have any number of subtables or sub categories, I use this to define four different rarities
	
	You can also go for a shared upgrade pool between all classes, or Demo and Soldier etc.]]

--attributes are defined as text on menu, attribute name, min, increment, max

--[[The 1st field is actually the most important, as it used to uniquely identify upgrades, this allows the second field
	to exist beyond just attributes, and you can utilize "custom" to write a function that can do anything, as shown in
	Max Ammo and Mixed Concotion On Hit
	
	Note that max is typicallly optional for attributes, and if you're using "custom", min increment and max are also optional
	and can be defined in the AddUpgrade function instead]]

AllShops =
{
    [1] = --Scout Shop
	{
		CommonAttribute =
		{
			--base char
			{"melee damage test upgrade", "custom",0,1,5,2},
			{"All Resistance Upgrade +20%", "custom",0,1,4,0},
			{"All Max Ammo +35%", "custom",1,0.35,2.05,0},
			{"Ammo Regen +10% every 5 seconds", "ammo regen",0,0.1,0.2,0},
			{"Consumable Recharge Rate +50%", "effect bar recharge rate increased",1,-0.25,0.25,0},
			{"Move Speed/Jump Height +10%", "custom",0,1,4,0},
			{"Damage Mult +0.15", "stack",0,0.15,0.45,0,"damage penalty"},
			--base weapon
			
			{"Pri:Heal On Kill +25", "heal on kill",0,25,75,1},
			{"Sec:Heal On Kill +25", "heal on kill",0,25,75,2},
			{"Mle:Heal On Kill +50", "heal on kill",0,50,100,3},
			{"Pri:Clip Size +25%", "stat",0,0.25,0.75,1,"ClipSize"},
			{"Pri:Reload Rate +20%", "stat",0,-0.2,-0.6,1,"ReloadRate"},
			{"Pri:Fire Rate +15%", "stat",0,-0.15,-0.45,1,"FireRate"},
			{"Sec:Clip Size +25%", "stack",0,0.25,0.75,2,"clip size bonus"},
			{"Sec:Reload Rate +20%","stack",0,-0.2,-0.6,2,"faster reload rate"},
			{"Sec:Fire Rate +15%", "stat",0,-0.15,-0.45,2,"SecFireRateMult"},
			
			{"Pri:Damage Bonus +15%", "stat",0,0.15,0.45,1,"DamageBonus"},
			{"Sec:Damage Bonus +20%", "stat",0,0.2,0.6,2,"SecDamageBonus"},
			{"Mle:Damage Bonus +25%", "stat",0,0.25,0.75,3,"MleDamageBonus"},
		},
		RareAttribute =
		{
			--base char
			{"(R) Max Health +50", "stat",0,50,300,0,"MaxHealth"},
			{"(R) Health Regen +5", "health regen",0,5,10,0},
			{"(R) Bleed Damage +300%", "mult bleeding dmg",1,3,10,0},
			{"(R) Ranged Resistance +10%", "stat",0,-0.1,-0.3,0,"RangedResistance"},
			
			--base weapon
			{"(R) Pri:Damage Bonus +20%", "stat",0,0.2,0.6,1,"DamageBonus"},
			{"(R) Pri:Bullets Per Shot +10%", "stat",0,0.1,0.3,1,"BulletPerShot"},
			{"(R) Sec:Damage Bonus +35%", "stat",0,0.35,1.05,2,"SecDamageBonus"},
			{"(R) Mle:Damage Bonus +50%", "stat",0,0.5,1,3,"MleDamageBonus"},
			
			{"(R) Pri:Killing Turns Mini Crits to Crits for 2s", "custom",0,1,1,1},
			{"(R) Pri:Damage Bonus +25%/Move Speed -25%", "custom",0,1,2,1},
			{"(R) Pri:Hype Also Gives You -45% Spread", "custom",0,1,2,1},
			{"(R) Jar:Debuff Apply Damage -10%", "custom",0,1,2,2},
			{"(R) Drink:Also Gain Extra Jump +6", "custom",0,1,1,2},
			{"(R) Drink:Also Gain Damage x1.2", "custom",0,1,2,2},
			{"(R) Sec:Mad Milk Slows Targets", "applies snare effect",1,-0.35,0.65,2},
			{"(R) Sec:Secondary Hit and Bleed Tick Gives Buff", "custom",0,1,1,2,
			"Buff Gives x1.2 Damage and Lasts 1s"},
			{"(R) Meter Effect/Debuff Duration +50%", "stack",0,0.5,1,0,"mult effect duration"},
			{"(R) Cleaver:Damage Bonus +300%", "custom",0,1,3,2},
			
			{"(R) Damage Mult +0.2/Ammo -20%/Switch +40%", "custom",0,1,3,0},
			{"(R) Push Force -40%", "damage force reduction",1,-0.4,0.2,0},
			{"(R) Mle:Recharge Rate +100%", "stack",0,-0.5,-0.5,3,"effect bar recharge rate increased"},
			{"(R) Mle:Mark for Death", "mark for death",0,1,1,3},
			{"(R) Mle:Melee Hit and Bleed Tick Gives Buff", "custom",0,1,1,3,
			"Buff Gives x1.3 Damage and Lasts 1s"},
			{"(R) Mle:Mini Crit to Crits/Damage Bonus +25%", "custom",0,1,1,3},
			
		},
		EpicAttribute =
		{
			{"[EP] Pri:Damage Bonus +40%", "stat",0,0.4,0.8,1,"DamageBonus"},
			{"[EP] Pri:Bullets Per Shot +30%", "stat",0,0.3,0.6,1,"BulletPerShot"},
			{"[EP] Sec:Damage Bonus +75%", "stat",0,0.75,1.5,2,"SecDamageBonus"},
			{"[EP] Mle:Damage Mult +1.0", "stat",0,1,2,3,"MleDamageMult"},
			
			{"[EP] Pri:Hype Also Gives You Damage x1.4", "custom",0,1,1,1},
			{"[EP] Pri:Damage Mult +0.5/Spread -100%", "custom",0,1,3,1},
			{"[EP] Pri:Damage +50%/Clip Size -50%/FireRate Mult -0.6", "custom",0,1,1,1},
			{"[EP] Pri:Spread Bonus +50%", "stat",0,-0.5,-0.99,1,"BulletSpread"},
			{"[EP] Pri:Force Fire Full Clip/Firerate Mult +1.0", "custom",0,1,1,1},
			{"[EP] Pri:Force Fire Full Clip/Accuracy is Key", "custom",0,1,1,1,"Damage Mult +0.5/Fire Rate -30%/Ammo -40%"},
			{"[EP] Pri:No DMG Falloff/Piercing", "custom",0,1,1,1},
			{"[EP] Pri:Damage Mult +2.0/Reload -400%", "custom",0,1,1,1},
			{"[EP] Pri:Damage Mult +0.5/Move Speed -60%", "custom",0,1,1,1},
			
			
			{"[EP] Jar:Debuff Apply -80% Crit Damage/Recharge -50%", "custom",0,1,1,2},
			{"[EP] Drink:Also Turn Mini to Crit/Recharge -50%", "custom",0,1,1,2},
			{"[EP] Sec:Spread Bonus +99%/No DMG Falloff", "custom",0,1,1,2},
			{"[EP] Sec:FireRate Mult +0.5/Ammo +50%", "custom",0,1,2,2},
			{"[EP] Sec:Damage Mult +2/FireRate Mult -0.5", "custom",0,1,1,2},
			{"[EP] Sec:Damage Mult +0.5/Ammo +50%", "custom",0,1,2,2},
			
			{"[EP] Mle:Crit on kill 5s", "critboost on kill",0,5,5,3},
			{"[EP] Mle:DMG vs Burn +300%", "dmg penalty vs nonburning",0,4,4,3},
			{"[EP] Mle:Damage Mult +1.0", "stat",0,1,2,3,"MleDamageMult"},
			
			{"[EP] Heal on kill can Overheal", "overheal from heal on kill",0,1,1,0},
			{"[EP] Kill to Live", "custom",0,1,1,0,
			"Crit and Speed Boost on kill 5s/Heal on Kill +100/Move Speed -50%/Damage Mult -0.2"},
			{"[EP] Damage Bonus +100%/Max Health +100/Pri-Clip Size -100%", "custom",0,1,1,0},
			{"[EP] Crit vs Wet", "crit vs wet players",0,1,1,0},
			{"[EP] Max Health Drain/Ranged Resistance 30%", "custom",0,1,1,0,"Health always drain to 100"},
			
			{"[EP] Available Epic + 1", "custom",0,1,2},
			{"[EP] ReRoll Points + 3","custom",0,1,4},
			{"[EP] Next Purchase is Rare Shop","custom",0,1,4},
		},
		MinorEpicAttribute =
		{
		    
			{"[EP] Crit Damage Bonus +10%", "mult crit dmg",1,0.1,10,0},
			{"[EP] ReRoll Points + 1","custom",0,1},
		},
		LegendaryAttribute =
		{
			{"【LEGEN】Next Purchase is Epic Shop","custom",0,1,4},
			{"【LEGEN】Upgrade Point + 1","custom",0,1,2},
			{"【LEGEN】All Stats Up", "custom",0,1,1,0},
		
			{"【LEGEN】Reload Full Clip At Once", "reload full clip at once",0,1,1}, --[[재장전 한번에]]
			{"【LEGEN】Super Scout", "custom",0,1,1,0,"Double speed with push force resistance"}, -- double speed 1% push force
			{"【LEGEN】Jar:Causes Bind", "custom",0,1,1,2,
			"Debuff Duration -40%/Recharge Rate -50%"},
			{"【LEGEN】Pri-Crit On Kill 3s", "critboost on kill",0,3,3,1},
			{"【LEGEN】Mini crits to Crits", "minicrits become crits",0,1,1,0},
			
		},
	},
	[3] = --Soldier Shop
	{
		CommonAttribute =
		{
			--base char
			{"melee damage test upgrade", "custom",0,1,4,3},
			{"All Resistance Upgrade +20%", "custom",0,1,4,0},
			{"All Max Ammo +35%", "custom",1,0.35,2.05,0},
			{"Self Blast -40%", "blast dmg to self increased",1,-0.4,0.2,0},
			{"Ammo Regen +10% every 5 seconds", "ammo regen",0,0.1,0.2,0},
			{"Move Speed +20%", "stat",0,0.2,0.4,0,"MoveSpeed"},
			
			--weapon
			{"Pri:Heal On Kill +25", "heal on kill",0,25,75,1},
			{"Sec:Heal On Kill +25", "heal on kill",0,25,75,2},
			{"Mle:Heal On Kill +50", "heal on kill",0,50,100,3},
			{"Pri:Clip Size +25%", "stat",0,0.25,0.75,1,"ClipSizeSoldier"},
			{"Pri:Reload Rate +20%", "stat",0,-0.2,-0.6,1,"ReloadRate"},
			{"Pri:Fire Rate +15%", "stat",0,-0.15,-0.45,1,"FireRate"},
			{"Sec:Clip Size +25%", "stack",0,0.25,0.75,2,"clip size bonus"},
			{"Sec:Reload Rate +20%","stack",0,-0.2,-0.6,2,"faster reload rate"},
			{"Sec:Fire Rate +15%", "stat",0,-0.15,-0.45,2,"SecFireRateMult"},
			--special
			{"Pri:Damage Bonus +15%", "stat",0,0.15,0.45,1,"DamageBonus"},
			{"Sec:Damage Bonus +20%", "stat",0,0.2,0.6,2,"SecDamageBonus"},
			{"Mle:Damage Bonus +25%", "stat",0,0.25,0.75,3,"MleDamageBonus"},
			{"Damage mult +0.15/Pri:Blast Radius -15%", "custom",0,1,4,1},
			{"Damage mult +0.15/Pri:Clip Size -25%", "custom",0,1,4,1},
		},
		RareAttribute =
		{
			{"(R) Health Regen +5", "health regen",0,5,10,0},
			{"(R) Max Health +50", "stat",0,50,300,0,"MaxHealth"},
			{"(R) Health +100/Max Ammo -20%", "custom",0,1,8,0},
			{"(R) Healing Received +100%/Medic Healing -50%", "custom",0,1,2,0},
		
			--base weapon
			{"(R) Pri:Damage Bonus +20%", "stat",0,0.2,0.6,1,"DamageBonus"},
			{"(R) Sec:Damage Bonus +35%", "stat",0,0.35,1.05,2,"SecDamageBonus"},
			{"(R) Mle:Damage Bonus +50%", "stat",0,0.5,1,3,"MleDamageBonus"},
			
			{"(R) Damage mult +0.2/Pri:Blast Radius -10%", "custom",0,1,4,1},
			{"(R) Pri:Damage Bonus +25%/Clip Size -25%", "custom",0,1,3,1},
			{"(R) Sec:Bullet Per Shot +30%/Weapon Switch +25%", "custom",0,1,4,2},
			{"(R) Sec:Buff Duration +40%/Buff Radius +15%", "custom",0,1,3,2},
			
			{"(R) Mle:Escape Plan No Mark for Death", "self mark for death",1,-1,0,3},
			{"(R) Mle:Crit Damage +50%", "stack",0,0.5,1.5,3,"mult crit dmg"},
			{"(R) Mle:Attack Rate Increases as Health Reduce", "fire rate bonus with reduced health",0,1,1,3},
			{"(R) Sec:Buff Duration +40%/Buff Radius +15%", "custom",0,1,3,2},
		},
		EpicAttribute =
		{
			{"[EP] Pri:Damage Bonus +30%", "stat",0,0.3,0.6,1,"DamageBonus"},
			{"[EP] Sec:Bullets Per Shot +100%", "stat",0,1,2,2,"SecBulletPerShot"},
			{"[EP] Sec:Damage Bonus +75%", "stat",0,0.75,1.5,2,"SecDamageBonus"},
			{"[EP] Mle:Damage Mult +1.0", "stat",0,1,2,3,"MleDamageMult"},
			
			{"[EP] Pri:FireRate Mult +0.4/Rocket Speed -25%", "custom",0,1,2,1},
			{"[EP] Pri:Rocket Speed +100%/Rocket Specialist", "custom",0,1,2,1},
			{"[EP] Pri:Mortar Rocket/Blast Radius +50%", "custom",0,1,1,1},
			{"[EP] Pri:Burn Damage +2000%", "weapon burn dmg increased",0,20,40,1},
			{"[EP] Pri:Damage mult +0.5/FireRate Mult -0.5", "custom",0,1,2,1},
			{"[EP] Pri:Blast Radius +50%/FireRate Mult -0.5", "custom",0,1,2,1},
			{"[EP] Pri:Reload Rate -30%", "stat",0,-0.3,-0.3,1,"ReloadRate"},
			{"[EP] Pri:Clip Size +100%/Max Ammo +50%", "custom",0,1,2,1},
			{"[EP] Pri:FireRate Mult +0.7/Force Fire Full Clip/Ammo +50%", "custom",0,1,1,1},
			{"[EP] Pri:No FireRate/Clip Size -25%/Damage Mult -0.33/Ammo +50%", "custom",0,1,1,1},
			{"[EP] Pri:Homing", "mod projectile heat seek power",0,90,90,1},
			{"[EP] Pri:Damage Bonus +35%/Rocket Decelerate", "custom",0,1,1,1},
			{"[EP] Pri:Damage Bonus +25%/Rocket Accelerate", "custom",0,1,1,1},
			{"[EP] Pri:Damage Per Target +30%/FireRate Mult -0.5", "custom",0,1,2,1},
			
			{"[EP] Sec:Buff gives +50% Damage/Duration -50%", "custom",0,1,1,2},
			{"[EP] Sec:Buff gives +25% Speed/Duration +50%", "custom",0,1,1,2},
			{"[EP] Sec:Buff gives +50% FireRate/Duration -50%", "custom",0,1,1,2},
			{"[EP] Sec:Buff gives 40 Regen/Duration -50%", "custom",0,1,1,2},
			{"[EP] Sec:Damage Mult +2.0/Clip and Reload -90%", "custom",0,1,1,2},
			{"[EP] Sec:Damage Mult +1/FireRate Mult -0.4", "custom",0,1,2,2},
			{"[EP] Sec:Damage Mult +2.0/Reload -400%", "custom",0,1,1,1},
			{"[EP] Sec:Reload Mult +9.5", "Reload time decreased",0,-0.95,-0.95,2},
			{"[EP] Sec:Bullet Per Shot +100%/Spread -20%", "custom",0,1,2,2},
			
			{"[EP] Mle:Crit Damage +100%", "stack",0,1,2,3,"mult crit dmg"},
			{"[EP] Mle:Damage +150%/Mark of Death", "custom",0,1,1,3},
			
			{"[EP] Ranged Resistance +15%/Heal on Hit +15", "custom",0,1,2,0},
			{"[EP] Mini crits to Crits/Crit Damage -30%", "custom",0,1,1,0},
			{"[EP] Max Health +1000/Damage Taken 500%", "custom",0,1,3,0},
		    
			{"[EP] Available Epic + 1", "custom",0,1,2},
			{"[EP] ReRoll Points + 3","custom",0,1,4},
			{"[EP] Next Purchase is Rare Shop","custom",0,1,4},
		},
		MinorEpicAttribute =
		{
		    {"[EP] Fall Damage Immunity", "cancel falling damage",0,1,1},
			{"[EP] Tank Damage +10%", "mult dmg vs tanks",1,0.1,10,0},
			{"[EP] ReRoll Points + 1","custom",0,1},
		},
		LegendaryAttribute =
		{
			{"【LEGEN】Next Purchase is Epic Shop","custom",0,1,4},
			{"【LEGEN】Upgrade Point + 1","custom",0,1,2},
			{"【LEGEN】All Stats Up", "custom",0,1,1,0},
			
			{"【LEGEN】Sec:Free Pair of Mantread", "boots falling stomp",0,1,1,2},
			{"【LEGEN】Pri:Nuke", "custom",0,1,1,1},
			{"【LEGEN】Pri:Rapid Fire/Damage Mult -0.7", "custom",0,1,1,1},
			{"【LEGEN】Super Bison", "custom",0,1,1,2},
			{"【LEGEN】Reload Full Clip At Once", "reload full clip at once",0,1,1}, --[[재장전 한번에]]
		}
	},
	[7] = --Pyro Shop
	{
		CommonAttribute =
		{
		--base char
			{"melee damage test upgrade", "custom",0,1,5,0},
		    {"All Resistance Upgrade +20%", "custom",0,1,5},
			{"Movement Speed +20%", "move speed bonus",1,0.2,1.2},
			{"All Max Ammo +35%", "custom",1,0.35,2.05,0},
			{"Ammo Regen +10% every 5 seconds", "ammo regen",0,0.1,0.2},
			{"Push Force -40%", "damage force reduction",1,-0.4,0.2},
			{"Burn Duration 50%", "weapon burn time increased",1,0.5,2.5,0},
		--base weapon
			{"Pri:Heal On Kill +25", "heal on kill",0,25,75,1},
			{"Sec:Heal On Kill +25", "heal on kill",0,25,75,2},
			{"Sec:Clip Size +25%", "stack",0,0.25,1.75,2,"clip size bonus"},
			{"Sec:Reload Rate +20%", "faster reload rate",0,-0.2,-0.6,2},
			{"Sec:Fire Rate +15%", "stat",0,-0.15,-0.45,2,"SecFireRateMult"},
			{"Mle:Damage Bonus +25%", "stat",0,0.25,0.75,3,"MleDamageBonus"},
			{"Mle:Heal On Kill +100", "heal on kill",0,100,200,3},
			
			{"Pri:Damage Bonus +15%", "stat",0,0.15,0.45,1,"DamageBonus"},
			{"Sec:Damage Bonus +20%", "stat",0,0.2,0.6,2,"SecDamageBonus"},
			{"Mle:Damage Bonus +25%", "stat",0,0.25,0.75,3,"MleDamageBonus"},
		},
		RareAttribute =
		{
			--base char
			{"(R) Health Regen +8 every second", "health regen",0,8,16,0},
			{"(R) Max Health +50", "stat",0,50,300,0,"MaxHealth"},
			{"(R) Ranged Res +15%/Move Speed -20%", "custom",0,1,4,0},
			{"(R) Burn Damage Delay +15%", "stack",0,0.5,1.5,0,"weapon burn dmg increased"},
			--base weapon
			{"(R) Pri:Damage Bonus +20%", "stat",0,0.2,0.6,1,"DamageBonus"},
			{"(R) Sec:Damage Bonus +35%", "stat",0,0.35,1.05,2,"SecDamageBonus"},
			{"(R) Sec:Bullet Per Shot +30%/Weapon Switch +25%", "custom",0,1,4,2},
			{"(R) Mle:Damage Bonus +50%", "stat",0,0.5,1,3,"MleDamageBonus"},
			
			{"(R) Pri:Crit Damage +25%/Buff Duration -25%","custom",0,1,2,1},
			{"(R) Pri:Buff Duration +25%","stack",0,0.25,0.5,1,"increase buff duration"},
			{"(R) Pri:Heal-on-Hit +1","stat",0,1,3,1,"HealonHit"},
			
			{"(R) Sec:All Thermal Thruster Mod/Stompy", "custom",0,1,1,2},
			{"(R) Sec:Crit DMG +100%/No Medic Healing", "custom",0,1,3,2},
			{"(R) Sec:Effect Bar Recharge +25%/Switch +40%", "custom",0,1,1,2},
			{"(R) Sec:Mini Crits to Crits", "minicrits become crits",0,1,1,2},
			{"(R) Gas:Apply -25% Damage Debuff", "custom",0,1,2,2},
			
			{"(R) Mle:Crit DMG +100%/No Medic Healing", "custom",0,1,3,3},
			{"(R) Mle:Heal On Hit +50", "heal on hit for slowfire",0,50,100,3},
			{"(R) Mle:Mini-Crits to Crits", "minicrits become crits",0,1,1,3},
			
			{"(R) Burn Damage +300%", "weapon burn dmg increased",0,3,9,0},
			{"(R) Damage Mult +0.2/Ammo -20%/Switch +40%", "custom",0,1,3,0},
			{"(R) Override Airblast Mod:Efficiency", "custom",0,1,1,1,"Overrides other Airblast Upgrade/Airblast costs lesser ammo"},
			{"(R) Override Airblast Mod:Power", "custom",0,1,1,1,"Overrides other Airblast Upgrade/Airblast push power doubled"},
			{"(R) Override Airblast Mod:Repressure", "custom",0,1,1,1,"Overrides other Airblast Upgrade/Airblast refire quicker but reduced power"},
			{"(R) Drop On Kill: Small Health Pack", "drop health pack on kill",0,1,1,0},
		},
		EpicAttribute =
		{
			{"[EP] Pri:Damage Bonus +40%", "stat",0,0.4,0.8,1,"DamageBonus"},
			{"[EP] Sec:Bullets Per Shot +100%", "stat",0,1,2,2,"BulletPerShot"},
			{"[EP] Sec:Damage Bonus +75%", "stat",0,0.75,1.5,2,"SecDamageBonus"},
			{"[EP] Mle:Damage Mult +1.0", "stat",0,1,2,3,"MleDamageMult"},
			
			{"[EP] Pri:Heal On Hit +2 health","stat",0,2,4,1,"HealonHit"},
			{"[EP] Pri:Mini-Critboost on Kill +1s", "minicritboost on kill",0,1,1,1},
			{"[EP] Pri:Crit Damage +40%","stack",0,0.4,0.8,1,"mult crit dmg"},
			{"[EP] Pri:Burn Damage Delay +100%", "weapon burn dmg increased",0,2,2,1},
			{"[EP] Pri:Slow Enemy On Hit/Damage Mult +0.5", "custom",0,1,1,1},
			{"[EP] Pri:Damage Mult +0.5/Flamethrower spin up -0.8s", "custom",0,1,1,1},
			{"[EP] Pri:Flame Life x4/Gravity/Damage Mult +1", "custom",0,1,1,1},
			{"[EP] Pri:Flame Speed x1.3/Damage Mult +0.2", "custom",0,1,1,1},
			{"[EP] Pri:Flame Speed x0.2/Damage Mult +1", "custom",0,1,1,1},
			{"[EP] Pri:Damage Mult +0.5/Flamethrower Ammo Cost x2", "custom",0,1,2,1},
			{"[EP] Pri:Burining Enemy Gives You +25 Health Regen", "custom",0,1,2,1},
			{"[EP] Pri:Burining Enemies Take +100% Melee Damage", "custom",0,1,2,1},
			{"[EP] Phlog:Buff Also Applies +25% Resistance","custom",0,1,1,1},
			
			{"[EP] Sec:Damage Mult +2.0/Reload -400%", "custom",0,1,1,1},
			{"[EP] Sec:Damage Mult +1/FireRate Mult -0.4", "custom",0,1,2,2},
			{"[EP] Sec:Bullet Per Shot +100%/Spread -20%", "custom",0,1,2,2},
			{"[EP] Sec:Heal On Hit +12 health","heal on hit for slowfire",0,12,24,2},
			{"[EP] Sec:Gas Passer: Explode On Ignite", "explode_on_ignite",0,1,1,2},
			{"[EP] Sec:Projectile Multishot +3/Projectile Spread -4", "custom",0,1,1,2},
			
			{"[EP] Mle:Burn Damage +1000%", "weapon burn dmg increased",1,10,10,3},
			{"[EP] Mle:Ranged Resistance +30% While Active","dmg from ranged reduced",0,0.3,1.3,3},
			
			{"[EP] Burn Damage Delay +80%", "stack",0,1.6,3.2,0,"weapon burn dmg increased"},
			{"[EP] Ranged Resistance +15%","stat",0,-0.15,-0.3,0,"RangedResistance"},
			{"[EP] Max Health +200/Pri:Damage Mult -20%","custom",0,1,2,1},
			{"[EP] Max Health +100", "stat",0,100,200,0,"MaxHealth"},
			{"[EP] Crit Damage +20%","mult crit dmg",1,0.2,1.4,0},
			{"[EP] DMG vs Non-Burning x1.5", "dmg penalty vs nonburning",1,0.5,2,0},
			
			{"[EP] Available Epic + 1", "custom",0,1,2},
			{"[EP] ReRoll Points + 3","custom",0,1,4},
			{"[EP] Next Purchase is Rare Shop","custom",0,1,4},
		},
		MinorEpicAttribute =
		{
		    {"[EP] Pri:Heal On Hit +1 health", "stat",0,1,4,1,"HealonHit"},
		    {"[EP] Tank Damage Bonus +10%", "mult dmg vs tanks",1,0.1,2},
		    {"[EP] Recall On Death +25% chance", "teleport instead of die",0,0.25,1,0},
			{"[EP] ReRoll Points + 1","custom",0,1},
		},
		LegendaryAttribute =
		{
			{"【LEGEN】Next Purchase is Epic Shop","custom",0,1,4},
			{"【LEGEN】Upgrade Point + 1","custom",0,1,2},
			{"【LEGEN】All Stats Up", "custom",0,1,1,0},
		
			{"【LEGEN】Damage x1.25", "dmg penalty vs players",1,0.25,1.25,0},
			{"【LEGEN】Dragon's Fury", "stack",0,-0.3,-0.3,1,"mult_item_meter_charge_rate"},
			{"【LEGEN】Very Big Pyro", "custom",0,1,1,0,"Pyro is very big"},
			{"【LEGEN】Double Healing", "healing received bonus",1,1,1},
		},
	},
	[4] = --Demoman Shop
	{
		CommonAttribute =
		{
			--base character
			{"melee damage test upgrade", "custom",0,1,5,2},
			{"All Resistance Upgrade +20%", "custom",0,1,4,0},
			{"All Max Ammo +35%", "custom",1,0.35,2.05,0},
			{"Self Blast -40%", "blast dmg to self increased",1,-0.4,0.2,0},
			{"Ammo Regen +10% every 5 seconds", "ammo regen",0,0.1,0.2,0},
			{"Move Speed +20%", "stat",0,0.2,0.4,0,"MoveSpeed"},
			--base weapon
			{"Pri:Heal On Kill +25", "heal on kill",0,25,75,1},
			{"Sec:Heal On Kill +25", "heal on kill",0,25,75,2},
			{"Mle:Heal On Kill +50", "heal on kill",0,50,100,3},
			{"Pri:Clip Size +25%", "stat",0,0.25,0.75,1,"ClipSize"},
			{"Pri:Reload Rate +20%", "stat",0,-0.2,-0.6,1,"ReloadRate"},
			{"Pri:Fire Rate +15%", "stat",0,-0.15,0.45,1,"FireRate"},
			{"Sec:Clip Size +25%", "stack",0,0.25,0.75,2,"clip size bonus"},
			{"Sec:Reload Rate +20%","stack",0,-0.2,-0.6,2,"faster reload rate"},
			{"Sec:Fire Rate +15%", "stat",0,-0.15,-0.45,2,"SecFireRateMult"},
			{"Mle:Damage Bonus +25%", "stat",0,0.25,0.75,3,"MleDamageBonus"},
			{"Damage +10%/Sec:Charge Recharge +75%/Time +1", "custom",0,1,5,2},
			--special
			{"Damage mult +0.15/Pri:Blast Radius -15%", "custom",0,1,3,1},
			{"Damage mult +0.15/Sec:Sticky Arm Penalty -0.1", "custom",0,1,3,2},
			
			{"Pri:Damage Bonus +15%", "stat",0,0.15,0.45,1,"DamageBonus"},
			{"Sec:Damage Bonus +15%", "stat",0,0.15,0.45,2,"SecDamageBonus"},
			{"Mle:Damage Bonus +15%", "stat",0,0.15,0.45,3,"MleDamageBonus"},
		},
		RareAttribute =
		{
			--base weapon
			{"(R) Pri:Damage Bonus +20%", "stat",0,0.2,0.8,1,"DamageBonus"},
			{"(R) Sec:Damage Bonus +20%", "stat",0,0.2,0.8,2,"SecDamageBonus"},
			{"(R) Mle:Damage Bonus +25%", "stat",0,0.25,1,3,"MleDamageBonus"},
			{"(R) Mle:Heal on Hit +15", "heal on hit for slowfire",0,15,30,3},
			{"(R) Sec:Shield Control +100%/Push Force -50%", "custom",0,1,2,2},
			{"(R) Sec:Sticky Arm Bonus +0.2s", "custom",0,1,2,2},
			{"(R) Sec:Blast Radius +20%", "stack",0,0.2,0.6,2,"Blast radius increased"},
			--base char
			{"(R) Sec:Damage Taken -10%", "dmg taken increased",1,-0.1,0.8,2},
			{"(R) Health Regen +5", "health regen",0,5,10,0},
			{"(R) Max Health +50", "stat",0,50,300,0,"MaxHealth"},
			{"(R) Health +75/Max Ammo -20%", "custom",0,1,3,0},
			{"(R) Weapon Switch +50%", "deploy time decreased",1,-0.5,0.05,0},
			--special
			{"(R) Pri:Fire Rate +25%/Spread Angle -2", "custom",0,1,3,1},
			{"(R) Pri:Clip Size +50%", "stat",0,0.5,1,1,"ClipSize"},
			{"(R) Sec:Charge Crash Damage +100%", "stack",0,1,3,2,"charge impact damage increased"},
			{"(R) Mle:Crit On Kill +2s", "critboost on kill",0,2,4,3},
			{"(R) Mle:Melee Hit Refill Charge +20%", "charge meter on hit",0,0.2,0.4,3},
			{"(R) Taunt Speed +100%", "custom",0,1,2,0},
		},
		EpicAttribute =
		{
			{"[EP] Pri:Damage Bonus +40%", "stat",0,0.4,0.8,1,"DamageBonus"},
			{"[EP] Sec:Damage Bonus +40%", "stat",0,0.4,0.8,2,"SecDamageBonus"},
			{"[EP] Mle:Damage Mult +0.5", "stat",0,0.5,1,3,"MleDamageMult"},
			
			{"[EP] Pri:Damage mult +0.5/FireRate Mult -0.5", "custom",0,1,2,1},
			{"[EP] Pri:Blast Radius +50%/FireRate Mult -1", "custom",0,1,2,1},
			{"[EP] Pri:Reload Rate -30%", "stat",0,-0.3,-0.3,1,"ReloadRate"},
			{"[EP] Pri:Fire Rate +60%/Ammo +50%", "custom",0,1,2,1},
			{"[EP] Pri:No FireRate/Clip Size -25%/Damage Mult -0.33/Ammo +50%", "custom",0,1,1,1},
			{"[EP] Pri:Grenade Fuse x0.3/Detonation DMG +100%/Damage Mult -0.2", "custom",0,1,1,1,
			"Grenade deals extra damage upon explode on air"},
			{"[EP] Pri:Rolling Grenade Damage x4/Damage Mult -0.2", "custom",0,1,1,1,
			"Grenade deals double damage after contacting surface"},
			{"[EP] Pri:Grenade Explode On Impact", "grenade explode on impact",0,1,1,1},
			{"[EP] Sec:No Fire Delay/Reload All At Once/Clip Size -0.75", "custom",0,1,1,2},
			{"[EP] Sec:No Fire Delay/Reload All At Once/Clip Size -0.5", "custom",0,1,1,2},
			{"[EP] Sec:Reload Rate -30%", "stack",0,-0.3,-0.3,2,"faster reload rate"},
			{"[EP] Sec:Bazooka/FireRate Mult +1", "custom",0,1,1,2,
			"Weapons uses Beggar's bazooka mechanism"},
			{"[EP] Sec:FireRate Mult +2/Sticky Arm Penalty -0.4s", "custom",0,1,1,2},
			{"[EP] Sec:Sticky Only Stick on Enemies/Damage Mult +0.3", "custom",0,1,1,2},
			{"[EP] Sec:Damage Per Target +30%/FireRate Mult -0.25", "custom",0,1,2,2},
			{"[EP] Mle:Melee Range/Attack Rate +200%/Damage Mult -0.7", "custom",0,1,1,3},
			{"[EP] Mle:Melee Cleave/Attack Rate -100%/Damage Mult +0.5", "custom",0,1,1,3},
			{"[EP] Mle:Honor Bound/Live for Honor", "custom",0,1,1,3,
			"Damage Taken from Melee +100%/Damage Taken from Ranged -40%"},
			{"[EP] Mle:Honor Bound/Critboost Other Weapon", "custom",0,1,1,3,
			"Critboost on kill +10s/Melee Crit damage -66%"},
			
			{"[EP] Max Health +100", "stat",0,100,200,0,"MaxHealth"},
			{"[EP] Ranged Resistance +25%/Jump x2.5", "custom",0,1,1,0},
		    
			{"[EP] Available Epic + 1", "custom",0,1,2},
			{"[EP] ReRoll Points + 3","custom",0,1,4},
			{"[EP] Next Purchase is Rare Shop","custom",0,1,4},
		},
		MinorEpicAttribute =
		{
		    {"[EP] Tank Damage Bonus +15%", "mult dmg vs tanks",1,0.15,1.3},
		    {"[EP] Damage Bonus vs Buildings +25%", "dmg bonus vs buildings",1,0.25,1.5},
		    {"[EP] Speed Boost On Kill +5 seconds", "speed_boost_on_kill",0,5,5},
			{"[EP] ReRoll Points + 1","custom",0,1},
		},
		LegendaryAttribute =
		{
			{"【LEGEN】Next Purchase is Epic Shop","custom",0,1,4},
			{"【LEGEN】Upgrade Point + 1","custom",0,1,2},
			{"【LEGEN】All Stats Up", "custom",0,1,1,0},
		
			{"【LEGEN】Full Heal on Kill", "restore health on kill",0,100,100,0},
			{"【LEGEN】Pri:Nuke", "custom",0,1,1,1,"Weapon projectile replaced with cannonball that causes huge explosion"},
			{"【LEGEN】Sec:Charge Hit like Train", "stack",0,19,19,2,"charge impact damage increased"},
		}
	},
     [6] = --Heavy Shop
	{
		CommonAttribute =
		{
		--base char
		    {"melee damage test upgrade", "custom",0,1,4,0},
			{"All Resistance Upgrade +20%", "custom",0,1,4},
			{"All Max Ammo +35%", "custom",1,0.35,2.05,0},
			{"Health +50/-25% OverHealed", "custom",0,1,4,0},
			{"Health Regen +4 every second", "health regen",0,4,12},
		--base weapon
			{"Pri:Heal On Kill +25", "heal on kill",0,25,75,1},
			{"Sec:Heal On Kill +25", "heal on kill",0,25,75,2},
			{"Mle:Heal On Kill +50", "heal on kill",0,50,100,3},
			{"Pri:Fire Rate +10%", "stat",0,-0.1,-0.4,1,"FireRate"},
			{"Sec:Clip Size +25%", "stack",0,0.25,0.75,2,"clip size bonus"},
			{"Sec:Reload Rate +20%","stack",0,-0.2,-0.6,2,"faster reload rate"},
			{"Sec:Fire Rate +15%", "stat",0,-0.15,-0.45,2,"SecFireRateMult"},
			{"Mle:Damage Bonus +25%", "stat",0,0.25,0.75,3,"MleDamageBonus"},
		--special
			{"Sec:Food Consume/Recharge and Switch +40%","custom",0,1,2,2},
			
			{"Sec:Damage Bonus +20%", "stat",0,0.2,0.6,2,"SecDamageBonus"},
			{"Mle:Damage Bonus +25%", "stat",0,0.25,0.75,3,"MleDamageBonus"},
			
		},
		RareAttribute =
		{
		--base char
			{"(R) Pri:Damage Bonus +10%/Spin Up Penalty -100%", "custom",0,1,3,1},
			{"(R) Sec:Damage Bonus +35%", "stat",0,0.35,1.05,2,"SecDamageBonus"},
			{"(R) Sec:Bullet Per Shot +30%/Weapon Switch +25%", "custom",0,1,4,2},
			{"(R) Mle:Damage Bonus +50%", "stat",0,0.5,1,3,"MleDamageBonus"},
			
			{"(R) Mle:Heal on Hit +15", "heal on hit for slowfire",0,15,30,3},
			{"(R) Blast Resistance +20%", "dmg taken from blast increased",1,-0.2,0.8,0},
			{"(R) Bullet Resistance +20%", "dmg taken from bullets increased",1,-0.2,0.8,0},
			{"(R) Extra Jump +1/Jump Height +20%","custom",0,1,1,0},
			{"(R) Move Speed +20%", "stat",0,0.2,0.4,0,"MoveSpeed"},
			{"(R) Max Health +50", "stat",0,50,300,0,"MaxHealth"},
		--base weapon
			{"(R) Pri:Weapon Switch On-Spin", "mod minigun can holster while spinning",0,1,1,1},
			{"(R) Pri:Spin Up Time +15%/Spun Up Speed +10%", "custom",0,1,3,1},
			{"(R) Pri:Projectile Penetration +1", "projectile penetration heavy",0,1,3,1},
			{"(R) Pri:Minigun Destroy Projectiles +1/Ammo +25%", "custom",0,1,2,1},
			
			{"(R) Steak:Buff Also Applies Damage x1.5","custom",0,1,1,2},
			
			{"(R) Mle:DMG Resistance +10%/Debuff Target on Hit", "custom",0,1,1,3,
			"Removes penalty of Warrior's Spirit/Debuff causes target to take 20% more damage for 5s"},
		--special
			{"(R) Spun Up Protection 20% Below 50% Health","stack",0,-0.2,-0.4,1,"spunup_damage_resistance"},
			{"(R) Damage Mult +10%/Pri:Spin Up Time -130%", "custom",0,1,3,1},
			{"(R) Fire Rate Bonus on Reduced Health", "fire rate bonus with reduced health",0,1,1,0},
			{"(R) Mle:Disable Max Health Drain","mod_maxhealth_drain_rate",0,-1,-1,3},
		},
		EpicAttribute =
		{
		--special modifier
			{"[EP] Pri:Damage Bonus +10%", "stat",0,0.1,0.2,1,"DamageBonus"},
			{"[EP] Sec:Bullets Per Shot +100%", "stat",0,1,2,2,"SecBulletPerShot"},
			{"[EP] Sec:Damage Bonus +75%", "stat",0,0.75,1.5,2,"SecDamageBonus"},
			{"[EP] Mle:Damage Mult +1.0", "stat",0,1,2,3,"MleDamageMult"},
			
			{"[EP] Pri:Override Firing Mod:Spread", "custom",0,1,1,1,
			"Bullet Per Shot +25%/Spread Penalty -60%/FireRate Mult +0.2"},
			{"[EP] Pri:Override Firing Mod:Single", "custom",0,1,1,1,
			"DamageMult +2/Bullet Per Shot -75%/Spread Bonus +70%/FireRate Mult +0.2"},
			{"[EP] Pri:Override Firing Mod:Focus", "custom",0,1,1,1,
			"Spread Bonus +95%/FireRate Mult -0.4"},
			{"[EP] Pri:Override Firing Mod:Burst", "custom",0,1,1,1,
			"Damage Mult +0.2/Bullet Per Shot +300%/Spread Penalty -40%/FireRate Mult -4.5"},
			{"[EP] Pri:Bullet Per Shot +25%/Spread -60%", "custom",0,1,2,1},
			{"[EP] Pri:Damage Bonus +20%/Bullet Per Shot -25%", "custom",0,1,2,1},
			{"[EP] Pri:Spread Bonus +25%", "custom",0,1,2,1},
			{"[EP] Pri:Damage Bonus +25%/Fire Rate Mult -0.3/Spread -20%", "custom",0,1,2,1},
			{"[EP] Pri:Damage Mult +1/Above 50% Health Damage x0.4", "custom",0,1,2,1},
			{"[EP] Pri:DMG vs Burning +40%", "stack",0,0.4,0.8,1,"damage bonus vs burning"},
			{"[EP] Pri:Generate Rage/Piercing", "custom",0,1,1,1},
			{"[EP] Pri:Rocket Rain/No Ramp up", "custom",0,1,1,1},
			
			{"[EP] Steak:Buff Also Applies +35% Resistance","custom",0,1,1,2},
			{"[EP] Sec:Damage Mult +2.0/Reload -400%", "custom",0,1,1,1},
			{"[EP] Sec:Bullet Per Shot +100%/Spread -20%", "custom",0,1,2,2},
			{"[EP] Sec:Damage Mult +1/FireRate Mult -0.4", "custom",0,1,2,2},
			{"[EP] Sec:Bullets +100%/Reload +30%/FireRate Mult -0.4", "custom",0,1,2,2},
			{"[EP] Mle:Attack Rate +100%", "stack",0,-0.5,-0.5,3,"fire rate bonus"},
			{"[EP] Mle:Crit Damage +100%", "mult crit dmg",1,1,3,3},
			{"[EP] Mle:Damage Mult +2/Move Speed -40%/FireRate -40%", "custom",0,1,2,3},
			
			{"[EP] No Damage Falloff/Ramp Up", "custom",0,1,1,0},
			{"[EP] Move Speed +35%", "stat",0,0.35,0.35,0,"MoveSpeed"},
			{"[EP] Ranged Resistance +10%/Heal on Hit +2", "custom",0,1,2,0},
			{"[EP] Size Up/+150 Health", "custom",0,1,2,0},
			{"[EP] Max Health +100/Ranged Resistance +10%", "custom",0,1,2,0},
			{"[EP] Max Health +200/Pri:Damage Mult -20%", "custom",0,1,2,0},
			
			{"[EP] Available Epic + 1", "custom",0,1,2},
			{"[EP] ReRoll Points + 3","custom",0,1,4},
			{"[EP] Next Purchase is Rare Shop","custom",0,1,4},
		},
		MinorEpicAttribute =
		{
		    {"[EP] Tank Damage Bonus +30%", "mult dmg vs tanks",1,0.3,0.9,0},
			{"[EP] ReRoll Points + 1","custom",0,1},
		},
		LegendaryAttribute =
		{
			{"【LEGEN】Next Purchase is Epic Shop","custom",0,1,4},
			{"【LEGEN】Upgrade Point + 1","custom",0,1,2},
			{"【LEGEN】All Stats Up", "custom",0,1,1,0},
		
			{"【LEGEN】Health +200", "max health additive penalty",0,200,200,0},
			{"【LEGEN】Crit vs Burning", "crit vs burning players",0,1,1,0},
			{"【LEGEN】No Spin up", "custom",0,1,1,1},
			{"【LEGEN】No Reload", "faster reload rate",1,-1,0,2},
			{"【LEGEN】Rocket", "custom",0,1,1,1},
		}
	},
	[9] = --Engineer Shop
	{
		CommonAttribute =
		{
			--base char
			{"melee damage test upgrade", "custom",0,1,5,0},
			{"All Resistance Upgrade +20%", "custom",0,1,4,0},
			{"All Max Ammo +35%", "custom",1,0.35,2.05,0},
			{"Move Speed +20%", "stat",0,0.2,0.4,0,"MoveSpeed"},
			--base weapon
			{"Dispenser Range +100%/Metal Pickup +50%", "custom",1,1,3,4},
			{"Max Metal Capacity +100%/Metal Regen +15", "custom",0,1,3,0},
			{"Building Health +50%/Repair Rate +25%", "custom",0,1,4,4},
			{"Upgrade Rate +240%", "upgrade rate decrease",1,2.4,8},
			
			{"Heal On Kill +25", "heal on kill",0,25,75,0},
			{"Damage Bonus +30%/Pri:Ammo -25%", "custom",0,1,3,1},
			{"Pri:Reload Rate +20%", "stat",0,-0.2,-0.6,1,"ReloadRate"},
			{"Sec:Reload Rate +20%", "stack",0,-0.2,-0.6,2,"faster reload rate"},
			
			{"Damage Mult +0.2", "stack",0,0.2,0.6,0,"damage penalty"},
			{"Mle:Damage Bonus +25%", "stat",0,0.25,0.75,3,"MleDamageBonus"},
		},
		RareAttribute =
		{
			--base char
			{"(R) Health Regen +5", "health regen",0,5,10,0},
			{"(R) Metal Regen +30", "stat",0,30,90,0,"MetalRegen"},
			{"(R) Max Metal +200%", "stat",0,2,4,0,"MaxMetal"},
			{"(R) Max Health +40", "stat",0,40,240,0,"MaxHealth"},
			
			--weapon
			{"(R) Pri:Damage Bonus +35%", "stat",0,0.35,1.05,1,"DamageBonus"},
			{"(R) Sec:Damage Bonus +35%", "stat",0,0.35,1.05,2,"SecDamageBonus"},
			{"(R) Mle:Damage Bonus +50%", "stat",0,0.5,1,3,"MleDamageBonus"},
			{"(R) Mle:Heal On Kill +100", "heal on kill",0,100,100,3},
			{"(R) Damage Mult +0.3/Ranged Resistance +10%", "custom",0,1,3,0},
			
			{"(R) Pri:Crit Damage +50%", "stack",0,0.5,1,1,"mult crit dmg"},
			{"(R) Pri:Energy Weapon Projectile Penetration", "energy weapon penetration",0,1,1,1},
			{"(R) Taunt Speed +100%/Eureka:Lesser Penalty", "custom",0,1,2,3},
			
			{"(R) Building Health +100%/Repair Rate +25%", "custom",0,1,3,4},
			{"(R) Sentry Firing Speed +10%", "sentry rapid fire",1,0.1,1.3,4},
			{"(R) Sentry Rocket Specialist","rocket specialist",0,1,1,4},
			{"(R) Teleporter Build Rate +300%", "engineer teleporter build rate multiplier",1,3,4,4},
			{"(R) Mle:120 Metal Ranged Building Pickup", "engineer building teleporting pickup",160,-40,1,3,"each upgrade reduces ammo use by 40"},
			{"(R) Rescue Ranger: No Mark for Death", "mark for death on building pickup",1,-1,0,1},
		},
		EpicAttribute =
		{
			--combat
			{"[EP] Damage Bonus +50%", "stat",0,1,2,1,"DamageBonusSelf"},
			{"[EP] Mle:Damage Mult +1.0", "stat",0,1,2,3,"MleDamageMult"},
			{"[EP] Pri:Damage Mult +1/Sentry Damage -20%", "custom",0,1,2,1},
			
			{"[EP] Sec:Damage Bonus +300%/FireRate Mult -2", "custom",0,1,1,2},
			
			{"[EP] Pri:Damage Mult +2.0/Reload -400%", "custom",0,1,1,1},
			{"[EP] Pri:Reload Rate -30%", "stack",0,-0.3,-0.3,1,"Reload time decreased"},
			{"[EP] Pri:Damage Mult +1/FireRate Mult -0.4", "custom",0,1,2,2},
			{"[EP] Pri:Bullet Per Shot +100%/Spread -20%", "custom",0,1,2,2},
			{"[EP] Pri:Bullets Per Shot +200%/FireRate Mult -1", "custom",0,1,2,1},
			
			{"[EP] Energy Weapon Damage x3", "custom",0,1,1,0},
			{"[EP] Mle:Bleed Damage +1900%", "mult bleeding dmg",1,19,20,3},
			{"[EP] Mle:Crit on Kill +5s", "critboost on kill",0,5,10,3},
			{"[EP] Mle:Mini Crit on Kill +5s", "minicritboost on kill",0,5,10,3},
			{"[EP] Mle:Crit Damage +150%/No Random Crits", "custom",0,1,2,3},
			{"[EP] Mini Sentry/Sentry Damage +100%", "custom",0,1,1,4},
			{"[EP] Damage vs Sentry Target +50%", "damage bonus bullet vs sentry target",1,0.5,2,0},
			{"[EP] Max Health +100", "stat",0,100,200,0,"MaxHealth"},
			--buildings
			{"[EP] Mle:Build Speed +40%", "build rate bonus",1,-0.4,0.6,3},
			
			{"[EP] Building Max Level 2/No Sentry Cost/Metal Regen +60", "custom",0,1,1,4},
			{"[EP] Metal Regen +50", "stat",0,50,50,0,"MetalRegen"},
			{"[EP] Sentry Damage +20%", "stat",0,0.2,0.4,4,"SentryDamage"},
			{"[EP] Sentry Damage +40%/Wrangler Shield Disabled", "custom",0,1,1,4},
			{"[EP] Sentry Range +25%", "stat",0,0.25,0.5,4,"SentryRange"},
			{"[EP] Building Health +300%/Sentry Damage -20%", "custom",1,1,2,4},
			{"[EP] Upgraded Sentry/Sentry Cost +150%", "custom",0,1,1,4,
			"Sentry Damage +30%/Building Health +100%"},
			{"[EP] Override Sentry Firing Mod:Rocket", "custom",0,1,1,4,
			"Sentry only fires rocket/Sentry Damage Mult +1.5/Self Blast DMG -95%"},
			{"[EP] Override Sentry Firing Mod:Machine Gun", "custom",0,1,1,4,
			"Sentry only fires Machine gun/Sentry FireRate Mult +1.0/Sentry Ammo -15%"},
			{"[EP] Override Sentry Firing Mod:Sentinel", "custom",0,1,1,4,
			"Sentry only fires rocket/Sentry Damage Mult +4.0/Sentry Range +100%/Self Blast DMG -95%"},
			{"[EP] Disposable Sentry +2/Sentry No Repair", "custom",0,1,2,4},
			{"[EP] Two-Way Teleporter/Instant Recharge", "custom",0,1,1,4},
			{"[EP] Dispenser Rate x5/Dispenser Range +100%", "custom",0,5,10,4},
			
			{"[EP] Available Epic + 1", "custom",0,1,2},
			{"[EP] ReRoll Points + 3","custom",0,1,4},
			{"[EP] Next Purchase is Rare Shop","custom",0,1,4},
		},
		MinorEpicAttribute =
		{
		    {"[EP] Crit Damage Bonus +10%", "mult crit dmg",1,0.1,10,0},
			{"[EP] ReRoll Points + 1","custom",0,1},
		},
		LegendaryAttribute =
		{
			{"【LEGEN】Next Purchase is Epic Shop","custom",0,1,4},
			{"【LEGEN】Upgrade Point + 1","custom",0,1,2},
			{"【LEGEN】All Stats Up", "custom",0,1,1,0},
		
			{"【LEGEN】Crit On Kill +5 seconds", "critboost on kill",0,5,5,0},
		}
	},
	[5] = --Medic Shop
	{
		CommonAttribute =
		{
			--base char
			--{"med upgrade test", "custom",0,1,4,0},
			--{"med upgrade test2", "custom",0,1,4,0},
			--{"med upgrade check", "custom",0,1,4,0},
			{"melee damage test upgrade", "custom",0,1,4,2},
			{"All Resistance Upgrade +20%", "custom",0,1,4,0},
			{"All Max Ammo +35%", "custom",1,0.35,2.05,0},
			{"Move Speed +20%", "stat",0,0.2,0.4,0,"MoveSpeed"},
			{"Ammo Regen +10% every 5 seconds", "ammo regen",0,0.1,0.2,0},
			--base weapon
			{"Pri:Clip Size +25%", "clip size bonus",0,4,4,1},
			{"Pri:Reload Rate +20%", "stat",0,-0.2,-0.6,1,"ReloadRate"},
			{"Pri:Fire Rate +15%", "stat",0,-0.15,-0.45,1,"FireRate"},
			{"Mle:Damage Bonus +25%", "stat",0,0.25,0.75,3,"MleDamageBonus"},
			{"Sec:UberCharge Rate +35%", "stat",0,0.35,1.05,2,"UberRate"},
			{"Sec:Overheal Bonus +50%", "stat",0,0.5,1.5,2,"OverhealBonus"},
			{"Sec:Heal Rate +25%", "stat",0,0.25,1,2,"HealRate"},
			{"Sec:Projectile Shield/Rage Duration -70%", "custom",0,1,1,2},
			{"Weapon Switch Speed +70%", "deploy time decreased",1,-0.7,0.3},
			{"Heal On Kill +25", "heal on kill",0,25,75,0},
			
			{"Pri:Damage Bonus +35%", "stat",0,0.35,0.7,1,"DamageBonus"},
			{"Mle:Damage Bonus +25%", "stat",0,0.25,0.75,3,"MleDamageBonus"},
		},
		RareAttribute =
		{
			{"(R) Pri:Damage Bonus +50%", "stat",0,0.5,1,1,"DamageBonus"},
			{"(R) Mle:Damage Bonus +50%", "stat",0,0.5,1,3,"MleDamageBonus"},
			{"(R) Mle:Heal On Kill +100", "heal on kill",0,100,200,3},
			
			{"(R) Sec:Uber Duration +2s", "stat",0,2,6,2,"UberDuration"},
			{"(R) Sec:Overheal Expert +2", "overheal expert",0,1,3,2},
			{"(R) Sec:Healing Mastery +1", "healing mastery",0,1,3,2},
			{"(R) Sec:Rage Duration +30%", "stat",0,0.3,0.6,2,"RageDuration"},
			{"(R) Sec:Heal Rate +35%", "stat",0,0.35,1.05,2,"HealRate"},
			{"(R) Sec:Overheal Bonus +75%", "stat",0,0.75,2.25,2,"OverhealBonus"},
			{"(R) Sec:Minor Canteen Sharing", "canteen specialist",0,1,1,2},
			{"(R) Sec:Healing Ally Applies +50% Reload Rate", "custom",0,1,1,2},
			{"(R) Mle:Uber Saw Bonus on Other Melee", "add uber charge on hit",0.15,0.1,0.45,3,
			"Upgrade increases uber gain further by 10%"},
			
			{"(R) Damage Bonus +50%", "stack",1,0.5,3,0,"damage bonus"},
			{"(R) Max Health +40", "stat",0,40,240,0,"MaxHealth"},
			{"(R) Damage Mult +0.3/Ranged Res +10%/Uber Rate -25%", "custom",0,1,3,0},
			{"(R) Heal On Kill +50", "heal on kill",0,50,100,0},
			{"(R) Heal Buildings", "medic machinery beam",0,10,10,2},
			{"(R) Taunt Speed +40%", "gesture speed increase",1,0.4,1.4},
			--{"(R) Extra Jump +1", "air dash count",0,1},
			--{"(R) Mad Milk Syringes", "mad milk syringes",0,1,1},
			--{"(R) Medigun Range +25%", "mult medigun range",1,0.25},
			--{"(R) Revive Speed +60%", "revive rate",1,0.6,2.2},
			--{"(R) Speed Boost On Kill +5 seconds", "speed_boost_on_kill",0,5,5},
		},
		EpicAttribute =
		{
			{"[EP] Pri:Damage Bonus +100%", "stat",0,1,2,1,"DamageBonus"},
			{"[EP] Mle:Damage Mult +1.0", "stat",0,1,2,3,"MleDamageMult"},
			
			{"[EP] Pri:Damage Mult +1/Sec:Instant OverHeal Decay", "custom",0,1,1,2},
			{"[EP] Pri:FireRate Mult +9/Clip Size -95%/Spread -4", "custom",0,1,1,1},
			{"[EP] Pri:Burst Fire +2/FireRate Mult -1", "custom",0,1,1,1},
			{"[EP] Pri:Damage Mult +2/Use Ubercharge as Ammo", "custom",0,1,1,1},
			{"[EP] Pri:Damage Mult +2.0/Reload -400%", "custom",0,1,1,1},
		
			{"[EP] Sec:Ranged Res -15%/Pri:Damage Mult +1", "custom",0,1,1,1},
			{"[EP] Recall/Sec:Revive Speed x3/No OverHeal", "custom",0,1,1,2},
			{"[EP] Sec:UberCharging Mod:Blank", "custom",0,1,1,2,"Very quick and instantly discharging Ubercharge"},
			{"[EP] Sec:UberCharging Mod:Extended", "custom",0,1,1,2,"Way longer Uber duration"},
			{"[EP] Sec:UberCharging Mod:Balanced", "custom",0,1,1,2,"Slight quicker Ubercharging and longer duration"},
			{"[EP] Sec:Overheal Rate +500%/HealRate -70%", "custom",0,1,1,2},
			{"[EP] Sec:No OverHeal Decay", "overheal decay bonus",0,50,50,2},
			{"[EP] Sec:Overheal Bonus +100%", "stat",0,1,1,2,"OverhealBonus"},
			{"[EP] Sec:Heal Rate +75%", "stat",0,0.75,1.5,2,"HealRate"},
			{"[EP] Sec:Heal Rate +300%/Rage Duration -100%", "custom",0,1,1,2},
			
			{"[EP] Mle:Hitting Enemy Gives you Double Damage for 5s", "custom",0,1,1,3},
			{"[EP] Mle:Hitting Enemy Gives you Health Regen +20 for 5s", "custom",0,1,1,3},
			{"[EP] Mle:Hitting Enemy Gives you Double Heal Rate for 5s", "custom",0,1,1,3},
			{"[EP] Mle:Crit on Kill 5s", "critboost on kill",0,5,5,3},
			
			{"[EP] Max Health +200/Sec:Health Drain", "custom",0,1,1,"You have 30 seconds to live"},
		    {"[EP] Major Canteen Sharing", "canteen specialist",0,4,4,2},
		    
			{"[EP] Available Epic + 1", "custom",0,1,2},
			{"[EP] ReRoll Points + 3","custom",0,1,4},
			{"[EP] Next Purchase is Rare Shop","custom",0,1,4},
		},
		MinorEpicAttribute =
		{
		    {"[EP] Heal-on-Hit +1", "heal on hit for rapidfire",0,1,10,1},
			{"[EP] ReRoll Points + 1","custom",0,1},
		},
		LegendaryAttribute =
		{
			{"【LEGEN】Next Purchase is Epic Shop","custom",0,1,4},
			{"【LEGEN】Upgrade Point + 1","custom",0,1,2},
			{"【LEGEN】All Stats Up", "custom",0,1,1,0},
		
			{"【LEGEN】Override UberCharging : Infinite", "custom",0,1,1,"Greatly increase Ubercharging rate and reduced duration no shield"},
			{"【LEGEN】Crit on Kill +5s", "critboost on kill",0,5,5},
			{"【LEGEN】Mark of Death on Hit", "mark for death",0,1,1},
			{"【LEGEN】Invulnerable Chance on Taking Damage +30%", "uber on damage taken",0,0.3,0.3},
			{"【LEGEN】Mini crits become Crits", "minicrits become crits",0,1,1,0},
			{"【LEGEN】All Healing Received +100%", "healing received bonus",1,1,2,0},
			{"【LEGEN】Mixed Concoction On Hit", "custom",0,1,1,2,
			"Shield Duration -50%"},
			--{"【LEGEN】 Gain Uber On Hit +1%", "add uber charge on hit",0,0.01,0.01},
		}
	},
	[2] = --Sniper Shop
	{
		CommonAttribute =
		{
			--base char
			{"melee damage test upgrade", "custom",0,1,4,1},
			{"All Resistance Upgrade +20%", "custom",0,1,4},
			{"All Max Ammo +35%", "custom",1,0.35,2.05,0},
			{"Move Speed +20%", "stat",0,0.2,0.4,0,"MoveSpeed"},
			{"Weapon Switch Speed +70%", "deploy time decreased",1,-0.7,0.3},
			--base weapon
			{"Pri:Heal On Kill +25", "heal on kill",0,25,75,1},
			{"Sec:Heal On Kill +25", "heal on kill",0,25,75,2},
			{"Mle:Heal On Kill +50", "heal on kill",0,50,100,3},
			{"Pri:Reload Rate +20%", "stat",0,-0.2,-0.6,1,"ReloadRate"},
			{"Sec:Clip Size +25%", "stack",0,0.25,0.75,2,"clip size bonus"},
			{"Sec:Reload Rate +20%","stack",0,-0.2,-0.6,2,"faster reload rate"},
			{"Pri:Minor Explosive Headshot", "explosive sniper shot",0,1,1,1},
			
			{"Pri:Damage Bonus +15%", "stat",0,0.15,0.45,1,"DamageBonus"},
			{"Sec:Damage Bonus +25%", "stat",0,0.25,0.75,2,"SecDamageBonus"},
			{"Mle:Damage Bonus +25%", "stat",0,0.25,0.75,3,"MleDamageBonus"},
		},
		RareAttribute =
		{
			--base char
			{"(R) Ammo Regen +10% every 5 seconds", "ammo regen",0,0.1,0.1},
			{"(R) Health Regen +4 every second", "health regen",0,4,8,0},
			{"(R) Max Health +40", "stat",0,40,240,0,"MaxHealth"},
			{"(R) Extra Jump +1 Jump Height +20%","custom",0,1,1},
			
			{"(R) Damage Bonus +25%/Pri:Max Ammo -25%", "custom",0,1,3,1},
			{"(R) Damage Res +15%/Pri:Ammo -25%", "custom",0,1,3,1},
			--base weapon
			{"(R) Pri:Damage Bonus +20%", "stat",0,0.2,0.8,1,"DamageBonus"},
			{"(R) Sec:Damage Bonus +50%", "stat",0,0.5,1.5,2,"SecDamageBonus"},
			
			{"(R) Pri:Major Explosive Headshot", "explosive sniper shot",0,2,2,1},
			{"(R) Sec:Fire Rate +25%", "fire rate bonus",1,-0.25,0.5,2},
			{"(R) Sec:Bullet Per Shot +100%", "stat",0,1,3,2,"SecBulletPerShot"},
			{"(R) Sec:Spread Bonus +40%", "stat",0,-0.4,-0.8,2,"SecBulletSpread"},
			{"(R) Mle:Damage Bonus +50%", "stat",0,0.5,1,3,"MleDamageBonus"},
			
			{"(R) Pri:Damage Bonus On Full Charge +35%", "stat",0,0.35,1.05,1,"FullChargeDamage"},
			{"(R) Pri:Charge Speed +50%", "stat",0,0.5,1.5,1,"ChargeRate"},
			{"(R) Sec:Jarate Slows Targets", "applies snare effect",1,-0.35,0.65,2},
			{"(R) Sec:Jarate Recharge Rate +50%", "effect bar recharge rate increased",1,-0.5,0.5,2},
			{"(R) Jar:Also Applies Accuracy Penalty", "custom",0,1,1,2},
			{"(R) Sec:RazorBack Recharge Rate +100%", "mult_item_meter_charge_rate",1,-0.5,0.01,2},
			{"(R) Sec:MiniCrits to Crits", "minicrits become crits",0,1,1,2},
			{"(R) Mle:Hit and Bleed Tick gives you Invulnerablity for 1s", "custom",1,0.5,2,3},
			{"(R) Mle:Crit Damage +100%", "mult crit dmg",1,1,3,3},
			{"(R) Mle:Mark for Death/Speed Boost Based on Health", "custom",0,1,1,3},
			
			--{"(R) Pri:Projectile Penetration", "projectile penetration",0,1,1,1},
			
			
		},
		EpicAttribute =
		{
			{"[EP] Pri:Damage Bonus +40%", "stat",0,0.4,0.8,1,"DamageBonus"},
			{"[EP] Sec:Damage Mult +1.0", "stat",0,1,2,2,"SecDamageMult"},
			{"[EP] Mle:Damage Mult +1.0", "stat",0,1,2,3,"MleDamageMult"},
			{"[EP] Pri:Charge Speed +150%", "stat",0,1.5,3,1,"ChargeRate"},
			{"[EP] Pri:Full Charge Damage +150%", "stat",0,1.5,3,1,"FullChargeDamage"},
			
			{"[EP] Pri:Override Ammunition Type:Crits", "custom",0,1,1,
			"headshot damage"},
			{"[EP] Pri:Headshot Damage +50%", "stat",0,0.5,1,1,"HeadshotDamage"},
			{"[EP] Pri:Override Ammunition Type:Snap", "custom",0,1,1,
			"Quicker reload"},
			{"[EP] Pri:Reload Speed +30%/Bodyshot Penalty -25%", "custom",0,1,2,1},
			{"[EP] Pri:Override Ammunition Type:AP", "custom",0,1,1,
			"Periodic strong shot"},
			{"[EP] Pri:Damage Mult +0.5/Reload Rate -25%", "custom",0,1,2,1},
			{"[EP] Pri:Override Ammunition Type:Incendiary", "custom",0,1,1,1,
			"Burn Damage"},
			{"[EP] Pri:Override Ammunition Type:Explosive", "custom",0,1,1,1,
			"Explosive bullat"},
			{"[EP] Pri:Override Ammunition Type:Hollow Point", "custom",0,1,1,1,
			"knockback"},
			{"[EP] Pri:Explosive Headshot/Reload Rate -50%", "custom",0,1,1,1},
			{"[EP] Pri:Damage Mult +0.5/Cannot move while aiming", "custom",0,1,1,1},
			{"[EP] Pri:No Reload/Damage Mult -0.5/Ammo Regen", "custom",0,1,1,1,
			"MaxAmmo +100%/No Ammo From Dispenser While Active"},
			
			
			{"[EP] Bow:Projectile Ricochet/Ricochet Damage x2", "custom",0,1,1,1},
			{"[EP] Bow:Multishot Projectile +2", "custom",0,1,3,1},
			{"[EP] Bow:Homing", "mod projectile heat seek power",0,90,90,1},
			{"[EP] Bow:Heavier Arrow/Damage Mult +0.5", "custom",0,1,1,1},
			
			{"[EP] Sec:Headshot/Fire RateMult -2/Damage Mult +3", "custom",0,1,1,2,
			"Bullet Spread Bonus +20%"},
			{"[EP] Sec:Headshot/Explosive Headshot/Spread +60%", "custom",0,1,1,2},
			{"[EP] Sec:Bullet Per Shot +300%/Spread -120%", "custom",0,1,2,2},
			{"[EP] Sec:FireRate Mult +1/Spread -20%/Ammo +100%", "custom",0,1,2,2},
			{"[EP] Sec:Explosive rounds/Clip Size -50%/Ammo -25%", "custom",0,1,1,2},
			{"[EP] Sec:Damage Mult +2.0/Reload -400%", "custom",0,1,1,1},
			{"[EP] Sec:MiniCrits to Crits", "minicrits become crits",0,1,1,2},
			
			{"[EP] Mle:Ranged Res +25%", "dmg from ranged reduced",0,-0.25,0.75,3},
			{"[EP] Mle:Crit on Kill 5s", "critboost on kill",0,5,5,3},
			
			{"[EP] Max Health +100", "stat",0,100,200,0,"MaxHealth"},
			{"[EP] Ranged Res +25%/Pri:No Headshot", "custom",0,1,1,1},
			
			{"[EP] Available Epic + 1", "custom",0,1,2},
			{"[EP] ReRoll Points + 3","custom",0,1,4},
			{"[EP] Next Purchase is Rare Shop","custom",0,1,4},
		--	{"[EP] Meter Effect/Debuff Duration +50%", "mult effect duration",1,0.5},
		},
		MinorEpicAttribute =
		{
		    {"[EP] Rifle Charge Speed +50%", "stat",0,0.5,10,1,"ChargeRate"},
			{"[EP] ReRoll Points + 1","custom",0,1},
		},
		LegendaryAttribute =
		{
			{"【LEGEN】Next Purchase is Epic Shop","custom",0,1,4},
			{"【LEGEN】Upgrade Point + 1","custom",0,1,2},
			{"【LEGEN】All Stats Up", "custom",0,1,1,0},
		
			--{"【LEGEN】 Glass Cannon", "custom",0,1,1}, -- no idea
			{"【LEGEN】Crit on Kill +3s", "critboost on kill",0,3,3},
		}
	},	
	[8] = --Spy Shop
	{
		CommonAttribute =
		{
			--base char
			{"melee damage test upgrade", "custom",0,1,4,1},
			{"All Resistance Upgrade +20%", "custom",0,1,4,0},
			{"All Max Ammo +35%", "custom",1,0.35,2.05,0},
			{"Move Speed +20%", "stat",0,0.2,0.4,0,"MoveSpeed"},
			{"Ammo Regen +10% every 5 seconds", "ammo regen",0,0.1,0.2,0},
			--base weapon
			{"Pri:Clip Size +25%", "stat",0,0.25,0.75,1,"ClipSize"},
			{"Pri:Reload Rate +20%", "stat",0,-0.2,-0.6,1,"ReloadRate"},
			{"Pri:Fire Rate +15%", "stat",0,-0.15,0.45,1,"FireRate"},
			{"Pri:Heal On Kill +25", "heal on kill",0,25,75,1},
			{"Mle:Attack Rate +15%", "stat",0,-0.15,-0.45,3,"MleFireRate"},
			{"Mle:Heal On Kill +25", "heal on kill",0,100,200,3},
			{"Mle:Backstab Giant Damage +40%", "stat",0,10,40,3,"BackstabDamage"},
			
			{"Damage Mult +0.3/Switch +40/Mle:Backstab Damage -50%", "custom",0,1,3,3},
			
			
			{"Pri:Damage Bonus +25%", "stat",0,0.25,1,1,"DamageBonus"},
			{"Mle:Damage Bonus +25%", "stat",0,0.25,1,3,"MleDamageBonus"},
		--	{"Cloak Duration +20%", "cloak consume rate decreased",1,-0.2},
		},
		RareAttribute =
		{
			{"(R) Pri:Damage Bonus +50%", "stat",0,0.5,1,1,"DamageBonus"},
			{"(R) Mle:Damage Bonus +50%", "stat",0,0.5,1,3,"MleDamageBonus"},
			{"(R) Mle:Backstab Giant Damage +60%", "stat",0,15,45,3,"BackstabDamage"},
			
			{"(R) Wet Immunity", "wet immunity",0,1,1,0},
			{"(R) Pri:Bullet Spread Bonus +50%", "stat",0,-0.5,-0.01,1,"BulletSpread"},
			{"(R) Pri:Imitation Upgrade:Pyro", "custom",0,1,1,1,
			"Revolver penetration/Ignite/Afterburn Immune"},
			{"(R) Pri:Imitation Upgrade:Medic", "custom",0,1,1,1,
			"Health Regen +4/Revolver Milk Round"},
			{"(R) Pri:Imitation Upgrade:Soldier", "custom",0,1,1,1,
			"Minor Explosive Round/Self Blast Damage -40%"},
			{"(R) Pri:Crit Damage +100%", "mult crit dmg",1,1,3,1},
			
			{"(R) Sec:Robot Sapper Power", "robo sapper",0,2,4,2},
			
			{"(R) Cloak Recharge +100%/Fire Res -20%", "custom",0,1,2,4},
			{"(R) Cloak Recharge from Ammo +100%", "ReducedCloakFromAmmo",1,1,3,4},
			{"(R) Max Health +75/Move Speed -20%", "custom",0,1,2,0},
			{"(R) +40% Healing Received", "healing received bonus",1,0.4,1.8,0},
			
			{"(R) Imitation Upgrade:Scout", "custom",0,1,1,0,
			"Move Speed +40%/Double Jump"}, 
			{"(R) Recall On Death +50%", "teleport instead of die",0,0.5,1,0},
			{"(R) Max Health +40", "max health additive bonus",0,40,160},
			{"(R) Credit Collect Range +100%/Collect on Kill", "custom",0,1,2,0},
			{"(R) Cloak Recharge Rate +50%", "stat",0,0.5,1.5,4,"CloakRechargeRate"},
		},
		EpicAttribute =
		{
			{"[EP] Pri:Damage Bonus +100%", "stat",0,1,2,1,"DamageBonus"},
			{"[EP] Mle:Damage Mult +1.0", "stat",0,1,2,3,"MleDamageMult"},
			
			{"[EP] Pri:Damage Mult +1/FireRate Mult +1/Spread -700%", "custom",0,1,1,1},
			{"[EP] Pri:Damage Bonus x8 While Disguised/Damage", "damage bonus while disguised",1,3,7,1},
			{"[EP] Pri:Last Bullet Is A Crit", "last shot crits",0,1,1,1},
			
			{"[EP] Pri:Override Imitation:Demo", "custom",0,1,1,1,
			"Revolver periodic large explosion with huge self blast dmg"},
			{"[EP] Pri:Override Imitation:Sniper", "custom",0,1,1,1,
			"No damage falloff with periodic accurate shot"},
			{"[EP] Pri:Override Imitation:Engineer", "custom",0,1,1,1,
			"Revolver fires like shotgun blast"},
			{"[EP] Pri:Major Explosive Headshot", "explosive sniper shot",0,3,3,1},
			
			{"[EP] Mle:Backstab Giant DMG +200%/Attack Rate -30%", "custom",0,1,2,3},
			{"[EP] Mle:Damage Mult +2/Attack Rate -40%", "custom",0,1,1,3},
			{"[EP] Mle:Crit on Kill 4s", "critboost on kill",0,4,8,3},
			{"[EP] Mle:Move Speed +40%", "mult_player_movespeed_active",1,0.4,1.4,3},
			
			{"[EP] Sec:Sapper Damage +200%", "sapper damage bonus",1,2,3,2},
			{"[EP] Sec:Sapper Recharge Rate +150%", "effect bar recharge rate increased",1,-0.75,0.25,2},
			
			{"[EP] Cloak Duration +150%", "stat",0,-0.75,-0.75,4,"CloakDuration"},
			{"[EP] Damage vs Same Class +250%/Backstab Immune", "custom",0,1,1,0},
			{"[EP] Weapon Switch +95%/Mle:Deflect Projectile", "custom",0,1,1,3},
			{"[EP] Insta Cloak/Cloak Recharge +100%/Duration -40%", "custom",0,1,1,4},
			{"[EP] DMG Taken -25%/Mle:Backstab Giant Damage -100%", "custom",0,1,1,3},
		    
			{"[EP] Available Epic + 1", "custom",0,1,2},
			{"[EP] ReRoll Points + 3","custom",0,1,4},
			{"[EP] Next Purchase is Rare Shop","custom",0,1,4},
		},
		MinorEpicAttribute =
		{
		    {"[EP] Damage Bonus +5%", "stack",0,0.05,2,"damage bonus"},
			{"[EP] ReRoll Points + 1","custom",0,1},
		},
		LegendaryAttribute =
		{
			{"【LEGEN】Next Purchase is Epic Shop","custom",0,1,4},
			{"【LEGEN】Upgrade Point + 1","custom",0,1,2},
			{"【LEGEN】All Stats Up", "custom",0,1,1,0},
		
			{"【LEGEN】Crit on Kill +5s", "critboost on kill",0,5,5},
			{"【LEGEN】Damage All Connected By Medigun", "damage all connected",0,1,1,3},
			{"【LEGEN】Pri:Override Imitation:Heavy", "custom",0,1,1,1,"Crit damage decreased by 80%"},
			{"【LEGEN】Melee Hit Grants Protection 1s", "melee grants protection",0,1,2,3},
		}
	}
}

--Used for returning the class name
classIndices_Internal = {
    [1] = "Scout",
    [3] = "Soldier",
    [7] = "Pyro",
    [4] = "Demoman",
    [6] = "Heavy",
    [9] = "Engineer",
    [5] = "Medic",
    [2] = "Sniper",
    [8] = "Spy",
}


--[[This table is essential, it will store the SteamID3 of a player and act as a "save file" for the player,
		Things that are stored in here for each player:
			UpgradePoints - how many upgrade points the player has, persists between classes
			RerollPoints - how many rerolls the player has, persists between classes

			An index from [1] to [9] which will represent the player's class
			Inside the index, each class has its own
				hasRolled - boolean, used as a flag if the player has rolled for upgrades on that class
				PurchasedUpgrades - table, which upgrades have been purchased for that player on that class
				MaxedUpgrades - table, which upgrades are maxed for that player on that class
				UpgradeMenu - table, show a unique upgrade menu for that player on that class
			]]
UniqueAccountIDs = {}
StatBonus = {}

--[[Also very important, this table is akin to an emulator's "save state" where it will copy everything from
	UniqueAccountIDs, TotalUpgradePoints, and TotalRerollPoints. In the case that players lose a wave, this table is used
	to store save states]]
WaveState = {}

--[[Finds all func_upgradestation's on the map and lets the player interact with them for bringing up the menu]]
function EnableUpgradeStations()
	for _, v in pairs(ents.FindAllByClass("func_upgradestation")) do
		v:AddCallback(ON_START_TOUCH,
		function(_,player)
		    if player:IsRealPlayer() then
				RollUpgrades(player)
				ShowUpgradeMenu(player)
				player:Print(2, "Weclome to the Randomizer Upgrade Station!")
				local stats = (ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[player:GetNetIndex()+1]
				StatBonus[stats].respawned = nil
			end
		end)
		v:AddCallback(ON_END_TOUCH,
		function(_,player)
		    if player:IsRealPlayer() then
				CloseUpgradeMenu(player) --probably redundnant
				player:Print(2, "You have left the Randomizer Upgrade Station.")
			end
		end)
	end
end

--[[Adds the OnSpawn callback so that everytime a player spawns their upgrades are reapplied]]
function OnPlayerConnected(player)
    local stats = (ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[player:GetNetIndex()+1]
    if player:IsRealPlayer() then
        player:AddCallback(ON_SPAWN, function(player)
        util.PrintToChatAll(StatBonus[stats].respawned,"respawned")
		InitUserId(player)
		ReAddPurchasedUpgrades(player)
		end)
        player:AddCallback(ON_PROVIDE_ITEMS, function(player)
		--reset stat bonus
		StatBonus[stats] =
		{
		    DamageBonus = 1,
	    	DamageMult = 1,
			FireRate = 1,
			FireRateMult = 1,
			ReloadRate = 1,
			BulletSpread = 1,
			BulletPerShot = 1,
			MaxHealth = 1,
			MaxAmmo = 1,
			MoveSpeed = 1,
			RangedResistance = 1,
			AllMaxAmmo = 1,
			SecDamageBonus = 1,
			SecDamageMult = 1,
			--SecFireRate = 1,
			SecFireRateMult = 1,
			SecBulletPerShot = 1,
			MleDamageBonus = 1,
			MleDamageMult = 1,
	    	respawned = 1,
	    }
		--scout stat bonus
		if player:DumpProperties().m_iClass == 1 then
			StatBonus[stats].ClipSize = 1
		--soldier stat bonus
		elseif player:DumpProperties().m_iClass == 3 then
			StatBonus[stats].ProjectileSpread = 1
			StatBonus[stats].ClipSizeSoldier = 1
			StatBonus[stats].BlastRadius = 1
			StatBonus[stats].RageDuration = 1
		--demo stat bonus
		elseif player:DumpProperties().m_iClass == 4 then
			StatBonus[stats].ProjectileSpread = 1
			StatBonus[stats].ClipSize = 1
			StatBonus[stats].BlastRadius = 1
			StatBonus[stats].SecMultishot = 1
		--pyro stat bonus
		elseif player:DumpProperties().m_iClass == 7 then
			StatBonus[stats].HealonHit = 1
			StatBonus[stats].EffectBarRecharge = 1
		--heavy stat bonus
		elseif player:DumpProperties().m_iClass == 6 then
			StatBonus[stats].SpunRate = 1
		--engineer stat bonus
		elseif player:DumpProperties().m_iClass == 9 then
			StatBonus[stats].DamageBonusSelf = 1
			StatBonus[stats].MaxMetal = 1
			StatBonus[stats].MetalRegen = 1
			StatBonus[stats].BuildingHealth = 1
			StatBonus[stats].SentryDamage = 1
			StatBonus[stats].SentryRange = 1
		--medic stat bonus
		elseif player:DumpProperties().m_iClass == 5 then
			StatBonus[stats].HealRate = 1
			StatBonus[stats].OverhealBonus = 1
			StatBonus[stats].UberDuration = 1
			StatBonus[stats].UberRate = 1
			StatBonus[stats].RageDuration = 1
		--sniper stat bonus
		elseif player:DumpProperties().m_iClass == 2 then
			StatBonus[stats].HeadshotDamage = 1
			StatBonus[stats].ChargeRate = 1
			StatBonus[stats].SecBulletSpread = 1
			StatBonus[stats].FullChargeDamage = 1
			StatBonus[stats].BodyshotDamage = 1
		--spy stat bonus
		elseif player:DumpProperties().m_iClass == 8 then
			StatBonus[stats].CloakDuration = 1
			StatBonus[stats].CloakRechargeRate = 1
			StatBonus[stats].BackstabDamage = 1
			StatBonus[stats].MleFireRate = 1
		end
		end)
    end
end

--[[If the player joins the server for the first time, their SteamID3 is added to UniqueAccountIDs
	Note that the function for pruchasing upgrades is stored here]]
function InitUserId(activator)
	local player = (ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]
	if UniqueAccountIDs[player] == nil then
		UniqueAccountIDs[player] =
		{
			UpgradePoints = TotalUpgradePoints,
			RerollPoints = TotalRerollPoints,
			AvailableEpic = TotalAvailableEpic,
		}
	end

	local class = activator:DumpProperties().m_iClass
	if UniqueAccountIDs[player][class] == nil then
		UniqueAccountIDs[player][class] =
		{
			hasRolled = false,
			PurchasedUpgrades = {}, --Stored as key [Upgrade name] with value equal to how many times it was purchased
			MaxedUpgrades = {}, --Used a temporary table, similar to PurchasedUpgrades, probably not needed in style2
			UpgradeMenu =
			{
				timeout = 0,
				title = "Select an upgrade - ",
				itemsPerPage = nil,
				flags = MENUFLAG_BUTTON_EXIT,
				onSelect = function(activator, index, value) --Responsible for subtracting upgrade/reroll points, disabling purchased upgrades
					local player = UniqueAccountIDs[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
					local class = activator:DumpProperties().m_iClass
					local purchased = player[class].PurchasedUpgrades
					local menu = player[class].UpgradeMenu
					local playername = activator:DumpProperties().m_szNetname[1]

					if value ~= "reroll" then
						if purchased[value] == nil then
							purchased[value] = 1
						else
							purchased[value] = purchased[value] + 1
						end

						menu[index].disabled = true
						AddUpgrade(activator, value)

						local upgradetable = {}
						for i in (string.gmatch(value, "[^,]+")) do
							upgradetable[#upgradetable + 1] = i
						end
						local upgrade = upgradetable[1]
						local upgrade_attribute = upgradetable[2]
						local upgrade_desc = upgradetable[7]
						

						if string.find(upgrade, "(R)",1,true) then
							util.PrintToChatAll("\x07ff3d3d"  .. playername .. "\x07fbeccb has purchased: " .. "\x074B69FF".. string.sub(upgrade,1,3) .. "\x07FFD700".. string.sub(upgrade,4,#upgrade) .. "\x07fbeccb Level " .. purchased[value])
						elseif string.find(upgrade, "[EP]",1,true) then
							util.PrintToChatAll("\x07ff3d3d"  .. playername .. "\x07fbeccb has purchased: " .. "\x078847FF".. string.sub(upgrade,1,4) .. "\x07FFD700".. string.sub(upgrade,5,#upgrade) .. "\x07fbeccb Level " .. purchased[value])
							if player.AvailableEpic > 0 then 
							    player.AvailableEpic = player.AvailableEpic - 1
							end
						elseif string.find(upgrade, "【LEGEN】",1,true) then
							util.PrintToChatAll("\x07ff3d3d"  .. playername .. "\x07fbeccb has purchased: " .. "\x07EB4B4B".. string.sub(upgrade,1,11) .. "\x07FFD700".. string.sub(upgrade,12,#upgrade) .. "\x07fbeccb Level " .. purchased[value])
						else
						util.PrintToChatAll("\x07ff3d3d"  .. playername .. "\x07fbeccb has purchased: " .. "\x07FFD700" .. upgrade .. "\x07fbeccb Level " .. purchased[value])
						end
						
						if upgrade_desc ~= nil and upgrade_attribute ~= "stat" then
							activator:PrintToChat("\x0798FF3DDescription : \x07fbeccb" .. upgrade_desc)
						end
						
						if string.find(upgrade, "(FREE)",1,true) then
					        player.UpgradePoints = player.UpgradePoints - 0
						elseif string.find(upgrade, "【LEGEN】Upgrade Point + 1",1,true) then
						    player.UpgradePoints = player.UpgradePoints + 1
						elseif string.find(upgrade, "[EP] Available Epic + 1",1,true) then
							player.AvailableEpic = player.AvailableEpic + 2
						elseif string.find(upgrade, "[EP] ReRoll Points + 3",1,true) then
							player.RerollPoints = player.RerollPoints + 3
							player.AvailableEpic = player.AvailableEpic + 1
						elseif string.find(upgrade, "[EP] ReRoll Points + 1",1,true) then
							player.RerollPoints = player.RerollPoints + 1
						elseif string.find(upgrade, "【LEGEN】Next Purchase is Epic Shop",1,true) then
							player.EpicShop = 1
						elseif string.find(upgrade, "[EP] Next Purchase is Rare Shop",1,true) then
							player.RareShop = 1
							player.AvailableEpic = player.AvailableEpic + 1
						else
                            player.UpgradePoints = player.UpgradePoints - 1
                        end
						

						player[class].hasRolled = false
						RollUpgrades(activator) --after purchasing an upgrade, reroll for new set of upgrades

					else
						RerollUpgrades(activator)
					end

					ShowUpgradeMenu(activator)
				end,
				onCancel = nil
			}
		}
	end
end

--[[Your random number generator, returns a float to allow for decimal probabilities
	In this example, it rolls for rarity first, then rolls a second time to pick an upgrade
	So the probability of a specific upgrade is based on two rng rolls]]
WaveNum = 0

function UpgradeRoulette(activator)
    local player = UniqueAccountIDs[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
	local number = math.random() --returns float from 0 to 1
	local class = activator:DumpProperties().m_iClass
	local shop = AllShops[class]
	local pool = {}
	local chance = {}
	if WaveNum == 1 then
		chance.common = 0.4
		chance.rare = 0.7
		chance.epic = 0.9
		--[[chance.common = 0.70
		chance.rare = 0.98
		chance.epic = 1]]
	elseif WaveNum > 1 and WaveNum < 5 then
		chance.common = 0.60
		chance.rare = 0.96
		chance.epic = 0.995
	else	
		chance.common = 0.55
		chance.rare = 0.93
		chance.epic = 0.995
	end
	if player.EpicShop == 1 then
		chance.common = 0
		chance.rare = 0
		chance.epic = 1
	elseif player.RareShop == 1 then
		chance.common = 0
		chance.rare = 1
		chance.epic = 1
	end
	if number <= chance.common then
	pool = shop.CommonAttribute
	elseif (number > chance.common and number <= chance.rare) then
		pool = shop.RareAttribute
	elseif (number > chance.rare and number <= chance.epic) then
	    if player.AvailableEpic > 0 then
		    pool = shop.EpicAttribute
		else    
			pool = shop.MinorEpicAttribute
		end
	elseif number > chance.epic then --probably should be less than 1%
		pool = shop.LegendaryAttribute
	end

	local index = math.random(1,(#pool)) --returns integer from 1 to number of upgrades in pool
	local upgrade = pool[index]

	return upgrade
end

--[[This function calls UpgradeRoulette and sends the chosen upgrades to the upgrade menu]]
function RollUpgrades(activator)
	local player = UniqueAccountIDs[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
	local class = activator:DumpProperties().m_iClass
	local menu = player[class].UpgradeMenu
	local purchased = player[class].PurchasedUpgrades
	local maxed = player[class].MaxedUpgrades

	if player[class].hasRolled ~= true then
		for index = 1, MenuCapacity, 1 do
			menu[index] = {}
			maxed = {}
		end

		for index = 1, MenuCapacity, 1 do
			local upgrade = UpgradeRoulette(activator)
			local upgradestring = table.concat(upgrade,",")

			--[[Used to prevent maxed out upgrades from reappearing in the shop
				Note that this is possibly bugged in style2, will fix later]]
			function CheckMaxed(upgrade)
				local min = upgrade[3]
				local increment = upgrade[4]
				local max = upgrade[5]
				if max ~= nil then
					if maxed[upgradestring] == nil then
						if purchased[upgradestring] == nil then
							maxed[upgradestring] = 0
						else
							maxed[upgradestring] = purchased[upgradestring]
						end
					else
						maxed[upgradestring] = maxed[upgradestring] + 1
					end
					local value = min + maxed[upgradestring] * increment
					if increment > 0 then
						return (tostring(value) >= tostring(max))  --floating point issue
					else
						return (tostring(value) <= tostring(max))
					end
				end
			end

			if CheckMaxed(upgrade) == true then --If upgrade is maxed, reroll
				while CheckMaxed(upgrade) == true do
					upgrade = UpgradeRoulette(activator)
				end
			end

			for i = 1, MenuCapacity, 1 do --If upgrade is duplicate, reroll
				if menu[i].text == upgrade[1] then
					while menu[i].text == upgrade[1] do
						upgrade = UpgradeRoulette(activator)
					end
				end
			end

			menu[index] = {text = upgrade[1], value = table.concat(upgrade,","), disabled = false} --value can't accept tables, only strings/numbers
		end
		player[class].hasRolled = true
	end
	if player.EpicShop == 1 then
		player.EpicShop = 0
	elseif player.RareShop == 1 then
		player.RareShop = 0
	end
end

--Called when the reroll option is selected, subtracts a reroll point
function RerollUpgrades(activator)
	local player = UniqueAccountIDs[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
	local class = activator:DumpProperties().m_iClass

	player.RerollPoints = player.RerollPoints - 1
	player[class].hasRolled = false
	RollUpgrades(activator)
end

--Sets hasRolled to false for all players in the game, usually called on wave end
function ResetRolls()
	for _, v in pairs(UniqueAccountIDs) do
		for i = 1, 9, 1 do
			if v[i] ~= nil then
				v[i].hasRolled = false
			end
		end
	end
end

function GetAllItemName(activator)
	local AllItems = {}
	d = 0
	while(d <= 6) do
		if activator:GetPlayerItemBySlot(d) ~= nil then
			AllItems[1+d] = activator:GetPlayerItemBySlot(d):GetItemName()
		else
			AllItems[1+d] = "nil"
		end
		d = d+1
	end
	return AllItems
end
function UpdateStats(activator,purchased,stat,value,max)
	local stats = StatBonus[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
	if value > 0 then
		if stats.respawned == 1 then
			stats[stat] = stats[stat] + math.min(value*purchased,max)
		else stats[stat] = stats[stat] + value
		end
	else
		if stats.respawned == 1 then
			stats[stat] = stats[stat] + math.max(value*purchased,max)
		else stats[stat] = stats[stat] + value
		end
	end
	if stat == "DamageBonus" then
	   StackAttributeValue(activator,purchased,"damage bonus",value,max,1,"primary")
	elseif stat == "DamageMult"  then
	   StackAttributeValue(activator,purchased,"damage penalty",value,max,1,"primary")
	elseif stat == "FireRate" then
	   StackAttributeValue(activator,purchased,"fire rate bonus",value,max,1,"primary")
	elseif stat == "FireRateMult" then
	   StackAttributeValue(activator,purchased,"fire rate penalty",value,max,1,"primary")
	elseif stat == "ReloadRate" then
	   StackAttributeValue(activator,purchased,"faster reload rate",value,max,1,"primary")
	elseif stat == "ClipSize" then
	   StackAttributeValue(activator,purchased,"clip size bonus",value,max,1,"primary")
	elseif stat == "BulletSpread" then
	   StackAttributeValue(activator,purchased,"weapon spread bonus",value,max,1,"primary")
	elseif stat == "BulletPerShot" then
	   StackAttributeValue(activator,purchased,"bullets per shot bonus",value,max,1,"primary")
	elseif stat == "ProjectileSpread" then
	   StackAttributeValue(activator,purchased,"projectile spread angle penalty",value,max,0,"primary")
	elseif stat == "BlastRadius" then
	   StackAttributeValue(activator,purchased,"Blast radius increased",value,max,1,"primary")
	elseif stat == "HealonHit" then
	   StackAttributeValue(activator,purchased,"heal on hit for rapidfire",value,max,0,"primary")
	elseif stat == "SpunRate" then
	   StackAttributeValue(activator,purchased,"minigun spinup time decreased",value,max,1,"primary")
	elseif stat == "SecDamageBonus" then
	   StackAttributeValue(activator,purchased,"damage bonus",value,max,1,"secondary")
	elseif stat == "SecDamageMult" then
	   StackAttributeValue(activator,purchased,"damage penalty",value,max,1,"secondary")
	elseif stat == "SecFireRateMult" then
	   StackAttributeValue(activator,purchased,"fire rate penalty",value,max,1,"secondary")
	elseif stat == "SecBulletPerShot" then
	   StackAttributeValue(activator,purchased,"bullets per shot bonus",value,max,1,"secondary")
	elseif stat == "SecMultishot" then
	   StackAttributeValue(activator,purchased,"mult projectile count",value,max,1,"secondary")
	elseif stat == "EffectBarRecharge" then
	   StackAttributeValue(activator,purchased,nil,"mult_item_meter_charge_rate",value,max,1,"secondary")
	elseif stat == "HealRate" then
	   StackAttributeValue(activator,purchased,"heal rate bonus",value,max,1,"secondary")
	elseif stat == "OverhealBonus" then
	   StackAttributeValue(activator,purchased,"overheal bonus",value,max,1,"secondary")
	elseif stat == "UberRate" then
	   StackAttributeValue(activator,purchased,"ubercharge rate bonus",value,max,1,"secondary")
	elseif stat == "UberDuration" then
	   StackAttributeValue(activator,purchased,"uber duration bonus",value,max,0,"secondary")
	elseif stat == "RageDuration" then
	   StackAttributeValue(activator,purchased,"increase buff duration",value,max,1,"secondary")
	elseif stat == "MleDamageBonus" then
	   StackAttributeValue(activator,purchased,"damage bonus",value,max,1,"melee")
	elseif stat == "MleDamageMult" then
	   StackAttributeValue(activator,purchased,"damage penalty",value,max,1,"melee")
	elseif stat == "MleFireRate" then
	   StackAttributeValue(activator,purchased,"fire rate bonus",value,max,1,"melee")
	elseif stat == "HeadshotDamage" then
	   StackAttributeValue(activator,purchased,"headshot damage increase",value,max,1,"primary")
	elseif stat == "MaxHealth" then
	   StackAttributeValue(activator,purchased,"max health additive bonus",value,max,0,"player")
	elseif stat == "MaxAmmo" then
	   StackAttributeValue(activator,purchased,"maxammo primary increased",value,max,1,"primary")
	elseif stat == "AllMaxAmmo" then
		StackAttributeValue(activator,purchased,"maxammo primary increased",value,max,1,"player")
		StackAttributeValue(activator,purchased,"maxammo secondary increased",value,max,1,"player")
		StackAttributeValue(activator,purchased,"maxammo grenades1 increased",value*2,max,1,"player")
	elseif stat == "MoveSpeed" then
	   StackAttributeValue(activator,purchased,"move speed bonus",value,max,1,"player")
	elseif stat == "RangedResistance" then
	   StackAttributeValue(activator,purchased,"dmg from ranged reduced",value,max,1,"player")
	elseif stat == "ClipSizeSoldier" then
		StackAttributeValue(activator,purchased,"clip size bonus",value,max,1,"primary")
		StackAttributeValue(activator,purchased,"clip size bonus upgrade",value,max,1,"primary")
	elseif stat == "DamageBonusSelf" then
	   StackAttributeValue(activator,purchased,"damage bonus",value,max,1,"player")
	elseif stat == "MaxMetal" then
	   StackAttributeValue(activator,purchased,"maxammo metal increased",value,max,1,"player")
	elseif stat == "MetalRegen" then
	   StackAttributeValue(activator,purchased,"metal regen",value,max,0,"player")
	elseif stat == "BuildingHealth" then
	   StackAttributeValue(activator,purchased,"engy building health bonus",value,max,1,"special")
	elseif stat == "SentryRange" then
	   StackAttributeValue(activator,purchased,"engy sentry radius increased",value,max,1,"special")
	elseif stat == "SentryDamage" then
	   StackAttributeValue(activator,purchased,"engy sentry damage bonus",value,max,1,"special")
	elseif stat == "ChargeRate" then
	   StackAttributeValue(activator,purchased,"sniper charge per sec",value,max,1,"primary")
	elseif stat == "SecBulletSpread" then
	   StackAttributeValue(activator,purchased,"weapon spread bonus",value,max,1,"secondary")
	elseif stat == "FullChargeDamage" then
	   StackAttributeValue(activator,purchased,"sniper full charge damage bonus",value,max,1,"primary")
	elseif stat == "BodyshotDamage" then
	   StackAttributeValue(activator,purchased,"damage penalty on bodyshot",value,max,1,"primary")
	elseif stat == "CloakRechargeRate" then
	   StackAttributeValue(activator,purchased,"mult cloak meter regen rate",value,max,1,"special")
	elseif stat == "CloakDuration" then
	   StackAttributeValue(activator,purchased,"cloak consume rate decreased",value,max,1,"special")
	elseif stat == "BackstabDamage" then
	   StackAttributeValue(activator,purchased,"armor piercing",value,max,0,"melee")
	else
		util.PrintToChatAll("funny stat")
		StackAttributeValue(activator,purchased,stat,value,max,weapon)
    end
	activator:PrintToChat("stat updated", stats[stat])
end
function AddMultipleAttributes(activator,purchased,attributename,value,valuenum,duration,max,basevalue,weaponslot)
    local currentvalue = weapon:GetAttributeValue(attributename)
    local valuenumlen = #tostring(valuenum)
    local durationlen = #tostring(duration)
	if purchased == nil then
		purchased = 1
	end
	if basevalue == nil then
		basevalue = 1
	end
	if max == nil then
		max = valuenum
	end
	if weaponslot == "melee" then
		weaponslot = activator:GetPlayerItemBySlot(2)
    elseif weaponslot == "secondary" then
		if activator:DumpProperties().m_iClass == 8 then
			weaponslot = activator:GetPlayerItemBySlot(3)
		else
			weaponslot = activator:GetPlayerItemBySlot(1)
		end
    elseif weaponslot == "primary" then
		if activator:DumpProperties().m_iClass == 8 then
			weaponslot = activator:GetPlayerItemBySlot(1)
		else
			weaponslot = activator:GetPlayerItemBySlot(0)
		end
    elseif weaponslot == "special" and activator:DumpProperties().m_iClass == 9 then -- engi item slot
        weaponslot = activator:GetPlayerItemBySlot(5)
    elseif weaponslot == "special" and activator:DumpProperties().m_iClass == 8 then -- spaps item slot
        weaponslot = activator:GetPlayerItemBySlot(6)
	elseif weaponslot == "player" then
        weaponslot = activator
	else
		weaponslot = weapon
	end
	if valuenum > 0 then
		function f(fi,fj)
			return math.min(fi,fj)
		end
	else
		function f(fi,fj)
			return math.max(fi,fj)
		end
	end
	if duration == nil then
		if currentvalue ~= nil then
			repatedi, repeatedj = string.find(currentvalue, value)
			if repatedi ~= nil then
				activator:PrintToChat("moniter", currentvalue, value, currentvalue:sub(repatedi, repeatedj+1+valuenumlen))
				newvalue = currentvalue:gsub(currentvalue:sub(repatedi, repeatedj+1+valuenumlen),value .. "|" .. f(basevalue+(valuenum*purchased),basevalue+max))
				activator:PrintToChat("output", newvalue)
				weaponslot:SetAttributeValue(attributename,newvalue)
			else
				weaponslot:SetAttributeValue(attributename,currentvalue .. "|" .. value .. "|" .. f(basevalue+(valuenum*purchased),basevalue+max))
			end
		else 
			weaponslot:SetAttributeValue(attributename,value .. "|" .. f(basevalue+(valuenum*purchased),basevalue+max))
		end
		activator:PrintToChat(weaponslot:GetAttributeValue(attributename))
	else
		if currentvalue ~= nil then
			repatedi, repeatedj = string.find(currentvalue, value)
			if repatedi ~= nil then
				activator:PrintToChat("moniter", currentvalue, value, duration, currentvalue:sub(repatedi, repeatedj+2+valuenumlen+durationlen))
				newvalue = currentvalue:gsub(currentvalue:sub(repatedi, repeatedj+2+valuenumlen+durationlen),value .. "|" .. f(basevalue+(valuenum*purchased),basevalue+max) .. "|" .. duration)
				activator:PrintToChat("output", newvalue)
				weaponslot:SetAttributeValue(attributename,newvalue)
			else
				weaponslot:SetAttributeValue(attributename,currentvalue .. "|" .. value .. "|" .. f(basevalue+(valuenum*purchased),basevalue+max) .. "|" .. duration)
			end
		else 
			weaponslot:SetAttributeValue(attributename,value .. "|" .. f(basevalue+(valuenum*purchased),basevalue+max) .. "|" .. duration)
		end
		activator:PrintToChat(weaponslot:GetAttributeValue(attributename))
	end
end
function AddMultipleAddconds(activator,purchased,attributename,value,weaponslot)
	local currentvalue = weapon:GetAttributeValue(attributename)
	if currentvalue == nil then
		currentvalue = 0
	end
	if weaponslot == "melee" then
		weaponslot = activator:GetPlayerItemBySlot(2)
    elseif weaponslot == "secondary" then
		if activator:DumpProperties().m_iClass == 8 then
			weaponslot = activator:GetPlayerItemBySlot(3)
		else
			weaponslot = activator:GetPlayerItemBySlot(1)
		end
    elseif weaponslot == "primary" then
		if activator:DumpProperties().m_iClass == 8 then
			weaponslot = activator:GetPlayerItemBySlot(1)
		else
			weaponslot = activator:GetPlayerItemBySlot(0)
		end
	
    elseif weaponslot == "special" and activator:DumpProperties().m_iClass == 9 then -- engi item slot
        weaponslot = activator:GetPlayerItemBySlot(5)
    elseif weaponslot == "special" and activator:DumpProperties().m_iClass == 8 then -- spaps item slot
        weaponslot = activator:GetPlayerItemBySlot(6)
	elseif weaponslot == "player" then
        weaponslot = activator
	else
		weaponslot = weapon
	end
	
	if currentvalue < 1 then
		newvalue = currentvalue + value
	elseif currentvalue > 1 and currentvalue < 256 then
		newvalue = currentvalue + value*256
	elseif currentvalue > 256 then
		newvalue = currentvalue + value*65536
	else
		activator:PrintToChat("too much addcond attributes")
	end
	weaponslot:SetAttributeValue(attributename,newvalue)
end
function StackAttributeValue(activator,purchased,attributename,value,max,basevalue,weaponslot)
    local stats = StatBonus[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
	if weaponslot == "melee" then
		weaponslot = activator:GetPlayerItemBySlot(2)
    elseif weaponslot == "secondary" then
		if activator:DumpProperties().m_iClass == 8 then
			weaponslot = activator:GetPlayerItemBySlot(3)
		else
			weaponslot = activator:GetPlayerItemBySlot(1)
		end
    elseif weaponslot == "primary" then
		if activator:DumpProperties().m_iClass == 8 then
			weaponslot = activator:GetPlayerItemBySlot(1)
		else
			weaponslot = activator:GetPlayerItemBySlot(0)
		end
    elseif weaponslot == "special" and activator:DumpProperties().m_iClass == 9 then -- engi item slot
        weaponslot = activator:GetPlayerItemBySlot(5)
    elseif weaponslot == "special" and activator:DumpProperties().m_iClass == 8 then -- spaps item slot
        weaponslot = activator:GetPlayerItemBySlot(6)
	elseif weaponslot == "player" then
        weaponslot = activator
	else
		weaponslot = weapon
	end
	if attributename == "fire rate bonus" or attributename == "faster reload rate" or attributename == "Reload time increased" or attributename == "clip size bonus" then
		activator:PrintToChat(attributename)
		function f(comparevalue)
		return math.max(comparevalue,0)
		
		end
	elseif attributename == "weapon spread bonus" then
		function f(comparevalue)
		return math.max(comparevalue,0.01)
		end
	elseif attributename == "dmg penalty vs players" then
		function f(comparevalue)
		return math.max(comparevalue,0.05)
		end
	else
		function f(comparevalue)
		return comparevalue
		end
	end
	local currentvalue = weaponslot:GetAttributeValue(attributename,true)
    if weaponslot:GetAttributeValue("obsolete ammo penalty") and stats.respawned == 1 then
		activator:PrintToChat("u r ded")
	else
	    if purchased == nil then
	        purchased = 1
	    end
		if max == nil then
			max = value*purchased
		end
		if basevalue == nil then
			basevalue = 1
		end
		if	currentvalue == nil then
			currentvalue = basevalue
		end
		
		if value > 0 then
			if stats.respawned == 1 then
				weaponslot:SetAttributeValue(attributename,f(currentvalue+math.min(value*purchased,max)))
			else
				weaponslot:SetAttributeValue(attributename,f(currentvalue+value))
			end
		else
			if stats.respawned == 1 then
				weaponslot:SetAttributeValue(attributename,f(currentvalue+math.max(value*purchased,max)))
			else 
				weaponslot:SetAttributeValue(attributename,f(currentvalue+value))
			end
		end
		activator:PrintToChat("updated", attributename,f(weaponslot:GetAttributeValue(attributename)))
	end
end
--[[Apply upgrades to players
	using "custom" allows you do anything you define in the function as an upgrade
	meaning PointTemplate upgrades are possible]]
function AddUpgrade(activator, value)
	local player = UniqueAccountIDs[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
	local class = activator:DumpProperties().m_iClass
	local purchased = player[class].PurchasedUpgrades
	local upgradetable = {}
	
	local stats = StatBonus[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
    
	for i in string.gmatch(value, "[^,]+") do
		upgradetable[#upgradetable + 1] = i
	end
	local upgrade = upgradetable[1]
	local attributename = upgradetable[2]
	local min = tonumber(upgradetable[3])
	local increment = tonumber(upgradetable[4])
	local max = tonumber(upgradetable[5])
	
	local melee = activator:GetPlayerItemBySlot(2)
    local secondary = activator:GetPlayerItemBySlot(1)
    local primary = activator:GetPlayerItemBySlot(0)
    if activator:DumpProperties().m_iClass == 9 then -- engi item slot
        special = activator:GetPlayerItemBySlot(5)
    elseif activator:DumpProperties().m_iClass == 8 then -- spaps item slot
        special = activator:GetPlayerItemBySlot(6)
        melee = activator:GetPlayerItemBySlot(2)
        secondary = activator:GetPlayerItemBySlot(4)
        primary = activator:GetPlayerItemBySlot(1)
	end
	
	local slot = tonumber(upgradetable[6])
	if slot == 1 then
			weapon = primary
		elseif slot == 2 then
			weapon = secondary
		elseif slot == 3 then
			weapon = melee
		elseif slot == 4 then
			weapon = special
		else weapon = activator
	end
	local attribute_desc = tostring(upgradetable[7])
	
	local AllItems = GetAllItemName(activator)
	
	local widow = 0
	for k,v in pairs(AllItems) do 
		if v == "The Widowmaker" then
			activator:PrintToChat("Widowmaker")
			widow = 1
		end
	end
	
	if attributename == "custom" then
	    
		if upgrade == "Max Ammo +50%" then
			activator:SetAttributeValue("maxammo primary increased",min+increment*purchased[value])
			activator:SetAttributeValue("maxammo secondary increased",min+increment*purchased[value])
			activator:SetAttributeValue("maxammo grenades1 increased",min+increment*2*purchased[value])
		elseif upgrade == "melee damage test upgrade" then
    			--UniqueAccountIDs = deepCopy(WaveState[1].UniqueAccountIDs)
    			--player:GetAllItems()
    			activator:PrintToChat(activator:GetPlayerItemBySlot(0))
    			activator:PrintToChat(activator:GetPlayerItemBySlot(1))
    			activator:PrintToChat(activator:GetPlayerItemBySlot(2))
    			activator:PrintToChat(activator:GetPlayerItemBySlot(3))
    			activator:PrintToChat(activator:GetPlayerItemBySlot(4))
    			activator:PrintToChat(activator:GetPlayerItemBySlot(5))
    			activator:PrintToChat(activator:GetPlayerItemBySlot(6))
    			for k,v in pairs(AllItems) do
					activator:PrintToChat(k,v)
				end
				UpdateStats(activator,purchased[value],"DamageMult",-0.5,-0.5)
    			UpdateStats(activator,purchased[value],"FireRateMult",1,1)
				AddMultipleAddconds(activator,purchased[value],"add cond on hit",71)
				weapon:SetAttributeValue("add cond on hit duration",6)
				weapon:SetAttributeValue("mult dmg vs giants",0)
				weapon:SetAttributeValue("allow friendly fire",1)
		elseif upgrade == "All Max Ammo +35%" then
			UpdateStats(activator,purchased[value],"AllMaxAmmo",0.35,1.05)
		elseif upgrade == "【LEGEN】Mixed Concoction On Hit" then
			activator:SetAttributeValue("add cond on hit",123 + 27*256 + 24*65536) --123 = gas, 27 = milk, 24 = jarate, total is 1579899
			activator:SetAttributeValue("add cond on hit duration",10)
			activator:SetAttributeValue("bleeding duration",10)
			UpdateStats(activator,purchased[value],"RageDuration",-0.5,-0.5)
		elseif upgrade == "All Resistance Upgrade +20%" then
			StackAttributeValue("dmg taken from blast reduced",-0.2,-0.8)
			StackAttributeValue("dmg taken from fire reduced",-0.2,-0.8)
			StackAttributeValue("dmg taken from crit reduced",-0.22,-0.88)
			StackAttributeValue("dmg taken from bullets reduced",-0.2,-0.8)
		elseif upgrade == "(R) All Resistance Upgrade +30%" then
			StackAttributeValue("dmg taken from blast reduced",-0.3,-0.9)
			StackAttributeValue("dmg taken from fire reduced",-0.3,-0.9)
			StackAttributeValue("dmg taken from crit reduced",-0.33,-0.99)
			StackAttributeValue("dmg taken from bullets reduced",-0.3,-0.9)
		elseif upgrade == "(R) Extra Jump +1/Jump Height +20%" then
			weapon:SetAttributeValue("air dash count",1)
			weapon:SetAttributeValue("increased jump height",1.2)
		elseif upgrade == "(R) Damage Mult +0.2/Ammo -20%/Switch +40%" then
			StackAttributeValue(activator,purchased[value],"damage penalty",0.2,0.6)
			UpdateStats(activator,purchased[value],"MaxAmmo",-0.2,-0.6)
			activator:SetAttributeValue("deploy time decreased",math.max(1+(-0.4*purchased[value]),0.05))
		elseif upgrade == "(R) Sec:Bullet Per Shot +30%/Weapon Switch +25%" then
			UpdateStats(activator,purchased[value],"SecBulletPerShot",0.3,1.2)
			weapon:SetAttributeValue("deploy time decreased",math.max(1+(-0.25*purchased[value]),0.01))
		elseif upgrade == "[EP] Sec:Damage Mult +1/FireRate Mult -0.4" then
			UpdateStats(activator,purchased[value],"SecDamageMult",0.8,1.6)
			UpdateStats(activator,purchased[value],"SecFireRateMult",1,2)
		elseif upgrade == "[EP] Sec:Bullet Per Shot +100%/Spread -20%" then
			UpdateStats(activator,purchased[value],"SecBulletPerShot",1,2)
			StackAttributeValue(activator,purchased[value],"spread penalty",0.2,0.6)
		elseif upgrade == "[EP] Pri:Damage Mult +2.0/Reload -400%" then
			UpdateStats(activator,purchased[value],"DamageMult",2,2)
			StackAttributeValue(activator,purchased[value],"reload time increased hidden",4)
		elseif upgrade == "[EP] Sec:Damage Mult +2.0/Reload -400%" then
			UpdateStats(activator,purchased[value],"SecDamageMult",2,2)
			StackAttributeValue(activator,purchased[value],"reload time increased hidden",4)
		elseif upgrade == "[EP] Max Health +200/Pri:Damage Mult -20%" then
			UpdateStats(activator,purchased[value],"DamageMult",-0.2,-0.4)
			UpdateStats(activator,purchased[value],"MaxHealth",200,400,0)
		elseif upgrade == "【LEGEN】All Stats Up" then
			StackAttributeValue(activator,purchased[value],"damage bonus",0.1,0.1)
			StackAttributeValue(activator,purchased[value],"fire rate bonus",-0.1,-0.1)
			UpdateStats(activator,purchased[value],"MaxHealth",50,50,0)
		end
		
		--scout custom upgrades
		if activator:DumpProperties().m_iClass == 1 then
		    activator:PrintToChat("Boink")
		    local drink = 0
			local bonk = 0
		    local milk = 0
		    local sodipop = 0
			local guillotin = 0
		    for k,v in pairs(AllItems) do 
        	    if v == "Crit-a-Cola" then
        	        activator:PrintToChat("you have a drink")
					drink = 1
				elseif v == "Bonk! Atomic Punch" then
        	        activator:PrintToChat("you have a drink")
					drink = 1
					bonk = 1
        	    elseif v == "Mad Milk" then
        	        activator:PrintToChat("you have a milk")
					milk = 1
        	    elseif v == "The Soda Popper" then
        	        activator:PrintToChat("you have a sodipop")
					sodipop = 1
				elseif v == "The Flying Guillotine" then
        	        activator:PrintToChat("you have a guillotin")
					guillotin = 1
        	    end
            end
    		if upgrade == "Move Speed/Jump Height +10%" then
    			UpdateStats(activator,purchased[value],"MoveSpeed",0.1,0.4)
    			activator:SetAttributeValue("increased jump height",math.min(1+(0.1*purchased[value]),1.4))
				AddMultipleAttributes(activator,purchased[value],"self add attributes on hit","move speed bonus",0.3,2)
			elseif upgrade == "(R) Pri:Killing Turns Mini Crits to Crits for 2s" then
				AddMultipleAttributes(activator,purchased[value],"add attributes on kill","minicrits become crits",1,2,nil,0)
			elseif upgrade == "(R) Pri:Damage Bonus +25%/Move Speed -25%" then
				UpdateStats(activator,purchased[value],"DamageBonus",0.25,0.5)
				UpdateStats(activator,purchased[value],"MoveSpeed",-0.25,-0.5)
			elseif upgrade == "(R) Pri:Hype Also Gives You -45% Spread" then
				if sodipop == 1 then
					AddMultipleAttributes(activator,purchased[value],"effect add attributes","spread penalty",-0.45,nil,-0.9,1)
				end
			elseif upgrade == "(R) Jar:Debuff Apply Damage -10%" then
				if milk == 1 then
					AddMultipleAttributes(activator,purchased[value],"effect add attributes","dmg penalty vs players",-0.1,nil,-0.2,1)
				end
			elseif upgrade == "(R) Drink:Also Gain Extra Jump +6" then
				if drink == 1 then
					AddMultipleAttributes(activator,purchased[value],"effect add attributes","air dash count",6,nil,nil,0)
				end
			elseif upgrade == "(R) Drink:Also Gain Damage x1.2" then
				if drink == 1 then
					AddMultipleAttributes(activator,purchased[value],"effect add attributes","damage bonus HIDDEN",0.2,nil,0.4,1)
				end
			elseif upgrade == "(R) Sec:Secondary Hit and Bleed Tick Gives Buff" then
				AddMultipleAttributes(activator,purchased[value],"self add attributes on hit","damage bonus HIDDEN",0.2,1)
			elseif upgrade == "(R) Mle:Melee Hit and Bleed Tick Gives Buff" then
				AddMultipleAttributes(activator,purchased[value],"self add attributes on hit","damage bonus HIDDEN",0.3,1)
			elseif upgrade == "(R) Mle:Mini Crit to Crits/Damage Bonus +25%" then
				UpdateStats(activator,purchased[value],"MleDamageBonus",0.25,0.25)
				weapon:SetAttributeValue("minicrits become crits",1)
			elseif upgrade == "[EP] Pri:Hype Also Gives You Damage x1.4" then
				if sodipop == 1 then
					AddMultipleAttributes(activator,purchased[value],"effect add attributes","damage bonus HIDDEN",0.4)
				end
    		elseif upgrade == "[EP] Pri:Damage Mult +0.5/Spread -100%" then
    			UpdateStats(activator,purchased[value],"DamageMult",0.5,1)
				UpdateStats(activator,purchased[value],"BulletSpread",1,2)
    		elseif upgrade == "[EP] Pri:Damage +50%/Clip Size -50%/FireRate Mult -0.6" then
    			UpdateStats(activator,purchased[value],"DamageBonus",0.5,0.5)
    			UpdateStats(activator,purchased[value],"ClipSize",-0.5,-0.5)
    			UpdateStats(activator,purchased[value],"FireRateMult",0.6,0.6)
    		elseif upgrade == "[EP] Pri:Force Fire Full Clip/Firerate Mult +1.0" then
    			weapon:SetAttributeValue("force fire full clip",1)
    			UpdateStats(activator,purchased[value],"FireRateMult",-0.5,-0.5)
    		elseif upgrade == "[EP] Pri:Force Fire Full Clip/Accuracy is Key" then
    			weapon:SetAttributeValue("force fire full clip",1)
    			UpdateStats(activator,purchased[value],"DamageMult",0.5,0.5)
    			UpdateStats(activator,purchased[value],"FireRate",0.3,0.3)
				UpdateStats(activator,purchased[value],"MaxAmmo",-0.4,-0.4)
			elseif upgrade == "[EP] Pri:No DMG Falloff/Piercing" then
    			weapon:SetAttributeValue("no damage falloff",1)
    			weapon:SetAttributeValue("no reduced damage rampup",1)
    			weapon:SetAttributeValue("projectile penetration",1)
				UpdateStats(activator,purchased[value],"DamageMult",0.5,0.5)
			elseif upgrade == "[EP] Pri:Damage Mult +0.5/Move Speed -60%" then
    			UpdateStats(activator,purchased[value],"DamageMult",0.5,0.5)
    			UpdateStats(activator,purchased[value],"MoveSpeed",-0.6,-0.6)
    		elseif upgrade == "[EP] Jar:Debuff Apply -80% Crit Damage/Recharge -50%" then
    		    if milk == 1 then
				    AddMultipleAttributes(activator,purchased[value],"effect add attributes","mult crit dmg",-0.8)
					StackAttributeValue(activator,purchased[value],"effect bar recharge rate increased",0.5)
				end
			elseif upgrade == "[EP] Drink:Also Turn Mini to Crit/Recharge -50%" then
    		    if drink == 1 then
				    AddMultipleAttributes(activator,purchased[value],"effect add attributes","minicrits become crits",1,nil,1,0,activator)
					StackAttributeValue(activator,purchased[value],"effect bar recharge rate increased",0.5)
				end
			elseif upgrade == "[EP] Sec:Spread Bonus +99%/No DMG Falloff" then
    			StackAttributeValue(activator,purchased[value],"weapon spread bonus",-0.99)
    			weapon:SetAttributeValue("no damage falloff",1)
    			weapon:SetAttributeValue("no reduced damage rampup",1)
				UpdateStats(activator,purchased[value],"SecDamageMult",0.5,0.5)
			elseif upgrade == "[EP] Sec:FireRate Mult +0.5/Ammo +50%" then
    			UpdateStats(activator,purchased[value],"SecFireRateMult",-0.25,-0.5)
    			StackAttributeValue(activator,purchased[value],"maxammo secondary increased",0.5,1)
			elseif upgrade == "[EP] Sec:Damage Mult +2/FireRate Mult -0.5" then
    			UpdateStats(activator,purchased[value],"SecFireRateMult",1,2)
    			UpdateStats(activator,purchased[value],"SecDamageMult",2,4)
			elseif upgrade == "[EP] Sec:Damage Mult +0.5/Ammo +50%" then
    			UpdateStats(activator,purchased[value],"SecDamageMult",0.5,1)
    			StackAttributeValue(activator,purchased[value],"maxammo secondary increased",0.5,1)
			elseif upgrade == "(R) Cleaver:Damage Bonus +300%" then
				if guillotin == 1 then
					StackAttributeValue(activator,purchased[value],"dmg penalty vs players",3,9)
				end
			elseif upgrade == "[EP] Kill to Live" then
    			activator:SetAttributeValue("critboost on kill",5)
    			activator:SetAttributeValue("heal on kill",100)
				activator:SetAttributeValue("speed_boost_on_kill",5)
				UpdateStats(activator,purchased[value],"MoveSpeed",-0.5,-0.5)
				UpdateStats(activator,purchased[value],"DamageMult",-0.2,-0.2)
			elseif upgrade == "[EP] Damage Bonus +100%/Max Health +100/Pri-Clip Size -100%" then
    			StackAttributeValue(activator,purchased[value],"damage bonus",1)
				UpdateStats(activator,purchased[value],"MaxHealth",100,100)
				UpdateStats(activator,purchased[value],"ClipSize",-10,-10)
    		elseif upgrade == "[EP] Max Health Drain/Ranged Resistance 30%" then
    			activator:SetAttributeValue("mod_maxhealth_drain_rate",50)
    			UpdateStats(activator,purchased[value],"RangedResistance",-0.3,-0.3)
			elseif upgrade == "【LEGEN】Jar:Causes Bind" then
    			AddMultipleAttributes(activator,purchased[value],"effect add attributes","major move speed bonus",-0.9)
				AddMultipleAttributes(activator,purchased[value],"effect add attributes","no_jump",1,nil,nil,0)
				AddMultipleAttributes(activator,purchased[value],"effect add attributes","override projectile type",15,nil,nil,1)
    			StackAttributeValue(activator,purchased[value],"effect bar recharge rate increased",0.5)
				StackAttributeValue(activator,purchased[value],"mult effect duration",-0.4)
    		elseif upgrade == "【LEGEN】Super Scout" then
    			activator:SetAttributeValue("major move speed bonus",2)
    			melee:SetAttributeValue("damage force reduction",0.01)
			end
		end

		--soldier custom upgrades
		if activator:DumpProperties().m_iClass == 3 then
		    activator:PrintToChat("Kah rit")
			if upgrade == "(R) Sec:Buff Duration +40%/Buff Radius +15%" then
				UpdateStats(activator,purchased[value],"RageDuration",0.4,1.2)
				weapon:SetAttributeValue("mod soldier buff range",math.min(1+(0.15*purchased[value]),1.45))
			elseif upgrade == "Damage mult +0.15/Pri:Blast Radius -15%" then
				StackAttributeValue(activator,purchased[value],"damage penalty",0.15,0.6,1,"player")
				UpdateStats(activator,purchased[value],"BlastRadius",-0.15,-0.6)
			elseif upgrade == "Damage mult +0.15/Pri:Clip Size -25%" then
				StackAttributeValue(activator,purchased[value],"damage penalty",0.15,0.6,1,"player")
				UpdateStats(activator,purchased[value],"ClipSizeSoldier",-0.25,-1)
			elseif upgrade == "(R) Damage mult +0.2/Pri:Blast Radius -10%" then
				StackAttributeValue(activator,purchased[value],"damage penalty",0.2,0.6,1,"player")
				UpdateStats(activator,purchased[value],"BlastRadius",-0.1,-0.3)
			elseif upgrade == "(R) Health +100/Max Ammo -20%" then
				UpdateStats(activator,purchased[value],"MaxAmmo",-0.2,-0.6)
				UpdateStats(activator,purchased[value],"MaxHealth",100,300)
			elseif upgrade == "(R) Pri:Damage Bonus +25%/Clip Size -25%" then
				UpdateStats(activator,purchased[value],"ClipSizeSoldier",-0.25,-0.75)
				UpdateStats(activator,purchased[value],"DamageBonus",0.25,0.75)
			elseif upgrade == "(R) Healing Received +100%/Medic Healing -50%" then
				StackAttributeValue(activator,purchased[value],"healing received bonus",1,2)
				StackAttributeValue(activator,purchased[value],"health from healers reduced",-0.5,-1)
			elseif upgrade == "[EP] Pri:FireRate Mult +0.4/Rocket Speed -25%" then
				UpdateStats(activator,purchased[value],"FireRateMult",-0.4,-0.8)
				StackAttributeValue(activator,purchased[value],"Projectile speed decreased",-0.25,-0.5)
			elseif upgrade == "[EP] Pri:Rocket Speed +100%/Rocket Specialist" then
				weapon:SetAttributeValue("rocket specialist",3)
				StackAttributeValue(activator,purchased[value],"Projectile speed increased",1)
			elseif upgrade == "[EP] Pri:Mortar Rocket/Blast Radius +50%" then
				weapon:SetAttributeValue("projectile gravity",800)
				UpdateStats(activator,purchased[value],"BlastRadius",0.5,0.5)
			elseif upgrade == "[EP] Pri:Damage mult +0.5/FireRate Mult -0.5" then
				UpdateStats(activator,purchased[value],"DamageMult",0.5,1)
				UpdateStats(activator,purchased[value],"FireRateMult",1,2)
			elseif upgrade == "[EP] Pri:Blast Radius +50%/FireRate Mult -0.5" then
				UpdateStats(activator,purchased[value],"BlastRadius",0.5,1)
				UpdateStats(activator,purchased[value],"FireRateMult",1,2)
			elseif upgrade == "[EP] Pri:Clip Size +100%/Max Ammo +50%" then
				UpdateStats(activator,purchased[value],"ClipSizeSoldier",1,2)
				UpdateStats(activator,purchased[value],"MaxAmmo",0.5,1)
			elseif upgrade == "[EP] Pri:No FireRate/Clip Size -25%/Damage Mult -0.33/Ammo +50%" then
				UpdateStats(activator,purchased[value],"FireRateMult",-1,-1)
				UpdateStats(activator,purchased[value],"ClipSizeSoldier",-0.25,-0.25)
				UpdateStats(activator,purchased[value],"DamageMult",-0.33,-0.33)
				UpdateStats(activator,purchased[value],"ProjectileSpread",4,4)
				UpdateStats(activator,purchased[value],"MaxAmmo",0.5,0.5)
			elseif upgrade == "[EP] Pri:FireRate Mult +0.7/Force Fire Full Clip/Ammo +50%" then
				UpdateStats(activator,purchased[value],"FireRateMult",-0.7)
				weapon:SetAttributeValue("force fire full clip",1)
				UpdateStats(activator,purchased[value],"MaxAmmo",0.5)
			elseif upgrade == "[EP] Pri:Damage Bonus +35%/Rocket Decelerate" then
				UpdateStats(activator,purchased[value],"DamageBonus",0.35,0.35)
				weapon:SetAttributeValue("projectile acceleration start time",0.2)
				weapon:SetAttributeValue("projectile acceleration time",0.2)
				weapon:SetAttributeValue("projectile acceleration",-4000)
				weapon:SetAttributeValue("projectile detonate time",4)
				weapon:SetAttributeValue("mod projectile heat no predict target speed",1)
				weapon:SetAttributeValue("mod projectile heat aim start time",0.2)
			elseif upgrade == "[EP] Pri:Damage Per Target +30%/FireRate Mult -0.5" then
				UpdateStats(activator,purchased[value],"FireRateMult",0.5,1)
				weapon:SetAttributeValue("add damage per target",math.min(0.3*purchased[value],0.6))
			elseif upgrade == "[EP] Pri:Damage Bonus +25%/Rocket Accelerate" then
				StackAttributeValue(activator,purchased[value],"Projectile speed decreased",-0.4,-0.4)
				UpdateStats(activator,purchased[value],"DamageBonus",0.25,0.25)
				weapon:SetAttributeValue("projectile acceleration start time",0.3)
				weapon:SetAttributeValue("projectile acceleration time",0.4)
				weapon:SetAttributeValue("projectile acceleration",6000)
				weapon:SetAttributeValue("mod projectile heat no predict target speed",0)
			elseif upgrade == "[EP] Sec:Buff gives +50% Damage/Duration -50%" then
				AddMultipleAttributes(activator,purchased[value],"effect add attributes","damage bonus HIDDEN",0.5)
				UpdateStats(activator,purchased[value],"RageDuration",-0.5,-0.5)
			elseif upgrade == "[EP] Sec:Buff gives +25% Speed/Duration +50%" then
				AddMultipleAttributes(activator,purchased[value],"effect add attributes","major move speed bonus",0.25)
				UpdateStats(activator,purchased[value],"RageDuration",0.5,0.5)
			elseif upgrade == "[EP] Sec:Buff gives +50% FireRate/Duration -50%" then
				AddMultipleAttributes(activator,purchased[value],"effect add attributes","fire rate bonus HIDDEN",-0.5)
				UpdateStats(activator,purchased[value],"RageDuration",-0.5,-0.5)
			elseif upgrade == "[EP] Sec:Buff gives 40 Regen/Duration -50%" then
				AddMultipleAttributes(activator,purchased[value],"effect add attributes","health regen",40,nil,nil,0)
				UpdateStats(activator,purchased[value],"RageDuration",-0.5,-0.5)
			elseif upgrade == "[EP] Sec:Damage Mult +2.0/Clip and Reload -90%" then
				UpdateStats(activator,purchased[value],"SecDamageMult",2,2)
				StackAttributeValue(activator,purchased[value],"clip size penalty",-0.5)
				StackAttributeValue(activator,purchased[value],"Reload time increased",0.9)
			elseif upgrade == "[EP] Mle:Damage +150%/Mark of Death" then
				UpdateStats(activator,purchased[value],"MleDamageBonus",1.5,1.5)
				weapon:SetAttributeValue("mark for death",1)
			elseif upgrade == "[EP] Ranged Resistance +15%/Heal on Hit +15" then
				UpdateStats(activator,purchased[value],"RangedResistance",-0.15,-0.3)
				StackAttributeValue(activator,purchased[value],"heal on hit for slowfire",15,30,0)
			elseif upgrade == "[EP] Mini crits to Crits/Crit Damage -30%" then
				weapon:SetAttributeValue("minicrits become crits",1)
				weapon:SetAttributeValue("mult crit dmg",0.7)
			elseif upgrade == "[EP] Max Health +1000/Damage Taken 500%" then
				UpdateStats(activator,purchased[value],"MaxHealth",1000,3000)
				weapon:SetAttributeValue("dmg taken increased",math.min(5*purchased[value],10))
				weapon:SetAttributeValue("reduced_healing_from_medics",math.min(2*purchased[value],4))
			elseif upgrade == "【LEGEN】Super Bison" then
				weapon:SetAttributeValue("dmg penalty vs players",1.5)
				UpdateStats(activator,purchased[value],"DamageMult",-0.25,-0.25)
				weapon:SetAttributeValue("projectile acceleration",-1000)
				weapon:SetAttributeValue("projectile acceleration start time",0.4)
			elseif upgrade == "【LEGEN】Pri:Nuke" then
				UpdateStats(activator,purchased[value],"ClipSizeSoldier",-0.75,-0.75)
				UpdateStats(activator,purchased[value],"DamageMult",3,3)
				UpdateStats(activator,purchased[value],"FireRateMult",6,6)
				UpdateStats(activator,purchased[value],"BlastRadius",0.25,0.25)
				weapon:SetAttributeValue("use large smoke explosion",1)
			elseif upgrade == "【LEGEN】Pri:Rapid Fire/Damage Mult -0.7" then
				UpdateStats(activator,purchased[value],"DamageMult",-0.7,-0.7)
				UpdateStats(activator,purchased[value],"FireRateMult",-0.8,-0.8)
				UpdateStats(activator,purchased[value],"ReloadRate",-0.99,-0.99)
			end
		end
		
		--pyro custom upgrades
		if activator:DumpProperties().m_iClass == 7 then
			local phlog = 0
			local gas = 0
			local dragon = 0
			for k,v in pairs(AllItems) do 
				if v == "The Phlogistinator" then
					activator:PrintToChat("you have a phlog")
					phlog = 1
				elseif v == "The Gas Passer" then
					activator:PrintToChat("you have a gas")
					gas = 1
				elseif v == "The Dragon's Fury" then
					activator:PrintToChat("you have a dragon's fury")
					dragon = 1
				end
			end
		    activator:PrintToChat("Fire fire fire")
			if upgrade == "(R) Sec:Effect Bar Recharge +25%/Switch +40%" then
				weapon:SetAttributeValue("mult_item_meter_charge_rate",math.max(1+(-0.25*purchased[value]),0.25))
				weapon:SetAttributeValue("single weaponslot deploy time decreased",math.max(1+(-0.4*purchased[value]),0.05))
			elseif upgrade == "(R) Sec:All Thermal Thruster Mod/Stompy" then
				weapon:SetAttributeValue("thermal_thruster_air_launch",1)
				weapon:SetAttributeValue("falling_impact_radius_stun",1)
				weapon:SetAttributeValue("boots falling stomp",1)
				weapon:SetAttributeValue("kb fall damage",150)
			elseif upgrade == "(R) Override Airblast Mod:Efficiency" then
				weapon:SetAttributeValue("airblast cost decreased",0.25)
				weapon:SetAttributeValue("mult airblast refire time",2)
				weapon:SetAttributeValue("airblast pushback scale",1.25)
			elseif upgrade == "(R) Override Airblast Mod:Power" then
				weapon:SetAttributeValue("airblast cost decreased",1.2)
				weapon:SetAttributeValue("mult airblast refire time",1.5)
				weapon:SetAttributeValue("airblast pushback scale",2)
			elseif upgrade == "(R) Override Airblast Mod:Repressure" then
				weapon:SetAttributeValue("airblast cost decreased",0.5)
				weapon:SetAttributeValue("mult airblast refire time",0.5)
				weapon:SetAttributeValue("airblast pushback scale",0.1)
			elseif upgrade == "(R) Pri:Crit Damage +25%/Buff Duration -25%" then
				StackAttributeValue(activator,purchased[value],"mult crit dmg",0.25,0.5)
				StackAttributeValue(activator,purchased[value],"increase buff duration",-0.25,-0.5)
			elseif upgrade == "(R) Sec:Crit DMG +100%/No Medic Healing" then
				weapon:SetAttributeValue("mult crit dmg",math.min(1+(1*purchased[value]),4))
				weapon:SetAttributeValue("mod weapon blocks healing",1)
			elseif upgrade == "(R) Gas:Apply -25% Damage Debuff" then
				if gas == 1 then
					AddMultipleAttributes(activator,purchased[value],"effect add attributes","dmg penalty vs players",-0.25,nil,-0.5)
				end
			elseif upgrade == "(R) Mle:Crit DMG +100%/No Medic Healing" then
				weapon:SetAttributeValue("mult crit dmg",math.min(1+(1*purchased[value]),4))
				weapon:SetAttributeValue("mod weapon blocks healing",1)
			elseif upgrade == "(R) Ranged Res +15%/Move Speed -20%" then
				UpdateStats(activator,purchased[value],"RangedResistance",-0.15,-0.6)
				UpdateStats(activator,purchased[value],"MoveSpeed",-0.2,-0.8)
			elseif upgrade == "[EP] Pri:Slow Enemy On Hit/Damage Mult +0.5" then
			    UpdateStats(activator,purchased[value],"DamageMult",0.5,0.5)
				weapon:SetAttributeValue("slow enemy on hit",1)
			elseif upgrade == "[EP] Pri:Damage Mult +0.5/Flamethrower spin up -0.8s" then
				UpdateStats(activator,purchased[value],"DamageMult",0.5,1)
				weapon:SetAttributeValue("mod flamethrower spinup time",math.min(0.8*purchased[value],1.6))
				if dragon == 1 then
					StackAttributeValue(activator,purchased[value],"mult_item_meter_charge_rate",0.5)
				end
			elseif upgrade == "[EP] Pri:Flame Life x4/Gravity/Damage Mult +1" then
			    UpdateStats(activator,purchased[value],"DamageMult",1,1)
				weapon:SetAttributeValue("flame_lifetime",3.9)
				weapon:SetAttributeValue("flame_up_speed",-100)
				if dragon == 1 then
					StackAttributeValue(activator,purchased[value],"mult_item_meter_charge_rate",1)
				end
			elseif upgrade == "[EP] Pri:Flame Speed x1.3/Damage Mult +0.2" then
			    UpdateStats(activator,purchased[value],"DamageMult",0.2,0.2)
				weapon:SetAttributeValue("flame_drag",5)
				if dragon == 1 then
					StackAttributeValue(activator,purchased[value],"mult_item_meter_charge_rate",0.2)
				end
			elseif upgrade == "[EP] Pri:Flame Speed x0.2/Damage Mult +1" then
			    UpdateStats(activator,purchased[value],"DamageMult",1,1)
				weapon:SetAttributeValue("flame_speed",450)
				if dragon == 1 then
					StackAttributeValue(activator,purchased[value],"mult_item_meter_charge_rate",1)
				end
			elseif upgrade == "[EP] Pri:Damage Mult +0.5/Flamethrower Ammo Cost x2" then
				UpdateStats(activator,purchased[value],"DamageMult",0.5,1)
				StackAttributeValue(activator,purchased[value],"flame ammopersec decreased",1,2)
			elseif upgrade == "[EP] Pri:Burining Enemy Gives You +25 Health Regen" then
				AddMultipleAttributes(activator,purchased[value],"self add attributes on hit","health regen",25,1,50,0)
			elseif upgrade == "[EP] Pri:Burining Enemies Take +100% Melee Damage" then
				AddMultipleAttributes(activator,purchased[value],"add attributes on hit","mult dmgtaken from melee",1,1,2)
			elseif upgrade == "[EP] Phlog:Buff Also Applies +25% Resistance" then
				if phlog == 1 then
					AddMultipleAttributes(activator,purchased[value],"effect add attributes","dmg taken increased",-0.25)
				end
			elseif upgrade == "[EP] Sec:Projectile Multishot +3/Projectile Spread -4" then
				weapon:SetAttributeValue("mult projectile count",math.min(1+(3*purchased[value]),4))
				weapon:SetAttributeValue("projectile spread angle penalty",math.min(-4*purchased[value],-4))
			elseif upgrade == "【LEGEN】Very Big Pyro" then
				weapon:SetAttributeValue("model scale",1.5)
				UpdateStats(activator,purchased[value],"MaxHealth",725,725)
				UpdateStats(activator,purchased[value],"MoveSpeed",-0.15,-0.15)
				weapon:SetAttributeValue("damage force increase",0.7)
				weapon:SetAttributeValue("patient overheal penalty",0.01)
			end
		end
			
		--demo custom upgrades
		if activator:DumpProperties().m_iClass == 4 then
		    activator:PrintToChat("Black scottish cyclops")
		
			if upgrade == "Damage +10%/Sec:Charge Recharge +75%/Time +1" then
				secondary:SetAttributeValue("charge recharge rate increased",math.min(1+(0.75*purchased[value]),4.75))
				secondary:SetAttributeValue("charge time increased",math.min(1+(0.5*purchased[value]),5))
				activator:SetAttributeValue("damage bonus",math.min(1+(0.1*purchased[value]),1.5))
			elseif upgrade == "Damage mult +0.15/Pri:Blast Radius -15%" then
				StackAttributeValue(activator,purchased[value],"damage penalty",0.15,0.45,1,"player")
				UpdateStats(activator,purchased[value],"BlastRadius",-0.15,-0.45)
			elseif upgrade == "Damage mult +0.15/Sec:Sticky Arm Penalty -0.1" then
				StackAttributeValue(activator,purchased[value],"damage penalty",0.15,0.45,1,"player")
				StackAttributeValue(activator,purchased[value],"sticky arm time bonus",0.1,0.3,0)
			elseif upgrade == "(R) Sec:Shield Control +100%/Push Force -50%" then
				weapon:SetAttributeValue("mult charge turn control",math.min(1+(1*purchased[value]),3))
				weapon:SetAttributeValue("damage force reduction",math.max(1+(-0.5*purchased[value]),0.01))
			elseif upgrade == "(R) Sec:Sticky Arm Bonus +0.2s" then
				StackAttributeValue(activator,purchased[value],"sticky arm time bonus",-0.2,-0.4,0)
			elseif upgrade == "(R) Health +75/Max Ammo -20%" then
				UpdateStats(activator,purchased[value],"MaxHealth",75,225)
				activator:SetAttributeValue("maxammo primary reduced",math.max(1+(-0.2*purchased[value]),0.4))
				activator:SetAttributeValue("maxammo secondary reduced",math.max(1+(-0.2*purchased[value]),0.4))
			elseif upgrade =="(R) Pri:Fire Rate +25%/Spread Angle -2" then
				UpdateStats(activator,purchased[value],"FireRate",-0.25,-0.75)
				UpdateStats(activator,purchased[value],"ProjectileSpread",2,6)
			elseif upgrade == "(R) Taunt Speed +100%" then
				weapon:SetAttributeValue("gesture speed increase",math.min(1+(1*purchased[value]),3))
				weapon:SetAttributeValue("taunt attack time mult",math.max(0.75+(-0.25*purchased[value]),0.25))
			elseif upgrade == "[EP] Pri:Damage mult +0.5/FireRate Mult -0.5" then
				UpdateStats(activator,purchased[value],"DamageMult",0.5,1)
				UpdateStats(activator,purchased[value],"FireRateMult",0.5,1)
			elseif upgrade == "[EP] Pri:Blast Radius +50%/FireRate Mult -1" then
				UpdateStats(activator,purchased[value],"BlastRadius",0.5,1)
				UpdateStats(activator,purchased[value],"FireRateMult",1,2)
			elseif upgrade == "[EP] Pri:Fire Rate +60%/Ammo +50%" then
				UpdateStats(activator,purchased[value],"FireRate",-0.6,-1)
				UpdateStats(activator,purchased[value],"MaxAmmo",0.5,1)
			elseif upgrade == "[EP] Pri:No FireRate/Clip Size -25%/Damage Mult -0.33/Ammo +50%" then
				UpdateStats(activator,purchased[value],"FireRateMult",-0.95,-0.95)
				UpdateStats(activator,purchased[value],"ClipSize",-0.25,-0.25)
				UpdateStats(activator,purchased[value],"ProjectileSpread",4,4)
				UpdateStats(activator,purchased[value],"DamageMult",-0.33,-0.33)
				UpdateStats(activator,purchased[value],"MaxAmmo",0.5,0.5)
			elseif upgrade == "[EP] Pri:Grenade Fuse x0.3/Detonation DMG +100%/Damage Mult -0.2" then
				UpdateStats(activator,purchased[value],"DamageMult",-0.2,-0.2)
				weapon:SetAttributeValue("fuse bonus",0.3)
				weapon:SetAttributeValue("grenade detonation damage penalty",4)
			elseif upgrade == "[EP] Pri:Rolling Grenade Damage x4/Damage Mult -0.2" then
				weapon:SetAttributeValue("grenade damage reduction on world contact",4)
				UpdateStats(activator,purchased[value],"DamageMult",-0.2,-0.2)
			elseif upgrade == "[EP] Pri:No FireRate/Clip Size -25%/Damage Mult -0.33/Ammo +50%" then
				UpdateStats(activator,purchased[value],"FireRateMult",-1,-1)
				UpdateStats(activator,purchased[value],"ClipSize",-0.25,-0.25)
				UpdateStats(activator,purchased[value],"DamageMult",-0.33,-0.33)
				UpdateStats(activator,purchased[value],"ProjectileSpread",4,4)
				UpdateStats(activator,purchased[value],"MaxAmmo",0.5,0.5)
			elseif upgrade == "[EP] Sec:Bazooka/FireRate Mult +1" then
				weapon:SetAttributeValue("auto fires full clip",1)
				weapon:SetAttributeValue("stickybomb charge rate",0)
				UpdateStats(activator,purchased[value],"SecFireRateMult",-0.5,-0.5)
			elseif upgrade == "[EP] Sec:FireRate Mult +2/Sticky Arm Penalty -0.4s" then
				weapon:SetAttributeValue("sticky arm time penalty",0.4)
				UpdateStats(activator,purchased[value],"SecFireRateMult",-0.75,-0.75)
			elseif upgrade == "[EP] Sec:Sticky Only Stick on Enemies/Damage Mult +0.3" then
				UpdateStats(activator,purchased[value],"SecDamageMult",0.3,0.3)
				activator:SetAttributeValue("stickybomb stick to enemies",1)
				activator:SetAttributeValue("stickybomb no stick",1)
			elseif upgrade == "[EP] Sec:Damage Per Target +30%/FireRate Mult -0.25" then
				UpdateStats(activator,purchased[value],"SecFireRateMult",0.25,1)
				weapon:SetAttributeValue("add damage per target",math.min(0.3*purchased[value],0.6))
			elseif upgrade == "[EP] Sec:No Fire Delay/Reload All At Once/Clip Size -0.75" then
				weapon:SetAttributeValue("clip size penalty",0.25)
				StackAttributeValue(activator,purchased[value],"faster reload rate",3)
				UpdateStats(activator,purchased[value],"SecFireRateMult",-1,-1)
				weapon:SetAttributeValue("projectile spread angle penalty",6)
				weapon:SetAttributeValue("reload full clip at once",1)
				UpdateStats(activator,purchased[value],"SecDamageMult",-0.1,-0.1)
			elseif upgrade == "[EP] Sec:No Fire Delay/Reload All At Once/Clip Size -0.5" then
				weapon:SetAttributeValue("clip size penalty",0.5)
				StackAttributeValue(activator,purchased[value],"faster reload rate",4)
				UpdateStats(activator,purchased[value],"SecFireRateMult",-1,-1)
				weapon:SetAttributeValue("projectile spread angle penalty",6)
				weapon:SetAttributeValue("reload full clip at once",1)
				UpdateStats(activator,purchased[value],"SecDamageMult",-0.2,-0.2)
			elseif upgrade == "[EP] Mle:Melee Range/Attack Rate +200%/Damage Mult -0.7" then
				UpdateStats(activator,purchased[value],"MleDamageMult",-0.7,-0.7)
				weapon:SetAttributeValue("fire rate bonus",0.25)
				weapon:SetAttributeValue("melee range multiplier",7)
			elseif upgrade == "[EP] Mle:Melee Cleave/Attack Rate -100%/Damage Mult +0.5" then
				UpdateStats(activator,purchased[value],"MleDamageMult",0.5,0.5)
				weapon:SetAttributeValue("fire rate bonus",2)
				weapon:SetAttributeValue("melee cleave attack",1)
			elseif upgrade == "[EP] Mle:Honor Bound/Live for Honor" then
				weapon:SetAttributeValue("honorbound",1)
				weapon:SetAttributeValue("dmg from melee increased",2)
				weapon:SetAttributeValue("dmg from ranged reduced",0.6)
			elseif upgrade == "[EP] Mle:Honor Bound/Critboost Other Weapon" then
				weapon:SetAttributeValue("honorbound",1)
				weapon:SetAttributeValue("critboost on kill",10)
				weapon:SetAttributeValue("mult crit dmg",0.34)
			elseif upgrade == "[EP] Ranged Resistance +25%/Jump x2.5" then
				UpdateStats(activator,purchased[value],"RangedResistance",-0.25,-0.25)
				weapon:SetAttributeValue("increased jump height",2.5)
				weapon:SetAttributeValue("bot custom jump particle",1)
			elseif upgrade == "【LEGEN】Pri:Nuke" then
				UpdateStats(activator,purchased[value],"ClipSize",-0.75,-0.75)
				UpdateStats(activator,purchased[value],"DamageMult",3.5,3.5)
				UpdateStats(activator,purchased[value],"FireRateMult",5,5)
				UpdateStats(activator,purchased[value],"BlastRadius",0.25,0.25)
				UpdateStats(activator,purchased[value],"ProjectileSpread",8,8)
				weapon:SetAttributeValue("override projectile type",17)
				weapon:SetAttributeValue("use large smoke explosion",1)
			end
		end
		
		--heavy custom upgrades
		if activator:DumpProperties().m_iClass == 6 then
		    activator:PrintToChat("Pootis spencer here")
			local steak = 0
			for k,v in pairs(AllItems) do 
				if v == "The Buffalo Steak Sandvich" then
					activator:PrintToChat("you have a steak")
					steak = 1
				end
			end
			if upgrade == "Health +50/-25% OverHealed" then
				UpdateStats(activator,purchased[value],"MaxHealth",50,200)
				weapon:SetAttributeValue("patient overheal penalty",math.max(1+(-0.25*purchased[value]),0))
			elseif upgrade == "Sec:Food Consume/Recharge and Switch +40%" then
				weapon:SetAttributeValue("mult_item_meter_charge_rate",math.max(1+(-0.4*purchased[value]),0.2))
				weapon:SetAttributeValue("gesture speed increase",math.max(1+(0.4*purchased[value]),1.8))
			elseif upgrade == "(R) Pri:Damage Bonus +10%/Spin Up Penalty -100%" then
				UpdateStats(activator,purchased[value],"DamageBonus",0.1,0.3)
				UpdateStats(activator,purchased[value],"SpunRate",1,2)
			elseif upgrade == "(R) Pri:Spin Up Time +15%/Spun Up Speed +10%" then
				UpdateStats(activator,purchased[value],"SpunRate",-0.15,-0.45)
				weapon:SetAttributeValue("aiming movespeed increased",math.min(1+(0.1*purchased[value]),1.3))
			elseif upgrade == "(R) Pri:Minigun Destroy Projectiles +1/Ammo +25%" then
				weapon:SetAttributeValue("attack projectiles",math.min(1*purchased[value]),2)
				UpdateStats(activator,purchased[value],"MaxAmmo",0.25,0.5)
			elseif upgrade == "(R) Steak:Buff Also Applies Damage x1.5" then
				if steak == 1 then
					AddMultipleAttributes(activator,purchased[value],"effect add attributes","damage bonus HIDDEN",0.5)
				end
			elseif upgrade == "(R) Damage Mult +10%/Pri:Spin Up Time -130%" then
				StackAttributeValue(activator,purchased[value],"damage penalty",0.1,0.3)
				UpdateStats(activator,purchased[value],"SpunRate",1.3,3.9)
			elseif upgrade == "(R) Weapon Switch On-Spin / Faster Switch" then
				activator:SetAttributeValue("mod minigun can holster while spinning",1)
				activator:SetAttributeValue("deploy time decreased",1+(-0.1*purchased[value]))
			elseif upgrade == "[EP] Pri:Override Firing Mod:Spread" then
				UpdateStats(activator,purchased[value],"BulletPerShot",0.25,0.25)
				UpdateStats(activator,purchased[value],"BulletSpread",0.6,0.6)
				UpdateStats(activator,purchased[value],"FireRateMult",-0.2,-0.2)
			elseif upgrade == "[EP] Pri:Override Firing Mod:Single" then
				UpdateStats(activator,purchased[value],"BulletPerShot",-0.75,-0.75)
				UpdateStats(activator,purchased[value],"DamageMult",2,2)
				UpdateStats(activator,purchased[value],"BulletSpread",-0.7,-0.7)
				UpdateStats(activator,purchased[value],"FireRateMult",-0.2,-0.2)
			elseif upgrade == "[EP] Pri:Override Firing Mod:Focus" then
				UpdateStats(activator,purchased[value],"BulletSpread",-0.95,-0.95)
				UpdateStats(activator,purchased[value],"FireRateMult",0.4,0.4)
			elseif upgrade == "[EP] Pri:Override Firing Mod:Burst" then
				UpdateStats(activator,purchased[value],"BulletPerShot",3,3)
				UpdateStats(activator,purchased[value],"DamageMult",0.2,0.2)
				UpdateStats(activator,purchased[value],"BulletSpread",0.4,0.4)
				UpdateStats(activator,purchased[value],"FireRateMult",4.5,4.5)
			elseif upgrade == "[EP] Pri:Bullet Per Shot +25%/Spread -60%" then
				UpdateStats(activator,purchased[value],"BulletPerShot",0.25,0.5)
				UpdateStats(activator,purchased[value],"BulletSpread",0.6,1.2)
			elseif upgrade == "[EP] Pri:Damage Bonus +20%/Bullet Per Shot -25%" then
				UpdateStats(activator,purchased[value],"DamageBonus",0.2,0.4)
				UpdateStats(activator,purchased[value],"BulletPerShot",-0.25,-0.5)
			elseif upgrade == "[EP] Pri:Spread Bonus +25%" then
				UpdateStats(activator,purchased[value],"BulletSpread",-0.25,-0.5)
			elseif upgrade == "[EP] Pri:Damage Bonus +25%/Fire Rate Mult -0.3/Spread -20%" then
				UpdateStats(activator,purchased[value],"DamageBonus",0.25,0.5)
				UpdateStats(activator,purchased[value],"FireRateMult",0.3,0.6)
				UpdateStats(activator,purchased[value],"BulletSpread",0.2,0.4)
			elseif upgrade == "[EP] Pri:Damage Mult +1/Above 50% Health Damage x0.4" then
				UpdateStats(activator,purchased[value],"DamageMult",1,1)
				weapon:SetAttributeValue("dmg penalty while half alive",0.4)
			elseif upgrade == "[EP] Pri:Generate Rage/Piercing" then
				weapon:SetAttributeValue("generate rage on damage",1)
				weapon:SetAttributeValue("shot penetrate all players",1)
			elseif upgrade == "[EP] Pri:Rocket Rain/No Ramp up" then
				weapon:SetAttributeValue("override projectile type",2)
				weapon:SetAttributeValue("projectile gravity",1200)
				UpdateStats(activator,purchased[value],"DamageMult",3,3)
				weapon:SetAttributeValue("projectile spread angle penalty",8)
				UpdateStats(activator,purchased[value],"FireRateMult",0.3,0.3)
				weapon:SetAttributeValue("no damage falloff",1)
			elseif upgrade == "[EP] No Damage Falloff/Ramp Up" then
				weapon:SetAttributeValue("no damage falloff",2)
				UpdateStats(activator,purchased[value],"DamageMult",0.5,0.5)
			elseif upgrade == "[EP] Sec:Bullets +100%/Reload +30%/FireRate Mult -0.4" then
				UpdateStats(activator,purchased[value],"SecBulletPerShot",1,2)
				UpdateStats(activator,purchased[value],"SecFireRateMult",0.4,0.4)
				weapon:SetAttributeValue("Reload time decreased",math.max(1-(0.3*purchased[value]),0.4))
			elseif upgrade == "[EP] Steak:Buff Also Applies +35% Resistance" then
				if steak == 1 then
					AddMultipleAttributes(activator,purchased[value],"effect add attributes","dmg taken increased",-0.35)
				end
			elseif upgrade == "[EP] Mle:Damage Mult +2/Move Speed -40%/FireRate -40%" then
				UpdateStats(activator,purchased[value],"MleDamageMult",2,4)
				UpdateStats(activator,purchased[value],"MoveSpeed",-0.4,-0.8)
				weapon:SetAttributeValue("fire rate penalty",math.min(1+(0.4*purchased[value]),1.8))
			elseif upgrade == "(R) Mle:DMG Resistance +10%/Debuff Target on Hit" then
				weapon:SetAttributeValue("dmg taken increased",math.min(1+(-0.1*purchased[value]),0.9))
				AddMultipleAttributes(activator,purchased[value],"add attributes on hit","dmg taken increased",0.2,5)
			elseif upgrade == "[EP] Size Up/+150 Health" then
				weapon:SetAttributeValue("model scale",math.min(1+(0.2*purchased[value]),1.4))
				UpdateStats(activator,purchased[value],"MaxHealth",150,300)
			elseif upgrade == "[EP] Damage x1.5 Below 50% Health / -50% Healed" then
				activator:SetAttributeValue("dmg bonus while half dead",math.min(1+(0.5*purchased[value]),max))
				activator:SetAttributeValue("healing received penalty",math.max(1+(-0.5*purchased[value]),0.01))
			elseif upgrade == "[EP] Ranged Resistance +10%/Heal on Hit +2" then
				UpdateStats(activator,purchased[value],"RangedResistance",-0.1,-0.2)
				weapon:SetAttributeValue("heal on hit for rapidfire",math.min(2*purchased[value],4))
			elseif upgrade == "[EP] Max Health +100/Ranged Resistance +10%" then
				UpdateStats(activator,purchased[value],"RangedResistance",-0.1,-0.2)
				UpdateStats(activator,purchased[value],"MaxHealth",100,200,0)
			elseif upgrade == "【LEGEN】No Spin up" then
				UpdateStats(activator,purchased[value],"SpunRate",-0.95,-0.95)
				activator:SetAttributeValue("aiming movespeed increased",2.1)
			elseif upgrade == "【LEGEN】Rocket" then
				weapon:SetAttributeValue("override projectile type",2)
				UpdateStats(activator,purchased[value],"DamageMult",4,4)
				weapon:SetAttributeValue("projectile spread angle penalty",2)
				UpdateStats(activator,purchased[value],"FireRateMult",1,1)
			end
		end
			
		--engineer custom upgrades
		if activator:DumpProperties().m_iClass == 9 then
		    activator:PrintToChat("Use more guns")
			local eureka = 0
			for k,v in pairs(AllItems) do 
				if v == "The Eureka Effect" then
					activator:PrintToChat("you have a effect")
					eureka = 1
				elseif v == "The Widowmaker" then
					activator:PrintToChat("Widowmaker")
					widow = 1
				end
			end
			if upgrade == "Dispenser Range +100%/Metal Pickup +50%" then
				weapon:SetAttributeValue("engy dispenser radius increased",math.min(1+(1*purchased[value]),4))
				activator:SetAttributeValue("metal_pickup_decreased",math.min(1+(0.5*purchased[value]),2.5))
			elseif upgrade == "Max Metal Capacity +100%/Metal Regen +15" then
				UpdateStats(activator,purchased[value],"MaxMetal",1,3)
				UpdateStats(activator,purchased[value],"MetalRegen",15,45)
			elseif upgrade == "Building Health +50%/Repair Rate +25%" then
				UpdateStats(activator,purchased[value],"BuildingHealth",0.5,2)
				melee:SetAttributeValue("Repair rate increased",math.min(1+(0.25*purchased[value]),2))
			elseif upgrade == "Damage Bonus +30%/Pri:Ammo -25%" then
				UpdateStats(activator,purchased[value],"DamageBonusSelf",0.3,0.9)
				UpdateStats(activator,purchased[value],"MaxAmmo",-0.25,-0.75)
			elseif upgrade == "(R) Building Health +100%/Repair Rate +25%" then
				UpdateStats(activator,purchased[value],"BuildingHealth",1,3)
				activator:SetAttributeValue("Repair rate increased",math.min(1+(0.25*purchased[value]),2.25))
			elseif upgrade == "(R) Damage Mult +0.3/Ranged Resistance +10%" then
				StackAttributeValue(activator,purchased[value],"damage penalty",0.3,0.9,1,"player")
				UpdateStats(activator,purchased[value],"RangedResistance",-0.1,-0.3)
			elseif upgrade == "(R) Taunt Speed +100%/Eureka:Lesser Penalty" then
				activator:SetAttributeValue("gesture speed increase",math.min(1+(1*purchased[value]),3))
				activator:SetAttributeValue("taunt attack time mult",math.max(1+(-0.5*purchased[value]),0.25))
				if eureka == 1 then
					activator:PrintToChat("you have a effect")
					StackAttributeValue(activator,purchased[value],"Construction rate decreased",0.25,0.5,0)
				end
			elseif upgrade == "[EP] Pri:Damage Mult +1/Sentry Damage -20%" then
				UpdateStats(activator,purchased[value],"DamageMult",1,2)
				UpdateStats(activator,purchased[value],"SentryDamage",-0.2,-0.4)
			elseif upgrade == "[EP] Pri:Bullets Per Shot +200%/FireRate Mult -1" then
				UpdateStats(activator,purchased[value],"BulletPerShot",2,4)
				UpdateStats(activator,purchased[value],"FireRateMult",1,2)
			elseif upgrade == "[EP] Sec:Damage Bonus +300%/FireRate Mult -2" then
				UpdateStats(activator,purchased[value],"SecDamageBonus",3,3)
				UpdateStats(activator,purchased[value],"SecFireRateMult",2,2)
			elseif upgrade == "[EP] Pri:Damage Mult +1/FireRate Mult -0.4" then
				UpdateStats(activator,purchased[value],"DamageMult",1,2)
				UpdateStats(activator,purchased[value],"FireRateMult",0.4,0.8)
			elseif upgrade == "[EP] Pri:Bullet Per Shot +100%/Spread -20%" then
				UpdateStats(activator,purchased[value],"BulletPerShot",1,2)
				UpdateStats(activator,purchased[value],"BulletSpread",0.2,0.4)
			elseif upgrade == "[EP] Mle:Crit Damage +150%/No Random Crits" then
				weapon:SetAttributeValue("mult crit dmg",math.min(1+(1.5*purchased[value]),4))
				weapon:SetAttributeValue("crit mod disabled",1)
			elseif upgrade == "[EP] Building Max Level 2/No Sentry Cost/Metal Regen +60" then
				special:SetAttributeValue("building max level",2)
				special:SetAttributeValue("mod sentry cost",0)
				UpdateStats(activator,purchased[value],"MetalRegen",60,60)
			elseif upgrade == "[EP] Sentry Damage +40%/Wrangler Shield Disabled" then
				UpdateStats(activator,purchased[value],"SentryDamage",0.4,0.4)
				secondary:SetAttributeValue("disable wrangler shield",1)
			elseif upgrade == "[EP] Upgraded Sentry/Sentry Cost +150%" then
				UpdateStats(activator,purchased[value],"SentryDamage",0.3,0.3)
				UpdateStats(activator,purchased[value],"BuildingHealth",1,1)
				weapon:SetAttributeValue("mod sentry cost",2.5)
			elseif upgrade == "[EP] Mini Sentry/Sentry Damage +100%" then
				UpdateStats(activator,purchased[value],"SentryDamage",1,1)
				melee:SetAttributeValue("mod wrench builds minisentry",1)
			elseif upgrade == "[EP] Building Health +300%/Sentry Damage -20%" then
				UpdateStats(activator,purchased[value],"BuildingHealth",3,6)
				UpdateStats(activator,purchased[value],"SentryDamage",-0.2,-0.4)
			elseif upgrade == "[EP] Two-Way Teleporter/Instant Recharge" then
				weapon:SetAttributeValue("bidirectional teleport",1)
				weapon:SetAttributeValue("mod teleporter speed boost",1)
				weapon:SetAttributeValue("mult teleporter recharge rate",0.05)
			elseif upgrade == "[EP] Energy Weapon Damage x3" then
				UpdateStats(activator,purchased[value],"DamageBonusSelf",-0.66,-0.66)
				activator:SetAttributeValue("dmg penalty vs players",3)
				activator:SetAttributeValue("dmg penalty vs buildings",3)
			elseif upgrade == "[EP] Override Sentry Firing Mod:Sentinel" then
				special:SetAttributeValue("sentry bullet weapon","tf_weapon_lunchbox_drink")
				special:SetAttributeValue("sentry rocket weapon","tf_weapon_rocketlauncher")
				special:SetAttributeValue("engy sentry fire rate increased",20)
				special:SetAttributeValue("mult firerocket rate",0.8)
				primary:SetAttributeValue("dmg penalty vs players",0.2)
				secondary:SetAttributeValue("dmg penalty vs players",0.2)
				melee:SetAttributeValue("dmg penalty vs players",0.2)
				activator:SetAttributeValue("damage bonus HIDDEN",5)
				UpdateStats(activator,purchased[value],"SentryRange",2,2)
				UpdateStats(activator,purchased[value],"BuildingHealth",2,2)
				activator:SetAttributeValue("blast dmg to self increased",0.05)
				activator:SetAttributeValue("no damage falloff",1)
				special:SetAttributeValue("mvm sentry ammo",3)
			elseif upgrade == "[EP] Override Sentry Firing Mod:Rocket" then
				special:SetAttributeValue("sentry bullet weapon","tf_weapon_lunchbox_drink")
				special:SetAttributeValue("engy sentry fire rate increased",20)
				activator:SetAttributeValue("engy sentry damage bonus",2.5)
				special:SetAttributeValue("mult firerocket rate",0.6)
				activator:SetAttributeValue("blast dmg to self increased",0.05)
			elseif upgrade == "[EP] Override Sentry Firing Mod:Machine Gun" then
				special:SetAttributeValue("engy sentry fire rate increased",0.5)
				special:SetAttributeValue("sentry rocket weapon","tf_weapon_lunchbox_drink")
				special:SetAttributeValue("mult firerocket rate",20)
				special:SetAttributeValue("mvm sentry ammo",0.85)
				UpdateStats(activator,purchased[value],"SentryRange",0.2,0.2)
			elseif upgrade == "[EP] Disposable Sentry +2/Sentry No Repair" then
				activator:SetAttributeValue("Repair rate decreased",0.01)
				special:SetAttributeValue("engy disposable sentries",2)
			elseif upgrade == "[EP] Dispenser Rate x5/Dispenser Range +100%" then
				activator:SetAttributeValue("mult dispenser rate",math.min(5*purchased[value],10))
				activator:SetAttributeValue("engy dispenser radius increased",math.min(1+(1*purchased[value]),3))
			end
		end
			
		--medic custom upgrades
		if activator:DumpProperties().m_iClass == 5 then
		    activator:PrintToChat("MEDIC")
			if upgrade == "Sec:Projectile Shield/Rage Duration -70%" then
				weapon:SetAttributeValue("generate rage on heal",2)
				UpdateStats(activator,purchased[value],"RageDuration",-0.6,-0.6)
			elseif upgrade == "med upgrade test" then
				AddMultipleAttributes(activator,purchased[value],"self add attributes on hit","health regen",25,1,nil,0)
			elseif upgrade == "med upgrade test2" then
				AddMultipleAttributes(activator,purchased[value],"self add attributes on hit","health regen",25,1,nil,0)
			elseif upgrade == "med upgrade check" then
				activator:PrintToChat(weapon:GetAttributeValue("self add attributes on hit"))
			elseif upgrade == "(R) Pri:Milk Syringe/Crossbow Milk Bolt" then
				weapon:SetAttributeValue("mad milk syringes",1)
				weapon:SetAttributeValue("fires milk bolt",1)
			elseif upgrade == "(R) Damage Mult +0.3/Ranged Res +10%/Uber Rate -25%" then
				activator:SetAttributeValue("damage penalty",math.min(1+(0.3*purchased[value]),1.9))
				UpdateStats(activator,purchased[value],"RangedResistance",-0.1,-0.3)
				UpdateStats(activator,purchased[value],"UberRate",-0.25,-0.75)
			elseif upgrade == "[EP] Sec:Ranged Res -15%/Pri:Damage Mult +1" then
				UpdateStats(activator,purchased[value],"DamageMult",1,2)
				secondary:SetAttributeValue("dmg from ranged reduced",math.max(1+(-0.15*purchased[value]),0.7))
			elseif upgrade == "[EP] Pri:FireRate Mult +9/Clip Size -95%/Spread -4" then
				UpdateStats(activator,purchased[value],"FireRateMult",-0.95,-0.95)
				StackAttributeValue(activator,purchased[value],"clip size penalty",-0.95)
				StackAttributeValue(activator,purchased[value],"clip size upgrade atomic",3)
				weapon:SetAttributeValue("projectile spread angle penalty",4)
			elseif upgrade == "[EP] Pri:Burst Fire +2/FireRate Mult -1" then
				UpdateStats(activator,purchased[value],"FireRateMult",-0.3,-0.3)
				weapon:SetAttributeValue("burst fire count",-3)
				weapon:SetAttributeValue("burst fire rate mult",3)
				UpdateStats(activator,purchased[value],"DamageMult",1,1)
			elseif upgrade == "[EP] Pri:Damage Mult +2/Use Ubercharge as Ammo" then
				UpdateStats(activator,purchased[value],"DamageMult",2,2)
				weapon:SetAttributeValue("ubercharge ammo",1)
				weapon:SetAttributeValue("Reload time increased",2.5)
			elseif upgrade == "[EP] Recall/Sec:Revive Speed x3/No OverHeal" then
				UpdateStats(activator,purchased[value],"OverhealBonus",-10,-10)
				activator:SetAttributeValue("teleport instead of die",1)
				weapon:SetAttributeValue("revive rate",3)
			elseif upgrade == "[EP] Pri:Damage Mult +1/Sec:Instant OverHeal Decay" then
				UpdateStats(activator,purchased[value],"DamageMult",1,1)
				weapon:SetAttributeValue("overheal decay penalty",0.02)
			elseif upgrade == "[EP] Sec:UberCharging Mod:Blank" then
				UpdateStats(activator,purchased[value],"UberDuration",-6,-6)
				UpdateStats(activator,purchased[value],"UberRate",10,10)
			elseif upgrade == "[EP] Sec:UberCharging Mod:Extended" then
				UpdateStats(activator,purchased[value],"UberDuration",12,12)
				UpdateStats(activator,purchased[value],"UberRate",-0.2,-0.2)
			elseif upgrade == "[EP] Sec:UberCharging Mod:Balanced" then
				UpdateStats(activator,purchased[value],"UberDuration",4,4)
				UpdateStats(activator,purchased[value],"UberRate",0.3,0.3)
			elseif upgrade == "[EP] Sec:Overheal Rate +500%/HealRate -70%" then
				UpdateStats(activator,purchased[value],"HealRate",-0.7,-0.7)
				weapon:SetAttributeValue("overheal fill rate reduced",6)
			elseif upgrade == "[EP] Sec:Heal Rate +300%/Rage Duration -100%" then
				UpdateStats(activator,purchased[value],"HealRate",3,3)
				UpdateStats(activator,purchased[value],"RageDuration",-1,-1)
			elseif upgrade == "[EP] Mle:Hitting Enemy Gives you Double Damage for 5s" then
				AddMultipleAttributes(activator,purchased[value],"self add attributes on hit","damage bonus HIDDEN",1,4)
			elseif upgrade == "[EP] Mle:Hitting Enemy Gives you Health Regen +20 for 5s" then
				AddMultipleAttributes(activator,purchased[value],"self add attributes on hit","health regen",20,5,nil,0)
			elseif upgrade == "[EP] Mle:Hitting Enemy Gives you Double Heal Rate for 5s" then
				AddMultipleAttributes(activator,purchased[value],"self add attributes on hit","heal rate penalty",1,4)
			elseif upgrade == "[EP] Max Health +200/Sec:Health Drain" then
				UpdateStats(activator,purchased[value],"MaxHealth",200,200)
				secondary:SetAttributeValue("health drain",-6)
			elseif upgrade == "【LEGEN】Override UberCharging : Infinite" then
				UpdateStats(activator,purchased[value],"UberDuration",30,30)
			end
		end
			
		--sniper custom upgrades
		if activator:DumpProperties().m_iClass == 2 then
		    activator:PrintToChat("Snoipars gj m8")
			if upgrade == "(R) Damage Bonus +25%/Pri:Max Ammo -25%" then
				activator:SetAttributeValue("damage bonus",math.min(1+(0.25*purchased[value]),1.75))
				UpdateStats(activator,purchased[value],"MaxAmmo",-0.25,-0.25)
			elseif upgrade == "(R) Damage Res +15%/Pri:Ammo -25%" then
				UpdateStats(activator,purchased[value],"RangedResistance",-0.15,-0.15)
				UpdateStats(activator,purchased[value],"MaxAmmo",-0.25,-0.25)
			elseif upgrade == "(R) Hitmaker:Focus Also Applies Charge Speed +100%" then
				AddMultipleAttributes(activator,purchased[value],"effect add attributes","sniper charge per sec",3)
			elseif upgrade == "(R) Jar:Also Applies Accuracy Penalty" then
				AddMultipleAttributes(activator,purchased[value],"effect add attributes","spread penalty",5)
				AddMultipleAttributes(activator,purchased[value],"effect add attributes","projectile spread angle penalty",12)
				AddMultipleAttributes(activator,purchased[value],"effect add attributes","flame_spread_degree",12)
			elseif upgrade == "(R) Mle:Hit and Bleed Tick gives you Invulnerablity for 1s" then
				AddMultipleAttributes(activator,purchased[value],"self add attributes on hit","dmg taken increased",0,1)
			elseif upgrade == "(R) Mle:Mark for Death/Speed Boost Based on Health" then
				weapon:SetAttributeValue("self mark for death",1)
				weapon:SetAttributeValue("mod shovel speed boost",1)
			elseif upgrade == "[EP] Pri:Override Ammunition Type:Crits" then
				UpdateStats(activator,purchased[value],"HeadshotDamage",1,1)
				UpdateStats(activator,purchased[value],"ChargeRate",0.25,0.25)
				UpdateStats(activator,purchased[value],"ReloadRate",0.5,0.5)
			elseif upgrade == "[EP] Pri:Override Ammunition Type:Snap" then
				UpdateStats(activator,purchased[value],"HeadshotDamage",-0.2,-0.2)
				UpdateStats(activator,purchased[value],"DamageMult",0.7,0.7)
				UpdateStats(activator,purchased[value],"FireRate",-0.2,-0.2)
				UpdateStats(activator,purchased[value],"ReloadRate",-0.4,-0.4)
				UpdateStats(activator,purchased[value],"ChargeRate",1,1)
				StackAttributeValue(activator,purchased[value],"dmg penalty vs players",-0.3)
			elseif upgrade == "[EP] Pri:Override Ammunition Type:AP" then
				UpdateStats(activator,purchased[value],"HeadshotDamage",-0.65,-0.65)
				UpdateStats(activator,purchased[value],"DamageMult",4,4)
				UpdateStats(activator,purchased[value],"ReloadRate",1.5,1.5)
				UpdateStats(activator,purchased[value],"ChargeRate",-0.25,-0.25)
				weapon:SetAttributeValue("projectile penetration",1)
			elseif upgrade == "[EP] Pri:Override Ammunition Type:Incendiary" then
				UpdateStats(activator,purchased[value],"HeadshotDamage",-0.2,-0.2)
				UpdateStats(activator,purchased[value],"DamageMult",-0.2,-0.2)
				UpdateStats(activator,purchased[value],"ReloadRate",0.4,0.4)
				weapon:SetAttributeValue("weapon burn dmg increased",10)
				weapon:SetAttributeValue("Set DamageType Ignite",1)
			elseif upgrade == "[EP] Pri:Override Ammunition Type:Explosive" then
				weapon:SetAttributeValue("explosive bullets",147)
				UpdateStats(activator,purchased[value],"HeadshotDamage",-0.5,-0.5)
				UpdateStats(activator,purchased[value],"DamageMult",2.5,2.5)
				UpdateStats(activator,purchased[value],"ReloadRate",1,1)
				UpdateStats(activator,purchased[value],"FireRateMult",1.5,1.5)
			elseif upgrade == "[EP] Pri:Override Ammunition Type:Hollow Point" then
				UpdateStats(activator,purchased[value],"HeadshotDamage",-0.25,-0.25)
				UpdateStats(activator,purchased[value],"DamageMult",0.5,0.5)
				UpdateStats(activator,purchased[value],"ReloadRate",0.7,0.7)
				weapon:SetAttributeValue("damage causes airblast",1)
				AddMultipleAttributes(activator,purchased[value],"add attributes on hit","mult_player_movespeed_active",0.2,3)
			elseif upgrade == "[EP] Pri:Reload Speed +30%/Bodyshot Penalty -25%" then
				UpdateStats(activator,purchased[value],"BodyshotDamage",-0.25,-0.25)
				UpdateStats(activator,purchased[value],"ReloadRate",-0.3,-0.6)
				UpdateStats(activator,purchased[value],"DamageMult",0.45,0.45)
				StackAttributeValue(activator,purchased[value],"dmg penalty vs players",-0.3)
			elseif upgrade == "[EP] Pri:Damage Mult +0.5/Reload Rate -25%" then
				UpdateStats(activator,purchased[value],"DamageMult",0.5,1)
				UpdateStats(activator,purchased[value],"ReloadRate",0.25,0.5)
			elseif upgrade == "[EP] Pri:Explosive Headshot/Reload Rate -50%" then
				activator:SetAttributeValue("explosive sniper shot",3)
				UpdateStats(activator,purchased[value],"ReloadRate",0.5,0.5)
			elseif upgrade == "[EP] Pri:Damage Mult +0.5/Cannot move while aiming" then
				weapon:SetAttributeValue("aiming movespeed increased",0.01)
				UpdateStats(activator,purchased[value],"DamageMult",0.5,0.5)
			elseif upgrade == "[EP] Pri:No Reload/No Explosive Headshot" then
				UpdateStats(activator,purchased[value],"ReloadRate",-1,-1)
				UpdateStats(activator,purchased[value],"MaxAmmo",1,1)
				UpdateStats(activator,purchased[value],"DamageMult",7,7)
				weapon:SetAttributeValue("explosive sniper shot",0)
				StackAttributeValue(activator,purchased[value],"dmg penalty vs players",-0.95)
				weapon:SetAttributeValue("ammo regen",0.5)
				weapon:SetAttributeValue("no primary ammo from dispensers while active",1)
			elseif upgrade == "[EP] Bow:Projectile Ricochet/Ricochet Damage x2" then
				weapon:SetAttributeValue("grenade bounce speed",1)
				weapon:SetAttributeValue("grenade bounce damage",2)
				weapon:SetAttributeValue("projectile lifetime",2)
			elseif upgrade == "[EP] Bow:Multishot Projectile +2" then
				weapon:SetAttributeValue("mult projectile count",math.min(1+(2*purchased[value]),7))
				weapon:SetAttributeValue("projectile spread angle penalty",3)
			elseif upgrade == "[EP] Bow:Heavier Arrow/Damage Mult +0.5" then
				UpdateStats(activator,purchased[value],"DamageMult",0.5)
				weapon:SetAttributeValue("projectile gravity native",2.5)
				
			elseif upgrade == "[EP] Sec:Headshot/Fire RateMult -2/Damage Mult +3" then
				UpdateStats(activator,purchased[value],"SecDamageMult",3,3)
				UpdateStats(activator,purchased[value],"SecFireRateMult",2,2)
				UpdateStats(activator,purchased[value],"SecBulletSpread",-0.2,-0.2)
				weapon:SetAttributeValue("can headshot",1)
			elseif upgrade == "[EP] Sec:Headshot/Explosive Headshot/Spread +60%" then
				weapon:SetAttributeValue("explosive sniper shot",2)
				UpdateStats(activator,purchased[value],"SecBulletSpread",-0.6,-0.6)
				weapon:SetAttributeValue("can headshot",1)
			elseif upgrade == "[EP] Sec:Bullet Per Shot +300%/Spread -120%" then
				UpdateStats(activator,purchased[value],"SecBulletPerShot",3,6)
				UpdateStats(activator,purchased[value],"SecBulletSpread",1.2,2.4)
			elseif upgrade == "[EP] Sec:FireRate Mult +1/Spread -20%/Ammo +100%" then
				UpdateStats(activator,purchased[value],"FireRateMult",1,2)
				UpdateStats(activator,purchased[value],"SecBulletSpread",0.2,0.4)
				StackAttributeValue(activator,purchased[value],"maxammo secondary increased",1,2)
			elseif upgrade == "[EP] Sec:Explosive rounds/Clip Size -50%/Ammo -25%" then
				weapon:SetAttributeValue("explosive bullets",147)
				StackAttributeValue(activator,purchased[value],"clip size penalty",-0.5)
				StackAttributeValue(activator,purchased[value],"maxammo secondary increased",-0.25)
				UpdateStats(activator,purchased[value],"SecBulletSpread",0.4,0.4)
			elseif upgrade == "[EP] Ranged Res +25%/Pri:No Headshot" then
				UpdateStats(activator,purchased[value],"RangedResistance",-0.25,-0.25)
				weapon:SetAttributeValue("sniper no headshots",1)
			elseif upgrade == "【LEGEN】Armor Piercing" then
				activator:SetAttributeValue("dmg pierces resists absorbs",1)
				activator:SetAttributeValue("mult dmg vs giants",1.5)
			end
		end
		--spy custom upgrades
		if activator:DumpProperties().m_iClass == 8 then
		    activator:PrintToChat("Spy come to visit your mother")
    		if upgrade == "Damage Mult +0.3/Switch +40/Mle:Backstab Damage -50%" then
    			StackAttributeValue(activator,purchased[value],"damage bonus",0.3,0.9)
				activator:SetAttributeValue("deploy time decreased",math.max(1+(-0.4*purchased[value]),0.05))
				UpdateStats(activator,purchased[value],"BackstabDamage",-12,-37)
			elseif upgrade == "(R) Pri:Imitation Upgrade:Pyro" then
    			weapon:SetAttributeValue("Set DamageType Ignite",1)
    			weapon:SetAttributeValue("projectile penetration",1)
				activator:SetAttributeValue("afterburn immunity",1)
			elseif upgrade == "(R) Pri:Imitation Upgrade:Medic" then
    		    activator:SetAttributeValue("active health regen",6)
    			weapon:SetAttributeValue("add cond on hit",27)
    			weapon:SetAttributeValue("add cond on hit duration",8)
			elseif upgrade == "(R) Pri:Imitation Upgrade:Soldier" then
    			weapon:SetAttributeValue("explosive bullets",100)
    			activator:SetAttributeValue("rocket jump damage reduction",0.6)
    		elseif upgrade == "(R) Imitation Upgrade : Scout" then
    			weapon:SetAttributeValue("major move speed bonus",1.4)
    			weapon:SetAttributeValue("air dash count",1)
			elseif upgrade == "(R) Max Health +75/Move Speed -20%" then
    			UpdateStats(activator,purchased[value],"MaxHealth",75,225)
    			UpdateStats(activator,purchased[value],"MoveSpeed",-0.2,-0.6)
			elseif upgrade == "(R) Credit Collect Range +100%/Collect on Kill" then
    			weapon:SetAttributeValue("mult credit collect range",math.min(1+(1*purchased[value]),2))
    			weapon:SetAttributeValue("collect currency on kill",1)
			elseif upgrade == "(R) Cloak Recharge +100%/Fire Res -20%" then
    			UpdateStats(activator,purchased[value],"CloakRechargeRate",1,2)
    			StackAttributeValue(activator,purchased[value],"dmg taken from fire increased",0.2,0.4)
    		elseif upgrade == "[EP] Pri:Damage Mult +1/FireRate Mult +1/Spread -700%" then
				UpdateStats(activator,purchased[value],"DamageMult",1,1)
    			UpdateStats(activator,purchased[value],"FireRateMult",-0.5,-0.5)
    			UpdateStats(activator,purchased[value],"BulletSpread",6,6)
    		elseif upgrade == "[EP] Pri:Override Imitation:Demo" then
    			UpdateStats(activator,purchased[value],"DamageMult",1,1)
    			UpdateStats(activator,purchased[value],"ReloadRate",2,2)
    			StackAttributeValue(activator,purchased[value],"clip size penalty",-0.33)
    			StackAttributeValue(activator,purchased[value],"maxammo secondary reduced",0.9)
    			weapon:SetAttributeValue("blast dmg to self increased",2)
    			weapon:SetAttributeValue("explosive bullets",200)
    		elseif upgrade == "[EP] Pri:Override Imitation:Sniper" then
    			UpdateStats(activator,purchased[value],"DamageMult",1.2,1.2)
				UpdateStats(activator,purchased[value],"FireRate",0.5,0.5)
				UpdateStats(activator,purchased[value],"BulletSpread",-0.99,-0.99)
    			StackAttributeValue(activator,purchased[value],"clip size penalty",0.17)
    			StackAttributeValue(activator,purchased[value],"maxammo secondary reduced",0.8)
    			weapon:SetAttributeValue("no damage falloff",1)
    		elseif upgrade == "[EP] Pri:Override Imitation:Engineer" then
    			UpdateStats(activator,purchased[value],"DamageMult",-0.7,-0.7)
    			UpdateStats(activator,purchased[value],"ReloadRate",2,2)
				UpdateStats(activator,purchased[value],"BulletSpread",3,3)
				UpdateStats(activator,purchased[value],"BulletPerShot",8,8)
    			StackAttributeValue(activator,purchased[value],"maxammo secondary reduced",2)
    		elseif upgrade == "[EP] Mle:Backstab Giant DMG +200%/Attack Rate -30%" then
    			UpdateStats(activator,purchased[value],"BackstabDamage",50,100)
    			UpdateStats(activator,purchased[value],"MleFireRate",0.3,0.6)
			elseif upgrade == "[EP] Mle:Damage Mult +2/Attack Rate -40%" then
    			UpdateStats(activator,purchased[value],"MleDamageMult",2,4)
    			UpdateStats(activator,purchased[value],"MleFireRate",0.4,0.8)
			elseif upgrade == "[EP] Damage vs Same Class +250%/Backstab Immune" then
    			weapon:SetAttributeValue("mult dmg vs same class",3.5)
    			weapon:SetAttributeValue("cannot be backstabbed",1)
			elseif upgrade == "[EP] Weapon Switch +95%/Mle:Deflect Projectile" then
    			activator:SetAttributeValue("deploy time increased",0.05)
    			weapon:SetAttributeValue("melee airblast",1)
			elseif upgrade == "[EP] Insta Cloak/Cloak Recharge +100%/Duration -40%" then
				UpdateStats(activator,purchased[value],"CloakDuration",0.4,0.4)
    			UpdateStats(activator,purchased[value],"CloakRechargeRate",1,1)
    			weapon:SetAttributeValue("mult cloak rate",0.01)
				weapon:SetAttributeValue("mult decloak rate",0.01)
    		elseif upgrade == "[EP] DMG Taken -25%/Mle:Backstab Giant Damage -100%" then
    			UpdateStats(activator,purchased[value],"BackstabDamage",-25,-25)
    			activator:SetAttributeValue("dmg taken increased",0.75)
    		elseif upgrade == "【LEGEN】Pri:Override Imitation:Heavy" then
    			UpdateStats(activator,purchased[value],"DamageMult",-0.85,-0.85)
    			UpdateStats(activator,purchased[value],"ReloadRate",-0.99,-0.99)
    			UpdateStats(activator,purchased[value],"FireRate",-0.8,-0.8)
    			--weapon:SetAttributeValue("clip size penalty",30)
    			activator:SetAttributeValue("hidden secondary max ammo penalty",7)
    			UpdateStats(activator,purchased[value],"BulletSpread",2,2)
    			UpdateStats(activator,purchased[value],"BulletPerShot",3,3)
    			--weapon:SetAttributeValue("mult crit dmg",0.2)
    		end
		end
	elseif attributename == "stat" then
		for k,v in pairs(stats) do
		    if k == attribute_desc then
		        util.PrintToChatAll("stat upgrade test " .. k)
				UpdateStats(activator,purchased[value],attribute_desc,increment,max)
        	end
		end
	elseif attributename == "stack" then
		StackAttributeValue(activator,purchased[value],attribute_desc,increment,max)
	elseif attributename ~= "custom" then
		if slot ~= nil then
		    util.PrintToChatAll("slot test")
		    
			if increment > 0 then
				weapon:SetAttributeValue(attributename,math.min(min+increment*purchased[value],max))
			else
				weapon:SetAttributeValue(attributename,math.max(min+increment*purchased[value],max))
			end
		else
		    util.PrintToChatAll("slot failed")
			if max ~= nil then
				if increment > 0 then
					activator:SetAttributeValue(attributename,math.min(min+increment*purchased[value],max))
				else
					activator:SetAttributeValue(attributename,math.max(min+increment*purchased[value],max))
				end
			else
				activator:SetAttributeValue(attributename,min+increment*purchased[value])
			end
		end
	end
	if widow > 0 then
		widow = 1
		DamageList = {}
		DamageList[1] = activator:GetAttributeValue("damage bonus")
		DamageList[2] = activator:GetAttributeValue("damage penalty")
		DamageList[3] = primary:GetAttributeValue("damage bonus")
		DamageList[4] = primary:GetAttributeValue("damage penalty")
		DamageList[5] = primary:GetAttributeValue("bullets per shot bonus")
		for _,v in pairs(DamageList) do
			if v == nil then
				v = 1
			end
			widow = widow*v
		end
		activator:SetAttributeValue("add onhit addammo",math.max(math.floor(100/widow)-100,-99))
		activator:PrintToChat("Widowmaker metal return is decreased by " .. activator:GetAttributeValue("add onhit addammo") .. "%")
	end
end

--Give all players specified amount of upgrade points, adds running total to TotalUpgradePoints for late joiners
function AddUpgradePoints(number)
	for _, v in pairs(UniqueAccountIDs) do
		v.UpgradePoints = v.UpgradePoints + number
	end
	TotalUpgradePoints = TotalUpgradePoints + number
end

--Give all players specified amount of rerolls, adds running total to TotalRerollPoints for late joiners
function AddRerollPoints(number)
	for _, v in pairs(UniqueAccountIDs) do
		v.RerollPoints = v.RerollPoints + number
	end
	TotalRerollPoints = TotalRerollPoints + number
end

--Set all players's upgrade points to specified value without adding or subtracting to TotalUpgradePoints
function SetUpgradePoints(number)
	for _, v in pairs(UniqueAccountIDs) do
		v.UpgradePoints = number
	end
end

--Set all players's rerolls to specified value without adding or subtracting to TotalRerollPoints
function SetRerollPoints(number)
	for _, v in pairs(UniqueAccountIDs) do
		v.RerollPoints = number
	end
end

--Iterates upon PurchasedUpgrades table and calls AddUpgrade for each upgrade, called OnSpawn of every player
function ReAddPurchasedUpgrades(activator)
	local player = UniqueAccountIDs[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
	local class = activator:DumpProperties().m_iClass
	local purchased = player[class].PurchasedUpgrades
	for k, _ in pairs(purchased) do
		AddUpgrade(activator, k)
	end
	activator:RefillAmmo()
	
	i = 0
	while(i <= 6) do
		if activator:GetPlayerItemBySlot(i) ~= nil then
			activator:GetPlayerItemBySlot(i):SetAttributeValue("obsolete ammo penalty",1)
		end
		i = i+1
	end
end

--[[This function will display the shop menu
	It shows how many upgrade levels were purchased and the max if it exists
	It will also show the corresponding class you are playing as in the title
	Shows how many upgrade points are remaining
	Always adds the reroll option to the bottom of the list
	Will disable the shop if the player has no more upgrade points]]
function ShowUpgradeMenu(activator)
	local player = UniqueAccountIDs[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
	local class = activator:DumpProperties().m_iClass
	local menu = player[class].UpgradeMenu
	local purchased = player[class].PurchasedUpgrades
	
	local stats = StatBonus[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]

	menu[MenuCapacity+1] = {text="Reroll " .. classIndices_Internal[class] .. " Shop\n    "  .. player.RerollPoints .. " rerolls remaining", value="reroll"}
	if player.RerollPoints == 1 then
		menu[MenuCapacity+1] = {text="Reroll " .. classIndices_Internal[class] .. " Shop\n    "  .. player.RerollPoints .. " reroll remaining", value="reroll"}
	elseif player.RerollPoints <= 0 then
		menu[MenuCapacity+1] = {text="Reroll " .. classIndices_Internal[class] .. " Shop\n    "  .. player.RerollPoints .. " rerolls remaining", value="reroll", disabled = true}
	end

	menu.title = classIndices_Internal[class] .. " Shop\nSelect an upgrade (" .. player.AvailableEpic .. " Epic Available)\n" .. player.UpgradePoints .. " upgrade point remaining\n "
	if player.UpgradePoints == 1 then
		menu.title = classIndices_Internal[class] .. " Shop\nSelect an upgrade (" .. player.AvailableEpic .. " Epic Available)\n" .. player.UpgradePoints .. " upgrade point remaining\n "
	elseif player.UpgradePoints <= 0 then
		for i = 1, MenuCapacity+1, 1 do
			menu[i].disabled = true
		end
	end

	for i = 1, MenuCapacity, 1 do
		local value = menu[i].value
		local upgradetable = {}
		for k in string.gmatch(value, "[^,]+") do
			upgradetable[#upgradetable + 1] = k
		end
		local min = upgradetable[3]
		local increment = upgradetable[4]
		local max = upgradetable[5]

		if purchased[value] ~= nil then
			menu[i].text = menu[i].text .. "\n    #: " .. purchased[value]
		else
			menu[i].text = menu[i].text .. "\n    #: 0"
		end
		if max ~= nil then
			menu[i].text = menu[i].text .. "          Max: " .. math.ceil((max-min)/increment) --big brain math
		end
	end

	activator:DisplayMenu(menu)

	for i = 1, MenuCapacity, 1 do
		local value = menu[i].value
		local upgradetable = {}
		for k in string.gmatch(value, "[^,]+") do
			upgradetable[#upgradetable + 1] = k
		end
		upgrade = upgradetable[1]

		menu[i].text = upgrade
	end
end

function CloseUpgradeMenu(activator) --probably redundnant
	activator:HideMenu()
end

function deepCopy(original) --special thx to https://developer.roblox.com
	local copy = {}
	for k, v in pairs(original) do
		if type(v) == "table" then
			v = deepCopy(v)
		end
		copy[k] = v
	end
	return copy
end

function OnWaveSuccess(wave) --adds however many upgrade points every wave, can also be edited to do other things
	if wave > 1 or wave < 5 then
	AddUpgradePoints(4)
	else
	AddUpgradePoints(3)
	end
end

function OnWaveReset(wave) --on wave reset, load save state from WaveState
	if WaveState[wave] ~= nil then
		TotalUpgradePoints = WaveState[wave].TotalUpgradePoints
		TotalRerollPoints = WaveState[wave].TotalRerollPoints
		UniqueAccountIDs = deepCopy(WaveState[wave].UniqueAccountIDs)
	end
end

function OnWaveInit(wave) --on wave init, create save state in WaveState, reset rolls
	EnableUpgradeStations() --for wave 1
	WaveNum = wave
	if WaveState[wave] == nil then
		WaveState[wave] =
		{
			TotalUpgradePoints = TotalUpgradePoints,
			TotalRerollPoints = TotalRerollPoints,
			UniqueAccountIDs = deepCopy(UniqueAccountIDs)
		}
	end
	ResetRolls()
end