--[[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
			{"All Resistance Upgrade +25%", "custom",0,1,5},
			{"All Max Ammo +25%", "custom",1,0.25,2},
			{"Bullet Resistance +20%", "dmg taken from bullets increased",1,-0.2,0.8},
			{"Blast Resistance +20%", "dmg taken from blast increased",1,-0.2,0.8},
			{"Ammo Regen +30% every 5 seconds", "ammo regen",0,0.3,0.6},
			{"Consumable Recharge Rate +50%", "effect bar recharge rate increased",1,-0.25,0.25},
			{"Move Speed / Jump Height +10%", "custom",0,1,4},
			--base weapon
			{"Clip Size +50%", "clip size bonus",1,0.5,3},
			{"Reload Speed +30%", "faster reload rate",1,-0.3,0.4},
			{"Firing Speed +15%", "fire rate bonus",1,-0.15,0.4},
			--{"Heal On Kill +25 health", "heal on kill",0,25},
			--{"Max Health +25", "max health additive bonus",0,25},
			--{"Weapon Switch Speed +45%", "deploy time decreased",1,-0.45,0.1},
			--{"Movement Speed +10%", "move speed bonus",1,0.1,1.3},
			--{"Jump Height +20%", "increased jump height",1,0.2},
			--{"Crit Resistance +20%", "dmg taken from crit reduced",1,-0.3,0.1},
			--{"Melee Resistance +25%", "dmg from melee increased",1,-0.25,0.25},
			--{"Health Regen +2 every second", "health regen",0,2},
			--{"Heal On Hit +15 health", "heal on hit for rapidfire",0,15},
			--{"Push Force -30%", "damage force reduction",1,-0.3,0.1},
			--{"Drop On Kill: Small Health Pack", "drop health pack on kill",0,1,1},
		},
		RareAttribute =
		{
			--base char
			{"(RARE) Bullets Per Shot +40%", "bullets per shot bonus",1,0.4,1.8},
			{"(RARE) Speed Boost On Kill +5 seconds", "speed_boost_on_kill",0,5,5},
			{"(RARE) Tank Damage Bonus +50%", "mult dmg vs tanks",1,0.5,1.5},
			--base weapon
			{"(RARE) Damage Bonus +25%", "damage bonus",1,0.25,2},
			{"(RARE) Mad Milk Slows Targets", "applies snare effect",1,-0.35,0.65},
			{"(RARE) Damage Mult +35%/Primary Ammo -30%/Switch +40%", "custom",0,1,3},
			{"(RARE) Health +50 / Medic Healing -25%", "custom",0,1,4},
			{"(RARE) Push Force -50%", "damage force reduction",1,-0.5,0.01},
			--{"(RARE) Crit vs Stunned", "crit vs stunned players",0,1,1},
			--special
			--{"(RARE) Extra Jump +1", "air dash count",0,1},
			--{"(RARE) Recall On Death +100% chance", "teleport instead of die",0,1,1},
			--{"(RARE) Projectile Penetration", "projectile penetration",0,1,1},
		},
		EpicAttribute =
		{
			{"[EPIC] Damage Mult x2/Spread -60%/Primary Ammo -40%", "custom",0,1,1},
			{"[EPIC] Damage Mult x10/Clip Size -100%", "custom",0,1,1},
			{"[EPIC] Damage x2.5/Clip Size -85%/Fire Rate -100%", "custom",0,1,1},
			{"[EPIC] Max Health Drain/Ranged Resistance 50%", "custom",0,1,1,"Health always drain to 50"},
			{"[EPIC] No DMG Falloff / Piercing", "custom",0,1,1},
			{"[EPIC] Force Fire Full Clip/Fire rate x2/No Milk", "custom",0,1,1},
			{"[EPIC] Spread Bonus -99%", "weapon spread bonus",1,-0.99,0.01},
            {"Free Reroll", "custom",0,1,1},
			--{"[EPIC] Bullets Per Shot +30%", "bullets per shot bonus",1,0.3}
			--{"[EPIC] Meter Effect/Debuff Duration +50%", "mult effect duration",1,0.5},
			--{"[EPIC] All Healing Received +100%", "healing received bonus",1,1},
		},
		MinorEpicAttribute =
		{
		    {"[EPIC] Extra Reroll +1 and Available Epic +1", "custom",0,1,1},
			{"[EPIC] Crit Damage Bonus +15%", "mult crit dmg",1,0.15,1.45},
			{"[EPIC] Meter Effect/Debuff Duration +50%", "mult effect duration",1,0.5,2},
			{"[EPIC] Building Damage +100%", "dmg bonus vs buildings",1,1,2},
		},
		LegendaryAttribute =
		{
			{"【LEGENDARY】 Reload Full Clip At Once", "reload full clip at once",0,1,1}, --[[재장전 한번에]]
			{"【LEGENDARY】 Super Scout", "custom",0,1,1,"Double speed with push force resistance"}, -- double speed 1% push force
			{"【LEGENDARY】 Extra Upgrade", "custom",0,1,2},
			{"【LEGENDARY】 Crit On Kill +3 seconds", "critboost on kill",0,3},
			{"【LEGENDARY】 Mini-crits to Crits", "minicrits become crits",0,1,1},
		--	{"【LEGENDARY】 Bunnyhop", "allow bunny hop",0,1,1}, not working
			
			--{"【LEGENDARY】 Mark for Death On Hit", "mark for death",0,1,1},
			--{"【LEGENDARY】 Passive Reload", "passive reload",0,1,1},
		},
	},
	[3] = --Soldier Shop
	{
		CommonAttribute =
		{
			--base char
			{"All Resistance Upgrade +20%", "custom",0,1,5},
			{"All Max Ammo +25%", "custom",1,0.25},
			{"Heal On Kill +35 health", "heal on kill",0,35,35},
			{"Self Blast -50%", "blast dmg to self increased",1,-0.5,0.01},
			{"Health Regen +4 every second", "health regen",0,4,8},
			{"Buff Duration +30%/Buff Radius +15%", "custom",0,1,3},
			--weapon
			{"Firing Speed +15%", "fire rate bonus",1,-0.15,0.4},
			{"Reload Speed +30%", "faster reload rate",1,-0.3,0.4},
			--special
			{"Primary : Clip Size Bonus +3", "clip size upgrade atomic",0,3,15},
			{"Blast Radius -35% / Damage mult +25%", "custom",0,1,4},
		--	{"Clip Size +50%", "clip size bonus",1,0.5},
		--	{"Heal On Kill +25 health", "heal on kill",0,25},
		--	{"Max Health +25", "max health additive bonus",0,25},
		--	{"Max Ammo +50%", "custom",1,0.5},
		--	{"Weapon Switch Speed +30%", "deploy time decreased",1,-0.3,0.1},
		--	{"Ammo Regen +20% every 5 seconds", "ammo regen",0,0.2,1}, --mangler
		--	{"Heal On Hit +15 health", "heal on hit for rapidfire",0,15},
		--	{"Projectile Speed +25%", "Projectile speed increased",1,0.25},
		--	{"Banners: Rage Gained +25%", "rage giving scale",1,0.25}, 
		--	{"B.A.S.E. Jumper: Infinite Redeploy", "parachute redeploy",0,1,1},
		--	{"Recall On Death +50% chance", "teleport instead of die",0,0.5,1},
		--	{"Mini-crit Airborne Targets", "mod mini-crit airborne",0,1,1}, --direct hit
		--	{"Movement Speed +10%", "move speed bonus",1,0.1},
		--	{"Jump Height +20%", "increased jump height",1,0.2},
		--	{"Fire Resistance +25%", "dmg taken from fire reduced",1,-0.25,0.25},
		--	{"Bullet Resistance +25%", "dmg taken from bullets reduced",1,-0.25,0.25},
		--	{"Blast Resistance +25%", "dmg taken from blast reduced",1,-0.25,0.25},
		--	{"Melee Resistance +25%", "dmg from melee increased",1,-0.25,0.25},
		},
		RareAttribute =
		{
			{"(FREE) Health +50 / Weapon Ammo -10%/-20%", "custom",0,1,8},
			{"(RARE) Fire Rate +25% / Primary Ammo -25%", "custom",0,1,2},
			{"(RARE) Damage Bonus +25%", "damage bonus",1,0.25,2},
			{"(RARE) Buff Durartion +40% / Move Speed +10%", "custom",0,1,3},
			{"(FREE) Clip Size +50% / Spread Angle -3", "custom",0,1,3},
			{"(RARE) Crit Resistance +25%", "dmg taken from crit reduced",1,-0.25,0.5},
			{"(RARE) Bullet Per Shot +50% / Weapon Switch +25%", "custom",0,1,4},
		--	{"(RARE) Drop On Kill: Small Health Pack", "drop health pack on kill",0,1,1},
		--	{"(RARE) Rocket Specialist", "rocket specialist",0,1,1},
		--	{"(RARE) Extra Jump +1", "air dash count",0,1},
		--	{"(RARE) Fall Damage Immunity", "cancel falling damage",0,1,1},
		--	{"(RARE) Banners: Buff Radius +50%", "mod soldier buff range",1,0.5},
		--	{"(RARE) Explosion Radius +30%", "Blast radius increased",1,0.3},
		},
		EpicAttribute =
		{
			{"[EPIC] Fire rate x2 / Rocket Speed -55%", "custom",0,1,1},
			{"[EPIC] Rocket Speed +100% / Direct Hit Stun", "custom",0,1,1},
			{"[EPIC] Ranged Resistance +25% / Heal-on-Hit +15", "custom",0,1,1},
			{"[EPIC] Mortar Rocket / Damage mult x1.5", "custom",0,1,1,"Gravity affects rockets"},
			{"[EPIC] Mini-crits to Crits / Damage x0.5", "custom",0,1,1},
			{"[EPIC] Burn Damage x20", "weapon burn dmg increased",0,20,40},
			{"[EPIC] Double Healing/No Medic Healing", "custom",0,1,1},
			{"[EPIC] DMG x1.3 While Healed by Medic/Medic Healing -99%", "custom",0,1,1},
		    {"Free Reroll", "custom",0,1,1},
		--	{"[EPIC] Tank Damage Bonus +50%", "mult dmg vs tanks",1,0.5,2}, --retire other classes
		--	{"[EPIC] Speed Boost On Kill +5 seconds", "speed_boost_on_kill",0,5,5},
		--	{"[EPIC] Projectiles Cannot Be Deflected", "projectile no deflect",0,1,1}, --make botpyro dumb
		},
		MinorEpicAttribute =
		{
		    {"[EPIC] Extra Reroll +1 and Available Epic +1", "custom",0,1,1},
		    {"[EPIC] Reload Speed -30% / Blast Radius +25%", "custom",0,1,4},
		    {"[EPIC] Fall Damage Immunity", "cancel falling damage",0,1,1},
		},
		LegendaryAttribute =
		{
			{"【LEGENDARY】 Free Pair of Mantread", "custom",0,1,1},
		--	{"【LEGENDARY】 Clip Size +500%", "clip size penalty HIDDEN",1,5,6}, --replaced as bison
			{"【LEGENDARY】 Extra Upgrade", "custom",0,1,2},
			{"【LEGENDARY】 Damage Bonus x2 Below 50% Health", "dmg bonus while half dead",0,2,2},
		--	{"【LEGENDARY】 Health +100", "max health additive penalty",0,100,100},
		--	{"【LEGENDARY】 No Fire Delay", "custom",0,1,1},
		--	{"【LEGENDARY】 Crit On Kill +3 seconds", "critboost on kill",0,3},
		--	{"【LEGENDARY】 All Healing Received +100%", "healing received bonus",1,1},
		--	{"【LEGENDARY】 Mark for Death On Hit", "mark for death",0,1,1},
			{"【LEGENDARY】 Reload Full Clip At Once(beggar not work)", "reload full clip at once",0,1,1}, --[[재장전 한번에]]
		}
	},
	[7] = --Pyro Shop
	{
		CommonAttribute =
		{
		--base char
		    {"All Resistance Upgrade +20%", "custom",0,1,5},
			{"Movement Speed +20%", "move speed bonus",1,0.2,1.2},
			{"All Max Ammo +25%", "custom",1,0.25,2},
			{"Health Regen +8 every second", "health regen",0,8,8},
			{"Ammo Regen +20% every 5 seconds", "ammo regen",0,0.2,0.4},
			{"Heal On Kill +35 health", "heal on kill",0,35,105},
			{"Push Force -40%", "damage force reduction",1,-0.4,0.6},
			{"Health +50 / -25% OverHealed", "custom",0,1,2},
			--{"Melee Resistance +25%", "dmg from melee increased",1,-0.25,0.25},
			--{"Max Health +25", "max health additive bonus",0,25},
			--{"Jump Height +20%", "increased jump height",1,0.2},
		--base weapon
			{"Secondary Clip Size +50% / Faster Reload + 25%", "custom",0,1,4},
			{"Weapon Ammo -20%/+50%/Sub Weapon Fire Rate +25%", "custom",0,1,3},
			--{"Secondary Fire Rate +35%", "fire rate bonus",1,-0.35,0.3},
			--{"Flame Ammo Consumption -25%", "flame ammopersec decreased",1,-0.25,0},
			--{"Weapon Switch Speed +35%", "deploy time decreased",1,-0.45,0.1},
			--{"Afterburn Damage +100%", "weapon burn dmg increased",1,1},
			--{"Flares: Projectile Speed +25%", "Projectile speed increased",1,0.25},
			--{"Thermal Thruster: Mid-Air Relaunch", "thermal_thruster_air_launch",0,1,1},
			--{"Thermal Thruster: Stun Targets On Landing", "falling_impact_radius_stun",0,1,1},
			--{"Airblasting Teammates Gives Speed Boost", "airblast_give_teammate_speed_boost",0,1,1},
			--{"Reflected Projectile Speed +100%", "mult reflect velocity",1,1,2},
		},
		RareAttribute =
		{
			--base char
			{"(RARE) Crit DMG +75%/No Medic Healing/Rage -30%", "custom",0,1,4},
			--base weapon
			{"(RARE) All Thermal Thruster Mod/Stompy", "custom",0,1,1},
		    {"(RARE) Damage Bonus +25%", "damage bonus",1,0.25},
			{"(RARE) Gas Passer: Explode On Ignite", "explode_on_ignite",0,1,1},
			{"(RARE) Afterburn Damage + 300%", "weapon burn dmg increased",1,2,7},
			{"(RARE) Damage Mult +35%/Primary Ammo -30%/Switch +40%", "custom",0,1,3},
			{"(RARE) Bullet Per Shot +50%", "bullets per shot bonus",1,0.5,2.5},
			{"(RARE) Heal-on-Hit +2", "heal on hit for rapidfire",0,2,4},
			{"(FREE) Airblast Override Mod : Efficiency", "custom",0,1,1,"Airblast costs lesser ammo"},
			{"(FREE) Airblast Override Mod : Power", "custom",0,1,1,"Airblast push power doubled"},
			{"(FREE) Airblast Override Mod : Repressure", "custom",0,1,1,"Airblast refire quicker but reduced power"},
			
			--{"(RARE) Drop On Kill: Small Health Pack", "drop health pack on kill",0,1,1},
			--{"(RARE) Recall On Death +100% chance", "teleport instead of die",0,1,1},
			--{"(RARE) Extra Jump +1", "air dash count",0,1},
			--{"(RARE) Flame Size +50%", "flame size bonus",1,0.50},	wrong attribute
			--{"(RARE) Flame Distance +50%", "flame life bonus",1,0.50},	wrong attribute
			--{"(RARE) Airblast Ammo Consumption -75%", "airblast cost decreased",1,-0.75,0.25},	buffing it will bring damnation
			--{"(RARE) Slow On Hit", "slow enemy on hit",0,1,1},
			--{"(RARE) Speed Boost On Kill +5 seconds", "speed_boost_on_kill",0,5,5},
		},
		EpicAttribute =
		{
			{"[EPIC] Heal On Hit +4 health", "health on radius damage",0,4,8},
			{"[EPIC] Flame Life x4/Gravity", "custom",0,1,1}, -- 화염 파티클 문제로인한 실제범위 가시성 곱창 + 발사하다가 일정 파티클 이상 발사시 먹통됨/못고침
			{"[EPIC] Flame Speed x1.3", "custom",0,1,1},
			{"[EPIC] Flame Speed x0.2 / DMG vs Burning x2", "custom",0,1,1,"Dragon's fury fire rate -100%"},
			{"[EPIC] Burn Speed x8", "weapon burn time increased",0,8,8},
			{"[EPIC] DMG vs Non-Burning x2/Reload -150%", "custom",0,1,1},
			{"[EPIC] Damage x1.7/Flamethrower spin up 0.8s", "custom",0,1,1},
		    {"[EPIC] Mini-Critboost on Kill +3s", "minicritboost on kill",0,3,6},
		    {"[EPIC] Damage x1.5/Flamethrower Ammo Cost x2", "custom",0,1,1},
		--    {"[EPIC] No Damage Falloff", "no damage falloff",0,1,1}, --not working
		    {"Free Reroll", "custom",0,1,1},
		    --{"[EPIC] Mini-crits to Crits", "minicrits become crits",0,1,1},
			--{"[EPIC] Tank Damage Bonus +50%", "mult dmg vs tanks",1,0.5,2},
			--{"[EPIC] Primary: Crits From Behind", "mod flamethrower back crit",0,1,1},
			--{"[EPIC] Airblast Refire Speed +50%", "mult airblast refire time",1,-0.5,0},	buffing it will bring damnation
		},
		MinorEpicAttribute =
		{
		    {"[EPIC] Extra Reroll +1 and Available Epic +1", "custom",0,1,1},
		    {"[EPIC] Heal On Hit +2 health", "heal on hit for slowfire",0,2,4},
		    {"[EPIC] Tank Damage Bonus +20%", "mult dmg vs tanks",1,0.2,1.4},
		    {"[EPIC] Recall On Death +25% chance", "teleport instead of die",0,0.25,0.5},
		},
		LegendaryAttribute =
		{
			--{"【LEGENDARY】 Crit On Kill +1s", "critboost on kill",0,1},
			--{"【LEGENDARY】 Damage Mult x1.5", "dmg penalty vs players",1,0.5,1.5},
			{"【LEGENDARY】 Extra Upgrade", "custom",0,1,2},
			{"【LEGENDARY】 Dragon's Fury", "mult_item_meter_charge_rate",1,-0.3,0.7,"Dragon's fury fire rate +30%"},
			{"【LEGENDARY】 Very Big Pyro", "custom",0,1,1,"Pyro is very big"},
			{"【LEGENDARY】 Double Healing", "healing received bonus",0,1,1},
			--{"【LEGENDARY】 Mark for Death On Hit", "mark for death",0,1,1},
			--{"【LEGENDARY】 300% Damage On Burning", "damage bonus vs burning",1,2,3},	wat is dis
		},
	},
	[4] = --Demoman Shop
	{
		CommonAttribute =
		{
			--base character
			{"All Resistance Upgrade +20%", "custom",0,1,5},
			{"Heal On Kill +35 health", "heal on kill",0,35,105},
			{"Melee Resistance +50%", "dmg from melee increased",1,-0.5,0.5},
			{"Health Regen +4 every second", "health regen",0,4,8},
			{"All Max Ammo +25%", "custom",1,0.25},
			{"Self Blast -50%", "blast dmg to self increased",1,-0.5,0.01},
			{"Movement Speed +20%", "custom",1,0.2,1.4},
			--{"Fire Resistance +30%", "dmg taken from fire reduced",1,-0.3,0.1},
			--{"Crit Resistance +30%", "dmg taken from crit reduced",1,-0.3,0.1},
			--{"Bullet Resistance +25%", "dmg taken from bullets reduced",1,-0.25,0.25},
			--{"Blast Resistance +25%", "dmg taken from blast reduced",1,-0.25,0.25},
			--base weapon
			{"Firing Speed +15%", "fire rate bonus",1,-0.15,0.4},
			{"Reload Speed +30%", "faster reload rate",1,-0.3,0.4},
			{"Damage +10%/Charge Recharge +75%/Time +1", "custom",0,1,5},
			--{"Projectile Speed +15%", "Projectile speed increased",1,0.15},
			{"Primary: Clip Size +2", "clip size upgrade atomic",0,2,12},
			--special
			{"Blast Radius -35% / Damage mult +25%", "custom",0,1,4},
			{"Fire Rate +25% / Secondary Ammo -50%", "custom",0,1,4},
			{"Health +50 / -25% OverHealed", "custom",0,1},
			--{"Clip Size +50%", "clip size bonus",1,0.5},
			--{"Max Health +25", "max health additive bonus",0,25},
			--{"Weapon Switch Speed +35%", "deploy time decreased",1,-0.35,0},
			--{"Shields: Charge Recharge Rate +100%", "charge recharge rate increased",1,1},
			--{"Shields: Charge Duration +2 second", "charge time increased",1,2},
			--{"Faster Move Speed On Shield +20%", "move speed bonus shield required",0,0.2,2},
			--{"Melee Range +25%", "melee range multiplier",1,0.25},
			--{"Ammo Regen +20% every 5 seconds", "ammo regen",0,0.2,1},
			--{"Push Force -35%", "damage force reduction",1,-0.35,0},
			--{"Max Stickybombs +2", "max pipebombs increased",1,2},
			--{"B.A.S.E. Jumper: Infinite Redeploy", "parachute redeploy",0,1,1},
			--{"Drop On Kill: Small Health Pack", "drop health pack on kill",0,1,1},
			
		},
		RareAttribute =
		{
			--base weapon
			{"(RARE) Damage Taken -15%", "dmg taken increased",1,-0.15,0.55},
			{"(FREE) Health +50 / Weapon Ammo -10%/-20%", "custom",0,1,8},
			{"(RARE) Damage Bonus +25%", "damage bonus",1,0.25,2},
			--{"(RARE) Explosion Radius +30%", "Blast radius increased",1,0.3},
			--{"(RARE) Melee Attack Width +50%", "melee bounds multiplier",1,0.5},
			{"(RARE) Shield Control x5 / Push Force -50%", "custom",0,5,10},
			{"(RARE) Stickybombs: Arm Time -0.2 seconds", "sticky arm time bonus",0,-0.2,-0.2},
			--{"(RARE) Heal On Hit +15 health", "heal on hit for rapidfire",0,15},
			--base char
			{"(FREE) Movement Speed +10% while Shield Equipped", "move speed bonus shield required",1,0.1,1.2},
			--{"(RARE) Speed Boost On Kill +5 seconds", "speed_boost_on_kill",0,5,5},
			--{"(RARE) Fall Damage Immunity", "cancel falling damage",0,1,1},
			--{"(RARE) Extra Jump +1", "air dash count",0,1},
			--special
			{"(FREE) Clip Size +50% / Spread Angle -3", "custom",0,1,3},
			{"(RARE) Crit On Kill +5s / -100% Clip Size", "custom",0,1,1},
			{"(RARE) Melee Hit Refill Charge +100%", "charge meter on hit",0,1,1}
			--{"(RARE) Melee Attacks Cleave All Targets", "melee cleave attack",0,1,1},
			
		},
		EpicAttribute =
		{
			{"[EPIC] Grenade Fuse x0.3 / Detonation DMG x1.5", "custom",0,1,1},
			{"[EPIC] Bazooka/Fire Rate x2/No Melee", "custom",0,1,1,"Weapons uses Beggar's bazooka mechanism"},
			{"[EPIC] Fire Rate x2 / Sticky Slower Detonate 0.4", "custom",0,1,1},
			{"[EPIC] Ranged Resistance +25% / Jump x2.5", "custom",0,1,1},
			{"[EPIC] Rolling Grenade Damage x4/Damage x0.8", "custom",0,1,1,"Grenade deals double damage after contacting surface"},
			{"[EPIC] Grenade Explode On Impact", "grenade explode on impact",0,1,1},
			{"[EPIC] Sticky Only Stick on Enemies/Projectile Speed x1.5", "custom",0,1,1},
			{"[EPIC] Taunt Speed +100%", "gesture speed increase",1,0.9,1.9},
		    {"Free Reroll", "custom",0,1,1},
			--{"[EPIC] Tank Damage Bonus +50%", "mult dmg vs tanks",1,0.5},
			--{"[EPIC] Recall On Death +50% chance", "teleport instead of die",0,0.5,1},
			--{"[EPIC] Stickybombs: Charging Increases Damage +35%", "stickybomb_charge_damage_increase",1,0.35},
			--{"[EPIC] Projectiles Cannot Be Deflected", "projectile no deflect",0,1,1},
		},
		MinorEpicAttribute =
		{
		    {"[EPIC] Extra Reroll +1 and Available Epic +1", "custom",0,1,1},
		    {"[EPIC] Tank Damage Bonus +15%", "mult dmg vs tanks",1,0.15,1.3},
		    {"[EPIC] Damage Bonus vs Buildings +25%", "dmg bonus vs buildings",1,0.25,1.5},
		    {"[EPIC] Speed Boost On Kill +5 seconds", "speed_boost_on_kill",0,5,5},
		},
		LegendaryAttribute =
		{
			{"【LEGENDARY】 Full Heal on Kill", "restore health on kill",0,1,1},
			--{"【LEGENDARY】 Reload Full Clip At Once", "reload full clip at once",0,1,1}, --[[재장전 한번에]]
			{"【LEGENDARY】 Nuke", "custom",0,1,1,"Weapon projectile replaced with cannonball that causes huge explosion"},
			{"【LEGENDARY】 Train", "charge impact damage increased",0,20,20,"Powerful Shield Crash"},
			{"【LEGENDARY】 Extra Upgrade", "custom",0,1,2},
			--{"【LEGENDARY】 Mark for Death On Hit", "mark for death",0,1,1},
			--{"【LEGENDARY】 Passive Reload", "passive reload",0,1,1},
			--{"【LEGENDARY】 Mini-crits become Crits", "minicrits become crits",0,1,1},
		}
	},
     [6] = --Heavy Shop
	{
		CommonAttribute =
		{
		--base char
			{"All Resistance Upgrade +25%", "custom",0,1,4},
			{"Blast Resistance +20%", "dmg taken from blast increased",1,-0.2,0.8},
			{"Bullet Resistance +20%", "dmg taken from bullets increased",1,-0.2,0.8},
			{"Movement Speed +20%", "move speed bonus",1,0.2,1.6},
			{"Health +50 / -25% OverHealed", "custom",0,1},
			--{"Jump Height +20%", "increased jump height",1,0.2},
			--{"Weapon Switch Speed +35%", "deploy time decreased",1,-0.35,0},
		--base weapon
			{"All Max Ammo +25%", "custom",1,0.25,2},
			{"Spinup Time +20% / Spun Up Speed +10%", "custom",0,1,3},
			--{"Secondary: Reload Speed +20%", "faster reload rate",1,-0.2,0.1},
		--special
			--{"Heal On Hit +2 health", "heal on hit for rapidfire",0,2},
		--base char
			{"Melee Resistance +25%", "dmg from melee increased",1,-0.25,0.25},
			{"Push Force -35%", "damage force reduction",1,-0.35,0.01},
			{"Health Regen +4 every second", "health regen",0,4,12},
		--base weapon
			{"Secondary Clip Size +50% / Faster Reload + 25%", "custom",0,1},
		--special
			{"Consume / Recharge and Switch Faster +40%","custom",0,1,2},
			
		},
		RareAttribute =
		{
		--base char
			{"(RARE) Ammo Regen +15% every 5 seconds", "ammo regen",0,0.15,0.30},
			{"(RARE) Extra Jump +1 Jump Height +20%","custom",0,1,1},
			{"(FREE) Heal On Kill +25 health", "custom",0,1,4},
			{"(RARE) Movement Speed +25%", "move speed bonus",1,0.25,1.5},
		--base weapon
		    {"(FREE) Fire Rate +25% / Primary Ammo -50%", "custom",0,1,2},
			
			{"(RARE) Projectile Penetration +1", "projectile penetration heavy",0,1,3},
			--{"(RARE) Destroy Projectiles", "attack projectiles",0,1,2},
			{"(RARE) Rage Knockback", "generate rage on damage",0,2,2},
			{"(RARE) Firing Rate +15%", "fire rate bonus",1,-0.15,0.55},
		--special
			{"(RARE) Weapon Switch On-Spin / Faster Switch", "custom",0,1,1},
			{"(RARE) Spun Up Protection 20% Below 50% Health", "spunup_damage_resistance",1,-0.2,0.4},
			{"(RARE) Minigun Destroy Projectiles", "attack projectiles",0,2,2},
			{"(RARE) Damage Mult +25% / Slower Spun up +75%", "custom",0,1,3},
			{"(FREE) DMG Taken -10% / Fire Rate -10%", "custom",0,1,4},
			{"(RARE) Fire Rate + on Reduced Health", "fire rate bonus with reduced health",0,1,1},
			--{"(RARE) Switch Weapons While Spinning", "mod minigun can holster while spinning",0,1,1},
			--{"(RARE) Slow On Hit", "slow enemy on hit",0,1,1},
			--{"(RARE) Drop On Kill: Small Health Pack", "drop health pack on kill",0,1,1},
			--{"(RARE) Extra Jump +1", "air dash count",0,1},
		},
		EpicAttribute =
		{
		--special modifier
			{"[EPIC] Override Firing Mod : Spread", "custom",0,1,1,"More bullets per shot with larger spread"}, --more bullet per shot
			{"[EPIC] Override Firing Mod : Single", "custom",0,1,1,"Accurate single bullet per shot"}, --75% less bullet per shot / damage mult, mess with shotgun
			{"[EPIC] Override Firing Mod : Focus", "custom",0,1,1,"Way less spread"}, -- super tomislave, even better with tomi
			{"[EPIC] Override Firing Mod : Burst", "custom",0,1,1,"Periodic large burst of bullet"}, -- periodic super burst
			{"[EPIC] Mini-crits to Crits/No Dispenser for Minigun", "custom",0,1,1},
			{"[EPIC] Damage x1.5 Below 50% Health / -50% Healed", "custom",0,1,2},
			{"[EPIC] Damage x2 / Above 50% Health x0.8", "custom",1,0.2,1.2},
			{"[EPIC] Damage Mult +25%/Spread -40%/Primary Ammo -25%", "custom",0,1,2},
			{"[EPIC] Ranged Resistance -15%/Heal-on-Hit +1", "custom",0,1,1},
			{"[EPIC] Size Up / +100 Health", "custom",0,1,1},
		    {"Free Reroll", "custom",0,1,1},
			--{"[EPIC] Ring Of Fire", "ring of fire while aiming",0,1,1},
			--{"[EPIC] Recall On Death +25% chance", "teleport instead of die",0,0.25,1},
		},
		MinorEpicAttribute =
		{
		    {"[EPIC] Extra Reroll +1 and Available Epic +1", "custom",0,1,1},
		    {"Free Reroll", "custom",0,1,1},
		    {"[EPIC] Damage Bonus +25%", "damage bonus",1,0.25,2},
		    {"[EPIC] Tank Damage Bonus +60%", "mult dmg vs tanks",1,0.6,0.6},
		},
		LegendaryAttribute =
		{
		--	{"【LEGENDARY】 +50% Healed", "healing received bonus",1,0.5,0.5}, op and not very interesting
			{"【LEGENDARY】 Health +100", "max health additive penalty",0,100,100},
			{"【LEGENDARY】 Crit vs Burning", "crit vs burning players",0,1,1}, -- might need to be reworked
			{"【LEGENDARY】 No Spin up", "custom",0,1,1},
			{"【LEGENDARY】 No Reload", "faster reload rate",1,-1,0},
		--	{"【LEGENDARY】 Punch to Rage", "custom",1,-1,0}, not working
			{"【LEGENDARY】 Rocket", "custom",0,1,1},
		--	{"【LEGENDARY】 Crit on kill +1", "critboost on kill",0,1,1}, op and not very interesting
			{"【LEGENDARY】 Extra Upgrade", "custom",0,1,2},
		--	{"【LEGENDARY】 Double Speed", "major move speed bonus",1,1,2},
			--{"【LEGENDARY】 Mini-crits become Crits", "minicrits become crits",0,1,1},
			--{"【LEGENDARY】 Mark for Death On Hit", "mark for death",0,1,1},
		}
	},
	[9] = --Engineer Shop
	{
		CommonAttribute =
		{
			--base char
			{"All Resistance Upgrade +25%", "custom",0,1,5},
			{"Movement Speed +20%", "move speed bonus",1,0.2,1.6},
			{"All Max Ammo +25%", "custom",1,0.25,2},
			{"Max Metal Capacity +100%", "maxammo metal increased",1,1,4},
			{"Building Health +100%/Repair Rate +20%", "custom",0,1,5},
			{"Health Regen +4 every second", "health regen",0,4,12},
			{"Upgrade Rate +140%", "upgrade rate decrease",1,1.4,8},
			--{"Construction Speed +50%", "Construction rate increased",1,0.5,2.5},
			--base weapon
			{"Reload Speed +35%", "faster reload rate",1,-0.35,0.3},
			{"Dispenser Range +100%", "engy dispenser radius increased",1,1,3},
			--{"Weapons: Clip Size +50%", "clip size bonus",1,0.5},
			--{"Weapons: Firing Speed +15%", "fire rate bonus",1,-0.15,0.1},
			--{"Weapons: Max Ammo +50%", "custom",1,0.5},
			--{"Weapon Switch Speed +70%", "deploy time decreased",1,-0.7,0.3},
			--{"Heal On Kill +25 health", "heal on kill",0,25},
			--{"Heal On Hit +15 health", "heal on hit for rapidfire",0,15,45},
		--	{"Sentry Max Ammo +30%", "mvm sentry ammo",1,0.3},
		--	{"Repair Rate +20%", "Repair rate increased",1,0.2},
		--	{"Increased Metal From Ammo +100%", "metal_pickup_decreased",1,1,2},
		--	{"Drop On Kill: Small Health Pack", "drop health pack on kill",0,1,1},
		--	{"Max Health +40", "max health additive bonus",0,40},
		--	{"Movement Speed +10%", "move speed bonus",1,0.1},
		--	{"Jump Height +20%", "increased jump height",1,0.2},
		--	{"Ammo Regen +20% every 5 seconds", "ammo regen",0,0.2,1},
		--	{"Fire Resistance +25%", "dmg taken from fire reduced",1,-0.25,0.25},
		--	{"Bullet Resistance +25%", "dmg taken from bullets reduced",1,-0.25,0.25},
		--	{"Blast Resistance +25%", "dmg taken from blast reduced",1,-0.25,0.25},
		--	{"Melee Resistance +45%", "dmg from melee increased",1,-0.45,0.1},
		--	{"Crit Resistance +30%", "dmg taken from crit reduced",1,-0.3,0.1},
		},
		RareAttribute =
		{
		--	{"(RARE) Damage Bonus vs Buildings +50%", "dmg bonus vs buildings",1,0.5,2},
		    {"(RARE) Build Speed +25%", "build rate bonus",1,-0.25,0.25},
			{"(RARE) Damage Bonus +50%", "custom",0,1,4},
			{"(RARE) Damage Mult x1.5/Ranged Resistance +15%", "custom",0,1,4},
			{"(RARE) Sentry Firing Speed +15%", "sentry rapid fire",1,0.15,1.3},
			{"(RARE) Teleporter cost -25%/Build Rate +150%", "custom",0,1,2},
			{"(RARE) Dispenser cost -50%", "mod dispenser cost",0,-0.5,-1},
		--	{"(RARE) Dispenser Heal/Resupply +75%", "mult dispenser rate",1,0.75},
		--	{"(RARE) Sentry Rocket Specialist", "rocket specialist",0,2,4},
		--	{"(RARE) Damage Bonus vs Sentry's Target +30%", "damage bonus bullet vs sentry target",1,0.3},
		--	{"(RARE) Recall On Death +50% chance", "teleport instead of die",0,0.5,1},
		--	{"(RARE) Speed Boost On Kill +5 seconds", "speed_boost_on_kill",0,5,5},
		--	{"(RARE) 50 Metal to pick up your targeted building from long range", "engineer building teleporting pickup",0,50,50},
		--	{"(RARE) Tank Damage Bonus +50%", "mult dmg vs tanks",1,0.5},
		--	{"(RARE) Extra Jump +1", "air dash count",0,1},
		--	{"(RARE) Projectile Penetration", "projectile penetration",0,1,1},
		--	{"(RARE) Sentry Range +50%", "engy sentry radius increased",1,0.5,5},
		},
		EpicAttribute =
		{
		    {"[EPIC] Damage Mult x2/Spread x1.6/Primary Ammo -30%", "custom",0,1,1},
			{"[EPIC] Bullets Per Shot +100%", "bullets per shot bonus",1,1,3},
			{"[EPIC] Override Sentry Module : Rocket", "custom",0,1,1,"Rocket sentry with wider detection range"},
			{"[EPIC] Override Sentry Module : Gatling", "custom",0,1,1,"Way faster machinegun firing with lot more bullet cost"},
			{"[EPIC] Disposable Sentry +4/Sentry No Repair", "custom",0,3},
			{"[EPIC] Two-Way Teleporter/Instant Recharge", "custom",0,1,1},
			{"[EPIC] Dispenser Rate x10/All Metal Gain -75%", "custom",0,1,1,"Dispenser healing and ammo dispense x10"},
			{"[EPIC] Energy Weapon Damage x3", "custom",0,1,1},
		    {"Free Reroll", "custom",0,1,1},
			--{"[EPIC] Upgrade Speed +100%", "upgrade rate decrease",1,1,5},
			--{"[EPIC] Sentry Damage Bonus +30%", "engy sentry damage bonus",1,0.3},
			--{"[EPIC] Build Speed +100%", "build rate bonus",1,-1,0},
			--{"[EPIC] On Hit: damage dealt is returned as ammo", "add onhit addammo",0,1,1},
			--{"[EPIC] Weapons Accuracy +100%", "weapon spread bonus",1,-1,0},
		},
		MinorEpicAttribute =
		{
		    {"[EPIC] Extra Reroll +1 and Available Epic +1", "custom",0,1,1},
		    {"Free Reroll", "custom",0,1,1},
		    {"[EPIC] Spread bonus 25%", "weapon spread bonus",1,-0.25,0.25},
		    {"[EPIC] Sentry Build Rate +25%", "engineer sentry build rate multiplier",1,-0.25,0.25},
		    {"[EPIC] Metal Regen +70 every 5s", "metal regen",0,70,140},
		    {"[EPIC] Firing Speed +15%", "fire rate bonus",1,-0.15,0.55}
		},
		LegendaryAttribute =
		{
			{"【LEGENDARY】 Crit On Kill +5 seconds", "critboost on kill",0,5,5},
			{"【LEGENDARY】 Extra Upgrade", "custom",0,1,2},
			--{"【LEGENDARY】 Mini-crits become Crits", "minicrits become crits",0,1,1},
		--	{"【LEGENDARY】 All Healing Received +200%", "healing received bonus",1,2,2},
		--	{"【LEGENDARY】 Mark for Death On Hit", "mark for death",0,1,1},
			--{"【LEGENDARY】 Construction Cost -100%", "building cost reduction",1,-1,0},
			--{"【LEGENDARY】 Sentry Overcharge (rapid fire mod)", "sentry rapid fire",0,1,1},
		}
	},
	[5] = --Medic Shop
	{
		CommonAttribute =
		{
			--base char
			{"All Resistance Upgrade +20%", "custom",0,1,5},
			{"Health Regen +3 every second", "health regen",0,3,3},
			{"Move Speed / Jump Height +10%", "custom",0,1,4},
			{"Max Ammo +50%", "custom",1,0.5,2},
			--base weapon
			{"Overheal Expert +2", "overheal expert",0,2,4},
			{"ÜberCharge Rate +35%", "ubercharge rate bonus",1,0.35,2.05},
			{"Healing Mastery +1", "healing mastery",0,1,3},
			--{"Über Duration +2 seconds", "uber duration bonus",0,2,6},
			{"Firing Speed +15%", "fire rate bonus",1,-0.15,0.55},
			--{"Damage Bonus +25%", "damage bonus",1,0.25},
			--{"Clip Size +50%", "clip size bonus",1,0.5},
			--{"Clip Size +2", "clip size upgrade atomic",1,2},
			--{"Reload Speed +20%", "faster reload rate",1,-0.2,0.1},
			--{"Heal On Kill +25 health", "heal on kill",0,25},
			--{"Heal On Hit +3 health", "heal on hit for rapidfire",0,3},
			--{"Overheal Duration +50%", "overheal bonus",1,0.25},
			--{"Push Force -30%", "damage force reduction",1,-0.3,0.1},
			--{"Movement Speed +10%", "move speed bonus",1,0.1},
			--{"Jump Height +20%", "increased jump height",1,0.2},
			--{"Weapon Switch Speed +70%", "deploy time decreased",1,-0.7,0.3},
			--{"Fire Resistance +25%", "dmg taken from fire reduced",1,-0.25,0.25},
			--{"Crit Resistance +30%", "dmg taken from crit reduced",1,-0.3,0.1},
			--{"Bullet Resistance +25%", "dmg taken from bullets reduced",1,-0.25,0.25},
			--{"Blast Resistance +25%", "dmg taken from blast reduced",1,-0.25,0.25},
			--{"Melee Resistance +25%", "dmg from melee increased",1,-0.25,0.25},
			--{"Ammo Regen +20% every 5 seconds", "ammo regen",0,0.2,1},
		},
		RareAttribute =
		{
		    {"(RARE) Damage Bonus +100%", "damage bonus",1,1,3},
			{"(RARE) Projectile Shield", "generate rage on heal",0,1,2},
			{"(RARE) Max Health +50", "max health additive bonus",0,50,200},
			{"(RARE) Heal Rate +30%/Switch +40%/Blast Res -15%", "custom",0,1,3},
			{"(RARE) Damage Mult x1.5/Ranged Resistance +15%", "custom",0,1,3},
			{"(RARE) Heal on kill +50%", "restore health on kill",0,0.5,1},
			{"(RARE) Max Overheal +50%", "overheal bonus",1,0.5,3},
			{"(RARE) Heal Buildings", "medic machinery beam",0,1,1},
			{"(RARE) Melee Resistance +35%", "dmg from melee increased",1,-0.35,0.65},
			{"(RARE) Minor Canteen Sharing", "canteen specialist",0,1,1},
			{"(RARE) Taunt Speed +50%", "gesture speed increase",1,0.4,1.4},
		    {"Free Reroll", "custom",0,1,1},
			--{"(RARE) Extra Jump +1", "air dash count",0,1},
			--{"(RARE) Mad Milk Syringes", "mad milk syringes",0,1,1},
			--{"(RARE) Medigun Range +25%", "mult medigun range",1,0.25},
			--{"(RARE) Revive Speed +60%", "revive rate",1,0.6,2.2},
			--{"(RARE) Speed Boost On Kill +5 seconds", "speed_boost_on_kill",0,5,5},
		},
		EpicAttribute =
		{
			{"[EPIC] Recall/Damage x2/DMG Taken x1.5 Except Crit", "custom",0,1,1},
			{"[EPIC] Recall/Revive Speed x3/No OverHeal", "custom",0,1,1},
			{"[EPIC] Override ÜberCharging : Blank", "custom",0,1,1,"Very quick and instantly discharging Übercharge"},
			{"[EPIC] Override ÜberCharging : Extended", "custom",0,1,1,"Way longer Über duration"},
			{"[EPIC] Override ÜberCharging : Balanced", "custom",0,1,1,"Slight quicker Übercharging and longer duration"},
			{"[EPIC] No OverHeal Decay/Overheal Rate +100%", "custom",0,1,1},
			{"[EPIC] Heal Rate x10/No Shield", "custom",0,1,1},
			{"[EPIC] Damage x2/Instant OverHeal Decay", "custom",0,1,1},
			{"[EPIC] Max Health +200/Health Drain/Milk Syringe", "custom",0,1,1,"You have 30 seconds to live"},
		    {"[EPIC] Major Canteen Sharing", "canteen specialist",0,4,4},
		    {"Free Reroll", "custom",0,1,1},
			--{"[EPIC] Mixed Concoction On Hit", "custom",0,1,1},
			--{"[EPIC] Melee Attacks Cleave All Targets", "melee cleave attack",0,1,1},
		},
		MinorEpicAttribute =
		{
		    {"[EPIC] Extra Reroll +1 and Available Epic +1", "custom",0,1,1},
		    {"[EPIC] Heal-on-Hit +1", "heal on hit for rapidfire",0,1,1},
		},
		LegendaryAttribute =
		{
			{"【LEGENDARY】 Override ÜberCharging : Infinite", "custom",0,1,1,"Greatly increase Übercharging rate and reduced duration no shield"},
			{"【LEGENDARY】 Crit on Kill +5s", "critboost on kill",0,5,5},
			{"【LEGENDARY】 Mark of Death on Hit", "mark for death",0,1,1},
			{"【LEGENDARY】 Extra Upgrade", "custom",0,1,2},
			{"【LEGENDARY】 Invulnerable Chance on Taking Damage +30%", "uber on damage taken",0,0.3,0.3},
			--{"【LEGENDARY】 Mini-crits become Crits", "minicrits become crits",0,1,1},
			--{"【LEGENDARY】 All Healing Received +200%", "healing received bonus",1,2,2},
			--{"【LEGENDARY】 Gain Über On Hit +1%", "add uber charge on hit",0,0.01,0.01},
		}
	},
	[2] = --Sniper Shop
	{
		CommonAttribute =
		{
			--base char
			{"All Resistance Upgrade +20%", "custom",0,1,4},
			{"All Max Ammo +25%", "custom",1,0.25,2},
			{"Health Regen +3 every second", "health regen",0,3,6},
			{"Ammo Regen +25%/No Dispenser for Primary", "custom",0,1,1},
			{"Heal On Kill +35 health", "heal on kill",0,35,70},
			{"Heal On Hit +15 health", "heal on hit for rapidfire",0,15,15},
			{"Movement Speed +20%", "move speed bonus",1,0.2,1.4},
			--base weapon
			{"Firing Speed +15%", "fire rate bonus",1,-0.15,0.55},
			{"Secondary Clip Size +50% / Faster Reload + 25%", "custom",0,1,2},
			{"Secondary Clip Size +100%/Ammo +50%", "custom",1,1,3},
		--	{"Max Health +25", "max health additive bonus",0,25},
		--	{"Max Ammo +50%", "custom",1,0.5},
		--	{"Jump Height +20%", "increased jump height",1,0.2},
		--	{"Weapon Switch Speed +70%", "deploy time decreased",1,-0.7,0.3},
		--	{"Secondary: Clip Size +50%", "clip size bonus",1,0.5},
		--	{"Bows: Arrow Mastery", "arrow mastery",0,1},
		--	{"Bleed On Hit +5 seconds", "bleeding duration",0,5},
		--	{"Consumable Recharge Rate +25%", "charge recharge rate increased",1,0.25},
		--	{"Fire Resistance +25%", "dmg taken from fire reduced",1,-0.25,0.25},
		--	{"Crit Resistance +30%", "dmg taken from crit reduced",1,-0.3,0.1},
		--	{"Bullet Resistance +25%", "dmg taken from bullets reduced",1,-0.25,0.25},
		--	{"Blast Resistance +25%", "dmg taken from blast reduced",1,-0.25,0.25},
		--	{"Melee Resistance +25%", "dmg from melee increased",1,-0.25,0.25},
		},
		RareAttribute =
		{
			{"(RARE) Extra Jump +1 Jump Height +20%","custom",0,1,1},
			{"(RARE) Max Health +50", "max health additive bonus",0,50,200},
			{"(RARE) Rifle Charge Speed +40%", "SRifle Charge rate increased",1,0.4,0.8},
			{"(RARE) Minor Explosive Headshot", "explosive sniper shot",0,1,1},
			{"(RARE) Damage Bonus +25%", "damage bonus",1,0.25,2},
			{"(RARE) Jarate Slows Targets", "applies snare effect",1,-0.35,0.65},
			{"(RARE) Damage Bonus On Full Charge +35%", "sniper full charge damage bonus",1,0.35,2.05},
			{"(FREE) Damage Taken -25%/Weapon Ammo -25%/-15%", "custom",0,1,3},
			{"(FREE) Damage +35%/Switch +40%/Primary Ammo -25%", "custom",0,1,3},
			{"(RARE) Spread x0.05", "weapon spread bonus",1,-0.95,0.05},
			{"(RARE) Spread x1.5 / Fire Rate Bonus +50%", "custom",0,1,1},
			{"(RARE) Tank Damage Bonus +70%", "mult dmg vs tanks",1,0.7,1.7},
		--	{"(RARE) Extra Jump +1", "air dash count",0,1},
		--	{"(RARE) Projectile Penetration", "projectile penetration",0,1,1},
		--	{"(RARE) No Fliching When Scoped", "no damage view flinch",0,1,1},
		--	{"(RARE) Recall On Death +50% chance", "teleport instead of die",0,0.5,1},
			
		},
		EpicAttribute =
		{
			{"[EPIC] SMG Headshot/Fire Rate -100%/Damage x1.5", "custom",0,1,1},
			{"[EPIC] Override Ammunition Type : Crits", "custom",0,1,1,"Periodic massive crit damage"},
			{"[EPIC] Override Ammunition Type : Snap", "custom",0,1,1,"Quicker reload and less crit damage"},
			{"[EPIC] Override Ammunition Type : ", "custom",0,1,1,"Periodic strong shot and lesser crit damage"},
			--{"[EPIC] Full Charge After Bodyshot", "mult sniper charge after bodyshot",0,20,20}, attribute not working
			{"[EPIC] Explosive Headshot/Reload Rate -100%", "custom",0,1,1},
			{"[EPIC] Damage Rampup to x1.5 at Close", "force damage falloff",0,1,1},
			{"[EPIC] Rifle Charge Speed +150%", "sniper charge per sec",1,1.5,4},
			{"[EPIC] Health +100/No Headshot", "custom",0,1,1},
			{"[EPIC] Projectile Ricochet/Ricochet Damage x2", "custom",0,1,1},
			{"[EPIC] Arrow Per Shot +2", "arrow mastery",0,1,2},
		    {"Free Reroll", "custom",0,1,1},
		--	{"[EPIC] Meter Effect/Debuff Duration +50%", "mult effect duration",1,0.5},
		--	{"[EPIC] Damage All Targets Connected By Medigun", "damage all connected",0,1,1},
		},
		MinorEpicAttribute =
		{
		    {"[EPIC] Extra Reroll +1 and Available Epic +1", "custom",0,1,1},
		    {"Free Reroll", "custom",0,1,1},
		    {"[EPIC] Arrow Per Shot +2", "arrow mastery",0,1,2},
		    {"[EPIC] Rifle Charge Speed +150%", "sniper charge per sec",1,1.5,4}
		},
		LegendaryAttribute =
		{
			{"【LEGENDARY】 Override Ammo.T : Explosive", "custom",0,1,1,"Periodic explosive shot"},
			--{"【LEGENDARY】 Glass Cannon", "custom",0,1,1},	-- cannot find appropriate attributes to use
			{"【LEGENDARY】 Extra Upgrade", "custom",0,1,2},
			{"【LEGENDARY】 Armor Piercing", "custom",0,1,2,"Increased giant damage and ignore resistance"},
			{"【LEGENDARY】 Crit on Kill +3s", "critboost on kill",0,3,3},
		--	{"【LEGENDARY】 Mini-crits become Crits", "minicrits become crits",0,1,1},
		--	{"【LEGENDARY】 Mark for Death On Hit", "mark for death",0,1,1},
		}
	},
	[8] = --Spy Shop
	{
		CommonAttribute =
		{
			--base char
			{"All Resistance Upgrade +25%", "custom",0,1,5},
			{"All Max Ammo +25%", "custom",1,0.25,2},
			{"Heal On Kill +35 health", "heal on kill",0,35,70},
			{"Ammo Regen +20% every 5 seconds", "ammo regen",0,0.2,0.2},
			{"Heal On Hit +15 health", "heal on hit for rapidfire",0,15,15},
			{"Movement Speed +20%", "move speed bonus",1,0.2,1.4},
			{"Clip Size +33%", "clip size bonus",1,0.33,1.99},
		--	{"Firing Speed +10%", "fire rate bonus",1,-0.1,0.1},
		--	{"Reload Speed +20%", "faster reload rate",1,-0.2,0.1},
		--	{"Max Ammo +50%", "custom",1,0.5},
		--	{"Weapon Switch Speed +35%", "deploy time decreased",1,-0.35,0},
			--base weapon
			{"Damage Bonus +50%", "damage bonus",1,0.5,3},
			{"Robot Sapper Power", "robo sapper",0,1,3},
			{"Cloak Recharge Rate +60%", "mult cloak meter regen rate",1,0.6,3.4},
			{"Credit Collect Range +100%/Collect on Kill", "custom",0,1,2},
		--	{"Armor Penetration", "armor piercing",0,25,100},
		--	{"Cloak Duration +20%", "cloak consume rate decreased",1,-0.2},
		--	{"Add Cloak On Hit +20%", "add cloak on hit",0,20},
		--	{"Add Cloak On Kill +30%", "add cloak on kill",0,30},
		--	{"Drop On Kill: Small Health Pack", "drop health pack on kill",0,1,1},
		},
		RareAttribute =
		{
			{"(RARE) Recall On Death +50% chance", "teleport instead of die",0,0.5,1},
			{"(RARE) Damage +50%/Ammo -35%/Switch +40%", "custom",0,1,4},
			{"(RARE) Max Health +50", "max health additive bonus",0,50,200},
			{"(RARE) Backstab Armor Piercing", "armor piercing",0,1,4},
			{"(RARE) Sapper Recharge Rate +90%", "effect bar recharge rate increased",1,-0.45,0.1},
			{"(RARE) Imitation Upgrade : Scout", "custom",0,1,1,"Increased move speed and double jump"}, 
			{"(RARE) Imitation Upgrade : Pyro", "custom",0,1,1,"Revolver pierce through and ignite enemies"},
			{"(RARE) Imitation Upgrade : Medic", "custom",0,1,1,"Health regen and milk revolver"},
			{"(RARE) Imitation Upgrade : Soldier", "custom",0,1,1,"Weapons causes small explosion and decreased self blast dmg"},
			--{"(RARE) Headshots Enabled", "can headshot",0,1,1},
			--{"(RARE) Decloak Speed +50%", "mult decloak rate",1,-0.5,0.01},
			--{"(RARE) Backstabs and Saps Store Crits", "sapper kills collect crits",0,1,1},
			--{"(RARE) Wet Immunity", "wet immunity",0,1,1},
			--{"(RARE) Afterburn Immunity", "afterburn immunity",0,1,1},
			--{"(RARE) Extra Jump +1", "air dash count",0,1},
			--{"(RARE) Projectile Penetration", "projectile penetration",0,1,1},
		},
		EpicAttribute =
		{
			{"[EPIC] Fire rate +50%/Spread x7/Damage x2", "custom",0,1,1},
			{"[EPIC] DMG Taken -35%/Crit Damage -80%", "custom",0,1,1},
			{"[EPIC] Damage x4 While Disguised", "damage bonus while disguised",1,3,10},
			{"[EPIC] Faster Cloak/Cloak Regen x2/Duration -40%", "custom",0,1,1},
			{"[EPIC] Melee Deflect/Bullet Resistance +20%", "custom",0,1,1},
			{"[EPIC] Last Bullet Is A Crit", "last shot crits",0,1,1},
			{"[EPIC] Override Imitation : Demo", "custom",0,1,1,"Revolver periodic large explosion with huge self blast dmg"},
			{"[EPIC] Override Imitation : Sniper", "custom",0,1,1,"No damage falloff with periodic accurate shot"},
			{"[EPIC] Override Imitation : Engineer", "custom",0,1,1,"Revolver fires like shotgun blast"},
		    {"Free Reroll", "custom",0,1,1},
			--{"[EPIC] Secondary: Buff/Debuff Duration +50%", "mult effect duration",1,0.5},
			--{"[EPIC] Speed Boost On Kill", "speed_boost_on_kill",0,1,1},
			--{"[EPIC] Tank Buster Damage Bonus +300%", "mult dmg vs tanks",1,3},
			--{"[EPIC] Sapper Recharge Rate +50%", "charge recharge rate increased",1,0.5,2},
		},
		MinorEpicAttribute =
		{
		    {"[EPIC] Extra Reroll +1 and Available Epic +1", "custom",0,1,1},
		    {"[EPIC] Sapper Damage/Health +100%", "custom",0,1,2},
		},
		LegendaryAttribute =
		{
			{"【LEGENDARY】 Infinite Cloak", "cloak consume rate decreased",1,-0.95,0.05},
			{"【LEGENDARY】 Crit on Kill +5s", "critboost on kill",0,5,5},
			{"【LEGENDARY】 Damage All Connected By Medigun", "damage all connected",0,1,1},
			{"【LEGENDARY】 Override Imitation : Heavy", "custom",0,1,1,"Crit damage decreased by 80%"},
			{"【LEGENDARY】 Extra Upgrade", "custom",0,1,2},
			--{"【LEGENDARY】 Revolver Retains Disguise", "keep disguise on attack",0,1,1},
			--{"【LEGENDARY】 All Healing Received +100%", "healing received bonus",1,1},
			--{"【LEGENDARY】 Disguise On Backstab", "disguise on backstab",0,1,1},
			--{"【LEGENDARY】 Melee Hit Grants Protection 1s", "melee grants protection",0,1,2},
		}
	}
}

--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 = {}

--[[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!")
			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)
    if player:IsRealPlayer() then
        player:AddCallback(ON_SPAWN, function(player)
			InitUserId(player)
			ReAddPurchasedUpgrades(player)
		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_desc = upgradetable[6]
						

						if string.find(upgrade, "(RARE)",1,true) then
							util.PrintToChatAll("\x07ff3d3d"  .. playername .. "\x07fbeccb has purchased: " .. "\x074B69FF".. string.sub(upgrade,1,6) .. "\x07FFD700".. string.sub(upgrade,7,#upgrade) .. "\x07fbeccb Level " .. purchased[value])
						elseif string.find(upgrade, "[EPIC]",1,true) then
							util.PrintToChatAll("\x07ff3d3d"  .. playername .. "\x07fbeccb has purchased: " .. "\x078847FF".. string.sub(upgrade,1,6) .. "\x07FFD700".. string.sub(upgrade,7,#upgrade) .. "\x07fbeccb Level " .. purchased[value])
							if player.AvailableEpic > 0 then 
							    player.AvailableEpic = player.AvailableEpic - 1
							end
						elseif string.find(upgrade, "【LEGENDARY】",1,true) then
							util.PrintToChatAll("\x07ff3d3d"  .. playername .. "\x07fbeccb has purchased: " .. "\x07EB4B4B".. string.sub(upgrade,1,15) .. "\x07FFD700".. string.sub(upgrade,16,#upgrade) .. "\x07fbeccb Level " .. purchased[value])
						else
						util.PrintToChatAll("\x07ff3d3d"  .. playername .. "\x07fbeccb has purchased: " .. "\x07FFD700" .. upgrade .. "\x07fbeccb Level " .. purchased[value])
						end
						if upgrade_desc ~=nil then
							activator:PrintToChat("\x0798FF3DDescription : \x07fbeccb" .. upgrade_desc)
						end
						if string.find(upgrade, "(FREE)",1,true) or string.find(upgrade, "Free Reroll",1,true) then
					        player.UpgradePoints = player.UpgradePoints - 0
						elseif string.find(upgrade, "【LEGENDARY】 Extra Upgrade",1,true) or string.find(upgrade, "test",1,true) then
						    player.UpgradePoints = player.UpgradePoints + 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]]
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 = {}

	if number < 0.71 then
	pool = shop.CommonAttribute
	elseif (number >= 0.71 and number < 0.91) then
		pool = shop.RareAttribute
	elseif (number >= 0.91 and number < 0.99) then
	    if player.AvailableEpic > 0 then
		    pool = shop.EpicAttribute
		else    pool = shop.MinorEpicAttribute
		end
	elseif number >= 0.99 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
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

--[[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 = {}

	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])

	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 == "All Max Ammo +25%" 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 == "[EPIC] 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)
		elseif upgrade == "(FREE) Fire Rate +25% / Primary Ammo -50%" then
			activator:SetAttributeValue("melee attack rate bonus",math.max(1+(-0.25*purchased[value]),0.5))
			activator:SetAttributeValue("maxammo primary reduced",math.max(1+(-0.5*purchased[value]),0.01))
		elseif upgrade == "All Resistance Upgrade +20%" then
			activator:SetAttributeValue("dmg taken from blast reduced",math.max(1+(-0.2*purchased[value]),0.2))
			activator:SetAttributeValue("dmg taken from fire reduced",math.max(1+(-0.2*purchased[value]),0.2))
			activator:SetAttributeValue("dmg taken from crit reduced",math.max(1+(-0.3*purchased[value]),0.1))
			activator:SetAttributeValue("dmg taken from bullets reduced",math.max(1+(-0.2*purchased[value]),0.2))
		elseif upgrade == "All Resistance Upgrade +25%" then
			activator:SetAttributeValue("dmg taken from blast reduced",math.max(1+(-0.25*purchased[value]),0.15))
			activator:SetAttributeValue("dmg taken from fire reduced",math.max(1+(-0.25*purchased[value]),0.15))
			activator:SetAttributeValue("dmg taken from crit reduced",math.max(1+(-0.3*purchased[value]),0.1))
			activator:SetAttributeValue("dmg taken from bullets reduced",math.max(1+(-0.25*purchased[value]),0.15))
		elseif upgrade == "[EPIC] Extra Reroll +1 and Available Epic +1" then
		    player.RerollPoints = player.RerollPoints + 1
		    player.AvailableEpic = player.AvailableEpic + 2
		elseif upgrade == "Health +50 / -25% OverHealed" then
			activator:SetAttributeValue("hidden maxhealth non buffed",50*purchased[value])
			activator:SetAttributeValue("patient overheal penalty",math.max(1+(-0.25*purchased[value]),0.01))
		elseif upgrade == "(RARE) Damage Mult +35%/Primary Ammo -30%/Switch +40%" then
			activator:SetAttributeValue("deploy time decreased",math.max(1+(-0.4*purchased[value]),0.1))
			activator:SetAttributeValue("damage penalty",math.min(1+(0.35*purchased[value]),2.05))
			activator:SetAttributeValue("hidden primary max ammo bonus",math.max(1+(-0.3*purchased[value]),0.1))
		elseif upgrade == "Secondary Clip Size +50% / Faster Reload + 25%" then
			activator:SetAttributeValue("Reload time decreased",math.max(1+(-0.25*purchased[value]),0.25))
			activator:SetAttributeValue("clip size bonus",1+(0.5*purchased[value]))
		elseif upgrade == "(FREE) Clip Size +50% / Spread Angle -3" then
			activator:SetAttributeValue("clip size penalty",math.min(1+(0.5*purchased[value]),2.5))
			activator:SetAttributeValue("projectile spread angle penalty",math.min(3*purchased[value],9))
			 
		--scout custom upgrades
		
		elseif upgrade == "Move Speed / Jump Height +10%" then
			activator:SetAttributeValue("move speed bonus",math.min(1+(0.1*purchased[value]),1.4))
			activator:SetAttributeValue("increased jump height",math.min(1+(0.1*purchased[value]),1.4))
		elseif upgrade == "(RARE) Health +50 / Medic Healing -25%" then
			activator:SetAttributeValue("hidden maxhealth non buffed",math.min(50*purchased[value]),200)
			activator:SetAttributeValue("health from healers reduced",math.max(1+(-0.25*purchased[value]),0))
		elseif upgrade == "[EPIC] Force Fire Full Clip/Fire rate x2/No Milk" then
			activator:SetAttributeValue("force fire full clip",1)
			activator:SetAttributeValue("fire rate penalty",0.5)
		elseif upgrade == "[EPIC] Damage Mult x2/Spread x2/Primary Ammo -40%" then
			activator:SetAttributeValue("damage bonus HIDDEN",2)
			activator:SetAttributeValue("spread penalty",2)
			activator:SetAttributeValue("maxammo primary reduced",0.6)
		elseif upgrade == "[EPIC] Damage Mult x10/Clip Size -100%" then
			activator:SetAttributeValue("clip size penalty HIDDEN",-10)
			activator:SetAttributeValue("damage bonus vs burning",7)
			activator:SetAttributeValue("dmg penalty vs nonburning",7)
			activator:SetAttributeValue("fire rate bonus HIDDEN",2)
		elseif upgrade == "[EPIC] Damage x2.5/Clip Size -85%/Fire Rate -100%" then
			activator:SetAttributeValue("CARD: damage bonus",2.5)
			activator:SetAttributeValue("fire rate penalty HIDDEN",2)
			activator:SetAttributeValue("clip size penalty",0.15)
		elseif upgrade == "[EPIC] Max Health Drain/Ranged Resistance 50%" then
			activator:SetAttributeValue("mod_maxhealth_drain_rate",50)
			activator:SetAttributeValue("dmg from ranged reduced",0.5)
		elseif upgrade == "[EPIC] No DMG Falloff / Piercing" then
			activator:SetAttributeValue("no damage falloff",1)
			activator:SetAttributeValue("no reduced damage rampup",1)
			activator:SetAttributeValue("projectile penetration",1)
		elseif upgrade == "[EPIC] Crit on Kill 3s/Damage mult x0.7" then
			activator:SetAttributeValue("critboost on kill",3)
			activator:SetAttributeValue("dmg penalty vs players",0.7)
		elseif upgrade == "【LEGENDARY】 Super Scout" then
			activator:SetAttributeValue("major move speed bonus",2)
			activator:SetAttributeValue("damage force reduction",0.01)
		--soldier custom upgrades
		
		elseif upgrade == "Clip Size Bonus +50%" then
			activator:SetAttributeValue("clip size upgrade atomic",math.min(2*purchased[value],12))
			activator:SetAttributeValue("clip size bonus upgrade",math.min(1+(0.5*purchased[value]),4))
		elseif upgrade == "(RARE) Bullet Per Shot +50% / Weapon Switch +25%" then
			activator:SetAttributeValue("bullets per shot bonus",math.min(1+(0.5*purchased[value]),3))
			activator:SetAttributeValue("deploy time decreased",math.max(1+(-0.25*purchased[value]),0.01))
		elseif upgrade == "Buff Duration +30%/Buff Radius +15%" then
			activator:SetAttributeValue("increase buff duration",math.min(1+(0.3*purchased[value]),1.9))
			activator:SetAttributeValue("mod soldier buff range",math.min(1+(0.15*purchased[value]),1.45))
			
		elseif upgrade == "(RARE) Buff Durartion +40% / Move Speed +10%" then
			activator:SetAttributeValue("increase buff duration HIDDEN",math.min(1+(0.4*purchased[value]),2.2))
			activator:SetAttributeValue("move speed bonus",math.max(1+(0.10*purchased[value]),1.3))
		elseif upgrade == "(RARE) Fire Rate +25% / Primary Ammo -25%" then
			activator:SetAttributeValue("fire rate penalty HIDDEN",math.min(1+(-0.25*purchased[value]),0.5))
			activator:SetAttributeValue("maxammo primary reduced",math.max(1+(-0.25*purchased[value]),0.01))
			activator:SetAttributeValue("clip size bonus upgrade",math.max(1+(-0.25*purchased[value]),0.25))
			activator:SetAttributeValue("clip size bonus",math.max(1+(0.25*purchased[value]),1.75))
			  -- return upgrade point
	    elseif upgrade == "[EPIC] Force Fire Full Clip/Fire rate +25%" then
			activator:SetAttributeValue("force fire full clip",1)
			activator:SetAttributeValue("fire rate penalty",0.75)
		elseif upgrade == "[EPIC] Mortar Rocket / Damage mult x1.5" then
			activator:SetAttributeValue("projectile gravity",800)
			activator:SetAttributeValue("CARD: damage bonus",1.5)
		elseif upgrade == "[EPIC] Fire rate x2 / Rocket Speed -55%" then
			activator:SetAttributeValue("fire rate bonus HIDDEN",0.5)
			activator:SetAttributeValue("Projectile speed decreased",0.45)
		elseif upgrade == "[EPIC] Rocket Speed +100% / Direct Hit Stun" then
			activator:SetAttributeValue("rocket specialist",1)
			activator:SetAttributeValue("Projectile speed increased",1.85)
		elseif upgrade == "[EPIC] Ranged Resistance +25% / Heal-on-Hit +15" then
			activator:SetAttributeValue("dmg from ranged reduced",0.75)
			activator:SetAttributeValue("heal on hit for slowfire",15)
		elseif upgrade == "[EPIC] Reload Speed -30% / Blast Radius +25%" then
			activator:SetAttributeValue("Reload time increased",math.min(1+(0.3*purchased[value]),2.2))
			activator:SetAttributeValue("Blast radius increased",math.min(1+(0.25*purchased[value]),2))
		elseif upgrade == "[EPIC] Mini-crits to Crits / Damage x0.5" then
			activator:SetAttributeValue("minicrits become crits",1)
			activator:SetAttributeValue("damage bonus HIDDEN",0.5)
		elseif upgrade == "[EPIC] Double Healing/No Medic Healing" then
			activator:SetAttributeValue("healing received bonus",2)
			activator:SetAttributeValue("mod weapon blocks healing",1)
		elseif upgrade == "[EPIC] DMG x1.3 While Healed by Medic/Medic Healing -99%" then
			activator:SetAttributeValue("mod medic healed damage bonus",1.5)
			activator:SetAttributeValue("reduced_healing_from_medics",0.01)
		elseif upgrade == "【LEGENDARY】 Super Bison/Clip Size x0" then
		    activator:SetAttributeValue("clip size penalty HIDDEN",-10)
			activator:SetAttributeValue("dmg penalty vs players",2.5)
			activator:SetAttributeValue("projectile acceleration",-1000)
			activator:SetAttributeValue("projectile acceleration start time",0.5)
	    elseif upgrade == "【LEGENDARY】 Free Pair of Mantread" then
			activator:SetAttributeValue("max health additive penalty",800)
			activator:SetAttributeValue("dmg taken increased",4)
			activator:SetAttributeValue("reduced_healing_from_medics",10)
			activator:SetAttributeValue("boots falling stomp",1)
		
		--pyro custom upgrades
		
		elseif upgrade == "Health +50 / -25% OverHealed" then
			activator:SetAttributeValue("hidden maxhealth non buffed",math.min(50*purchased[value]),100)
			activator:SetAttributeValue("patient overheal penalty",math.max(1+(-0.25*purchased[value]),0))
		elseif upgrade == "Weapon Ammo -20%/+50%/Sub Weapon Fire Rate +25%" then
			activator:SetAttributeValue("fire rate penalty",math.max(1+(-0.25*purchased[value]),0.25))
			activator:SetAttributeValue("maxammo primary reduced",math.max(1+(-0.20*purchased[value]),0.4))
			activator:SetAttributeValue("hidden secondary max ammo penalty",math.min(1+(0.5*purchased[value]),2))
		elseif upgrade == "(RARE) Crit DMG +75%/No Medic Healing/Rage -30%" then
			activator:SetAttributeValue("mult crit dmg",math.min(1+(0.75*purchased[value]),4))
			activator:SetAttributeValue("mod weapon blocks healing",1)
			activator:SetAttributeValue("increase buff duration",math.max(1+(-0.3*purchased[value]),0.01))
		elseif upgrade == "(RARE) All Thermal Thruster Mod/Stompy" then
			activator:SetAttributeValue("thermal_thruster_air_launch",1)
			activator:SetAttributeValue("falling_impact_radius_stun",1)
			activator:SetAttributeValue("boots falling stomp",1)
			activator:SetAttributeValue("max health additive penalty",525)
			activator:SetAttributeValue("dmg taken increased",4)
		elseif upgrade == "(FREE) Airblast Override Mod : Efficiency" then
			activator:SetAttributeValue("airblast cost decreased",0.25)
			activator:SetAttributeValue("mult airblast refire time",2)
			activator:SetAttributeValue("airblast pushback scale",1.25)
			 
		elseif upgrade == "(FREE) Airblast Override Mod : Power" then
			activator:SetAttributeValue("airblast cost decreased",0.75)
			activator:SetAttributeValue("mult airblast refire time",1.5)
			activator:SetAttributeValue("airblast pushback scale",2)
			 
		elseif upgrade == "(FREE) Airblast Override Mod : Repressure" then
			activator:SetAttributeValue("airblast cost decreased",0.5)
			activator:SetAttributeValue("mult airblast refire time",0.5)
			activator:SetAttributeValue("airblast pushback scale",0.1)
			 
		elseif upgrade == "[EPIC] Flame Life x4/Gravity" then
			activator:SetAttributeValue("flame_lifetime",3.9)
			activator:SetAttributeValue("flame_up_speed",-100)
		elseif upgrade == "[EPIC] Flame Speed x1.3" then
			activator:SetAttributeValue("flame_drag",-2)
		elseif upgrade == "[EPIC] Flame Speed x0.2 / DMG vs Burning x2" then
			activator:SetAttributeValue("flame_speed",-1900)
			activator:SetAttributeValue("mult_item_meter_charge_rate",2)
			activator:SetAttributeValue("damage bonus vs burning",2)
		elseif upgrade == "[EPIC] DMG vs Non-Burning x2/Reload -150%" then
			activator:SetAttributeValue("dmg penalty vs nonburning",2)
			activator:SetAttributeValue("reload time increased hidden",2.5)
			activator:SetAttributeValue("weapon spread bonus",2)
		elseif upgrade == "[EPIC] Damage x1.7/Flamethrower spin up 0.8s" then
			activator:SetAttributeValue("damage bonus HIDDEN",1.7)
			activator:SetAttributeValue("mod flamethrower spinup time",1)
		elseif upgrade == "[EPIC] Damage x1.5/Flamethrower Ammo Cost x2" then
			activator:SetAttributeValue("dmg penalty vs players",1.5)
			activator:SetAttributeValue("flame ammopersec decreased",2)
		elseif upgrade == "【LEGENDARY】 Very Big Pyro" then
			activator:SetAttributeValue("model scale",1.5)
			activator:SetAttributeValue("max health additive bonus",725)
			activator:SetAttributeValue("damage force increase",0.7)
			activator:SetAttributeValue("major move speed bonus",0.85)
			activator:SetAttributeValue("patient overheal penalty",0.01)
		--demo custom upgrades
		
		elseif upgrade == "Damage +10%/Charge Recharge +75%/Time +1" then
			activator:SetAttributeValue("charge recharge rate increased",math.min(1+(0.75*purchased[value]),4.75))
			activator:SetAttributeValue("charge time increased",math.min(1+(0.5*purchased[value]),5))
			activator:SetAttributeValue("damage bonus HIDDEN",math.min(1+(0.1*purchased[value]),1.5))
		elseif upgrade == "Blast Radius -35% / Damage mult +25%" then
			activator:SetAttributeValue("Blast radius decreased",math.max(1+(-0.35*purchased[value]),0.01))
			activator:SetAttributeValue("damage penalty",math.min(1+(0.25*purchased[value]),2))
		elseif upgrade == "Fire Rate +25% / Secondary Ammo -50%" then
			activator:SetAttributeValue("fire rate penalty",math.max(1+(-0.25*purchased[value]),0.01))
			activator:SetAttributeValue("maxammo secondary reduced",math.max(1+(-0.5*purchased[value]),0.01))
		elseif upgrade == "(FREE) Health +50 / Weapon Ammo -10%/-20%" then
			activator:SetAttributeValue("max health additive bonus",math.min(50*purchased[value],200))
			activator:SetAttributeValue("hidden primary max ammo bonus",math.max(1+(-0.10*purchased[value]),0.6))
			activator:SetAttributeValue("hidden secondary max ammo penalty",math.max(1+(-0.20*purchased[value]),0.2))
			  -- return upgrade point
		elseif upgrade == "(RARE) Shield Control x5 / Push Force -50%" then
			activator:SetAttributeValue("mult charge turn control",math.min(5*purchased[value],10))
			activator:SetAttributeValue("damage force reduction",math.max(1+(-0.5*purchased[value]),0.01))
		elseif upgrade == "(FREE) Movement Speed +10%" then
			activator:SetAttributeValue("move speed bonus",math.min(min+increment*purchased[value],max))
		elseif upgrade == "(RARE) Crit On Kill +5s / -100% Clip Size" then
			activator:SetAttributeValue("critboost on kill",5)
			activator:SetAttributeValue("clip size bonus",0.01)
		elseif upgrade == "[EPIC] Grenade Fuse x0.3 / Detonation DMG x1.5" then
			activator:SetAttributeValue("fuse bonus",0.3)
			activator:SetAttributeValue("grenade detonation damage penalty",3)
		elseif upgrade == "[EPIC] Bazooka/Fire Rate x2/No Melee" then
			activator:SetAttributeValue("auto fires full clip",1)
			activator:SetAttributeValue("stickybomb charge rate",0)
			activator:SetAttributeValue("fire rate penalty HIDDEN",0.5)
		elseif upgrade == "[EPIC] Fire Rate x2 / Sticky Slower Detonate 0.4" then
			activator:SetAttributeValue("sticky arm time penalty",0.4)
			activator:SetAttributeValue("melee attack rate bonus",0.5)
		elseif upgrade == "[EPIC] Ranged Resistance +25% / Jump x2.5" then
			activator:SetAttributeValue("dmg from ranged reduced",0.75)
			activator:SetAttributeValue("increased jump height",2.5)
			activator:SetAttributeValue("bot custom jump particle",1)
		elseif upgrade == "[EPIC] Rolling Grenade Damage x4/Damage x0.8" then
			activator:SetAttributeValue("grenade damage reduction on world contact",4)
			activator:SetAttributeValue("CARD: damage bonus",0.8)
		elseif upgrade == "[EPIC] Sticky Only Stick on Enemies/Projectile Speed x1.5" then
			activator:SetAttributeValue("stickybomb stick to enemies",1)
			activator:SetAttributeValue("stickybomb no stick",1)
			activator:SetAttributeValue("Projectile speed increased",1.5)
		elseif upgrade == "【LEGENDARY】 Nuke" then
			activator:SetAttributeValue("clip size penalty",0.01)
			activator:SetAttributeValue("dmg penalty vs players",3)
			activator:SetAttributeValue("fire rate bonus HIDDEN",7)
			activator:SetAttributeValue("Blast radius increased",1.25)
			activator:SetAttributeValue("clip size upgrade atomic",1)
			activator:SetAttributeValue("override projectile type",17)
			activator:SetAttributeValue("grenade damage reduction on world contact",2)
			activator:SetAttributeValue("use large smoke explosion",1)
		--heavy custom upgrades
		
		elseif upgrade == "Spinup Time +15% / Spun Up Speed +10%" then
			activator:SetAttributeValue("minigun spinup time decreased",math.max(1+(-0.15*purchased[value]),0.55))
			activator:SetAttributeValue("aiming movespeed increased",math.min(1+(0.1*purchased[value]),1.3))
		elseif upgrade == "Consume / Recharge and Switch Faster +40%" then
			activator:SetAttributeValue("charge recharge rate increased",math.max(1+(-0.4*purchased[value]),0.2))
			activator:SetAttributeValue("gesture speed increase",math.max(1+(-0.4*purchased[value]),0.2))
			activator:SetAttributeValue("deploy time increased",0.8)
		elseif upgrade == "(FREE) Heal On Kill +25 health" then
			activator:SetAttributeValue("heal on kill",math.min(25*purchased[value],75))
			  -- return upgrade point{"(FREE) DMG Taken -10% / Fire Rate -10%", "custom",0,1,4},
		elseif upgrade == "(RARE) Damage Mult +25% / Slower Spun up +75%" then
			activator:SetAttributeValue("CARD: damage bonus",math.min(1+(0.25*purchased[value]),1.5))
			activator:SetAttributeValue("minigun spinup time increased",math.max(1+(0.75*purchased[value]),2.5))
		elseif upgrade == "(FREE) DMG Taken -10% / Fire Rate -10%" then
			activator:SetAttributeValue("dmg taken increased",math.max(1+(-0.1*purchased[value]),0.6))
			activator:SetAttributeValue("fire rate penalty HIDDEN",math.min(1+(0.1*purchased[value]),1.4))
		elseif upgrade == "(RARE) Extra Jump +1 Jump Height +20%" then
			activator:SetAttributeValue("air dash count",1)
			activator:SetAttributeValue("increased jump height",1.2)
		elseif upgrade == "(RARE) 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 == "[EPIC] Size Up / +100 Health" then
			activator:SetAttributeValue("model scale",math.min(1+(0.4*purchased[value]),1.4))
			activator:SetAttributeValue("max health additive bonus",math.min(100*purchased[value],100))
			activator:SetAttributeValue("damage force increase",math.max(1+(-0.5*purchased[value]),0.5))
		elseif upgrade == "[EPIC] Damage Mult +25%/Spread -40%/Primary Ammo -25%" then
			activator:SetAttributeValue("spread penalty",math.min(1+(0.4*purchased[value]),1.8))
			activator:SetAttributeValue("damage penalty",math.min(1+(0.25*purchased[value]),1.5))
			activator:SetAttributeValue("hidden primary max ammo bonus",math.max(1+(-0.25*purchased[value]),0.5))
		elseif upgrade == "[EPIC] Override Firing Mod : Single" then
			activator:SetAttributeValue("bullets per shot bonus",0.25)
			activator:SetAttributeValue("damage bonus HIDDEN",3.5)
			activator:SetAttributeValue("weapon spread bonus",0.3)
			activator:SetAttributeValue("projectile penetration",1)
			activator:SetAttributeValue("fire rate penalty",1.2)
			activator:SetAttributeValue("uses ammo while aiming",0)
		elseif upgrade == "[EPIC] Override Firing Mod : Spread" then
			activator:SetAttributeValue("bullets per shot bonus",1.5)
			activator:SetAttributeValue("damage bonus HIDDEN",0.8)
			activator:SetAttributeValue("weapon spread bonus",1.3)
			activator:SetAttributeValue("projectile penetration",0)
			activator:SetAttributeValue("fire rate penalty",1.2)
			activator:SetAttributeValue("uses ammo while aiming",1)
		elseif upgrade == "[EPIC] Override Firing Mod : Focus" then
			activator:SetAttributeValue("bullets per shot bonus",1)
			activator:SetAttributeValue("damage bonus HIDDEN",2)
			activator:SetAttributeValue("weapon spread bonus",0.01)
			activator:SetAttributeValue("projectile penetration",1)
			activator:SetAttributeValue("fire rate penalty",3.5)
			activator:SetAttributeValue("uses ammo while aiming",5)
		elseif upgrade == "[EPIC] Override Firing Mod : Burst" then
			activator:SetAttributeValue("bullets per shot bonus",3)
			activator:SetAttributeValue("damage bonus HIDDEN",1.4)
			activator:SetAttributeValue("weapon spread bonus",1.15)
			activator:SetAttributeValue("projectile penetration",0)
			activator:SetAttributeValue("fire rate penalty",5)
			activator:SetAttributeValue("uses ammo while aiming",5)
		elseif upgrade == "[EPIC] 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 == "[EPIC] Mini-crits to Crits/No Dispenser for Minigun" then
			activator:SetAttributeValue("minicrits become crits",1)
			activator:SetAttributeValue("no primary ammo from dispensers while active",1)
		elseif upgrade == "[EPIC] Fire Rate + on Reduced Health" then
			activator:SetAttributeValue("fire rate bonus with reduced health",1)
			activator:SetAttributeValue("increased jump height",1.2)
		elseif upgrade == "[EPIC] Damage x2 / Above 50% Health x0.8" then
			activator:SetAttributeValue("damage bonus vs burning",2)
			activator:SetAttributeValue("dmg penalty vs nonburning",2)
			activator:SetAttributeValue("dmg penalty while half alive",0.4)
		elseif upgrade == "[EPIC] Ranged Resistance -15%/Heal-on-Hit +1" then
			activator:SetAttributeValue("dmg from ranged reduced",0.85)
			activator:SetAttributeValue("health on radius damage",1)
		elseif upgrade == "【LEGENDARY】 No Spin up" then
			activator:SetAttributeValue("minigun spinup time decreased",0)
			activator:SetAttributeValue("aiming movespeed increased",2.1)
		elseif upgrade == "【LEGENDARY】 Rocket" then
			activator:SetAttributeValue("override projectile type",2)
			activator:SetAttributeValue("dmg penalty vs players",4)
			activator:SetAttributeValue("projectile spread angle penalty",2)
			activator:SetAttributeValue("fire rate bonus HIDDEN",2)
		--engineer custom upgrades
		elseif upgrade == "(RARE) Damage Bonus +50%" then
			activator:SetAttributeValue("damage bonus",math.min(1+(0.5*purchased[value]),3))
			activator:SetAttributeValue("add onhit addammo",math.max(-35*purchased[value],-140))
		elseif upgrade == "Building Health +100%/Repair Rate +20%" then
			activator:SetAttributeValue("engy building health bonus",math.min(1+(1*purchased[value]),6))
			activator:SetAttributeValue("Repair rate increased",math.min(1+(0.2*purchased[value]),2.2))
		elseif upgrade == "(RARE) Teleporter cost -25%/Build Rate +150%" then
			activator:SetAttributeValue("engineer teleporter build rate multiplier",math.min(1+(1.5*purchased[value]),4))
			activator:SetAttributeValue("mod teleporter cost",math.max(1+(-0.25*purchased[value]),0.5))
		elseif upgrade == "(RARE) Upgrade Rate +140%/Building Cost -10%" then
			activator:SetAttributeValue("upgrade rate decrease",math.min(1+(1.4*purchased[value]),8))
			activator:SetAttributeValue("building cost reduction",math.max(1+(-0.1*purchased[value]),0.5))
		elseif upgrade == "[EPIC] Damage Mult x2/Spread x1.6/Primary Ammo -30%" then
			activator:SetAttributeValue("damage bonus vs burning",2)
			activator:SetAttributeValue("dmg penalty vs nonburning",2)
			activator:SetAttributeValue("spread penalty",1.6)
			activator:SetAttributeValue("maxammo primary reduced",0.7)
		elseif upgrade == "[EPIC] Two-Way Teleporter/Instant Recharge" then
			activator:SetAttributeValue("bidirectional teleport",1)
			activator:SetAttributeValue("mod teleporter speed boost",1)
			activator:SetAttributeValue("mult teleporter recharge rate",0.05)
		elseif upgrade == "[EPIC] Energy Weapon Damage x3" then
			activator:SetAttributeValue("damage bonus HIDDEN",0.33)
			activator:SetAttributeValue("dmg penalty vs players",3)
			activator:SetAttributeValue("dmg penalty vs buildings",3)
		elseif upgrade == "[EPIC] Override Sentry Module : Rocket" then
			activator:SetAttributeValue("engy sentry fire rate increased",20)
			activator:SetAttributeValue("mult firerocket rate",0.55)
			activator:SetAttributeValue("rocket specialist",1)
			activator:SetAttributeValue("engy sentry radius increased",1.7)
			activator:SetAttributeValue("engy sentry damage bonus",1.8)
			activator:SetAttributeValue("mvm sentry ammo",1)
			activator:SetAttributeValue("blast dmg to self increased",0.01)
		elseif upgrade == "[EPIC] Override Sentry Module : Gatling" then
			activator:SetAttributeValue("engy sentry fire rate increased",0.5)
			activator:SetAttributeValue("mult firerocket rate",20)
			activator:SetAttributeValue("rocket specialist",0)
			activator:SetAttributeValue("engy sentry radius increased",1.2)
			activator:SetAttributeValue("engy sentry damage bonus",1.2)
			activator:SetAttributeValue("mvm sentry ammo",0.5)
			activator:SetAttributeValue("blast dmg to self increased",1)
		elseif upgrade == "[EPIC] Disposable Sentry +4/Sentry No Repair" then
			activator:SetAttributeValue("Repair rate decreased",0.01)
			activator:SetAttributeValue("engy disposable sentries",4)
			
		--medic custom upgrades
		
		elseif upgrade == "(RARE) Heal Rate +30%/Switch +40%/Blast Res -15%" then
			activator:SetAttributeValue("heal rate bonus",math.min(1+(0.3*purchased[value]),1.9))
			activator:SetAttributeValue("deploy time decreased",math.max(1+(-0.4*purchased[value]),0.01))
			activator:SetAttributeValue("dmg taken from blast increased",math.max(1+(0.15*purchased[value]),0.45))
		elseif upgrade == "(RARE) Damage Mult x1.5/Ranged Resistance +15%" then
			activator:SetAttributeValue("damage penalty",math.min(1+(0.5*purchased[value]),2.5))
			activator:SetAttributeValue("dmg from ranged reduced",math.max(1+(-0.15*purchased[value]),0.55))
		elseif upgrade == "[EPIC] Recall/Damage x2/DMG Taken x1.5 Except Crit" then
			activator:SetAttributeValue("teleport instead of die",1)
			activator:SetAttributeValue("dmg taken increased",1.5)
			activator:SetAttributeValue("dmg taken from crit increased",0.1)
		elseif upgrade == "[EPIC] Recall/Revive Speed x3/No OverHeal" then
			activator:SetAttributeValue("teleport instead of die",1)
			activator:SetAttributeValue("overheal penalty",0)
			activator:SetAttributeValue("revive rate",3)
		elseif upgrade == "[EPIC] Override ÜberCharging : Blank" then
			activator:SetAttributeValue("uber duration bonus",-6)
			activator:SetAttributeValue("ubercharge rate penalty",10)
			activator:SetAttributeValue("increase buff duration",0.7)
		elseif upgrade == "[EPIC] Override ÜberCharging : Extended" then
			activator:SetAttributeValue("uber duration bonus",8)
			activator:SetAttributeValue("ubercharge rate penalty",1)
			activator:SetAttributeValue("increase buff duration",1)
		elseif upgrade == "[EPIC] Override ÜberCharging : Balanced" then
			activator:SetAttributeValue("uber duration bonus",4)
			activator:SetAttributeValue("ubercharge rate penalty",1.3)
			activator:SetAttributeValue("increase buff duration",1)
		elseif upgrade == "[EPIC] No OverHeal Decay/Overheal Rate +100%" then
			activator:SetAttributeValue("overheal decay bonus",50)
			activator:SetAttributeValue("overheal fill rate reduced",2)
		elseif upgrade == "[EPIC] Heal Rate x10/No Shield" then
			activator:SetAttributeValue("heal rate penalty",10)
			activator:SetAttributeValue("increase buff duration HIDDEN",0.01)
			activator:SetAttributeValue("generate rage on heal",0)
			activator:SetAttributeValue("revive rate",0.1)
		elseif upgrade == "[EPIC] Damage x2/Instant OverHeal Decay" then
			activator:SetAttributeValue("damage bonus HIDDEN",2)
			activator:SetAttributeValue("overheal decay penalty",0.01)
		elseif upgrade == "[EPIC] Max Health +200/Health Drain/Milk Syringe" then
			activator:SetAttributeValue("max health additive penalty",200)
			activator:SetAttributeValue("health regen",3)
		    activator:SetAttributeValue("health drain",-12)
		    activator:SetAttributeValue("mad milk syringes",1)
		elseif upgrade == "【LEGENDARY】 Override ÜberCharging : Infinite" then
			activator:SetAttributeValue("uber duration bonus",-4)
			activator:SetAttributeValue("ubercharge rate penalty",50)
			activator:SetAttributeValue("increase buff duration HIDDEN",0.01)
			activator:SetAttributeValue("generate rage on heal",0)
		
		--sniper custom upgrades
		
		elseif upgrade == "Ammo Regen +25%/No Dispenser for Primary" then
			activator:SetAttributeValue("ammo regen",0.25)
			activator:SetAttributeValue("no primary ammo from dispensers while active",1)
		elseif upgrade == "Secondary Clip Size +100%/Ammo +50%" then
			activator:SetAttributeValue("clip size penalty",math.min(1+(1*purchased[value]),4))
			activator:SetAttributeValue("maxammo secondary reduced",math.min(1+(0.5*purchased[value]),2.5))
		elseif upgrade == "(FREE) Damage Taken -25%/Weapon Ammo -25%/-15%" then
			activator:SetAttributeValue("dmg taken increased",math.max(1+(-0.25*purchased[value]),0.25))
			activator:SetAttributeValue("hidden primary max ammo bonus",math.max(1+(-0.25*purchased[value]),0.25))
			activator:SetAttributeValue("hidden secondary max ammo penalty",math.max(1+(-0.15*purchased[value]),0.55))
			  -- return upgrade point
		elseif upgrade == "(FREE) Damage +35%/Switch +40%/Primary Ammo -25%" then
			activator:SetAttributeValue("damage penalty",math.min(1+(0.35*purchased[value]),2.05))
			activator:SetAttributeValue("deploy time decreased",math.max(1+(-0.4*purchased[value]),0.01))
			activator:SetAttributeValue("maxammo primary reduced",math.max(1+(-0.25*purchased[value]),0.01))
			  -- return upgrade point
		elseif upgrade == "(RARE) Spread x1.5 / Fire Rate Bonus +50%" then
			activator:SetAttributeValue("weapon spread bonus",0.10) --prevent spread bonus upgrade from completly negating this penalty
			activator:SetAttributeValue("spread penalty",15)
			activator:SetAttributeValue("fire rate penalty",0.5)
		elseif upgrade == "[EPIC] SMG Headshot/Fire Rate -100%/Damage x1.5" then
			activator:SetAttributeValue("can headshot",1)
			activator:SetAttributeValue("fire rate penalty HIDDEN",2)
			activator:SetAttributeValue("CARD: damage bonus",1.5)
		elseif upgrade == "[EPIC] Override Ammunition Type : Crits" then
			activator:SetAttributeValue("mult crit dmg",3)
			activator:SetAttributeValue("damage bonus HIDDEN",0.75)
			activator:SetAttributeValue("fire rate bonus HIDDEN",2)
			activator:SetAttributeValue("faster reload rate",2.5)
			activator:SetAttributeValue("projectile penetration",1)
		elseif upgrade == "[EPIC] Override Ammunition Type : Snap" then
			activator:SetAttributeValue("mult crit dmg",0.75)
			activator:SetAttributeValue("damage bonus HIDDEN",1.25)
			activator:SetAttributeValue("fire rate bonus HIDDEN",0.8)
			activator:SetAttributeValue("faster reload rate",0.25)
			activator:SetAttributeValue("projectile penetration",0)
		elseif upgrade == "[EPIC] Override Ammunition Type : Heavy" then
			activator:SetAttributeValue("mult crit dmg",0.66)
			activator:SetAttributeValue("damage bonus HIDDEN",2.5)
			activator:SetAttributeValue("fire rate bonus HIDDEN",2)
			activator:SetAttributeValue("faster reload rate",2)
			activator:SetAttributeValue("projectile penetration",1)
		elseif upgrade == "[EPIC] Explosive Headshot/Reload Rate -100%" then
			activator:SetAttributeValue("explosive sniper shot",3)
			activator:SetAttributeValue("reload time increased hidden",2)
		elseif upgrade == "[EPIC] Health +100/No Headshot" then
			activator:SetAttributeValue("sniper no headshots",1)
			activator:SetAttributeValue("hidden maxhealth non buffed",100)
		elseif upgrade == "[EPIC] Projectile Ricochet/Ricochet Damage x2" then
			activator:SetAttributeValue("grenade bounce speed",1)
			activator:SetAttributeValue("grenade bounce damage",2)
		elseif upgrade == "【LEGENDARY】 Armor Piercing" then
			activator:SetAttributeValue("dmg pierces resists absorbs",1)
			activator:SetAttributeValue("mult dmg vs giants",1.5)
		elseif upgrade == "【LEGENDARY】 Override Ammo.T : Explosive" then
			activator:SetAttributeValue("explosive bullets",147)
			activator:SetAttributeValue("mult crit dmg",0.66)
			activator:SetAttributeValue("damage bonus HIDDEN",4)
			activator:SetAttributeValue("faster reload rate",3)
			activator:SetAttributeValue("fire rate bonus HIDDEN",2.5)
			activator:SetAttributeValue("projectile penetration",0)
		--spy custom upgrades
		
		elseif upgrade == "Credit Collect Range +100%/Collect on Kill" then
			activator:SetAttributeValue("mult credit collect range",math.min(1+(1*purchased[value]),3))
			activator:SetAttributeValue("collect currency on kill",1)
		elseif upgrade == "(RARE) Damage +50%/Ammo -35%/Switch +40%" then
			activator:SetAttributeValue("CARD: damage bonus",math.min(1+(0.5*purchased[value]),3))
			activator:SetAttributeValue("hidden primary max ammo bonus",math.max(1+(-0.35*purchased[value]),0.01))
			activator:SetAttributeValue("hidden secondary max ammo penalty",math.max(1+(-0.35*purchased[value]),0.01))
			activator:SetAttributeValue("deploy time decreased",math.max(1+(-0.4*purchased[value]),0.01))
		elseif upgrade == "(RARE) Imitation Upgrade : Scout" then
			activator:SetAttributeValue("major move speed bonus",1.4)
			activator:SetAttributeValue("air dash count",1)
		elseif upgrade == "(RARE) Imitation Upgrade : Medic" then
		    activator:SetAttributeValue("health regen",6)
			activator:SetAttributeValue("add cond on hit",27)
			activator:SetAttributeValue("add cond on hit duration",12)
		elseif upgrade == "(RARE) Imitation Upgrade : Pyro" then
			activator:SetAttributeValue("Set DamageType Ignite",1)
			activator:SetAttributeValue("projectile penetration",1)
		elseif upgrade == "(RARE) Imitation Upgrade : Soldier" then
			activator:SetAttributeValue("explosive bullets",100)
			activator:SetAttributeValue("rocket jump damage reduction",0.6)
		elseif upgrade == "[EPIC] Sapper Damage/Health +100%" then
			activator:SetAttributeValue("sapper health bonus",math.min(1+(1*purchased[value]),3))
			activator:SetAttributeValue("sapper damage bonus",math.min(1+(1*purchased[value]),3))
		elseif upgrade == "[EPIC] Override Imitation : Demo" then
			activator:SetAttributeValue("damage penalty",3)
			activator:SetAttributeValue("reload time increased hidden",3)
			activator:SetAttributeValue("fire rate penalty",1)
			activator:SetAttributeValue("clip size penalty",0.5)
			activator:SetAttributeValue("maxammo secondary reduced",0.9)
			activator:SetAttributeValue("weapon spread bonus",1)
			activator:SetAttributeValue("bullets per shot bonus",1)
			activator:SetAttributeValue("blast dmg to self increased",2)
			activator:SetAttributeValue("explosive bullets",200)
		elseif upgrade == "[EPIC] Override Imitation : Sniper" then
			activator:SetAttributeValue("damage penalty",3.5)
			activator:SetAttributeValue("reload time increased hidden",1)
			activator:SetAttributeValue("fire rate penalty",1)
			activator:SetAttributeValue("clip size penalty",0.17)
			activator:SetAttributeValue("maxammo secondary reduced",0.8)
			activator:SetAttributeValue("weapon spread bonus",0.05)
			activator:SetAttributeValue("bullets per shot bonus",1)
			activator:SetAttributeValue("explosive bullets",0)
			activator:SetAttributeValue("no damage falloff",1)
		elseif upgrade == "[EPIC] Override Imitation : Engineer" then
			activator:SetAttributeValue("damage penalty",0.2)
			activator:SetAttributeValue("reload time increased hidden",3)
			activator:SetAttributeValue("fire rate penalty",1)
			activator:SetAttributeValue("clip size penalty",1)
			activator:SetAttributeValue("maxammo secondary reduced",2)
			activator:SetAttributeValue("weapon spread bonus",4)
			activator:SetAttributeValue("bullets per shot bonus",9)
		elseif upgrade == "[EPIC] Fire rate +50%/Spread x7/Damage x2" then
			activator:SetAttributeValue("fire rate bonus",0.5)
			activator:SetAttributeValue("spread penalty",7)
			activator:SetAttributeValue("damage bonus HIDDEN",2)
		elseif upgrade == "[EPIC] DMG Taken -35%/Crit Damage -80%" then
			activator:SetAttributeValue("dmg taken increased",0.65)
			activator:SetAttributeValue("mult crit dmg",0.2)
		elseif upgrade == "[EPIC] Faster Decloak/Cloak Res +90%/Duration -50%" then
			activator:SetAttributeValue("mult cloak rate",-0.9)
			activator:SetAttributeValue("mult cloak meter consume rate",2)
			activator:SetAttributeValue("mult cloak meter regen rate",2)
			activator:SetAttributeValue("absorb damage while cloaked",0.9)
		elseif upgrade == "[EPIC] Melee Deflect/Bullet Resistance +20%" then
			activator:SetAttributeValue("melee airblast",1)
			activator:SetAttributeValue("dmg taken from bullets increased",0.8)
		elseif upgrade == "【LEGENDARY】 Override Imitation : Heavy" then
			activator:SetAttributeValue("damage penalty",0.2)
			activator:SetAttributeValue("reload time increased hidden",0.01)
			activator:SetAttributeValue("fire rate penalty",0.2)
			--activator:SetAttributeValue("clip size penalty",30)
			activator:SetAttributeValue("maxammo secondary reduced",7)
			activator:SetAttributeValue("weapon spread bonus",3)
			activator:SetAttributeValue("bullets per shot bonus",4)
			--activator:SetAttributeValue("mult crit dmg",0.2)
		end
	elseif attributename ~= "custom" then
		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

--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()
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

	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
	AddUpgradePoints(3)
	AddRerollPoints(1)
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
	if WaveState[wave] == nil then
		WaveState[wave] =
		{
			TotalUpgradePoints = TotalUpgradePoints,
			TotalRerollPoints = TotalRerollPoints,
			UniqueAccountIDs = deepCopy(UniqueAccountIDs)
		}
	end
	ResetRolls()
end