
--Made by Wacev
--I used the build-a-bot script as a *template* for the enemy spawning logic

--[[----------------+
	MISC VARS
+------------------]]--

Global = ents.FindByClass( "tf_gamerules" )

PlayerTable = {}
PlayerCount = 0

if Global.NewSpawns ~= nil then
	if ARENA_SPAWNS ~= Global.NewSpawns then
		ARENA_SPAWNS = Global.NewSpawns
	end
	Global.NewSpawns = nil
end

buildings = {
	obj_sentrygun  = 1,
	obj_dispenser  = 2,
	obj_teleporter = 3
}

LOADOUT_POSITION_BODY = -1
LOADOUT_POSITION_PRIMARY_AND_SECONDARY = -2

--[[----------------+
	WAVE VARS
+------------------]]--

WAVE = 0
TotalCount = 0
SpawnTimer = nil
InWave = false
InWave = false
WaveStarted = false
GLOBAL_CASH_MULT = 1 
VARIANT_CHANCE = 0.05
SHOP_WAVE = false
ARENA = 1
ARENA_SPAWNS = {
	[1] = {
		{ pos = Vector(1400, -311, 0), teamnum = 3 },
		{ pos = Vector(1200, -311, 0), teamnum = 3 },
		{ pos = Vector(1000, -311, 0), teamnum = 3 },
		{ pos = Vector(800, -311, 0), teamnum = 3 },
		{ pos = Vector(600, -311, 0), teamnum = 3 },
		-- { pos = Vector(1695, -338, 320), teamnum = 3 },
		-- { pos = Vector(1895, -338, 320), teamnum = 3 },
		{ pos = Vector(345, -353, 128), teamnum = 3 },
		{ pos = Vector(2280, -889, 0), teamnum = 3 },
		{ pos = Vector(2280, -889, 0), teamnum = 3 },
		{ pos = Vector(2280, -889, 0), teamnum = 3 },
		
		{ pos = Vector(1116, -2333, 64), teamnum = 2 },
		{ pos = Vector(1034, -2333, 64), teamnum = 2 },
		{ pos = Vector(952, -2333, 64), teamnum = 2 },
	},
	[2] = {
		{ pos = Vector(3422, -1688, -629), teamnum = 3 },
		{ pos = Vector(3436, -1523, -634), teamnum = 3 },
		{ pos = Vector(3453, -1306, -641), teamnum = 3 },
		{ pos = Vector(3681, -1324, -644), teamnum = 3 },
		{ pos = Vector(3664, -1543, -634), teamnum = 3 },
		{ pos = Vector(3649, -1731, -618), teamnum = 3 },
		-- { pos = Vector(1934, -1404, -634), teamnum = 3 },
		-- { pos = Vector(1939, -1523, -639), teamnum = 3 },
		-- { pos = Vector(1790, -1529, -632), teamnum = 3 },
		-- { pos = Vector(1784, -1387, -633), teamnum = 3 },
		
		{ pos = Vector(2272, 1141, -128), teamnum = 2 },
		{ pos = Vector(2276, 1065, -128), teamnum = 2 },
		{ pos = Vector(2281, 957, -128), teamnum = 2 },
	},
	[3] = {
		{ pos = Vector(-3966, -2765, -206), teamnum = 3 },
		{ pos = Vector(-3696, 712, -393), teamnum = 3 },
		
		{ pos = Vector(-600, -1369, -824), teamnum = 2 },
		{ pos = Vector(-603, -1256, -831), teamnum = 2 },
		{ pos = Vector(-606, -1135, -831), teamnum = 2 },
	},
}

WAVE_TYPE_STANDARD = 1
WAVE_TYPE_HORDE = 2
WAVE_TYPE_CURRENT = WAVE_TYPE_STANDARD
WAVE_TYPE_CHANCE_TABLE = {
	[WAVE_TYPE_STANDARD] = 1,
	[WAVE_TYPE_HORDE] = 0.15,
}
WAVE_HORDE_DURATION = 30
WAVE_DURATION = 0

-- DEV FUNCTIONS {{

function AddPosToSpawns( _, activator )
	table.insert( ARENA_SPAWNS[ARENA], { pos = activator:GetAbsOrigin(), teamnum = activator.m_iTeamNum } )
end
function GetSpawns()
	PrintTable( ARENA_SPAWNS )
end
function CopySpawns()
	Global.NewSpawns = ARENA_SPAWNS
end

function TestToggleShop() 
	for _, player in pairs( ents.GetAllPlayers() ) do
		if player.InShop == false then
			player.InShop = true
		else
			player.InShop = false
		end
	end
end

function GiveUpgrade( index, dev )
	UpgradeBrought( dev, 1, index )
end

-- }}

MODIFY_VARIANT_CHANCE = 1
MODIFY_VOTE_OPTIONS = 2
MODIFY_ENEMY_GLOBALCASH = 3
MODIFY_ENEMY_MULT = 4
MODIFY_ENEMY_GOLDEN_CHANCE = 5
MODIFY_ENEMY_MAX_GIANTS = 6

ENCOUNTER_MODIFY_STATS = {
	[MODIFY_VARIANT_CHANCE] = 1,
	[MODIFY_VOTE_OPTIONS] = 0,
	[MODIFY_ENEMY_GLOBALCASH] = 1,
	[MODIFY_ENEMY_MULT] = 1,
	[MODIFY_ENEMY_GOLDEN_CHANCE] = 0,
	[MODIFY_ENEMY_MAX_GIANTS] = 1,
}

VOTING = false
VOTE_OPTIONS = 3
VOTE_RESULTS = {}
VOTE_MENU = nil

--[[----------------+
	UPGRADES
+------------------]]--

UPGRADE_COMMON_CHANCE = 0.70
UPGRADE_UNCOMMON_CHANCE = 0.2
UPGRADE_RARE_CHANCE = 0.07
UPGRADE_EPIC_CHANCE = 0.02
UPGRADE_LEGENDARY_CHANCE = 0.01

UPGRADE_GREED_CHANCE = 0.78
UPGRADE_GREED_RARE_CHANCE = 0.13
UPGRADE_GREED_EPIC_CHANCE = 0.07
UPGRADE_GREED_LEGENDARY_CHANCE = 0.02

UPGRADE_SHOP_COMMON_CHANCE = 0.55
UPGRADE_SHOP_UNCOMMON_CHANCE = 0.2
UPGRADE_SHOP_RARE_CHANCE = 0.1
UPGRADE_SHOP_GREED_CHANCE = 0.08
UPGRADE_SHOP_EPIC_CHANCE = 0.05
UPGRADE_SHOP_LEGENDARY_CHANCE = 0.02

UPGRADE_TYPE_COMMON = 0
UPGRADE_TYPE_UNCOMMON = 1
UPGRADE_TYPE_RARE = 2
UPGRADE_TYPE_EPIC = 3
UPGRADE_TYPE_LEGENDARY = 4
UPGRADE_TYPE_GREED = 5

UPGRADE_COST_COMMON_BASE = 100
UPGRADE_COST_UNCOMMON_BASE = 125
UPGRADE_COST_RARE_BASE = 180
UPGRADE_COST_EPIC_BASE = 275
UPGRADE_COST_LEGENDARY_BASE = 600
UPGRADE_COST_GREED_BASE = 400
UPGRADE_COST_RAMP_COEF = 1.05 -- math.floor( COST * ( ( WAVE - 1 )^UPGRADE_COST_RAMP_COEF ) )

UpgradeChances = {
	[UPGRADE_TYPE_COMMON] = UPGRADE_COMMON_CHANCE, 
	[UPGRADE_TYPE_UNCOMMON] = UPGRADE_UNCOMMON_CHANCE, 
	[UPGRADE_TYPE_RARE] = UPGRADE_RARE_CHANCE, 
	[UPGRADE_TYPE_EPIC] = UPGRADE_EPIC_CHANCE, 
	[UPGRADE_TYPE_LEGENDARY] = UPGRADE_LEGENDARY_CHANCE
}

UpgradeChancesEPIC = {
	[UPGRADE_TYPE_EPIC] = 1 - UPGRADE_LEGENDARY_CHANCE, 
	[UPGRADE_TYPE_LEGENDARY] = UPGRADE_LEGENDARY_CHANCE
}

UpgradeChancesGREED = {
	[UPGRADE_TYPE_GREED] = UPGRADE_GREED_CHANCE, 
	[UPGRADE_TYPE_RARE] = UPGRADE_GREED_RARE_CHANCE, 
	[UPGRADE_TYPE_EPIC] = UPGRADE_GREED_EPIC_CHANCE, 
	[UPGRADE_TYPE_LEGENDARY] = UPGRADE_GREED_LEGENDARY_CHANCE
}

UpgradeChancesSHOP = {
	[UPGRADE_TYPE_COMMON] = UPGRADE_SHOP_COMMON_CHANCE, 
	[UPGRADE_TYPE_UNCOMMON] = UPGRADE_SHOP_UNCOMMON_CHANCE, 
	[UPGRADE_TYPE_RARE] = UPGRADE_SHOP_RARE_CHANCE, 
	[UPGRADE_TYPE_EPIC] = UPGRADE_SHOP_EPIC_CHANCE, 
	[UPGRADE_TYPE_LEGENDARY] = UPGRADE_SHOP_LEGENDARY_CHANCE, 
	[UPGRADE_TYPE_GREED] = UPGRADE_SHOP_GREED_CHANCE,
}

UPGRADE_LOOT_COMMON = 0
UPGRADE_LOOT_GREED = 1
UPGRADE_LOOT_EPIC = 2
UPGRADE_LOOT_SHOP = 3

UPGRADE_TYPE_TABLE = {
	[UPGRADE_TYPE_COMMON] = "Common",
	[UPGRADE_TYPE_UNCOMMON] = "Uncommon",
	[UPGRADE_TYPE_RARE] = "Rare",
	[UPGRADE_TYPE_EPIC] = "Epic",
	[UPGRADE_TYPE_LEGENDARY] = "Legendary",
	[UPGRADE_TYPE_GREED] = "GREED",
}

UPGRADE_LOOT_TABLE = {
	[UPGRADE_LOOT_COMMON] = UpgradeChances,
	[UPGRADE_LOOT_GREED] = UpgradeChancesGREED,
	[UPGRADE_LOOT_EPIC] = UpgradeChancesEPIC,
	[UPGRADE_LOOT_SHOP] = UpgradeChancesSHOP,
}

UPGRADE_COST_TABLE = {
	[UPGRADE_TYPE_COMMON] = UPGRADE_COST_COMMON_BASE,
	[UPGRADE_TYPE_UNCOMMON] = UPGRADE_COST_UNCOMMON_BASE,
	[UPGRADE_TYPE_RARE] = UPGRADE_COST_RARE_BASE,
	[UPGRADE_TYPE_EPIC] = UPGRADE_COST_EPIC_BASE,
	[UPGRADE_TYPE_LEGENDARY] = UPGRADE_COST_LEGENDARY_BASE,
	[UPGRADE_TYPE_GREED] = UPGRADE_COST_GREED_BASE,
}

COMMANDS_TABLE = { "!Upgrades", "/Upgrades" }


UPGRADE_DEFAULT_COUNT = 3
UPGRADE_DEFAULT_MAX_REROLLS = 1
UPGRADE_SKIP_BONUS = 250
UPGRADE_REROLL = -1
UPGRADE_REROLL_COST = 10
UPGRADE_REROLL_COST_RAMP_COEF = 1.15

UPGRADE_CATEGORY_ALL = 0
UPGRADE_CATEGORY_DAMAGE = 1
UPGRADE_CATEGORY_SPEED = 2
UPGRADE_CATEGORY_HEALTH = 3
UPGRADE_CATEGORY_MONEY = 4
UPGRADE_CATEGORY_GREED = 5
UPGRADE_CATEGORY_EPIC = 6
UPGRADE_CATEGORY_ELITE_BOSS = 7
UPGRADE_CATEGORY_SHOP = 8
UPGRADE_CATEGORY_WEAPON = 9

UPGRADE_LOOT_CATEGORY = UPGRADE_CATEGORY_ALL
VOTE_CATEGORIES = {
	[UPGRADE_CATEGORY_ALL] = { name = "Random Loot", Weight = 0.65 },
	[UPGRADE_CATEGORY_DAMAGE] = { name = "Damage", Weight = 1 },
	[UPGRADE_CATEGORY_SPEED] = { name = "Speed", Weight = 1 },
	[UPGRADE_CATEGORY_HEALTH] = { name = "Health", Weight = 0.85 },
	[UPGRADE_CATEGORY_MONEY] = { name = "Money", Weight = 0.75 },
	[UPGRADE_CATEGORY_GREED] = { name = "GREED", Weight = 0.4 },
	[UPGRADE_CATEGORY_EPIC] = { name = "Random Epic", Weight = 0.3 },
	[UPGRADE_CATEGORY_ELITE_BOSS] = { name = "Elite Fight", Weight = 0 },
	[UPGRADE_CATEGORY_SHOP] = { name = "Shop!", Weight = 0 },
	[UPGRADE_CATEGORY_WEAPON] = { name = "Weapon", Weight = 1 },
}

--Common
UPGRADE_COMMON_DMG = 0
UPGRADE_COMMON_DMG_CRIT_RATE = 2
UPGRADE_COMMON_DMG_CRIT_DAMAGE = 3
UPGRADE_COMMON_DMG_BULLETS_PER_SHOT = 4
UPGRADE_COMMON_DMG_AT_CLOSE = 5
UPGRADE_COMMON_DMG_MELEE = 6
UPGRADE_COMMON_DMG_JARATE_SHOT = 7
UPGRADE_COMMON_DMG_BURN = 8
UPGRADE_COMMON_DMG_BLEED = 9

UPGRADE_COMMON_SPEED_FIRERATE = 1
UPGRADE_COMMON_SPEED_MOVESPEED = 10
UPGRADE_COMMON_SPEED_PROJSPEED = 11
UPGRADE_COMMON_SPEED_DEPLOYSPEED = 12
UPGRADE_COMMON_SPEED_SLOW_ON_HIT = 13
UPGRADE_COMMON_SPEED_RECHARGE_RATE = 31

UPGRADE_COMMON_WEAPON_CLIPSIZE = 14
UPGRADE_COMMON_WEAPON_RESERVEAMMO = 15
UPGRADE_COMMON_WEAPON_AMMOREGEN = 16
UPGRADE_COMMON_WEAPON_BLAST_RADIUS = 17
UPGRADE_COMMON_WEAPON_SPREAD = 18
UPGRADE_COMMON_WEAPON_MELEE_RANGE = 19

UPGRADE_COMMON_HEALTH_BONUS = 20
UPGRADE_COMMON_HEALTH_MULT = 21
UPGRADE_COMMON_HEALTH_REGEN = 22
UPGRADE_COMMON_HEALTH_HOK = 23
UPGRADE_COMMON_HEALTH_MELEE_AOE = 24
UPGRADE_COMMON_HEALTH_RECEIVED = 25
UPGRADE_COMMON_HEALTH_MILKY = 26

UPGRADE_COMMON_MONEY_INCOME = 27
UPGRADE_COMMON_MONEY_GOLDEN_ENEMIES = 28
UPGRADE_COMMON_MONEY_WIRE_TAP = 29
UPGRADE_COMMON_MONEY_DISCOUNT = 30

UPGRADE_COMMON_WEAPON_PENETRATION = 31

UPGRADE_COMMON_HEALTH_BUILDING = 32
UPGRADE_COMMON_HEALTH_DISPENSER_RATE = 33

UPGRADE_COMMON_DMG_SENTRY_DMG = 34

UPGRADE_COMMON_SPEED_SENTRY_FIRERATE = 35
UPGRADE_COMMON_SPEED_TELEPORTERRECHARGE = 36
UPGRADE_COMMON_SPEED_CONSTRUCTION = 37
UPGRADE_COMMON_SPEED_SENTRY_ROCKET = 38

UPGRADE_COMMON_WEAPON_SENTRY_RANGE = 39
UPGRADE_COMMON_WEAPON_SENTRY_AMMO = 40

UPGRADE_COMMON_HEALTH_HEALRATE = 41
UPGRADE_COMMON_HEALTH_OVERHEAL = 42

UPGRADE_COMMON_SPEED_OVERHEAL_DECAY = 43
UPGRADE_COMMON_SPEED_OVERHEAL_RATE = 44

UPGRADE_COMMON_WEAPON_MEDIGUN_RANGE = 45
UPGRADE_COMMON_WEAPON_MEDIGUN_UBERRATE = 46
UPGRADE_COMMON_WEAPON_MEDIGUN_UBERDURATION = 47

UPGRADE_COMMON_WEAPON_EFFECT_DURATION = 48
UPGRADE_COMMON_WEAPON_BANNER_EFFECT_DURATION = 49
UPGRADE_COMMON_WEAPON_BANNER_EFFECT_RANGE = 50
UPGRADE_COMMON_WEAPON_FLAME_RANGE = 51

UPGRADE_COMMON_SPEED_AFTERBURN_RATE = 52

UPGRADE_COMMON_SPEED_STICKY_CHARGE = 53
UPGRADE_COMMON_SPEED_SHIELD_CHARGE = 54
UPGRADE_COMMON_SPEED_SHIELD_KBRES = 55

UPGRADE_COMMON_DMG_SHIELD_IMPACT = 56

UPGRADE_COMMON_SPEED_MINIGUN_SPINUP = 57

UPGRADE_COMMON_HEALTH_LUNCHBOX = 58

UPGRADE_COMMON_SPEED_SNIPER_CHARGERATE = 59

UPGRADE_COMMON_DMG_REVOLVER_DISGUISED = 60

UPGRADE_COMMON_SPEED_CLOAKREGEN = 61
UPGRADE_COMMON_SPEED_CLOAKDURATION = 62
UPGRADE_COMMON_SPEED_CLOAKSPEED = 63

UPGRADE_COMMON_WEAPON_SAPPER = 64
UPGRADE_COMMON_WEAPON_TWOWAY = 65
UPGRADE_COMMON_WEAPON_METALAMMO = 66

UPGRADE_COMMON_DMG_FIREARROWS = 67
UPGRADE_COMMON_WEAPON_METALAMMO2 = 68
UPGRADE_COMMON_WEAPON_PARACHUTE_REDEPLOY = 69

UPGRADE_COMMON_SPEED_PARACHUTE_AIRCONTROL = 70
UPGRADE_COMMON_SPEED_PARACHUTE_FALLSPEED = 71
UPGRADE_COMMON_SPEED_JETPACK_RELAUNCH = 72

UPGRADE_COMMON_WEAPON_GUNSLINGER_SENTRIES = 73
UPGRADE_COMMON_WEAPON_SYDNEY_RADIUSSLEEPER = 74
UPGRADE_COMMON_WEAPON_SYDNEY_MAXDURATION = 75

UPGRADE_COMMON_DMG_MACHINA_DMG = 76
UPGRADE_COMMON_DMG_AMBIE_NOFALLOFF = 77

UPGRADE_COMMON_SPEED_SPYCICLE_COOLDOWN = 78

UPGRADE_COMMON_HEALTH_SPYCICLE_DURATION = 79
UPGRADE_COMMON_WEAPON_HUO_AMMODRAIN = 80
UPGRADE_COMMON_WEAPON_MITTEN_ALWAYSCRIT = 81
UPGRADE_COMMON_SPEED_GRU_EVIC_DRAINRATE = 82

--Uncommon
UPGRADE_UNCOMMON_DMG = 1000
UPGRADE_UNCOMMON_DMG_CRIT_RATE = 1002
UPGRADE_UNCOMMON_DMG_CRIT_DAMAGE = 1003
UPGRADE_UNCOMMON_DMG_BULLETS_PER_SHOT = 1004
UPGRADE_UNCOMMON_DMG_AT_CLOSE = 1005
UPGRADE_UNCOMMON_DMG_MELEE = 1006
UPGRADE_UNCOMMON_DMG_JARATE_SHOT = 1007
UPGRADE_UNCOMMON_DMG_BURN = 1008
UPGRADE_UNCOMMON_DMG_BLEED = 1009

UPGRADE_UNCOMMON_SPEED_FIRERATE = 1001
UPGRADE_UNCOMMON_SPEED_MOVESPEED = 1010
UPGRADE_UNCOMMON_SPEED_PROJSPEED = 1011
UPGRADE_UNCOMMON_SPEED_DEPLOYSPEED = 1012
UPGRADE_UNCOMMON_SPEED_SLOW_ON_HIT = 1013
UPGRADE_UNCOMMON_SPEED_RECHARGE_RATE = 1034

UPGRADE_UNCOMMON_WEAPON_CLIPSIZE = 1014
UPGRADE_UNCOMMON_WEAPON_RESERVEAMMO = 1015
UPGRADE_UNCOMMON_WEAPON_AMMOREGEN = 1016
UPGRADE_UNCOMMON_WEAPON_BLAST_RADIUS = 1017
UPGRADE_UNCOMMON_WEAPON_SPREAD = 1018
UPGRADE_UNCOMMON_WEAPON_MELEE_RANGE = 1019

UPGRADE_UNCOMMON_HEALTH_BONUS = 1020
UPGRADE_UNCOMMON_HEALTH_MULT = 1021
UPGRADE_UNCOMMON_HEALTH_REGEN = 1022
UPGRADE_UNCOMMON_HEALTH_HOK = 1023
UPGRADE_UNCOMMON_HEALTH_MELEE_AOE = 1024
UPGRADE_UNCOMMON_HEALTH_RECEIVED = 1025
UPGRADE_UNCOMMON_HEALTH_MILKY = 1026

UPGRADE_UNCOMMON_MONEY_INCOME = 1027
UPGRADE_UNCOMMON_MONEY_GOLDEN_ENEMIES = 1028
UPGRADE_UNCOMMON_MONEY_WIRE_TAP = 1029
UPGRADE_UNCOMMON_MONEY_LARGER_SHOPS = 1030
UPGRADE_UNCOMMON_MONEY_REROLLS = 1031

UPGRADE_UNCOMMON_HEALTH_AOE_HEAL = 1032
UPGRADE_UNCOMMON_HEALTH_FIGHT_INCREASE = 1033

UPGRADE_UNCOMMON_WEAPON_PENETRATION = 1034

UPGRADE_UNCOMMON_HEALTH_BUILDING = 1035
UPGRADE_UNCOMMON_HEALTH_DISPENSER_RATE = 1036

UPGRADE_UNCOMMON_DMG_SENTRY_DMG = 1037

UPGRADE_UNCOMMON_SPEED_SENTRY_FIRERATE = 1038
UPGRADE_UNCOMMON_SPEED_TELEPORTERRECHARGE = 1039
UPGRADE_UNCOMMON_SPEED_CONSTRUCTION = 1040
UPGRADE_UNCOMMON_SPEED_SENTRY_ROCKET = 1041

UPGRADE_UNCOMMON_WEAPON_SENTRY_RANGE = 1042
UPGRADE_UNCOMMON_WEAPON_SENTRY_AMMO = 1043

UPGRADE_UNCOMMON_HEALTH_HEALRATE = 1044
UPGRADE_UNCOMMON_HEALTH_OVERHEAL = 1045

UPGRADE_UNCOMMON_SPEED_OVERHEAL_DECAY = 1046
UPGRADE_UNCOMMON_SPEED_OVERHEAL_RATE = 1047

UPGRADE_UNCOMMON_WEAPON_MEDIGUN_RANGE = 1048
UPGRADE_UNCOMMON_WEAPON_MEDIGUN_UBERRATE = 1049
UPGRADE_UNCOMMON_WEAPON_MEDIGUN_UBERDURATION = 1050

UPGRADE_UNCOMMON_WEAPON_EFFECT_DURATION = 1051
UPGRADE_UNCOMMON_WEAPON_BANNER_EFFECT_DURATION = 1052
UPGRADE_UNCOMMON_WEAPON_BANNER_EFFECT_RANGE = 1053
UPGRADE_UNCOMMON_WEAPON_FLAME_RANGE = 1054

UPGRADE_UNCOMMON_SPEED_AFTERBURN_RATE = 1055

UPGRADE_UNCOMMON_SPEED_STICKY_CHARGE = 1056
UPGRADE_UNCOMMON_SPEED_SHIELD_CHARGE = 1057
UPGRADE_UNCOMMON_SPEED_SHIELD_KBRES = 1058

UPGRADE_UNCOMMON_DMG_SHIELD_IMPACT = 1059

UPGRADE_UNCOMMON_SPEED_MINIGUN_SPINUP = 1060

UPGRADE_UNCOMMON_HEALTH_LUNCHBOX = 1061

UPGRADE_UNCOMMON_SPEED_SNIPER_CHARGERATE = 1062

UPGRADE_UNCOMMON_DMG_REVOLVER_DISGUISED = 1063

UPGRADE_UNCOMMON_SPEED_CLOAKREGEN = 1064
UPGRADE_UNCOMMON_SPEED_CLOAKDURATION = 1065
UPGRADE_UNCOMMON_SPEED_CLOAKRATE = 1066
UPGRADE_UNCOMMON_SPEED_CLOAKSPEED = 1067

UPGRADE_UNCOMMON_SPEED_TELEPORTER_SPEEDBOOST = 1068

UPGRADE_UNCOMMON_WEAPON_FLAME_RICOCHET = 1069

UPGRADE_UNCOMMON_HEALTH_SHIELD_BULLETRES = 1070

UPGRADE_UNCOMMON_WEAPON_ARROW_PEN = 1071

UPGRADE_UNCOMMON_DMG_REVOLVER_CRIT = 1072

UPGRADE_UNCOMMON_WEAPON_REVOLVER_UBERDRAIN = 1073
UPGRADE_UNCOMMON_WEAPON_SAPPER_MARK = 1074
UPGRADE_UNCOMMON_WEAPON_METALGAIN = 1075

UPGRADE_UNCOMMON_DMG_EOI = 1076

UPGRADE_UNCOMMON_SPEED_PARACHUTE_XYSPEED = 1077

UPGRADE_UNCOMMON_WEAPON_JETPACKSTUN = 1078
UPGRADE_UNCOMMON_WEAPON_LOCH_IMPACTEXP = 1079
UPGRADE_UNCOMMON_WEAPON_SNIPER_EH = 1080

UPGRADE_UNCOMMON_DMG_MACHINA_DMG = 1081
UPGRADE_UNCOMMON_DMG_AMBIE_NOCOOLDOWN = 1082
UPGRADE_UNCOMMON_DMG_HUO_RINGDAMAGE = 1083

UPGRADE_UNCOMMON_HEALTH_FOS_MELEERES = 1084

--Rare
UPGRADE_RARE_DMG = 2000
UPGRADE_RARE_DMG_CRIT_RATE = 2002
UPGRADE_RARE_DMG_CRIT_DAMAGE = 2003
UPGRADE_RARE_DMG_BULLETS_PER_SHOT = 2004
UPGRADE_RARE_DMG_AT_CLOSE = 2005
UPGRADE_RARE_DMG_MELEE = 2006
UPGRADE_RARE_DMG_JARATE_SHOT = 2007
UPGRADE_RARE_DMG_BURN = 2008
UPGRADE_RARE_DMG_BLEED = 2009

UPGRADE_RARE_SPEED_FIRERATE = 2001
UPGRADE_RARE_SPEED_MOVESPEED = 2010
UPGRADE_RARE_SPEED_PROJSPEED = 2011
UPGRADE_RARE_SPEED_DEPLOYSPEED = 2012
UPGRADE_RARE_SPEED_SLOW_ON_HIT = 2013
UPGRADE_RARE_SPEED_RECHARGE_RATE = 2034

UPGRADE_RARE_WEAPON_CLIPSIZE = 2014
UPGRADE_RARE_WEAPON_RESERVEAMMO = 2015
UPGRADE_RARE_WEAPON_AMMOREGEN = 2016
UPGRADE_RARE_WEAPON_BLAST_RADIUS = 2017
UPGRADE_RARE_WEAPON_SPREAD = 2018
UPGRADE_RARE_WEAPON_MELEE_RANGE = 2019

UPGRADE_RARE_HEALTH_BONUS = 2020
UPGRADE_RARE_HEALTH_MULT = 2021
UPGRADE_RARE_HEALTH_REGEN = 2022
UPGRADE_RARE_HEALTH_HOK = 2023
UPGRADE_RARE_HEALTH_MELEE_AOE = 2024
UPGRADE_RARE_HEALTH_RECEIVED = 2025
UPGRADE_RARE_HEALTH_MILKY = 2026

UPGRADE_RARE_MONEY_INCOME = 2027
UPGRADE_RARE_MONEY_GOLDEN_ENEMIES = 2028
UPGRADE_RARE_MONEY_WIRE_TAP = 2029
UPGRADE_RARE_MONEY_DISCOUNT = 2030

UPGRADE_RARE_DMG_MELEE_MARK = 2031

UPGRADE_RARE_SPEED_PARTY = 2032

UPGRADE_RARE_WEAPON_MELEE_CLEAVE = 2033

UPGRADE_RARE_WEAPON_PENETRATION = 2034

UPGRADE_RARE_HEALTH_BUILDING = 2035
UPGRADE_RARE_HEALTH_DISPENSER_RATE = 2036

UPGRADE_RARE_DMG_SENTRY_DMG = 2037

UPGRADE_RARE_SPEED_SENTRY_FIRERATE = 2038
UPGRADE_RARE_SPEED_TELEPORTERRECHARGE = 2039
UPGRADE_RARE_SPEED_CONSTRUCTION = 2040
UPGRADE_RARE_SPEED_SENTRY_ROCKET = 2041

UPGRADE_RARE_WEAPON_SENTRY_RANGE = 2042
UPGRADE_RARE_WEAPON_SENTRY_AMMO = 2043

UPGRADE_RARE_HEALTH_HEALRATE = 2044
UPGRADE_RARE_HEALTH_OVERHEAL = 2045

UPGRADE_RARE_SPEED_OVERHEAL_DECAY = 2046
UPGRADE_RARE_SPEED_OVERHEAL_RATE = 2047

UPGRADE_RARE_WEAPON_MEDIGUN_RANGE = 2048
UPGRADE_RARE_WEAPON_MEDIGUN_UBERRATE = 2049
UPGRADE_RARE_WEAPON_MEDIGUN_UBERDURATION = 2050

UPGRADE_RARE_WEAPON_EFFECT_DURATION = 2051
UPGRADE_RARE_WEAPON_BANNER_EFFECT_DURATION = 2052
UPGRADE_RARE_WEAPON_BANNER_EFFECT_RANGE = 2053
UPGRADE_RARE_WEAPON_FLAME_RANGE = 2054

UPGRADE_RARE_SPEED_AFTERBURN_RATE = 2055

UPGRADE_RARE_SPEED_STICKY_CHARGE = 2056
UPGRADE_RARE_SPEED_SHIELD_CHARGE = 2057
UPGRADE_RARE_SPEED_SHIELD_KBRES = 2058

UPGRADE_RARE_DMG_SHIELD_IMPACT = 2059

UPGRADE_RARE_SPEED_MINIGUN_SPINUP = 2060

UPGRADE_RARE_HEALTH_LUNCHBOX = 2061

UPGRADE_RARE_SPEED_SNIPER_CHARGERATE = 2062

UPGRADE_RARE_DMG_REVOLVER_DISGUISED = 2063

UPGRADE_RARE_SPEED_CLOAKREGEN = 2064
UPGRADE_RARE_SPEED_CLOAKDURATION = 2065
UPGRADE_RARE_SPEED_CLOAKSPEED = 2066

UPGRADE_RARE_WEAPON_METALCHEAP = 2067
UPGRADE_RARE_WEAPON_ATTACK_PROJ = 2068
UPGRADE_RARE_WEAPON_PACKEDLUNCH = 2069

UPGRADE_RARE_SPEED_SNIPER_REZOOM = 2070

UPGRADE_RARE_WEAPON_ARROWMULT = 2071
UPGRADE_RARE_WEAPON_CLOAKSNEAK = 2072
UPGRADE_RARE_WEAPON_SAPPERMILK = 2073

UPGRADE_RARE_DMG_GASMULT = 2074

UPGRADE_RARE_HEALTH_ROCKETJUMP_REDUC = 2075

UPGRADE_RARE_HEALTH_DISGUISED_RES = 2076

UPGRADE_RARE_SPEED_BUILDING_UPGRADESTART = 2077

UPGRADE_RARE_WEAPON_METALCOST_REDUC = 2078

UPGRADE_RARE_DMG_MACHINA_DMG = 2079
UPGRADE_RARE_DMG_AXTING_MINITOCRIT = 2080

UPGRADE_RARE_HEALTH_FOS_RANGERES = 2081

UPGRADE_RARE_DMG_KGB_CRITDURATION = 2082

--Epic
UPGRADE_EPIC_DMG = 3000
UPGRADE_EPIC_DMG_CRIT_RATE = 3002
UPGRADE_EPIC_DMG_CRIT_DAMAGE = 3003
UPGRADE_EPIC_DMG_BULLETS_PER_SHOT = 3004
UPGRADE_EPIC_DMG_AT_CLOSE = 3005
UPGRADE_EPIC_DMG_MELEE = 3006
UPGRADE_EPIC_DMG_JARATE_SHOT = 3007
UPGRADE_EPIC_DMG_BURN = 3008
UPGRADE_EPIC_DMG_BLEED = 3009

UPGRADE_EPIC_SPEED_FIRERATE = 3001
UPGRADE_EPIC_SPEED_MOVESPEED = 3010
UPGRADE_EPIC_SPEED_PROJSPEED = 3011
UPGRADE_EPIC_SPEED_DEPLOYSPEED = 3012
UPGRADE_EPIC_SPEED_SLOW_ON_HIT = 3013
UPGRADE_EPIC_SPEED_RECHARGE_RATE = 3037

UPGRADE_EPIC_WEAPON_CLIPSIZE = 3014
UPGRADE_EPIC_WEAPON_RESERVEAMMO = 3015
UPGRADE_EPIC_WEAPON_AMMOREGEN = 3016
UPGRADE_EPIC_WEAPON_BLAST_RADIUS = 3017
UPGRADE_EPIC_WEAPON_SPREAD = 3018
UPGRADE_EPIC_WEAPON_MELEE_RANGE = 3019

UPGRADE_EPIC_HEALTH_BONUS = 3020
UPGRADE_EPIC_HEALTH_MULT = 3021
UPGRADE_EPIC_HEALTH_REGEN = 3022
UPGRADE_EPIC_HEALTH_HOK = 3023
UPGRADE_EPIC_HEALTH_MELEE_AOE = 3024
UPGRADE_EPIC_HEALTH_RECEIVED = 3025
UPGRADE_EPIC_HEALTH_MILKY = 3026

UPGRADE_EPIC_MONEY_INCOME = 3027
UPGRADE_EPIC_MONEY_GOLDEN_ENEMIES = 3028
UPGRADE_EPIC_MONEY_WIRE_TAP = 3029

UPGRADE_EPIC_DMG_BULLET_MARK = 3030

UPGRADE_EPIC_SPEED_HASTE = 3031
UPGRADE_EPIC_SPEED_ADDERANLINE = 3032

UPGRADE_EPIC_WEAPON_RAMPUP = 3033
UPGRADE_EPIC_WEAPON_PASSIVE_RELOAD = 3034

UPGRADE_EPIC_HEALTH_TTG = 3036

UPGRADE_EPIC_WEAPON_PENETRATION = 3037

UPGRADE_EPIC_HEALTH_BUILDING = 3038
UPGRADE_EPIC_HEALTH_DISPENSER_RATE = 3039

UPGRADE_EPIC_DMG_SENTRY_DMG = 3040

UPGRADE_EPIC_SPEED_SENTRY_FIRERATE = 3041
UPGRADE_EPIC_SPEED_TELEPORTERRECHARGE = 3042
UPGRADE_EPIC_SPEED_CONSTRUCTION = 3043
UPGRADE_EPIC_SPEED_SENTRY_ROCKET = 3044

UPGRADE_EPIC_WEAPON_SENTRY_RANGE = 3045
UPGRADE_EPIC_WEAPON_SENTRY_AMMO = 3046

UPGRADE_EPIC_HEALTH_HEALRATE = 3047
UPGRADE_EPIC_HEALTH_OVERHEAL = 3048

UPGRADE_EPIC_SPEED_OVERHEAL_DECAY = 3049
UPGRADE_EPIC_SPEED_OVERHEAL_RATE = 3050

UPGRADE_EPIC_WEAPON_MEDIGUN_RANGE = 3051
UPGRADE_EPIC_WEAPON_MEDIGUN_UBERRATE = 3052
UPGRADE_EPIC_WEAPON_MEDIGUN_UBERDURATION = 3053

UPGRADE_EPIC_WEAPON_EFFECT_DURATION = 3054
UPGRADE_EPIC_WEAPON_BANNER_EFFECT_DURATION = 3055
UPGRADE_EPIC_WEAPON_BANNER_EFFECT_RANGE = 3056
UPGRADE_EPIC_WEAPON_FLAME_RANGE = 3057

UPGRADE_EPIC_SPEED_AFTERBURN_RATE = 3058

UPGRADE_EPIC_SPEED_STICKY_CHARGE = 3059
UPGRADE_EPIC_SPEED_SHIELD_CHARGE = 3060
UPGRADE_EPIC_SPEED_SHIELD_KBRES = 3061

UPGRADE_EPIC_DMG_SHIELD_IMPACT = 3062

UPGRADE_EPIC_SPEED_MINIGUN_SPINUP = 3063

UPGRADE_EPIC_HEALTH_LUNCHBOX = 3064

UPGRADE_EPIC_SPEED_SNIPER_CHARGERATE = 3065

UPGRADE_EPIC_DMG_REVOLVER_DISGUISED = 3066

UPGRADE_EPIC_SPEED_CLOAKREGEN = 3067
UPGRADE_EPIC_SPEED_CLOAKDURATION = 3068
UPGRADE_EPIC_SPEED_CLOAKSPEED = 3069

UPGRADE_EPIC_DMG_MEDIGUN_DAMAGE = 3070

UPGRADE_EPIC_SPEED_MINIGUN_MOVESPEED = 3071
UPGRADE_EPIC_SPEED_SNIPER_REZOOM = 3072

UPGRADE_EPIC_DMG_BLAST_INCREASED = 3073

UPGRADE_EPIC_HEALTH_ROCKETJUMP_REDUC = 3074

UPGRADE_EPIC_HEALTH_DISGUISED_RES = 3075
UPGRADE_EPIC_SPEED_BUILDRATE = 3076

UPGRADE_EPIC_WEAPON_MEDIGUN_UBERSTAY = 3077

UPGRADE_EPIC_DMG_SNIPER_EHDAMAGE = 3078
UPGRADE_EPIC_DMG_MACHINA_DMG = 3079

--Legendary
UPGRADE_LEGENDARY_DMG = 4000
UPGRADE_LEGENDARY_DMG_CRIT_RATE = 4002
UPGRADE_LEGENDARY_DMG_CRIT_DAMAGE = 4003
UPGRADE_LEGENDARY_DMG_BULLETS_PER_SHOT = 4004
UPGRADE_LEGENDARY_DMG_AT_CLOSE = 4005
UPGRADE_LEGENDARY_DMG_MELEE = 4006
UPGRADE_LEGENDARY_DMG_JARATE_SHOT = 4007
UPGRADE_LEGENDARY_DMG_BURN = 4008
UPGRADE_LEGENDARY_DMG_BLEED = 4009

UPGRADE_LEGENDARY_SPEED_FIRERATE = 4001
UPGRADE_LEGENDARY_SPEED_MOVESPEED = 4010
UPGRADE_LEGENDARY_SPEED_PROJSPEED = 4011
UPGRADE_LEGENDARY_SPEED_DEPLOYSPEED = 4012
UPGRADE_LEGENDARY_SPEED_SLOW_ON_HIT = 4013
UPGRADE_LEGENDARY_SPEED_RECHARGE_RATE = 4032

UPGRADE_LEGENDARY_WEAPON_CLIPSIZE = 4014
UPGRADE_LEGENDARY_WEAPON_RESERVEAMMO = 4015
UPGRADE_LEGENDARY_WEAPON_AMMOREGEN = 4016
UPGRADE_LEGENDARY_WEAPON_BLAST_RADIUS = 4017
UPGRADE_LEGENDARY_WEAPON_SPREAD = 4018
UPGRADE_LEGENDARY_WEAPON_MELEE_RANGE = 4019

UPGRADE_LEGENDARY_HEALTH_BONUS = 4020
UPGRADE_LEGENDARY_HEALTH_MULT = 4021
UPGRADE_LEGENDARY_HEALTH_REGEN = 4022
UPGRADE_LEGENDARY_HEALTH_HOK = 4023
UPGRADE_LEGENDARY_HEALTH_MELEE_AOE = 4024
UPGRADE_LEGENDARY_HEALTH_RECEIVED = 4025
UPGRADE_LEGENDARY_HEALTH_MILKY = 4026

UPGRADE_LEGENDARY_MONEY_INCOME = 4027
UPGRADE_LEGENDARY_MONEY_GOLDEN_ENEMIES = 4028
UPGRADE_LEGENDARY_MONEY_WIRE_TAP = 4029
UPGRADE_LEGENDARY_MONEY_DISCOUNT = 4030

UPGRADE_LEGENDARY_DMG_HEADSHOT = 4031

UPGRADE_LEGENDARY_WEAPON_PENETRATION = 4032

UPGRADE_LEGENDARY_HEALTH_BUILDING = 4033
UPGRADE_LEGENDARY_HEALTH_DISPENSER_RATE = 4034

UPGRADE_LEGENDARY_DMG_SENTRY_DMG = 4035

UPGRADE_LEGENDARY_SPEED_SENTRY_FIRERATE = 4036
UPGRADE_LEGENDARY_SPEED_TELEPORTERRECHARGE = 4037
UPGRADE_LEGENDARY_SPEED_CONSTRUCTION = 4038
UPGRADE_LEGENDARY_SPEED_SENTRY_ROCKET = 4039

UPGRADE_LEGENDARY_WEAPON_SENTRY_RANGE = 4040
UPGRADE_LEGENDARY_WEAPON_SENTRY_AMMO = 4041

UPGRADE_LEGENDARY_HEALTH_HEALRATE = 4042
UPGRADE_LEGENDARY_HEALTH_OVERHEAL = 4043

UPGRADE_LEGENDARY_SPEED_OVERHEAL_DECAY = 4044
UPGRADE_LEGENDARY_SPEED_OVERHEAL_RATE = 4045

UPGRADE_LEGENDARY_WEAPON_MEDIGUN_RANGE = 4046
UPGRADE_LEGENDARY_WEAPON_MEDIGUN_UBERRATE = 4047
UPGRADE_LEGENDARY_WEAPON_MEDIGUN_UBERDURATION = 4048

UPGRADE_LEGENDARY_WEAPON_EFFECT_DURATION = 4049
UPGRADE_LEGENDARY_WEAPON_BANNER_EFFECT_DURATION = 4050
UPGRADE_LEGENDARY_WEAPON_BANNER_EFFECT_RANGE = 4051
UPGRADE_LEGENDARY_WEAPON_FLAME_RANGE = 4052

UPGRADE_LEGENDARY_SPEED_AFTERBURN_RATE = 4053

UPGRADE_LEGENDARY_SPEED_STICKY_CHARGE = 4054
UPGRADE_LEGENDARY_SPEED_SHIELD_CHARGE = 4055
UPGRADE_LEGENDARY_SPEED_SHIELD_KBRES = 4056

UPGRADE_LEGENDARY_DMG_SHIELD_IMPACT = 4057

UPGRADE_LEGENDARY_SPEED_MINIGUN_SPINUP = 4058

UPGRADE_LEGENDARY_HEALTH_LUNCHBOX = 4059

UPGRADE_LEGENDARY_SPEED_SNIPER_CHARGERATE = 4060

UPGRADE_LEGENDARY_DMG_REVOLVER_DISGUISED = 4061

UPGRADE_LEGENDARY_SPEED_CLOAKREGEN = 4062
UPGRADE_LEGENDARY_SPEED_CLOAKDURATION = 4063
UPGRADE_LEGENDARY_SPEED_CLOAKSPEED = 4064

UPGRADE_LEGENDARY_WEAPON_ATTACK_PROJ = 4065
UPGRADE_LEGENDARY_WEAPON_EXPLOSIVE_ARROWS = 4066
UPGRADE_LEGENDARY_WEAPON_DISGUISE_FIREIMMUNE = 4067

UPGRADE_LEGENDARY_DMG_BLAST_INCREASED = 4068

UPGRADE_LEGENDARY_HEALTH_ROCKETJUMP_REDUC = 4069

UPGRADE_LEGENDARY_HEALTH_DISGUISED_RES = 4070

UPGRADE_LEGENDARY_SPEED_BUILDRATE = 4071
UPGRADE_LEGENDARY_SPEED_BUILDQUICKSTART = 4072

UPGRADE_LEGENDARY_DMG_MACHINA_DMG = 4073

--Greed
UPGRADE_GREED_DMG = 5000
UPGRADE_GREED_DMG_MELEE = 5003
UPGRADE_GREED_DMG_KB = 5002
UPGRADE_GREED_SPEED_FIRERATE = 5001 -- BARRAGE
UPGRADE_GREED_SPEED_MOVESPEED = 5004
UPGRADE_GREED_WEAPON_RELOAD = 5005
UPGRADE_GREED_WEAPON_TURRET = 5006
UPGRADE_GREED_HEALTH_MULT = 5007
UPGRADE_GREED_HEALTH_MULT_CLOSE_RANGE = 5008
UPGRADE_GREED_MONEY_PHYSICAL = 5009
UPGRADE_GREED_MONEY_HAGGLE = 5010
UPGRADE_GREED_MONEY_PERK_UPGRADE = 5011

Upgrades = {

	--ApplyFunction params (In order): player, upgrade 
	--SalvagedFunction params (In order): player, upgrade 
	
	--Common
	[UPGRADE_COMMON_DMG] =  	{ Name = "Damage Boost", Description = "+ 20% Damage", Attributes = { { attr = "damage bonus", increment = 0.2, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_DMG_CRIT_RATE] = { Name = "Sharpshooter", Description = "+ 3% Crit Rate", Attributes = { { attr = "crit mod disabled hidden", increment = 0.03, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_DMG_CRIT_DAMAGE] = { Name = "Critical Punch", Description = "+ 20% Crit Damage", Attributes = { { attr = "mult crit dmg", increment = 0.2, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_DMG_BULLETS_PER_SHOT] = { Name = "Packed Shot", Description = "+ 20% Bullets Per Shot (rounded down)", Attributes = { { attr = "bullets per shot bonus", increment = 0.2, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_DMG_AT_CLOSE] = { Name = "Danger Seeker", Description = "+ 15% Damage At Close Range", Attributes = { { attr = "mult dmg before distance", increment = 0.15, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 }, { attr = "mult dmg before distance specify", increment = 256, slot = LOADOUT_POSITION_BODY, type = "set", cap = nil, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_DMG_MELEE] = { Name = "Strong Arms", Description = "+ 30% Melee Damage", Attributes = { { attr = "damage bonus", increment = 0.3, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_DMG_JARATE_SHOT] = { Name = "Dirty Rounds", Description = "+ 1% Chance to apply jarate on hit", Attributes = { { attr = "throwable damage", increment = 1, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = 100, default = 0 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_DMG_BURN] = { Name = "Hot Fire", Description = "+ 50% Afterburn Damage", Attributes = { { attr = "weapon burn dmg increased", increment = 0.5, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 }, { attr = "weapon burn dmg increased", increment = 0.5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_AFTERBURN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_DMG_BLEED] = { Name = "Sharpened Blade", Description = "+ 50% Bleed Damage", Attributes = { { attr = "mult bleeding dmg", increment = 0.5, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 }, { attr = "mult bleeding dmg", increment = 0.5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_BLEED, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_SPEED_FIRERATE] = { Name = "Rapid Fire", Description = "+ 5% Fire rate", Attributes = { { attr = "fire rate bonus", increment = 0.95, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_FIRERATE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_MOVESPEED] = { Name = "Speed Boost", Description = "+ 5% Move Speed", Attributes = { { attr = "move speed bonus", increment = 0.05, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_PROJSPEED] = { Name = "Enhanced Propulsion", Description = "+ 15% Projectile Speed", Attributes = { { attr = "projectile speed increased", increment = 0.15, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_PROJECTILE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_DEPLOYSPEED] = { Name = "Fast Hands", Description = "+ 15% Deploy Speed", Attributes = { { attr = "deploy time decreased", increment = 0.85, slot = LOADOUT_POSITION_BODY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_RECHARGE_RATE] = { Name = "Heatsink", Description = "+ 7.5% Item Recharge Rate", Attributes = { { attr = "effect bar recharge rate increased", increment = 0.925, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  }, { attr = "mult_item_meter_charge_rate", increment = 0.925, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  }, { attr = "charge recharge rate increased", increment = 0.925, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_RECHARGEBARITEM, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_WEAPON_CLIPSIZE] = { Name = "Big Clip", Description = "+ 33% Clip Size", Attributes = { { attr = "clip size bonus", increment = 0.33, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_CLIPSIZE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_RESERVEAMMO] = { Name = "Big Pockets", Description = "+ 15% Reserve Ammo", Attributes = { { attr = "maxammo primary increased", increment = 0.15, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 }, { attr = "maxammo secondary increased", increment = 0.15, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_RESERVEAMMO, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_AMMOREGEN] = { Name = "Reuse", Description = "+ 5% Ammo Regen", Attributes = { { attr = "ammo regen", increment = 0.05, slot = LOADOUT_POSITION_BODY, type = "add", cap = 1, default = 0 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_RESERVEAMMO, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_BLAST_RADIUS] = { Name = "Big Blast", Description = "+ 12.5% Blast Radius", Attributes = { { attr = "blast radius increased", increment = 0.125, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_EXPLOSIVE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_SPREAD] = { Name = "Long Barrel", Description = "+ 6% Accuracy", Attributes = { { attr = "weapon spread bonus", increment = 0.94, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_MELEE_RANGE] = { Name = "Long Arms", Description = "+ 15% Melee Range", Attributes = { { attr = "melee range multiplier", increment = 0.15, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_HEALTH_BONUS] = { Name = "Health Bonus", Description = "+ 25 Max Health", Attributes = { { attr = "max health additive bonus", increment = 25, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_HEALTH_MULT] = { Name = "Banana", Description = "+ 5% Max Health Multiplier", Attributes = { { attr = "mult max health", increment = 0.05, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_HEALTH_REGEN] = { Name = "Health Regen", Description = "+ 1 Health Regen", Attributes = { { attr = "health regen", increment = 1, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_HEALTH_HOK] = { Name = "Bloodlust", Description = "+ 5 Health on kill", Attributes = { { attr = "heal on kill", increment = 5, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_HEALTH_MILKY] = { Name = "Milky Shots", Description = "+ 2% Chance to apply mad milk on hit", Attributes = { { attr = "throwable healing", increment = 2, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = 100, default = 0 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_MONEY_INCOME] = { Name = "Passive Income", Description = "+ 1 Credits every second while in combat \nMax of x*100 credits per combat", Attributes = { { attr = "currency bonus", increment = 1, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_MONEY_GOLDEN_ENEMIES] = { Name = "Rare Treasure", Description = "+ 0.5% Chance for enemies to give 5x the money on death \n+ Global upgrade: Affects everyone on your team", Attributes = { { attr = "is australium item", increment = 0.5, slot = LOADOUT_POSITION_BODY, type = "add", cap = 100, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = function(player, upgrade) ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] = ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] + 0.5 end, SalvagedFunction = function(player, upgrade) ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] = ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] - 0.5 end },
	[UPGRADE_COMMON_MONEY_WIRE_TAP] = { Name = "Money Shot", Description = "+ 2 Credits on hit", Attributes = { { attr = "expiration date", increment = 2, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_MONEY_DISCOUNT] = { Name = "Employee Discount", Description = "+ Shop prices are 10% Cheaper", Attributes = { { attr = "purchased", increment = 0.1, slot = LOADOUT_POSITION_BODY, type = "subtract", cap = 0.9, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = function(player,upgrade) player.CostMult = player.CostMult - 0.1 end, SalvagedFunction = function(player,upgrade) player.CostMult = player.CostMult + 0.1 end },
	
	
	
	[UPGRADE_COMMON_WEAPON_PENETRATION] = { Name = "Bullet Penetration", Description = "+ 1 Penetration", Attributes = { { attr = "projectile penetration heavy", increment = 1, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_HEALTH_BUILDING] = { Name = "Quality Metal", Description = "+ 33% Building Health", Attributes = { { attr = "engy building health bonus", increment = 0.33, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_HEALTH_DISPENSER_RATE] = { Name = "Flow Valve", Description = "+ 20% Dispenser Rate", Attributes = { { attr = "mult dispenser rate", increment = 0.2, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_DMG_SENTRY_DMG] = { Name = "Higher Caliber", Description = "+ 30% Sentry Damage", Attributes = { { attr = "engy sentry damage bonus", increment = 0.3, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_SPEED_SENTRY_FIRERATE] = { Name = "Auto Cycle", Description = "+ 5% Sentry Fire Rate", Attributes = { { attr = "engy sentry fire rate increased", increment = 0.95, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_TELEPORTERRECHARGE] = { Name = "Quick Charge", Description = "+ 7.5% Faster Teleporter Recharge", Attributes = { { attr = "mult teleporter recharge rate", increment = 0.925, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_CONSTRUCTION] = { Name = "Construction Boost", Description = "+ 20% Construction Boost", Attributes = { { attr = "Construction rate increased", increment = 0.2, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_SENTRY_ROCKET] = { Name = "Enhanced Propulsion", Description = "+ 15% Sentry Rocket Speed", Attributes = { { attr = "mult sentry rocket projectile speed", increment = 0.15, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_WEAPON_SENTRY_RANGE] = { Name = "Enhanced Sensors", Description = "+ 15% Sentry Range", Attributes = { { attr = "engy sentry radius increased", increment = 0.15, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_SENTRY_AMMO] = { Name = "Ammo Reserves", Description = "+ 20% Sentry Ammo", Attributes = { { attr = "mvm sentry ammo", increment = 0.2, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_METALAMMO] = { Name = "Metal Reserves", Description = "+ 200% Metal Capacity", Attributes = { { attr = "maxammo metal increased", increment = 2, slot = LOADOUT_POSITION_PDA, type = "add", cap = 5, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_METALAMMO2] = { Name = "Metal Reserves", Description = "+ 200% Metal Capacity", Attributes = { { attr = "maxammo metal increased", increment = 2, slot = LOADOUT_POSITION_PDA, type = "add", cap = 5, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_TWOWAY] = { Name = "Two-Way Teleporter", Description = "+ Two-Way Teleporter", Attributes = { { attr = "bidirectional teleport", increment = 1, slot = LOADOUT_POSITION_PDA, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_GUNSLINGER_SENTRIES] = { Name = "Sentry Army", Description = "+ 1 Disposable Sentries", Attributes = { { attr = "engy disposable sentries", increment = 1, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["The Gunslinger"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_HEALTH_HEALRATE] = { Name = "Flow Valve", Description = "+ 15% Heal Rate", Attributes = { { attr = "heal rate bonus", increment = 0.15, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_HEALTH_OVERHEAL] = { Name = "Bio-enhancements", Description = "+ 20% Max Overheal", Attributes = { { attr = "overheal bonus", increment = 0.2, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_SPEED_OVERHEAL_RATE] = { Name = "Excess Control", Description = "+ 10% Overheal Build Rate", Attributes = { { attr = "overheal fill rate reduced", increment = 0.1, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_OVERHEAL_DECAY] = { Name = "Drip Drain", Description = "+ 15% Slow Overheal Decay", Attributes = { { attr = "overheal decay bonus", increment = 0.15, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_WEAPON_MEDIGUN_RANGE] = { Name = "Long Nozzle", Description = "+ 25% Medigun Range", Attributes = { { attr = "mult medigun range", increment = 0.25, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_MEDIGUN_UBERRATE] = { Name = "Quick Uber", Description = "+ 10% Ubercharge Rate", Attributes = { { attr = "ubercharge rate bonus", increment = 0.1, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_MEDIGUN_UBERDURATION] = { Name = "Time Extension", Description = "+ 1 Second longer uber", Attributes = { { attr = "uber duration bonus", increment = 1, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_WEAPON_EFFECT_DURATION] = { Name = "Time Extension", Description = "+ 15% Longer Effect Duration", Attributes = { { attr = "mult effect duration", increment = 0.15, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_EFFECTITEM, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_WEAPON_BANNER_EFFECT_DURATION] = { Name = "Time Extension", Description = "+ 20% Longer Banner Duration", Attributes = { { attr = "increase buff duration", increment = 0.2, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_buff_item"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_BANNER_EFFECT_RANGE] = { Name = "Noise Amplification", Description = "+ 15% Banner Range", Attributes = { { attr = "mod soldier buff range", increment = 0.15, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_buff_item"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_PARACHUTE_REDEPLOY] = { Name = "Re-deploy", Description = "+ You can re-deploy your parachute", Attributes = { { attr = "parachute redeploy", increment = 1, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "set", cap = 1, default = 0, refund_set = nil} }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_parachute_secondary"] = true,["tf_weapon_parachute_primary"] = true,["The B.A.S.E. Jumper"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_SPEED_PARACHUTE_AIRCONTROL] = { Name = "Airflow", Description = "+ 50% Air Control While Parachuting", Attributes = { { attr = "mult parachute air control", increment = 0.5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1} }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_parachute_secondary"] = true,["tf_weapon_parachute_primary"] = true,["The B.A.S.E. Jumper"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_PARACHUTE_FALLSPEED] = { Name = "Air Resistance", Description = "+ 25% Slow descent while parachuting", Attributes = { { attr = "mult parachute z speed", increment = 0.75, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1} }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_parachute_secondary"] = true,["tf_weapon_parachute_primary"] = true,["The B.A.S.E. Jumper"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_WEAPON_FLAME_RANGE] = { Name = "Controlled Burn", Description = "+ 10% Flame Range", Attributes = { { attr = "flame_drag", increment = 0.9, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = nil, default = 8.5 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_flamethrower"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_SPEED_AFTERBURN_RATE] = { Name = "Quick Burn", Description = "+ 25% Afterburn Damage Rate", Attributes = { { attr = "weapon burn time increased", increment = 0.25, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_AFTERBURN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_JETPACK_RELAUNCH] = { Name = "Re-launch", Description = "+ Able to re-launch while already in-flight", Attributes = { { attr = "thermal_thruster_air_launch", increment = 1, slot = LOADOUT_POSITION_SECONDARY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_rocketpack"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_SPEED_STICKY_CHARGE] = { Name = "Quick Charge", Description = "+ 10% Sticky Charge Rate", Attributes = { { attr = "stickybomb charge rate", increment = 0.9, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_pipebomblauncher"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_SHIELD_CHARGE] = { Name = "Targe Train", Description = "+ 5% Charge Move Speed", Attributes = { { attr = "mult charging move speed", increment = 0.05, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_SHIELD_KBRES] = { Name = "Dense Shield", Description = "+ 10% Damage Push Force Reduction", Attributes = { { attr = "damage force reduction", increment = 0.9, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_DMG_SHIELD_IMPACT] = { Name = "Blunt Force", Description = "+ 15% Shield Impact Damage", Attributes = { { attr = "charge impact damage increased", increment = 0.15, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_SPEED_MINIGUN_SPINUP] = { Name = "Rapid Rotation", Description = "+ 10% Spinup Speed", Attributes = { { attr = "minigun spinup time decreased", increment = 0.9, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_minigun"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_GRU_EVIC_DRAINRATE] = { Name = "Fitness Training", Description = "+ 25% Slow Health Drain Rate From Melee", Attributes = { { attr = "mod_maxhealth_drain_rate", increment = 0.75, slot = LOADOUT_POSITION_MELEE, type = "multiply", cap = nil, default = 10, } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["Gloves of Running Urgently"] = true, ["Festive Gloves of Running Urgently"] = true, ["The Bread Bite"] = true, ["The Eviction Notice"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_WEAPON_HUO_AMMODRAIN] = { Name = "Efficient Fire", Description = "+ Fire Ring Costs 1 Less Ammo", Attributes = { { attr = "uses ammo while aiming", increment = 1, slot = LOADOUT_POSITION_PRIMARY, type = "subtract", cap = 0, default = 4 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["The Huo Long Heatmaker"] = true,["Promo Huo Long Heatmaker"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_MITTEN_ALWAYSCRIT] = { Name = "Extra Ticklish", Description = "+ Mittens Always Crit", Attributes = { { attr = "always crit", increment = 1, slot = LOADOUT_POSITION_MELEE, type = "set", cap = 1, default = 0, refund_set = nil, } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["The Holiday Punch"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_HEALTH_LUNCHBOX] = { Name = "Extra Toppings", Description = "+ 20% Healing Effect", Attributes = { { attr = "lunchbox healing decreased", increment = 0.2, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["tf_weapon_lunchbox"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_SPEED_SNIPER_CHARGERATE] = { Name = "Focus", Description = "+ 7.5% Faster Charge Rate", Attributes = { { attr = "SRifle Charge rate increased", increment = 1.075, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = 2, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_sniperrifle"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_DMG_FIREARROWS] = { Name = "Incendiary Arrows", Description = "+ Arrows ignite enemies on hit", Attributes = { { attr = "arrow ignite", increment = 1, slot = LOADOUT_POSITION_PRIMARY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_weapon_compound_bow"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_WEAPON_SYDNEY_RADIUSSLEEPER] = { Name = "Radius Sleeper", Description = "+ Headshots and full-charged bodyshots trigger a ''Jarate Explosion''", Attributes = { { attr = "radius sleeper", increment = 1, slot = LOADOUT_POSITION_PRIMARY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["The Sydney Sleeper"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_SYDNEY_MAXDURATION] = { Name = "Larger Dose", Description = "+ 2 Seconds of max jarate duration", Attributes = { { attr = "jarate duration", increment = 2, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 5 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["The Sydney Sleeper"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_DMG_MACHINA_DMG] = { Name = "Windup", Description = "+ 30% Full Charged Damage", Attributes = { { attr = "sniper full charge damage bonus", increment = 0.3, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["The Machina"] = true,["Shooting Star"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_DMG_REVOLVER_DISGUISED] = { Name = "First Strike", Description = "+ 15% Revolver Damage Bonus While Disguised", Attributes = { { attr = "damage bonus while disguised", increment = 0.15, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_weapon_revolver"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_DMG_AMBIE_NOFALLOFF] = { Name = "Marksman", Description = "+ No crititcal damage falloff", Attributes = { { attr = "crit_dmg_falloff", increment = 0, slot = LOADOUT_POSITION_SECONDARY, type = "set", cap = 0, default = 1, refund_set = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["The Ambassador"] = true,["Festive Ambassador"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_SPEED_CLOAKREGEN] = { Name = "Heatsink", Description = "+ 10% Cloak Regen Rate", Attributes = { { attr = "mult cloak meter regen rate", increment = 0.10, slot = LOADOUT_POSITION_PDA2, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_CLOAKDURATION] = { Name = "Time Stretch", Description = "+ 7.5% Slower Cloak Consume Rate", Attributes = { { attr = "cloak consume rate decreased", increment = 0.925, slot = LOADOUT_POSITION_PDA2, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_CLOAKSPEED] = { Name = "Quick Foot", Description = "+ 7.5% Move Speed While Cloaked", Attributes = { { attr = "move speed bonus resource level", increment = 0.075, slot = LOADOUT_POSITION_PDA2, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_SPEED_SPYCICLE_COOLDOWN] = { Name = "Refreeze", Description = "+ 50% Faster Spycicle Cooldown", Attributes = { { attr = "melts in fire", increment = 0.5, slot = LOADOUT_POSITION_MELEE, type = "multiply", cap = nil, default = 15 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["The Spy-cicle"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_COMMON_HEALTH_SPYCICLE_DURATION] = { Name = "Extra Cold", Description = "+ 50% Longer Afterburn Immunity", Attributes = { { attr = "become fireproof on hit by fire", increment = 5, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 10 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["The Spy-cicle"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_COMMON_WEAPON_SAPPER] = { Name = "Sapper Enhancements", Description = "+ Robo-Sapper Upgrade", Attributes = { { attr = "robo sapper", increment = 1, slot = LOADOUT_POSITION_BUILDING, type = "add", cap = 3, default = 0 } }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_BUILDER_SPY"] = true,["Upgradeable TF_WEAPON_BUILDER_SPY"] = true,["tf_weapon_sapper"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	--Uncommon: 50% More than common
	[UPGRADE_UNCOMMON_DMG] =  	{ Name = "Damage Boost", Description = "+ 30% Damage", Attributes = { { attr = "damage bonus", increment = 0.3, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_DMG_CRIT_RATE] = { Name = "Sharpshooter", Description = "+ 5% Crit Rate", Attributes = { { attr = "crit mod disabled hidden", increment = 0.05, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_DMG_CRIT_DAMAGE] = { Name = "Critical Punch", Description = "+ 30% Crit Damage", Attributes = { { attr = "mult crit dmg", increment = 0.3, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_DMG_BULLETS_PER_SHOT] = { Name = "Packed Shot", Description = "+ 30% Bullets Per Shot (rounded down)", Attributes = { { attr = "bullets per shot bonus", increment = 0.3, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_DMG_AT_CLOSE] = { Name = "Danger Seeker", Description = "+ 22.5% Damage At Close Range", Attributes = { { attr = "mult dmg before distance", increment = 0.255, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 }, { attr = "mult dmg before distance specify", increment = 256, slot = LOADOUT_POSITION_BODY, type = "set", cap = nil, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_DMG_MELEE] = { Name = "Strong Arms", Description = "+ 45% Melee Damage", Attributes = { { attr = "damage bonus", increment = 0.45, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_DMG_JARATE_SHOT] = { Name = "Dirty Rounds", Description = "+ 1.5% Chance to apply jarate on hit", Attributes = { { attr = "throwable damage", increment = 1.5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = 100, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_DMG_BURN] = { Name = "Hot Fire", Description = "+ 75% Afterburn Damage", Attributes = { { attr = "weapon burn dmg increased", increment = 0.75, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 }, { attr = "weapon burn dmg increased", increment = 0.75, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_AFTERBURN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_DMG_BLEED] = { Name = "Sharpened Blade", Description = "+ 75% Bleed Damage", Attributes = { { attr = "mult bleeding dmg", increment = 0.75, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 }, { attr = "mult bleeding dmg", increment = 0.75, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_BLEED, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_SPEED_FIRERATE] = { Name = "Rapid Fire", Description = "+ 7.5% Fire rate", Attributes = { { attr = "fire rate bonus", increment = 0.925, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_FIRERATE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_MOVESPEED] = { Name = "Speed Boost", Description = "+ 7.5% Move Speed", Attributes = { { attr = "move speed bonus", increment = 0.075, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_PROJSPEED] = { Name = "Enhanced Propulsion", Description = "+ 22.5% Projectile Speed", Attributes = { { attr = "projectile speed increased", increment = 0.225, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_PROJECTILE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_DEPLOYSPEED] = { Name = "Fast Hands", Description = "+ 22.5% Deploy Speed", Attributes = { { attr = "deploy time decreased", increment = 0.775, slot = LOADOUT_POSITION_BODY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_RECHARGE_RATE] = { Name = "Heatsink", Description = "+ 12.5% Item Recharge Rate", Attributes = { { attr = "effect bar recharge rate increased", increment = 0.875, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  }, { attr = "mult_item_meter_charge_rate", increment = 0.875, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  }, { attr = "charge recharge rate increased", increment = 0.875, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_RECHARGEBARITEM, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_WEAPON_CLIPSIZE] = { Name = "Big Clip", Description = "+ 50% Clip Size", Attributes = { { attr = "clip size bonus", increment = 0.5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_CLIPSIZE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_WEAPON_RESERVEAMMO] = { Name = "Big Pockets", Description = "+ 22.5% Reserve Ammo", Attributes = { { attr = "maxammo primary increased", increment = 0.225, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 }, { attr = "maxammo secondary increased", increment = 0.225, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_RESERVEAMMO, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_WEAPON_AMMOREGEN] = { Name = "Reuse", Description = "+ 7.5% Ammo Regen", Attributes = { { attr = "ammo regen", increment = 0.075, slot = LOADOUT_POSITION_BODY, type = "add", cap = 1, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_RESERVEAMMO, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_WEAPON_BLAST_RADIUS] = { Name = "Big Blast", Description = "+ 20% Blast Radius", Attributes = { { attr = "blast radius increased", increment = 0.2, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_EXPLOSIVE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_WEAPON_SPREAD] = { Name = "Long Barrel", Description = "+ 9% Accuracy", Attributes = { { attr = "weapon spread bonus", increment = 0.91, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_WEAPON_MELEE_RANGE] = { Name = "Long Arms", Description = "+ 22.5% Melee Range", Attributes = { { attr = "melee range multiplier", increment = 0.225, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_HEALTH_BONUS] = { Name = "Health Bonus", Description = "+ 50 Max Health", Attributes = { { attr = "max health additive bonus", increment = 50, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_HEALTH_MULT] = { Name = "Banana", Description = "+ 7.5% Max Health Multiplier", Attributes = { { attr = "mult max health", increment = 0.075, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_HEALTH_REGEN] = { Name = "Health Regen", Description = "+ 2 Health Regen", Attributes = { { attr = "health regen", increment = 2, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_HEALTH_HOK] = { Name = "Bloodlust", Description = "+ 10 Health on kill", Attributes = { { attr = "heal on kill", increment = 10, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_HEALTH_MILKY] = { Name = "Milky Shots", Description = "+ 3% Chance to apply mad milk on hit", Attributes = { { attr = "throwable healing", increment = 3, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = 100, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_HEALTH_AOE_HEAL] = { Name = "Melee AOE Heal", Description = "+ Trigger an AOE heal for 24 health on melee hit", Attributes = { { attr = "aoe heal chance", increment = 694201337, slot = LOADOUT_POSITION_MELEE, type = "set", cap = 694201337, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_HEALTH_FIGHT_INCREASE] = { Name = "Endurance", Description = "+ 10 Max health after clearing an encounter", Attributes = { { attr = "sapper health penalty", increment = 10, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_MONEY_INCOME] = { Name = "Passive Income", Description = "+ 2 Credits every second while in combat \nMax of x*100 credits per combat", Attributes = { { attr = "currency bonus", increment = 2, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_MONEY_GOLDEN_ENEMIES] = { Name = "Rare Treasure", Description = "+ 0.75% Chance for enemies to give 5x the money on death \n+ Global upgrade: Affects everyone on your team", Attributes = { { attr = "is australium item", increment = 0.75, slot = LOADOUT_POSITION_BODY, type = "add", cap = 100, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = function(player, upgrade) ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] = ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] + 0.75 end, SalvagedFunction = function(player, upgrade) ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] = ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] - 0.75 end },
	[UPGRADE_UNCOMMON_MONEY_WIRE_TAP] = { Name = "Money Shot", Description = "+ 3 Credits on hit", Attributes = { { attr = "expiration date", increment = 3, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_MONEY_LARGER_SHOPS] = { Name = "Larger Shops", Description = "+ 1 Shop item for sale", Attributes = { { attr = "never craftable", increment = 1, slot = LOADOUT_POSITION_BODY, type = "add", cap = 4, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = function(player,upgrade) player.DisplayedShopUpgrades = player.DisplayedShopUpgrades + 1 end, SalvagedFunction = function(player,upgrade) player.DisplayedShopUpgrades = player.DisplayedShopUpgrades - 1 end },
	[UPGRADE_UNCOMMON_MONEY_REROLLS] = { Name = "Luck of the Rats", Description = "+ 1 Rerolls", Attributes = { { attr = "duck rating", increment = 1, slot = LOADOUT_POSITION_BODY, type = "add", cap = 2, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = function(player,upgrade) player.MaxRerolls = player.MaxRerolls + 1 end, SalvagedFunction = function(player,upgrade) player.MaxRerolls = player.MaxRerolls - 1 end }, -- Roll From The Hip ref
	
	-- Specialized Upgrades --
	
	[UPGRADE_UNCOMMON_WEAPON_PENETRATION] = { Name = "Bullet Penetration", Description = "+ 2 Penetration", Attributes = { { attr = "projectile penetration heavy", increment = 2, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_HEALTH_BUILDING] = { Name = "Quality Metal", Description = "+ 50% Building Health", Attributes = { { attr = "engy building health bonus", increment = 0.5, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_HEALTH_DISPENSER_RATE] = { Name = "Flow Valve", Description = "+ 30% Dispenser Rate", Attributes = { { attr = "mult dispenser rate", increment = 0.3, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_DMG_SENTRY_DMG] = { Name = "Higher Caliber", Description = "+ 45% Sentry Damage", Attributes = { { attr = "engy sentry damage bonus", increment = 0.45, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_SPEED_SENTRY_FIRERATE] = { Name = "Auto Cycle", Description = "+ 7.5% Sentry Fire Rate", Attributes = { { attr = "engy sentry fire rate increased", increment = 0.925, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_TELEPORTERRECHARGE] = { Name = "Quick Charge", Description = "+ 12.5% Faster Teleporter Recharge", Attributes = { { attr = "mult teleporter recharge rate", increment = 0.875, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_CONSTRUCTION] = { Name = "Construction Boost", Description = "+ 30% Construction Boost", Attributes = { { attr = "Construction rate increased", increment = 0.3, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_SENTRY_ROCKET] = { Name = "Enhanced Propulsion", Description = "+ 22.5% Sentry Rocket Speed", Attributes = { { attr = "mult sentry rocket projectile speed", increment = 0.225, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_TELEPORTER_SPEEDBOOST] = { Name = "Teleporter Coffee Service", Description = "+ Telepoters give 4 second speedboost", Attributes = { { attr = "mod teleporter speed boost", increment = 1, slot = LOADOUT_POSITION_PDA, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_WEAPON_SENTRY_RANGE] = { Name = "Enhanced Sensors", Description = "+ 22.5% Sentry Range", Attributes = { { attr = "engy sentry radius increased", increment = 0.225, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_WEAPON_SENTRY_AMMO] = { Name = "Ammo Reserves", Description = "+ 30% Sentry Ammo", Attributes = { { attr = "mvm sentry ammo", increment = 0.3, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_WEAPON_METALGAIN] = { Name = "Metal Salvage", Description = "+ 50% Metal From Pickups", Attributes = { { attr = "metal_pickup_decreased", increment = 0.5, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_HEALTH_HEALRATE] = { Name = "Flow Valve", Description = "+ 22.5% Heal Rate", Attributes = { { attr = "heal rate bonus", increment = 0.225, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_HEALTH_OVERHEAL] = { Name = "Bio-enhancements", Description = "+ 30% Max Overheal", Attributes = { { attr = "overheal bonus", increment = 0.3, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_SPEED_OVERHEAL_RATE] = { Name = "Excess Control", Description = "+ 15% Overheal Build Rate", Attributes = { { attr = "overheal fill rate reduced", increment = 0.15, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_OVERHEAL_DECAY] = { Name = "Drip Drain", Description = "+ 25% Slow Overheal Decay", Attributes = { { attr = "overheal decay bonus", increment = 0.25, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_WEAPON_MEDIGUN_RANGE] = { Name = "Long Nozzle", Description = "+ 37.5% Medigun Range", Attributes = { { attr = "mult medigun range", increment = 0.375, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_WEAPON_MEDIGUN_UBERRATE] = { Name = "Quick Uber", Description = "+ 15% Ubercharge Rate", Attributes = { { attr = "ubercharge rate bonus", increment = 0.15, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_WEAPON_MEDIGUN_UBERDURATION] = { Name = "Time Extension", Description = "+ 2 Second longer uber", Attributes = { { attr = "uber duration bonus", increment = 2, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_WEAPON_EFFECT_DURATION] = { Name = "Time Extension", Description = "+ 22.5% Longer Effect Duration", Attributes = { { attr = "mult effect duration", increment = 0.225, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_EFFECTITEM, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_WEAPON_BANNER_EFFECT_DURATION] = { Name = "Time Extension", Description = "+ 30% Longer Banner Duration", Attributes = { { attr = "increase buff duration", increment = 0.3, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_buff_item"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_WEAPON_BANNER_EFFECT_RANGE] = { Name = "Noise Amplification", Description = "+ 22.5% Banner Range", Attributes = { { attr = "mod soldier buff range", increment = 0.225, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_buff_item"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_SPEED_PARACHUTE_XYSPEED] = { Name = "Lessened Drag", Description = "+ 25% Faster horizontal speed while parachuting", Attributes = { { attr = "mult parachute xy speed", increment = 0.25, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1} }, Type = UPGRADE_TYPE_COMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_parachute_secondary"] = true,["tf_weapon_parachute_primary"] = true,["The B.A.S.E. Jumper"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_WEAPON_FLAME_RANGE] = { Name = "Controlled Burn", Description = "+ 15% Flame Range", Attributes = { { attr = "flame_drag", increment = 0.85, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = nil, default = 8.5 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_flamethrower"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_WEAPON_FLAME_RICOCHET] = { Name = "Ricochet Flames", Description = "+ Flames bonus off of surfaces and gain speed and damage", Attributes = { { attr = "flame_reflect_on_collision", increment = 1, slot = LOADOUT_POSITION_PRIMARY, type = "set", cap = 1, default = 0, refund_set = nil }, { attr = "reflected_flame_dmg_reduction", increment = 1.75, slot = LOADOUT_POSITION_PRIMARY, type = "set", cap = 1.75, default = 0, refund_set = nil }, { attr = "redirected_flame_size_mult", increment = 2.5, slot = LOADOUT_POSITION_PRIMARY, type = "set", cap = 2.5, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_flamethrower"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_DMG_EOI] = { Name = "Explode On Ignite", Description = "+ Gat coating enemies will violently explode dealing 350 damage", Attributes = { { attr = "explode_on_ignite", increment = 1, slot = LOADOUT_POSITION_BODY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_weapon_jar_gas"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_SPEED_AFTERBURN_RATE] = { Name = "Quick Burn", Description = "+ 37.5% Afterburn Damage Rate", Attributes = { { attr = "weapon burn time increased", increment = 0.375, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_AFTERBURN, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_WEAPON_JETPACKSTUN] = { Name = "Hard Impact", Description = "+ Stun enemies when you land", Attributes = { { attr = "falling_impact_radius_stun", increment = 1, slot = LOADOUT_POSITION_SECONDARY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_rocketpack"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_SPEED_STICKY_CHARGE] = { Name = "Quick Charge", Description = "+ 15% Sticky Charge Rate", Attributes = { { attr = "stickybomb charge rate", increment = 0.85, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_pipebomblauncher"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_SHIELD_CHARGE] = { Name = "Targe Train", Description = "+ 7.5% Charge Move Speed", Attributes = { { attr = "mult charging move speed", increment = 0.075, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_SHIELD_KBRES] = { Name = "Dense Shield", Description = "+ 15% Damage Push Force Reduction", Attributes = { { attr = "damage force reduction", increment = 0.85, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_HEALTH_SHIELD_BULLETRES] = { Name = "Bigger Shield", Description = "+ 15% Bullet resistance", Attributes = { { attr = "dmg taken from bullets reduced", increment = 0.15, slot = LOADOUT_POSITION_SECONDARY, type = "subtract", cap = 0.55, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_DMG_SHIELD_IMPACT] = { Name = "Blunt Force", Description = "+ 22.5% Shield Impact Damage", Attributes = { { attr = "charge impact damage increased", increment = 0.225, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_WEAPON_LOCH_IMPACTEXP] = { Name = "Impact Grenade", Description = "+ Grenades instantly explode instead of shattering", Attributes = { { attr = "grenade explode on impact", increment = 1, slot = LOADOUT_POSITION_PRIMARY, type = "set", cap = 1, default = 0, refund_set = nil }, { attr = "sticky air burst mode", increment = 0, slot = LOADOUT_POSITION_PRIMARY, type = "set", cap = 0, default = 1, refund_set = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["The Loch-n-Load"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_SPEED_MINIGUN_SPINUP] = { Name = "Rapid Rotation", Description = "+ 15% Spinup Speed", Attributes = { { attr = "minigun spinup time decreased", increment = 0.85, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_minigun"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_DMG_HUO_RINGDAMAGE] = { Name = "Blazing Fire", Description = "+ 50% Ring Of Fire Pulse Damage", Attributes = { { attr = "ring of fire while aiming", increment = 6, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 12 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["The Huo Long Heatmaker"] = true,["Promo Huo Long Heatmaker"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_HEALTH_LUNCHBOX] = { Name = "Extra Toppings", Description = "+ 30% Healing Effect", Attributes = { { attr = "lunchbox healing decreased", increment = 0.3, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["tf_weapon_lunchbox"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_HEALTH_FOS_MELEERES] = { Name = "Steel Block", Description = "+ 20% Less Melee Vuln", Attributes = { { attr = "dmg from melee increased", increment = 0.2, slot = LOADOUT_POSITION_MELEE, type = "subtract", cap = 0.2, default = 2 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["Fists of Steel"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_SPEED_SNIPER_CHARGERATE] = { Name = "Focus", Description = "+ 12.5% Faster Charge Rate", Attributes = { { attr = "SRifle Charge rate increased", increment = 1.125, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = 2, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_sniperrifle"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_WEAPON_ARROW_PEN] = { Name = "Reinforced Arrow Tips", Description = "+ Arrows Penetration unlimited enemies", Attributes = { { attr = "projectile penetration", increment = 1, slot = LOADOUT_POSITION_SECONDARY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_compound_bow"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_WEAPON_SNIPER_EH] = { Name = "Explosive Headshot", Description = "+ 1 Tick of Explosive Headshot", Attributes = { { attr = "explosive sniper shot", increment = 1, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = 5, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_sniperrifle"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_DMG_MACHINA_DMG] = { Name = "Windup", Description = "+ 45% Full Charged Damage", Attributes = { { attr = "sniper full charge damage bonus", increment = 0.45, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["The Machina"] = true,["Shooting Star"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_DMG_REVOLVER_CRIT] = { Name = "Final Stand", Description = "+ Last Shot Crits", Attributes = { { attr = "last shot crits", increment = 1, slot = LOADOUT_POSITION_SECONDARY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_weapon_revolver"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_DMG_REVOLVER_DISGUISED] = { Name = "First Strike", Description = "+ 22.5% Revolver Damage Bonus While Disguised", Attributes = { { attr = "damage bonus while disguised", increment = 0.225, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_weapon_revolver"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_DMG_AMBIE_NOCOOLDOWN] = { Name = "Quick Fire", Description = "+ No Headshot Cooldown", Attributes = { { attr = "can headshot", increment = 1, slot = LOADOUT_POSITION_SECONDARY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["The Ambassador"] = true,["Festive Ambassador"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_WEAPON_REVOLVER_UBERDRAIN] = { Name = "Machinery Sabotage", Description = "+ Reduces Uber by 33% On hit", Attributes = { { attr = "subtract victim medigun charge on hit", increment = 33, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = 99, default = 0 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_revolver"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_SPEED_CLOAKREGEN] = { Name = "Heatsink", Description = "+ 15% Cloak Regen Rate", Attributes = { { attr = "mult cloak meter regen rate", increment = 0.15, slot = LOADOUT_POSITION_PDA2, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_CLOAKDURATION] = { Name = "Time Stretch", Description = "+ 12.5% Slower Cloak Consume Rate", Attributes = { { attr = "cloak consume rate decreased", increment = 0.875, slot = LOADOUT_POSITION_PDA2, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_CLOAKSPEED] = { Name = "Quick Foot", Description = "+ 12.5% Move Speed While Cloaked", Attributes = { { attr = "move speed bonus resource level", increment = 0.125, slot = LOADOUT_POSITION_PDA2, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_UNCOMMON_SPEED_CLOAKRATE] = { Name = "Ninja Cloak", Description = "+ 50% Faster cloak and decloak rate", Attributes = { { attr = "mult decloak rate", increment = 0.5, slot = LOADOUT_POSITION_PDA2, type = "set", cap = 0.5, default = 1, refund_set = nil }, { attr = "mult cloak rate", increment = -0.25, slot = LOADOUT_POSITION_PDA2, type = "set", cap = -0.25, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_UNCOMMON_WEAPON_SAPPER_MARK] = { Name = "Disable Defenses", Description = "+ Sapper also marks targets for death", Attributes = { { attr = "effect cond override", increment = (TF_COND_MARKEDFORDEATH*256), slot = LOADOUT_POSITION_PDA2, type = "add", cap = nil, default = TF_COND_SAPPED }, { attr = "duck badge level ", increment = 1, slot = LOADOUT_POSITION_BUILDING, type = "set", cap = 1, default = 0, refund_set = nil }  }, Type = UPGRADE_TYPE_UNCOMMON, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_BUILDER_SPY"] = true,["Upgradeable TF_WEAPON_BUILDER_SPY"] = true,["tf_weapon_sapper"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	--Rare: Common + Uncommon
	[UPGRADE_RARE_DMG] =  	{ Name = "Damage Shot", Description = "+ 50% Damage", Attributes = { { attr = "damage bonus", increment = 0.5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_DMG_CRIT_RATE] = { Name = "Deadeye", Description = "+ 8% Crit Rate", Attributes = { { attr = "crit mod disabled hidden", increment = 0.08, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_DMG_CRIT_DAMAGE] = { Name = "Hot Shot", Description = "+ 50% Crit Damage", Attributes = { { attr = "mult crit dmg", increment = 0.5, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_DMG_BULLETS_PER_SHOT] = { Name = "Overloaded Shot", Description = "+ 50% Bullets Per Shot (rounded down)", Attributes = { { attr = "bullets per shot bonus", increment = 0.5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_DMG_AT_CLOSE] = { Name = "Danger Enthusiast", Description = "+ 37.5% Damage At Close Range", Attributes = { { attr = "mult dmg before distance", increment = 0.375, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 }, { attr = "mult dmg before distance specify", increment = 256, slot = LOADOUT_POSITION_BODY, type = "set", cap = nil, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_DMG_MELEE] = { Name = "Dense Weapon", Description = "+ 75% Melee Damage", Attributes = { { attr = "damage bonus", increment = 0.75, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_DMG_JARATE_SHOT] = { Name = "Biohazard Rounds", Description = "+ 2.5% Chance to apply jarate on hit", Attributes = { { attr = "throwable damage", increment = 2.5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = 100, default = 0 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_DMG_BURN] = { Name = "Fire Starter", Description = "+ 125% Afterburn Damage", Attributes = { { attr = "weapon burn dmg increased", increment = 1.25, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 }, { attr = "weapon burn dmg increased", increment = 1.25, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_AFTERBURN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_DMG_BLEED] = { Name = "Serrated Blade", Description = "+ 125% Bleed Damage", Attributes = { { attr = "mult bleeding dmg", increment = 1.25, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 }, { attr = "mult bleeding dmg", increment = 1.25, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_BLEED, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_DMG_MELEE_MARK] = { Name = "Combo Melee", Description = "+ Melee marks any enemy for death for 5 seconds", Attributes = { { attr = "add cond on hit", increment = 30, slot = LOADOUT_POSITION_MELEE, type = "set", cap = 30, default = 0, refund_set = nil }, { attr = "add cond on hit duration", increment = 5, slot = LOADOUT_POSITION_MELEE, type = "set", cap = 5, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_SPEED_FIRERATE] = { Name = "Supercharged", Description = "+ 12.5% Fire rate", Attributes = { { attr = "fire rate bonus", increment = 0.875, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_FIRERATE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_MOVESPEED] = { Name = "Speed Boots", Description = "+ 12.5% Move Speed", Attributes = { { attr = "move speed bonus", increment = 0.125, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_PROJSPEED] = { Name = "Speed Shot", Description = "+ 37.5% Projectile Speed", Attributes = { { attr = "projectile speed increased", increment = 0.375, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_PROJECTILE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_DEPLOYSPEED] = { Name = "Quick Draw", Description = "+ 33% Deploy Speed", Attributes = { { attr = "deploy time decreased", increment = 0.67, slot = LOADOUT_POSITION_BODY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_RECHARGE_RATE] = { Name = "Rapid Recharge", Description = "+ 20% Item Recharge Rate", Attributes = { { attr = "effect bar recharge rate increased", increment = 0.8, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  }, { attr = "mult_item_meter_charge_rate", increment = 0.8, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  }, { attr = "charge recharge rate increased", increment = 0.8, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_RECHARGEBARITEM, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_PARTY] = { Name = "Party Boost", Description = "+ Give yourself and nearby teammates a slight fire and reload speed buff", Attributes = { { attr = "add cond when active", increment = 113, slot = LOADOUT_POSITION_BODY, type = "set", cap = 113, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_WEAPON_CLIPSIZE] = { Name = "Massive Clip", Description = "+ 85% Clip Size", Attributes = { { attr = "clip size bonus", increment = 0.85, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_CLIPSIZE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_WEAPON_RESERVEAMMO] = { Name = "Ammo Pack", Description = "+ 37.5% Reserve Ammo", Attributes = { { attr = "maxammo primary increased", increment = 0.375, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 }, { attr = "maxammo secondary increased", increment = 0.375, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_RESERVEAMMO, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_WEAPON_AMMOREGEN] = { Name = "Feedback Loop", Description = "+ 12.5% Ammo Regen", Attributes = { { attr = "ammo regen", increment = 0.125, slot = LOADOUT_POSITION_BODY, type = "add", cap = 1, default = 0 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_RESERVEAMMO, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_WEAPON_BLAST_RADIUS] = { Name = "Enhanced Payload", Description = "+ 32% Blast Radius", Attributes = { { attr = "blast radius increased", increment = 0.32, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_EXPLOSIVE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_WEAPON_SPREAD] = { Name = "Deadly Precision", Description = "+ 15% Accuracy", Attributes = { { attr = "weapon spread bonus", increment = 0.85, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_WEAPON_MELEE_RANGE] = { Name = "Comically Large Melee", Description = "+ 37.5% Melee Range", Attributes = { { attr = "melee range multiplier", increment = 0.375, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_WEAPON_MELEE_CLEAVE] = { Name = "Melee Cleave Attack", Description = "+ Melee hits all enemies in range", Attributes = { { attr = "melee cleave attack", increment = 1, slot = LOADOUT_POSITION_MELEE, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_HEALTH_BONUS] = { Name = "Health Boost", Description = "+ 75 Max Health", Attributes = { { attr = "max health additive bonus", increment = 75, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_HEALTH_MULT] = { Name = "Bunch O' Banana", Description = "+ 12.5% Max Health Multiplier", Attributes = { { attr = "mult max health", increment = 0.125, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_HEALTH_REGEN] = { Name = "Life Regen", Description = "+ 3 Health Regen", Attributes = { { attr = "health regen", increment = 3, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_HEALTH_HOK] = { Name = "Vampire", Description = "+ 15 Health on kill", Attributes = { { attr = "heal on kill", increment = 15, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_HEALTH_MILKY] = { Name = "Mad Shots", Description = "+ 5% Chance to apply mad milk on hit", Attributes = { { attr = "throwable healing", increment = 5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = 100, default = 0 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_MONEY_INCOME] = { Name = "Paycheck", Description = "+ 3 Credits every second while in combat \nMax of x*100 credits per combat", Attributes = { { attr = "currency bonus", increment = 3, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_MONEY_GOLDEN_ENEMIES] = { Name = "Golden Enemies", Description = "+ 1.25% Chance for enemies to give 5x the money on death \n+ Global upgrade: Affects everyone on your team", Attributes = { { attr = "is australium item", increment = 1.25, slot = LOADOUT_POSITION_BODY, type = "add", cap = 100, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = function(player, upgrade) ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] = ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] + 1.25 end, SalvagedFunction = function(player, upgrade) ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] = ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] - 1.25 end },
	[UPGRADE_RARE_MONEY_WIRE_TAP] = { Name = "Wire Tap", Description = "+ 5 Credits on hit", Attributes = { { attr = "expiration date", increment = 5, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_MONEY_DISCOUNT] = { Name = "Mercenary Discount", Description = "+ Shop prices are 20% Cheaper", Attributes = { { attr = "tool escrow until date", increment = 0.2, slot = LOADOUT_POSITION_BODY, type = "subtract", cap = 0.8, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = function(player,upgrade) player.CostMult = player.CostMult - 0.2 end, SalvagedFunction = function(player,upgrade) player.CostMult = player.CostMult + 0.2 end },
	
	-- Specialized Upgrades --
	
	[UPGRADE_RARE_WEAPON_PENETRATION] = { Name = "Bullet Penetration", Description = "+ 3 Penetration", Attributes = { { attr = "projectile penetration heavy", increment = 3, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_HEALTH_BUILDING] = { Name = "Hardened Steel", Description = "+ 80% Building Health", Attributes = { { attr = "engy building health bonus", increment = 0.8, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_HEALTH_DISPENSER_RATE] = { Name = "Mass Production", Description = "+ 50% Dispenser Rate", Attributes = { { attr = "mult dispenser rate", increment = 0.5, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_DMG_SENTRY_DMG] = { Name = "Damage Shot", Description = "+ 75% Sentry Damage", Attributes = { { attr = "engy sentry damage bonus", increment = 0.75, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_SPEED_SENTRY_FIRERATE] = { Name = "Super Cycle", Description = "+ 12.5% Sentry Fire Rate", Attributes = { { attr = "engy sentry fire rate increased", increment = 0.875, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_TELEPORTERRECHARGE] = { Name = "Ultra Charge", Description = "+ 20% Faster Teleporter Recharge", Attributes = { { attr = "mult teleporter recharge rate", increment = 0.8, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_CONSTRUCTION] = { Name = "Construction Permit", Description = "+ 50% Construction Boost", Attributes = { { attr = "Construction rate increased", increment = 0.5, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_BUILDING_UPGRADESTART] = { Name = "Quickstart: Upgrade", Description = "+ 25% Upgrade progress for new buildings", Attributes = { { attr = "building instant upgrade", increment = 0.25, slot = LOADOUT_POSITION_PDA, type = "add", cap = 1, default = 0 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_SENTRY_ROCKET] = { Name = "Speed Shot", Description = "+ 37.5% Sentry Rocket Speed", Attributes = { { attr = "mult sentry rocket projectile speed", increment = 0.375, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_WEAPON_SENTRY_RANGE] = { Name = "Long Range Sensors", Description = "+ 37.5% Sentry Range", Attributes = { { attr = "engy sentry radius increased", increment = 0.375, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_WEAPON_SENTRY_AMMO] = { Name = "Ammo Linkage", Description = "+ 50% Sentry Ammo", Attributes = { { attr = "mvm sentry ammo", increment = 0.5, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_WEAPON_METALCHEAP] = { Name = "Building Logistics", Description = "+ 35% Cheaper Buildings", Attributes = { { attr = "building cost reduction", increment = 0.35, slot = LOADOUT_POSITION_PDA, type = "subtract", cap = 0.3, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_WEAPON_METALCOST_REDUC] = { Name = "Metal Efficiency", Description = "+ 20% Less metal used on primary attack", Attributes = { { attr = "mod ammo per shot", increment = 0.8, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 30 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["The Widowmaker"] = true,["tf_weapon_mechanical_arm"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_HEALTH_HEALRATE] = { Name = "Quick-Fix", Description = "+ 37.5% Heal Rate", Attributes = { { attr = "heal rate bonus", increment = 0.375, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_HEALTH_OVERHEAL] = { Name = "Health Overdrive", Description = "+ 50% Max Overheal", Attributes = { { attr = "overheal bonus", increment = 0.5, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_SPEED_OVERHEAL_RATE] = { Name = "Losses Overhealing", Description = "+ 25% Overheal Build Rate", Attributes = { { attr = "overheal fill rate reduced", increment = 0.25, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_OVERHEAL_DECAY] = { Name = "Longevity", Description = "+ 40% Slow Overheal Decay", Attributes = { { attr = "overheal decay bonus", increment = 0.4, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_WEAPON_MEDIGUN_RANGE] = { Name = "Extreme Range", Description = "+ 62.5% Medigun Range", Attributes = { { attr = "mult medigun range", increment = 0.625, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_WEAPON_MEDIGUN_UBERRATE] = { Name = "Blitzuber", Description = "+ 25% Ubercharge Rate", Attributes = { { attr = "ubercharge rate bonus", increment = 0.25, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_WEAPON_MEDIGUN_UBERDURATION] = { Name = "Time Dilation", Description = "+ 3 Second longer uber", Attributes = { { attr = "uber duration bonus", increment = 3, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_WEAPON_EFFECT_DURATION] = { Name = "Time Dilation", Description = "+ 37.5% Longer Effect Duration", Attributes = { { attr = "mult effect duration", increment = 0.375, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_EFFECTITEM, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_WEAPON_BANNER_EFFECT_DURATION] = { Name = "Time Dilation", Description = "+ 50% Longer Banner Duration", Attributes = { { attr = "increase buff duration", increment = 0.5, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_buff_item"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_WEAPON_BANNER_EFFECT_RANGE] = { Name = "Charge Order", Description = "+ 37.5% Banner Range", Attributes = { { attr = "mod soldier buff range", increment = 0.375, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_buff_item"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_HEALTH_ROCKETJUMP_REDUC] = { Name = "Metal Boots", Description = "+ 10% Blast Jump Damage Resistance", Attributes = { { attr = "rocket jump damage reduction", increment = 0.9, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = WEAPONS_LIST_EXPLOSIVE, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_WEAPON_FLAME_RANGE] = { Name = "High Pressure", Description = "+ 25% Flame Range", Attributes = { { attr = "flame_drag", increment = 0.75, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = nil, default = 8.5 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_flamethrower"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_SPEED_AFTERBURN_RATE] = { Name = "Incineration", Description = "+ 62.5% Afterburn Damage Rate", Attributes = { { attr = "weapon burn time increased", increment = 0.625, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_AFTERBURN, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_DMG_AXTING_MINITOCRIT] = { Name = "Finishing Blow", Description = "+ Axtinguisher Mini-Crits Become Crits", Attributes = { { attr = "minicrits become crits", increment = 1, slot = LOADOUT_POSITION_MELEE, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["The Axtinguisher"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_DMG_GASMULT] = { Name = "Noxious Gas", Description = "+ 100% Gas Passer damage mult", Attributes = { { attr = "dmg penalty vs players", increment = 1, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_weapon_jar_gas"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_SPEED_STICKY_CHARGE] = { Name = "Fast Shot", Description = "+ 25% Sticky Charge Rate", Attributes = { { attr = "stickybomb charge rate", increment = 0.75, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_pipebomblauncher"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_SHIELD_CHARGE] = { Name = "DUI", Description = "+ 12.5% Charge Move Speed", Attributes = { { attr = "mult charging move speed", increment = 0.125, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_SHIELD_KBRES] = { Name = "Iron Wall", Description = "+ 25% Damage Push Force Reduction", Attributes = { { attr = "damage force reduction", increment = 0.75, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_DMG_SHIELD_IMPACT] = { Name = "Spiked Shield", Description = "+ 37.5% Shield Impact Damage", Attributes = { { attr = "charge impact damage increased", increment = 0.375, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_SPEED_MINIGUN_SPINUP] = { Name = "Mobile Turret", Description = "+ 25% Spinup Speed", Attributes = { { attr = "minigun spinup time decreased", increment = 0.75, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_minigun"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_WEAPON_ATTACK_PROJ] = { Name = "Attack Projectilies", Description = "+ Minigun can shoot down projectiles", Attributes = { { attr = "attack projectiles", increment = 1, slot = LOADOUT_POSITION_PRIMARY, type = "set", cap = 1, default = 0 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_minigun"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_HEALTH_LUNCHBOX] = { Name = "Extra Toppings", Description = "+ 50% Healing Effect", Attributes = { { attr = "lunchbox healing decreased", increment = 0.5, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["tf_weapon_lunchbox"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_HEALTH_FOS_RANGERES] = { Name = "Reinforced Steel", Description = "+ 10% Range Damage Resistance (FOS)", Attributes = { { attr = "dmg from ranged reduced", increment = 0.1, slot = LOADOUT_POSITION_MELEE, type = "subtract", cap = 0.2, default = 0.6 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["Fists of Steel"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_DMG_KGB_CRITDURATION] = { Name = "Heavyweight Camp", Description = "+ 3 Second of Crit Boost on kill (melee)", Attributes = { { attr = "critboost on kill", increment = 3, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 5 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["The Killing Gloves of Boxing"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_SPEED_SNIPER_CHARGERATE] = { Name = "Hard Focus", Description = "+ 20% Faster Charge Rate", Attributes = { { attr = "SRifle Charge rate increased", increment = 1.2, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = 2, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_sniperrifle"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_SNIPER_REZOOM] = { Name = "Sniper Expert", Description = "+ 40% Faster Re-zoom", Attributes = { { attr = "ability master sniper", increment = 1, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = 1, default = 0 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_sniperrifle"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_WEAPON_ARROWMULT] = { Name = "Arrow Mastery", Description = "+ 2 Arrows per shot", Attributes = { { attr = "mult projectile count", increment = 2, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = 8, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_compound_bow"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_DMG_MACHINA_DMG] = { Name = "Power Shot", Description = "+ 75% Full Charged Damage", Attributes = { { attr = "sniper full charge damage bonus", increment = 0.75, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["The Machina"] = true,["Shooting Star"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_DMG_REVOLVER_DISGUISED] = { Name = "Saboteur", Description = "+ 37.5% Revolver Damage Bonus While Disguised", Attributes = { { attr = "damage bonus while disguised", increment = 0.375, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_weapon_revolver"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_SPEED_CLOAKREGEN] = { Name = "Rapid Recharge", Description = "+ 25% Cloak Regen Rate", Attributes = { { attr = "mult cloak meter regen rate", increment = 0.25, slot = LOADOUT_POSITION_PDA2, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_CLOAKDURATION] = { Name = "Against The Cloak", Description = "+ 20% Slower Cloak Consume Rate", Attributes = { { attr = "cloak consume rate decreased", increment = 0.8, slot = LOADOUT_POSITION_PDA2, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_SPEED_CLOAKSPEED] = { Name = "Shadow Walk", Description = "+ 20% Move Speed While Cloaked", Attributes = { { attr = "move speed bonus resource level", increment = 0.2, slot = LOADOUT_POSITION_PDA2, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_HEALTH_DISGUISED_RES] = { Name = "Thick Suit", Description = "+ 5% Damage Resistance While Disguised", Attributes = { { attr = "disguise damage reduction", increment = 0.95, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = 0.4, default = 1 } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["tf_weapon_pda_spy"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_RARE_WEAPON_CLOAKSNEAK] = { Name = "Sneak Attack", Description = "+ You can break cloak by attacking", Attributes = { { attr = "effect cond override", increment = 66, slot = LOADOUT_POSITION_PDA2, type = "set", cap = 66, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["The Dead Ringer"] = false,["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_RARE_WEAPON_SAPPERMILK] = { Name = "Disable Defenses", Description = "+ Sapper also coats enemies in mad milk", Attributes = { { attr = "effect cond override", increment = (TF_COND_MAD_MILK*65536), slot = LOADOUT_POSITION_PDA2, type = "add", cap = nil, default = TF_COND_SAPPED }, { attr = "display duck leaderboard ", increment = 1, slot = LOADOUT_POSITION_BUILDING, type = "set", cap = 1, default = 0, refund_set = nil }  }, Type = UPGRADE_TYPE_RARE, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_BUILDER_SPY"] = true,["Upgradeable TF_WEAPON_BUILDER_SPY"] = true,["tf_weapon_sapper"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	--Epic: Common + Uncommon + Rare
	[UPGRADE_EPIC_DMG] =  	{ Name = "Damage Shot", Description = "+ 80% Damage", Attributes = { { attr = "damage bonus", increment = 0.8, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_DMG_CRIT_RATE] = { Name = "Deadeye", Description = "+ 15% Crit Rate", Attributes = { { attr = "crit mod disabled hidden", increment = 0.15, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_DMG_CRIT_DAMAGE] = { Name = "Hot Shot", Description = "+ 80% Crit Damage", Attributes = { { attr = "mult crit dmg", increment = 0.8, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_DMG_BULLETS_PER_SHOT] = { Name = "Overloaded Shot", Description = "+ 100% Bullets Per Shot (rounded down)", Attributes = { { attr = "bullets per shot bonus", increment = 1, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_DMG_AT_CLOSE] = { Name = "Danger Enthusiast", Description = "+ 60% Damage At Close Range", Attributes = { { attr = "mult dmg before distance", increment = 0.60, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 }, { attr = "mult dmg before distance specify", increment = 256, slot = LOADOUT_POSITION_BODY, type = "set", cap = nil, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_DMG_MELEE] = { Name = "Dense Weapon", Description = "+ 120% Melee Damage", Attributes = { { attr = "damage bonus", increment = 1.2, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_DMG_JARATE_SHOT] = { Name = "Biohazard Rounds", Description = "+ 4% Chance to apply jarate on hit", Attributes = { { attr = "throwable damage", increment = 4, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = 100, default = 0 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_DMG_BURN] = { Name = "Fire Starter", Description = "+ 200% Afterburn Damage", Attributes = { { attr = "weapon burn dmg increased", increment = 2, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 }, { attr = "weapon burn dmg increased", increment = 2, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_AFTERBURN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_DMG_BLEED] = { Name = "Serrated Blade", Description = "+ 200% Bleed Damage", Attributes = { { attr = "mult bleeding dmg", increment = 2, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 }, { attr = "mult bleeding dmg", increment = 2, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_BLEED, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_DMG_BULLET_MARK] = { Name = "Hunter's Mark", Description = "+ Mark one enemy for death on hit.", Attributes = { { attr = "mark for death", increment = 1, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil }, -- There it is!
	
	[UPGRADE_EPIC_SPEED_FIRERATE] = { Name = "Supercharged", Description = "+ 20% Fire rate", Attributes = { { attr = "fire rate bonus", increment = 0.8, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_FIRERATE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_MOVESPEED] = { Name = "Speed Boots", Description = "+ 25% Move Speed", Attributes = { { attr = "move speed bonus", increment = 0.25, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_PROJSPEED] = { Name = "Speed Shot", Description = "+ 60% Projectile Speed", Attributes = { { attr = "projectile speed increased", increment = 0.60, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_PROJECTILE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_DEPLOYSPEED] = { Name = "Quick Draw", Description = "+ 50% Deploy Speed", Attributes = { { attr = "deploy time decreased", increment = 0.5, slot = LOADOUT_POSITION_BODY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_SLOW_ON_HIT] = { Name = "Sludge Bullets", Description = "+ Slow on hit \n+ 15% Slow strength", Attributes = { { attr = "stun on hit", increment = 1, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "set", cap = nil, default = 0, refund_set = nil, }, { attr = "stun on hit slow", increment = 0.15, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = 0.75, default = 0  }, { attr = "stun on hit type", increment = "movement", slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "set", cap = nil, default = 0, refund_set = nil, } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_RECHARGE_RATE] = { Name = "Rapid Recharge", Description = "+ 33% Item Recharge Rate", Attributes = { { attr = "effect bar recharge rate increased", increment = 0.67, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  }, { attr = "mult_item_meter_charge_rate", increment = 0.67, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  }, { attr = "charge recharge rate increased", increment = 0.67, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_RECHARGEBARITEM, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_HASTE] = { Name = "Haste!", Description = "+ Gain the Haste Powerup for the first 6 seconds of an encounter", Attributes = { { attr = "kill eater user 1", increment = 1, slot = LOADOUT_POSITION_BODY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_ADDERANLINE] = { Name = "Adderanline", Description = "+ 33% Faster weapon fire rate on kill for 3 seconds", Attributes = { { attr = "kill eater user 2", increment = 0.67, slot = LOADOUT_POSITION_BODY, type = "set", cap = 0.67, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_WEAPON_CLIPSIZE] = { Name = "Massive Clip", Description = "+ 165% Clip Size", Attributes = { { attr = "clip size bonus", increment = 1.65, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_CLIPSIZE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_WEAPON_RESERVEAMMO] = { Name = "Ammo Pack", Description = "+ 60% Reserve Ammo", Attributes = { { attr = "maxammo primary increased", increment = 0.6, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 }, { attr = "maxammo secondary increased", increment = 0.6, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_RESERVEAMMO, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_WEAPON_AMMOREGEN] = { Name = "Feedback Loop", Description = "+ 20% Ammo Regen", Attributes = { { attr = "ammo regen", increment = 0.2, slot = LOADOUT_POSITION_BODY, type = "add", cap = 1, default = 0 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_RESERVEAMMO, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_WEAPON_BLAST_RADIUS] = { Name = "Enhanced Payload", Description = "+ 50% Blast Radius", Attributes = { { attr = "blast radius increased", increment = 0.5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_EXPLOSIVE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_WEAPON_SPREAD] = { Name = "Deadly Precision", Description = "+ 30% Accuracy", Attributes = { { attr = "weapon spread bonus", increment = 0.7, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_WEAPON_MELEE_RANGE] = { Name = "Comically Large Melee", Description = "+ 60% Melee Range", Attributes = { { attr = "melee range multiplier", increment = 0.6, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_WEAPON_RAMPUP] = { Name = "Increased Rampup", Description = "+ Maximum damage ramp-up increased to 50%", Attributes = { { attr = "no reduced damage rampup", increment = 1, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_RAMPUP, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_WEAPON_PASSIVE_RELOAD] = { Name = "Passive Reload", Description = "+ Weapons passive reload when not active \n+ Ignores reload speed penalties", Attributes = { { attr = "passive reload", increment = 1, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_RELOAD, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_HEALTH_BONUS] = { Name = "Health Boost", Description = "+ 100 Max Health", Attributes = { { attr = "max health additive bonus", increment = 100, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_HEALTH_MULT] = { Name = "Bunch O' Banana", Description = "+ 25% Max Health Multiplier", Attributes = { { attr = "mult max health", increment = 0.25, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_HEALTH_REGEN] = { Name = "Life Regen", Description = "+ 6 Health Regen", Attributes = { { attr = "health regen", increment = 6, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_HEALTH_HOK] = { Name = "Vampire", Description = "+ 25 Health on kill", Attributes = { { attr = "heal on kill", increment = 25, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_HEALTH_MILKY] = { Name = "Mad Shots", Description = "+ 8% Chance to apply mad milk on hit", Attributes = { { attr = "throwable healing", increment = 8, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = 100, default = 0 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_HEALTH_TTG] = { Name = "Grinding Monstera", Description = "+ Melee marks enemies for health \n  Killing the enemy will increase your max hp by 2", Attributes = { { attr = "duckstreaks active", increment = 2, slot = LOADOUT_POSITION_MELEE, type = "set", cap = 2, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_HEALTH_RECEIVED] = { Name = "Quick-Fix", Description = "+ 25% Health from all sources", Attributes = { { attr = "healing received bonus", increment = 0.25, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_MONEY_INCOME] = { Name = "Paycheck", Description = "+ 6 Credits every second while in combat \n  Max of x*100 credits per combat", Attributes = { { attr = "currency bonus", increment = 6, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_MONEY_GOLDEN_ENEMIES] = { Name = "Golden Enemies", Description = "+ 2.5% Chance for enemies to give 5x the money on death \n+ Global upgrade: Affects everyone on your team", Attributes = { { attr = "is australium item", increment = 2.5, slot = LOADOUT_POSITION_BODY, type = "add", cap = 100, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = function(player, upgrade) ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] = ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] + 2.5 end, SalvagedFunction = function(player, upgrade) ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] = ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] - 2.5 end },
	[UPGRADE_EPIC_MONEY_WIRE_TAP] = { Name = "Wire Tap", Description = "+ 8 Credits on hit", Attributes = { { attr = "expiration date", increment = 8, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	-- Specialized Upgrades --
	
	[UPGRADE_EPIC_WEAPON_PENETRATION] = { Name = "Bullet Penetration", Description = "+ 5 Penetration", Attributes = { { attr = "projectile penetration heavy", increment = 5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_HEALTH_BUILDING] = { Name = "Hardened Steel", Description = "+ 120% Building Health", Attributes = { { attr = "engy building health bonus", increment = 1.2, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_HEALTH_DISPENSER_RATE] = { Name = "Mass Production", Description = "+ 80% Dispenser Rate", Attributes = { { attr = "mult dispenser rate", increment = 0.8, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_DMG_SENTRY_DMG] = { Name = "Damage Shot", Description = "+ 120% Sentry Damage", Attributes = { { attr = "engy sentry damage bonus", increment = 1.2, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_SPEED_SENTRY_FIRERATE] = { Name = "Super Cycle", Description = "+ 20% Sentry Fire Rate", Attributes = { { attr = "engy sentry fire rate increased", increment = 0.8, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_TELEPORTERRECHARGE] = { Name = "Ultra Charge", Description = "+ 33% Faster Teleporter Recharge", Attributes = { { attr = "mult teleporter recharge rate", increment = 0.67, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_CONSTRUCTION] = { Name = "Construction Permit", Description = "+ 80% Construction Boost", Attributes = { { attr = "Construction rate increased", increment = 0.8, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_BUILDRATE] = { Name = "Turbo Boost", Description = "+ 25% Faster Building", Attributes = { { attr = "build rate bonus", increment = 0.75, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_SENTRY_ROCKET] = { Name = "Speed Shot", Description = "+ 60% Sentry Rocket Speed", Attributes = { { attr = "mult sentry rocket projectile speed", increment = 0.6, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_WEAPON_SENTRY_RANGE] = { Name = "Long Range Sensors", Description = "+ 60% Sentry Range", Attributes = { { attr = "engy sentry radius increased", increment = 0.6, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_WEAPON_SENTRY_AMMO] = { Name = "Ammo Linkage", Description = "+ 80% Sentry Ammo", Attributes = { { attr = "mvm sentry ammo", increment = 0.8, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_HEALTH_HEALRATE] = { Name = "Quick-Fix", Description = "+ 60% Heal Rate", Attributes = { { attr = "heal rate bonus", increment = 0.6, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_HEALTH_OVERHEAL] = { Name = "Health Overdrive", Description = "+ 80% Max Overheal", Attributes = { { attr = "overheal bonus", increment = 0.8, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_SPEED_OVERHEAL_RATE] = { Name = "Losses Overhealing", Description = "+ 40% Overheal Build Rate", Attributes = { { attr = "overheal fill rate reduced", increment = 0.4, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_OVERHEAL_DECAY] = { Name = "Longevity", Description = "+ 65% Slow Overheal Decay", Attributes = { { attr = "overheal decay bonus", increment = 0.65, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_WEAPON_MEDIGUN_RANGE] = { Name = "Extreme Range", Description = "+ 100% Medigun Range", Attributes = { { attr = "mult medigun range", increment = 1, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_WEAPON_MEDIGUN_UBERRATE] = { Name = "Blitzuber", Description = "+ 40% Ubercharge Rate", Attributes = { { attr = "ubercharge rate bonus", increment = 0.4, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_WEAPON_MEDIGUN_UBERDURATION] = { Name = "Time Dilation", Description = "+ 5 Second longer uber", Attributes = { { attr = "uber duration bonus", increment = 5, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_WEAPON_MEDIGUN_UBERSTAY] = { Name = "Persistent Uber", Description = "+ Uber effect stays on target", Attributes = { { attr = "medigun keep charged effect", increment = 1, slot = LOADOUT_POSITION_SECONDARY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_DMG_MEDIGUN_DAMAGE] = { Name = "Reverse Module", Description = "+ 50% Of heal rate to damage \n+ 25% Of damage back as health", Attributes = { { attr = "medigun attack enemy", increment = 0.5, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 0 }, { attr = "damage returns as health", increment = 0.25, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_WEAPON_EFFECT_DURATION] = { Name = "Time Dilation", Description = "+ 60% Longer Effect Duration", Attributes = { { attr = "mult effect duration", increment = 0.6, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_EFFECTITEM, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_WEAPON_BANNER_EFFECT_DURATION] = { Name = "Time Dilation", Description = "+ 80% Longer Banner Duration", Attributes = { { attr = "increase buff duration", increment = 0.8, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_buff_item"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_WEAPON_BANNER_EFFECT_RANGE] = { Name = "Charge Order", Description = "+ 60% Banner Range", Attributes = { { attr = "mod soldier buff range", increment = 0.6, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_buff_item"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_HEALTH_ROCKETJUMP_REDUC] = { Name = "Metal Boots", Description = "+ 20% Blast Jump Damage Resistance", Attributes = { { attr = "rocket jump damage reduction", increment = 0.8, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = WEAPONS_LIST_EXPLOSIVE, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_DMG_BLAST_INCREASED] = { Name = "Deadly Blast", Description = "+ 5% Damage per enemy in blast", Attributes = { { attr = "add damage per target", increment = 0.05, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_EXPLOSIVE, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_WEAPON_FLAME_RANGE] = { Name = "High Pressure", Description = "+ 33% Flame Range", Attributes = { { attr = "flame_drag", increment = 0.67, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = nil, default = 8.5 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_flamethrower"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_SPEED_AFTERBURN_RATE] = { Name = "Incineration", Description = "+ 100% Afterburn Damage Rate", Attributes = { { attr = "weapon burn time increased", increment = 1, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_AFTERBURN, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_SPEED_STICKY_CHARGE] = { Name = "Fast Shot", Description = "+ 33% Sticky Charge Rate", Attributes = { { attr = "stickybomb charge rate", increment = 0.67, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_pipebomblauncher"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_SHIELD_CHARGE] = { Name = "DUI", Description = "+ 20% Charge Move Speed", Attributes = { { attr = "mult charging move speed", increment = 0.2, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_SHIELD_KBRES] = { Name = "Iron Wall", Description = "+ 33% Damage Push Force Reduction", Attributes = { { attr = "damage force reduction", increment = 0.67, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_DMG_SHIELD_IMPACT] = { Name = "Spiked Shield", Description = "+ 60% Shield Impact Damage", Attributes = { { attr = "charge impact damage increased", increment = 0.6, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_SPEED_MINIGUN_SPINUP] = { Name = "Mobile Turret", Description = "+ 33% Spinup Speed", Attributes = { { attr = "minigun spinup time decreased", increment = 0.67, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_minigun"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_MINIGUN_MOVESPEED] = { Name = "Light Metal", Description = "+ 40% Move speed while spun up", Attributes = { { attr = "aiming movespeed increased", increment = 0.4, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = 1.2, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_minigun"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_HEALTH_LUNCHBOX] = { Name = "Extra Toppings", Description = "+ 80% Healing Effect", Attributes = { { attr = "lunchbox healing decreased", increment = 0.8, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["tf_weapon_lunchbox"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_SPEED_SNIPER_CHARGERATE] = { Name = "Hard Focus", Description = "+ 33% Faster Charge Rate", Attributes = { { attr = "SRifle Charge rate increased", increment = 1.33, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = 2, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_sniperrifle"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_SNIPER_REZOOM] = { Name = "Sniper Master", Description = "+ 30% Faster Re-zoom", Attributes = { { attr = "ability master sniper", increment = 1, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = 2, default = 0 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_sniperrifle"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_DMG_SNIPER_EHDAMAGE] = { Name = "Deadly Precision", Description = "+ 40% Explosive Headshot Damage", Attributes = { { attr = "bleeding dmg", increment = 0.2, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_weapon_sniperrifle"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_DMG_MACHINA_DMG] = { Name = "Power Shot", Description = "+ 120% Full Charged Damage", Attributes = { { attr = "sniper full charge damage bonus", increment = 1.2, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["The Machina"] = true,["Shooting Star"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_DMG_REVOLVER_DISGUISED] = { Name = "Saboteur", Description = "+ 60% Revolver Damage Bonus While Disguised", Attributes = { { attr = "damage bonus while disguised", increment = 0.6, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_weapon_revolver"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_SPEED_CLOAKREGEN] = { Name = "Rapid Recharge", Description = "+ 40% Cloak Regen Rate", Attributes = { { attr = "mult cloak meter regen rate", increment = 0.4, slot = LOADOUT_POSITION_PDA2, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_CLOAKDURATION] = { Name = "Against The Cloak", Description = "+ 33% Slower Cloak Consume Rate", Attributes = { { attr = "cloak consume rate decreased", increment = 0.67, slot = LOADOUT_POSITION_PDA2, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_EPIC_SPEED_CLOAKSPEED] = { Name = "Shadow Walk", Description = "+ 33% Move Speed While Cloaked", Attributes = { { attr = "move speed bonus resource level", increment = 0.33, slot = LOADOUT_POSITION_PDA2, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_EPIC_HEALTH_DISGUISED_RES] = { Name = "Thick Suit", Description = "+ 10% Damage Resistance While Disguised", Attributes = { { attr = "disguise damage reduction", increment = 0.9, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = 0.4, default = 1 } }, Type = UPGRADE_TYPE_EPIC, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["tf_weapon_pda_spy"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	--Legendary: 2Common + Uncommon + Rare + Epic
	[UPGRADE_LEGENDARY_DMG] =  	{ Name = "Pure Damage", Description = "+ 200% Damage", Attributes = { { attr = "damage bonus", increment = 2, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_DMG_CRIT_RATE] = { Name = "Kritzkrieg", Description = "+ 35% Crit Rate", Attributes = { { attr = "crit mod disabled hidden", increment = 0.35, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_DMG_CRIT_DAMAGE] = { Name = "Mega Crit", Description = "+ 200% Crit Damage", Attributes = { { attr = "mult crit dmg", increment = 2, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_DMG_BULLETS_PER_SHOT] = { Name = "Split Shot", Description = "+ 170% Bullets Per Shot (rounded down)", Attributes = { { attr = "bullets per shot bonus", increment = 1.7, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_DMG_AT_CLOSE] = { Name = "Close Range Expert", Description = "+ 135% Damage At Close Range", Attributes = { { attr = "mult dmg before distance", increment = 1.35, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 }, { attr = "mult dmg before distance specify", increment = 256, slot = LOADOUT_POSITION_BODY, type = "set", cap = nil, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_DMG_MELEE] = { Name = "Pure Muscle", Description = "+ 300% Melee Damage", Attributes = { { attr = "damage bonus", increment = 3, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_DMG_JARATE_SHOT] = { Name = "Bullet Based Karate", Description = "+ 10% Chance to apply jarate on hit", Attributes = { { attr = "throwable damage", increment = 10, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = 100, default = 0 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_DMG_BURN] = { Name = "Napalm Fire", Description = "+ 500% Afterburn Damage", Attributes = { { attr = "weapon burn dmg increased", increment = 5, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 }, { attr = "weapon burn dmg increased", increment = 5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_AFTERBURN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_DMG_BLEED] = { Name = "Internal Bleeding", Description = "+ 500% Bleed Damage", Attributes = { { attr = "mult bleeding dmg", increment = 5, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 }, { attr = "mult bleeding dmg", increment = 5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_BLEED, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_DMG_HEADSHOT] = { Name = "Can Headshot", Description = "+ Weapons can deal critical damage on headshot", Attributes = { { attr = "can headshot", increment = 1, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_SPEED_FIRERATE] = { Name = "Hailstorm", Description = "+ 33% Fire rate", Attributes = { { attr = "fire rate bonus", increment = 0.67, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_FIRERATE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_MOVESPEED] = { Name = "Pure Speed", Description = "+ 40% Move Speed", Attributes = { { attr = "move speed bonus", increment = 0.4, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_PROJSPEED] = { Name = "Instant Shot", Description = "+ 125% Projectile Speed", Attributes = { { attr = "projectile speed increased", increment = 1.25, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_PROJECTILE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_DEPLOYSPEED] = { Name = "Cowboy", Description = "+ 80% Deploy Speed", Attributes = { { attr = "deploy time decreased", increment = 0.2, slot = LOADOUT_POSITION_BODY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_RECHARGE_RATE] = { Name = "Instant Recharge", Description = "+ 50% Item Recharge Rate", Attributes = { { attr = "effect bar recharge rate increased", increment = 0.5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  }, { attr = "mult_item_meter_charge_rate", increment = 0.5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1  }, { attr = "charge recharge rate increased", increment = 0.5, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1  } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_RECHARGEBARITEM, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_WEAPON_CLIPSIZE] = { Name = "Terminator Logic", Description = "+ 350% Clip Size", Attributes = { { attr = "clip size bonus", increment = 3.5, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_CLIPSIZE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_WEAPON_RESERVEAMMO] = { Name = "Endless Ammo", Description = "+ 135% Reserve Ammo", Attributes = { { attr = "maxammo primary increased", increment = 1.35, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 }, { attr = "maxammo secondary increased", increment = 0.6, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_RESERVEAMMO, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_WEAPON_AMMOREGEN] = { Name = "Bluetooth Supply", Description = "+ 45% Ammo Regen", Attributes = { { attr = "ammo regen", increment = 0.45, slot = LOADOUT_POSITION_BODY, type = "add", cap = 1, default = 0 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_RESERVEAMMO, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_WEAPON_BLAST_RADIUS] = { Name = "Hyper Blast", Description = "+ 125% Blast Radius", Attributes = { { attr = "blast radius increased", increment = 1.25, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_EXPLOSIVE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_WEAPON_SPREAD] = { Name = "Nevamiss", Description = "+ 60% Accuracy", Attributes = { { attr = "weapon spread bonus", increment = 0.4, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_WEAPON_MELEE_RANGE] = { Name = "Absurd Range", Description = "+ 135% Melee Range", Attributes = { { attr = "melee range multiplier", increment = 1.35, slot = LOADOUT_POSITION_MELEE, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_HEALTH_BONUS] = { Name = "Pure Health", Description = "+ 200 Max Health", Attributes = { { attr = "max health additive bonus", increment = 100, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_HEALTH_MULT] = { Name = "Banana Harvest", Description = "+ 55% Max Health Multiplier", Attributes = { { attr = "mult max health", increment = 0.55, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_HEALTH_REGEN] = { Name = "Portable Sandvich", Description = "+ 10 Health Regen", Attributes = { { attr = "health regen", increment = 10, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_HEALTH_HOK] = { Name = "Health Shot", Description = "+ 40 Health on kill", Attributes = { { attr = "heal on kill", increment = 40, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_HEALTH_MILKY] = { Name = "Milk Shots", Description = "+ 20% Chance to apply mad milk on hit", Attributes = { { attr = "throwable healing", increment = 20, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = 100, default = 0 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_HEALTH_RECEIVED] = { Name = "Uber-Fix", Description = "+ 50% Health from all sources", Attributes = { { attr = "healing received bonus", increment = 0.5, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_MONEY_INCOME] = { Name = "Cashout", Description = "+ 15 Credits every second while in combat \nMax of x*100 credits per combat", Attributes = { { attr = "currency bonus", increment = 15, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_MONEY_GOLDEN_ENEMIES] = { Name = "Australium Enemies", Description = "+ 6% Chance for enemies to give 5x the money on death \n+ Global upgrade: Affects everyone on your team", Attributes = { { attr = "is australium item", increment = 6, slot = LOADOUT_POSITION_BODY, type = "add", cap = 100, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = function(player, upgrade) ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] = ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] + 6 end, SalvagedFunction = function(player, upgrade) ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] = ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] - 6 end },
	[UPGRADE_LEGENDARY_MONEY_WIRE_TAP] = { Name = "Tax Gun", Description = "+ 20 Credits on hit", Attributes = { { attr = "expiration date", increment = 20, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_MONEY_DISCOUNT] = { Name = "Hale’s Own Discount", Description = "+ Shop prices are 40% Cheaper", Attributes = { { attr = "tag__eotlearlysupport", increment = 0.4, slot = LOADOUT_POSITION_BODY, type = "subtract", cap = 0.6, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_MONEY, WeaponList = nil, ApplyFunction = function(player,upgrade) player.CostMult = player.CostMult - 0.4 end, SalvagedFunction = function(player,upgrade) player.CostMult = player.CostMult + 0.4 end },
	
	-- Specialized Upgrades --
	
	[UPGRADE_LEGENDARY_WEAPON_PENETRATION] = { Name = "Bullet Penetration", Description = "+ 8 Penetration", Attributes = { { attr = "projectile penetration heavy", increment = 8, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_HITSCAN, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_HEALTH_BUILDING] = { Name = "Energy Shield", Description = "+ 200% Building Health", Attributes = { { attr = "engy building health bonus", increment = 2, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_HEALTH_DISPENSER_RATE] = { Name = "Production Overdrive", Description = "+ 150% Dispenser Rate", Attributes = { { attr = "mult dispenser rate", increment = 1.5, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_DMG_SENTRY_DMG] = { Name = "Pure Damage", Description = "+ 300% Sentry Damage", Attributes = { { attr = "engy sentry damage bonus", increment = 3, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_SPEED_SENTRY_FIRERATE] = { Name = "Hailstorm", Description = "+ 33% Sentry Fire Rate", Attributes = { { attr = "engy sentry fire rate increased", increment = 0.8, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_TELEPORTERRECHARGE] = { Name = "Instant Recharge", Description = "+ 50% Faster Teleporter Recharge", Attributes = { { attr = "mult teleporter recharge rate", increment = 0.5, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_CONSTRUCTION] = { Name = "Build-A-Sentry", Description = "+ 200% Construction Boost", Attributes = { { attr = "Construction rate increased", increment = 2, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_BUILDRATE] = { Name = "Turbo Boost", Description = "+ 50% Faster Building", Attributes = { { attr = "build rate bonus", increment = 0.5, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_BUILDQUICKSTART] = { Name = "Quickstart: Buildings", Description = "+ Builds start 1 level higher", Attributes = { { attr = "merasmus hat level display ONLY", increment = 1, slot = LOADOUT_POSITION_PDA, type = "add", cap = 2, default = 0 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_SENTRY_ROCKET] = { Name = "Instant Rockets", Description = "+ 125% Sentry Rocket Speed", Attributes = { { attr = "mult sentry rocket projectile speed", increment = 1.25, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_WEAPON_SENTRY_RANGE] = { Name = "Portable Wrangler", Description = "+ 135% Sentry Range", Attributes = { { attr = "engy sentry radius increased", increment = 1.35, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_WEAPON_SENTRY_AMMO] = { Name = "Terminator Logic", Description = "+ 200% Sentry Ammo", Attributes = { { attr = "mvm sentry ammo", increment = 2, slot = LOADOUT_POSITION_PDA, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_PDA_ENGINEER_BUILD"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_HEALTH_HEALRATE] = { Name = "Perma-charge", Description = "+ 135% Heal Rate", Attributes = { { attr = "heal rate bonus", increment = 1.35, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_HEALTH_OVERHEAL] = { Name = "Absurd Health", Description = "+ 200% Max Overheal", Attributes = { { attr = "overheal bonus", increment = 2, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_SPEED_OVERHEAL_RATE] = { Name = "Instant Overheal", Description = "+ 100% Overheal Build Rate", Attributes = { { attr = "overheal fill rate reduced", increment = 1, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_OVERHEAL_DECAY] = { Name = "Forever Health", Description = "+ 150% Slow Overheal Decay", Attributes = { { attr = "overheal decay bonus", increment = 1.5, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_WEAPON_MEDIGUN_RANGE] = { Name = "Global Range", Description = "+ 250% Medigun Range", Attributes = { { attr = "mult medigun range", increment = 2.5, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_WEAPON_MEDIGUN_UBERRATE] = { Name = "Insta-Uber", Description = "+ 100% Ubercharge Rate", Attributes = { { attr = "ubercharge rate bonus", increment = 1, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_WEAPON_MEDIGUN_UBERDURATION] = { Name = "Extreme Duration", Description = "+ 8 Second longer uber", Attributes = { { attr = "uber duration bonus", increment = 8, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["TF_WEAPON_MEDIGUN"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_WEAPON_EFFECT_DURATION] = { Name = "Extreme Duration", Description = "+ 135% Longer Effect Duration", Attributes = { { attr = "mult effect duration", increment = 1.35, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = WEAPONS_LIST_EFFECTITEM, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_WEAPON_BANNER_EFFECT_DURATION] = { Name = "Extreme Duration", Description = "+ 200% Longer Banner Duration", Attributes = { { attr = "increase buff duration", increment = 2, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_buff_item"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_WEAPON_BANNER_EFFECT_RANGE] = { Name = "War Charge", Description = "+ 135% Banner Range", Attributes = { { attr = "mod soldier buff range", increment = 1.35, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_buff_item"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_HEALTH_ROCKETJUMP_REDUC] = { Name = "Pocket Gunboats", Description = "+ 40% Blast Jump Damage Resistance", Attributes = { { attr = "rocket jump damage reduction", increment = 0.6, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = WEAPONS_LIST_EXPLOSIVE, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_DMG_BLAST_INCREASED] = { Name = "Deadly Blast", Description = "+ 10% Damage per enemy in blast", Attributes = { { attr = "add damage per target", increment = 0.1, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = WEAPONS_LIST_EXPLOSIVE, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_WEAPON_FLAME_RANGE] = { Name = "Super Condensed Air", Description = "+ 50% Flame Range", Attributes = { { attr = "flame_drag", increment = 0.5, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = nil, default = 8.5 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_flamethrower"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_SPEED_AFTERBURN_RATE] = { Name = "Red Phosphorus", Description = "+ 250% Afterburn Damage Rate", Attributes = { { attr = "weapon burn time increased", increment = 2.5, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = WEAPONS_LIST_AFTERBURN, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_SPEED_STICKY_CHARGE] = { Name = "Instant Charge", Description = "+ 50% Sticky Charge Rate", Attributes = { { attr = "stickybomb charge rate", increment = 0.5, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_pipebomblauncher"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_SHIELD_CHARGE] = { Name = "Speeding Targe", Description = "+ 33% Charge Move Speed", Attributes = { { attr = "mult charging move speed", increment = 0.33, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_SHIELD_KBRES] = { Name = "Immoveable Targe", Description = "+ 50% Damage Push Force Reduction", Attributes = { { attr = "damage force reduction", increment = 0.50, slot = LOADOUT_POSITION_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_DMG_SHIELD_IMPACT] = { Name = "Unstoppable Force", Description = "+ 135% Shield Impact Damage", Attributes = { { attr = "charge impact damage increased", increment = 1.35, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_wearable_demoshield"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_SPEED_MINIGUN_SPINUP] = { Name = "Instant Spinup", Description = "+ 50% Spinup Speed", Attributes = { { attr = "minigun spinup time decreased", increment = 0.5, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_minigun"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_WEAPON_ATTACK_PROJ] = { Name = "Destroy Projectilies", Description = "+ Minigun will shoot down projectiles", Attributes = { { attr = "attack projectiles", increment = 2, slot = LOADOUT_POSITION_PRIMARY, type = "set", cap = 2, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_minigun"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_HEALTH_LUNCHBOX] = { Name = "Sandvich Deluxe", Description = "+ 200% Healing Effect", Attributes = { { attr = "lunchbox healing decreased", increment = 2, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["tf_weapon_lunchbox"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_SPEED_SNIPER_CHARGERATE] = { Name = "Unbreakable Focus", Description = "+ 50% Faster Charge Rate", Attributes = { { attr = "SRifle Charge rate increased", increment = 1.5, slot = LOADOUT_POSITION_PRIMARY, type = "multiply", cap = 2, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_sniperrifle"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_WEAPON_EXPLOSIVE_ARROWS] = { Name = "Explosive Arrows", Description = "+ Arrows explode on impact with enemy or after 2 seconds", Attributes = { { attr = "tag__summer2014", increment = 1, slot = LOADOUT_POSITION_PRIMARY, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_compound_bow"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_DMG_MACHINA_DMG] = { Name = "Railgun", Description = "+ 300% Full Charged Damage", Attributes = { { attr = "sniper full charge damage bonus", increment = 3, slot = LOADOUT_POSITION_PRIMARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["The Machina"] = true,["Shooting Star"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_DMG_REVOLVER_DISGUISED] = { Name = "Opportunistic", Description = "+ 135% Revolver Damage Bonus While Disguised", Attributes = { { attr = "damage bonus while disguised", increment = 1.35, slot = LOADOUT_POSITION_SECONDARY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_DAMAGE, WeaponList = {["tf_weapon_revolver"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_WEAPON_DISGUISE_FIREIMMUNE] = { Name = "Flame Retardant Suit", Description = "+ Immune to fire while disguised", Attributes = { { attr = "disguise no burn", increment = 1, slot = LOADOUT_POSITION_PDA, type = "set", cap = 1, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_WEAPON, WeaponList = {["tf_weapon_pda_spy"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_SPEED_CLOAKREGEN] = { Name = "Instant Recharge", Description = "+ 100% Cloak Regen Rate", Attributes = { { attr = "mult cloak meter regen rate", increment = 1, slot = LOADOUT_POSITION_PDA2, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_CLOAKDURATION] = { Name = "Cloak And Dagger", Description = "+ 50% Slower Cloak Consume Rate", Attributes = { { attr = "cloak consume rate decreased", increment = 0.5, slot = LOADOUT_POSITION_PDA2, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_LEGENDARY_SPEED_CLOAKSPEED] = { Name = "Speed of the Shadows", Description = "+ 50% Move Speed While Cloaked", Attributes = { { attr = "move speed bonus resource level", increment = 0.5, slot = LOADOUT_POSITION_PDA2, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_SPEED, WeaponList = {["tf_weapon_invis"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_LEGENDARY_HEALTH_DISGUISED_RES] = { Name = "Feigned Damage Report", Description = "+ 20% Damage Resistance While Disguised", Attributes = { { attr = "disguise damage reduction", increment = 0.8, slot = LOADOUT_POSITION_PDA, type = "multiply", cap = 0.4, default = 1 } }, Type = UPGRADE_TYPE_LEGENDARY, Category = UPGRADE_CATEGORY_HEALTH, WeaponList = {["tf_weapon_pda_spy"] = true}, ApplyFunction = nil, SalvagedFunction = nil },
	
	--Greed
	[UPGRADE_GREED_DMG] = { Name = "Double Or Nothing", Description = "+ 250% Global damage mult \n- 100% Damage vuln", Attributes = { { attr = "dmg penalty vs players", increment = 2.5, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 }, { attr = "dmg taken increased", increment = 1, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_GREED, Category = UPGRADE_CATEGORY_GREED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_GREED_DMG_MELEE] = { Name = "Brawler", Description = "+ 2x Melee Damage \n- 60% Range Damage", Attributes = { { attr = "dmg penalty vs players", increment = 2, slot = LOADOUT_POSITION_MELEE, type = "multiply", cap = nil, default = 1 }, { attr = "dmg penalty vs players", increment = 0.4, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_GREED, Category = UPGRADE_CATEGORY_GREED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_GREED_DMG_KB] = { Name = "Absurd Power", Description = "+ 100% Global damage mult \n- Shooting displaces you", Attributes = { { attr = "dmg penalty vs players", increment = 1, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 }, { attr = "airblast vulnerability multiplier hidden", increment = 200, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "add", cap = nil, default = 0 } }, Type = UPGRADE_TYPE_GREED, Category = UPGRADE_CATEGORY_GREED, WeaponList = WEAPONS_LIST_DAMAGE, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_GREED_SPEED_FIRERATE] = { Name = "Barrage Mode", Description = "+ 3x Fire rate \n+ 50% Clip Size \n- 30% Reload Speed", Attributes = { { attr = "fire rate bonus HIDDEN", increment = 0.33, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "multiply", cap = nil, default = 1 }, { attr = "clip size bonus", increment = 0.5, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 }, { attr = "reload time increased", increment = 0.3, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_GREED, Category = UPGRADE_CATEGORY_GREED, WeaponList = WEAPONS_LIST_FIRERATE, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_GREED_SPEED_MOVESPEED] = { Name = "Speed Demon", Description = "+ 100% Move speed \n- 30% Jump Height", Attributes = { { attr = "move speed bonus", increment = 1, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 }, { attr = "major increased jump height", increment = 0.3, slot = LOADOUT_POSITION_BODY, type = "subtract", cap = 0.1, default = 1 } }, Type = UPGRADE_TYPE_GREED, Category = UPGRADE_CATEGORY_GREED, WeaponList = nil, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_GREED_WEAPON_RELOAD] = { Name = "Committed Reload", Description = "+ 60% Reload Speed \n- Cannot switch or shoot while reloading", Attributes = { { attr = "faster reload rate", increment = 0.4, slot = LOADOUT_POSITION_BODY, type = "multiply", cap = nil, default = 1 }, { attr = "hold fire until full reload", increment = 2, slot = LOADOUT_POSITION_BODY, type = "set", cap = 2, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_GREED, Category = UPGRADE_CATEGORY_GREED, WeaponList = WEAPONS_LIST_RELOAD, ApplyFunction = nil, SalvagedFunction = nil },
	[UPGRADE_GREED_WEAPON_TURRET] = { Name = "Turret Mode", Description = "+ 33% Accuracy and fire rate while not moving \n- Inverted when moving", Attributes = { { attr = "throwable fire speed", increment = 0.67, slot = LOADOUT_POSITION_BODY, type = "set", cap = 0.67, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_GREED, Category = UPGRADE_CATEGORY_GREED, WeaponList = WEAPONS_LIST_FIRERATE, ApplyFunction = function(player,upgrade) StartTurretMode(player) end, SalvagedFunction = function(player,upgrade) StopTurretMode(player) end },
	
	[UPGRADE_GREED_HEALTH_MULT] = { Name = "Tank", Description = "+ 25% Max health multiplier stationary \n+ 5% Max health multiplier the end of an encounter \n- Lose max health when taking damage", Attributes = { { attr = "sapper health bonus", increment = 0.05, slot = LOADOUT_POSITION_BODY, type = "set", cap = 0.05, default = 0, refund_set = nil }, { attr = "mult max health", increment = 0.25, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 } }, Type = UPGRADE_TYPE_GREED, Category = UPGRADE_CATEGORY_GREED, WeaponList = WEAPONS_LIST_FIRERATE, ApplyFunction = function(player,upgrade) StartTankMode(player) end, SalvagedFunction = function(player,upgrade) StopTankMode(player) end },
	[UPGRADE_GREED_HEALTH_MULT_CLOSE_RANGE] = { Name = "Close Range Specialist", Description = "+ 150 Max health \n+ 100% Health Mult \n- Ranged attacks have limited rage", Attributes = { { attr = "max health additive bonus", increment = 150, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 0 }, { attr = "mult max health", increment = 1, slot = LOADOUT_POSITION_BODY, type = "add", cap = nil, default = 1 }, { attr = "max bullet range", increment = 350, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "set", cap = nil, default = 0, refund_set = nil }, { attr = "projectile detonate time", increment = 0.318, slot = LOADOUT_POSITION_PRIMARY_AND_SECONDARY, type = "set", cap = nil, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_GREED, Category = UPGRADE_CATEGORY_GREED, WeaponList = WEAPONS_LIST_FIRERATE, ApplyFunction = nil, SalvagedFunction = nil },
	
	[UPGRADE_GREED_MONEY_PHYSICAL] = { Name = "Physical Cash", Description = "+ Enemies give 3x the cash \n- You have to manually collect it \nTeammates are unaffected", Attributes = { { attr = "unlimited quantity", increment = 3, slot = LOADOUT_POSITION_BODY, type = "set", cap = 3, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_GREED, Category = UPGRADE_CATEGORY_GREED, WeaponList = nil, ApplyFunction = function(player,upgrade) player.CashMult = 0 end, SalvagedFunction = function(player,upgrade) player.CashMult = 1 end },
	[UPGRADE_GREED_MONEY_HAGGLE] = { Name = "Haggle", Description = "+ First purchase at a shop is 15% Cheaper \n- 1 Shop item for sale", Attributes = { { attr = "Wrench index", increment = 0.85, slot = LOADOUT_POSITION_BODY, type = "set", cap = 0.85, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_GREED, Category = UPGRADE_CATEGORY_GREED, WeaponList = nil, ApplyFunction = function(player,upgrade) player.DisplayedShopUpgrades = player.DisplayedShopUpgrades - 1; player.CanHaggle = true; end, SalvagedFunction = function(player,upgrade) player.DisplayedShopUpgrades = player.DisplayedShopUpgrades + 1; player.CanHaggle = false; end },
	[UPGRADE_GREED_MONEY_PERK_UPGRADE] = { Name = "High Roller", Description = "+ 33% Chance to upgrade loot by 1 tier \n- 1 Loot item from encounters", Attributes = { { attr = "freaky fair extra attrib1", increment = 0.33, slot = LOADOUT_POSITION_BODY, type = "set", cap = 0.33, default = 0, refund_set = nil } }, Type = UPGRADE_TYPE_GREED, Category = UPGRADE_CATEGORY_GREED, WeaponList = nil, ApplyFunction = function(player,upgrade) player.DisplayedUpgrades = player.DisplayedUpgrades - 1; end, SalvagedFunction = function(player,upgrade) player.DisplayedUpgrades = player.DisplayedUpgrades + 1; end },
}

UPGRADE_DEFAULT_MENU = {
	timeout	  = 0,
	title		= "Choose an Upgrade!",
	itemsPerPage = 5,
	flags		= MENUFLAG_BUTTON_EXIT | MENUFLAG_NO_SOUND,
	onSelect	 = UpgradeBrought,
	onCancel	 = UpgradeSkipped,
}

UPGRADE_VIEW_MENU = {
	timeout	  = 0,
	title		= "Your Upgrades (Press to salvage)",
	itemsPerPage = 5,
	flags		= MENUFLAG_BUTTON_EXIT,
	onSelect	 = UpgradeSalvaged,
	onCancel	 = nil,
}

UPGRADE_WARNING_MENU = {
	timeout	  = 0,
	title		= "Are you sure?",
	itemsPerPage = nil,
	flags		= MENUFLAG_BUTTON_EXITBACK,
	onSelect	 = UpgradeSalvaged,
	onCancel	 = nil,
}

UPGRADE_VOTING_MENU = {
	timeout	  = 0,
	title		= "Vote on Next Victory Loot!",
	itemsPerPage = nil,
	flags		= 0,
	onSelect	 = Voted,
	onCancel	 = nil,
}

--[[----------------+
	ENEMIES
+------------------]]--

ENEMY_BASE_COUNT = 15
ENEMY_BASE_MAXACTIVE_COUNT = 60
ENEMY_BASE_HEALTH_SCALER = 1.2
ENEMY_BASE_HEALTH_SCALER_PER_PLAYER = 0.025
ENEMY_BASE_COUNT_SCALER = 1.05
ENEMY_BASE_HEALTH = 25
ENEMY_MAX_COUNT_MULT = 1
ENEMY_BASE_CASH = 40
ENEMY_CURRENT_NUMBER_OF_GIANTS = 0

ATTR_REMOVE_ON_DEATH = 1 << 0 
ATTR_AGGRESSIVE = 1 << 1 						-- Push Behavior
ATTR_IS_NPC = 1 << 2
ATTR_SUPPRESS_FIRE = 1 << 3 					-- Don't shoot
ATTR_DISABLE_DODGE = 1 << 4					-- Disable Dodge
ATTR_BECOME_SPECTATOR_ON_DEATH = 1 << 5 		-- Send to Spec instantly
ATTR_QUOTA_MANANGED = 1 << 6
ATTR_RETAIN_BUILDINGS = 1 << 7 				-- Keep buildings
ATTR_SPAWN_WITH_FULL_CHARGE = 1 << 8			-- Spawn with full charge on meter items
ATTR_ALWAYS_CRIT = 1 << 9 					-- Always crit
ATTR_IGNORE_ENEMIES = 1 << 10				
ATTR_HOLD_FIRE_UNTIL_FULL_RELOAD = 1 << 11	-- Fully reload first
ATTR_PRIORITIZE_DEFENSE = 1 << 12
ATTR_ALWAYS_FIRE_WEAPON = 1 << 13				-- Always shoot
ATTR_TELEPORT_TO_HINT = 1 << 14				-- Teleport to engie hint (dependent on bomb pos)
ATTR_MINIBOSS = 1 << 15						-- Giant
ATTR_USE_BOSS_HEALTH_BAR = 1 << 16			-- Healthbar
ATTR_IGNORE_FLAG = 1 << 17					-- Ignore bomb
ATTR_AUTO_JUMP = 1 << 18						-- Auto jump (Doesn't work on it's own)
ATTR_AIR_CHARGE_ONLY = 1 << 19				-- Only charge in the air
ATTR_PREFER_VACCINATOR_BULLETS = 1 << 20		-- Sets vacc to bullet
ATTR_PREFER_VACCINATOR_BLAST = 1 << 21		-- Sets vacc to blast
ATTR_PREFER_VACCINATOR_FIRE = 1 << 22			-- Sets vacc to fire
ATTR_BULLET_IMMUNE = 1 << 23					-- Fully immune to bullets
ATTR_BLAST_IMMUNE = 1 << 24					-- Fully immune to blast
ATTR_FIRE_IMMUNE = 1 << 25					-- Fully immune to fire
ATTR_PARACHUTE = 1 << 26						-- Use parachute when falling for a while
ATTR_PROJECTILE_SHIELD = 1 << 27				-- Use proj shield

WEPRST_ANY_WEAPON = 0
WEPRST_MELEE_ONLY = 1
WEPRST_PRIMARY_ONLY = 2
WEPRST_SECONDARY_ONLY = 4

AI_EASY = 0
AI_NORMAL = 1
AI_HARD = 2
AI_EXPERT = 3

ENEMY_TYPE_COMMON = 1
ENEMY_TYPE_MINIGIANT = 2
ENEMY_TYPE_GIANT = 3
ENEMY_TYPE_BOSS = 4

ENEMY_TYPE_CHANCE_MULT = {
	[ENEMY_TYPE_COMMON] = 1,
	[ENEMY_TYPE_MINIGIANT] = 1,
	[ENEMY_TYPE_GIANT] = 1,
	[ENEMY_TYPE_BOSS] = 0,
}

ENEMY_TYPE_CHANCE_SCALE_MULT = {
	[1] = {
		[ENEMY_TYPE_COMMON] = 1,
		[ENEMY_TYPE_MINIGIANT] = 0,
		[ENEMY_TYPE_GIANT] = 0,
		[ENEMY_TYPE_BOSS] = 0,
	},
	[2] = {
		[ENEMY_TYPE_COMMON] = 1,
		[ENEMY_TYPE_MINIGIANT] = 0.25,
		[ENEMY_TYPE_GIANT] = 0,
		[ENEMY_TYPE_BOSS] = 0,
	},
	[3] = {
		[ENEMY_TYPE_COMMON] = 1,
		[ENEMY_TYPE_MINIGIANT] = 0.5,
		[ENEMY_TYPE_GIANT] = 0.33,
		[ENEMY_TYPE_BOSS] = 0,
	},
	[4] = {
		[ENEMY_TYPE_COMMON] = 1,
		[ENEMY_TYPE_MINIGIANT] = 0.75,
		[ENEMY_TYPE_GIANT] = 0.67,
		[ENEMY_TYPE_BOSS] = 0,
	},
	[5] = {
		[ENEMY_TYPE_COMMON] = 1,
		[ENEMY_TYPE_MINIGIANT] = 1,
		[ENEMY_TYPE_GIANT] = 1,
		[ENEMY_TYPE_BOSS] = 0,
	},
	[6] = {
		[ENEMY_TYPE_COMMON] = 0,
		[ENEMY_TYPE_MINIGIANT] = 0,
		[ENEMY_TYPE_GIANT] = 0,
		[ENEMY_TYPE_BOSS] = 0,
	},
	[7] = {
		[ENEMY_TYPE_COMMON] = 1,
		[ENEMY_TYPE_MINIGIANT] = 1,
		[ENEMY_TYPE_GIANT] = 1,
		[ENEMY_TYPE_BOSS] = 1,
	},
	[0] = {
		[ENEMY_TYPE_COMMON] = 1,
		[ENEMY_TYPE_MINIGIANT] = 1,
		[ENEMY_TYPE_GIANT] = 1,
		[ENEMY_TYPE_BOSS] = 1,
	},
}

ENEMY_MODEL_TABLE = {
	[0] = {	-- COMMONS
		[TF_CLASS_DEMOMAN] = "models/bots/demo/bot_demo.mdl",
		[TF_CLASS_CIVILIAN] = "models/bots/engineer/bot_engineer.mdl",
		[TF_CLASS_ENGINEER] = "models/bots/engineer/bot_engineer.mdl",
		[TF_CLASS_HEAVYWEAPONS] = "models/bots/heavy/bot_heavy.mdl",
		[TF_CLASS_MEDIC] = "models/bots/medic/bot_medic.mdl",
		[TF_CLASS_PYRO] = "models/bots/pyro/bot_pyro.mdl",
		[TF_CLASS_SCOUT] = "models/bots/scout/bot_scout.mdl",
		[TF_CLASS_SNIPER] = "models/bots/sniper/bot_sniper.mdl",
		[TF_CLASS_SOLDIER] = "models/bots/soldier/bot_soldier.mdl",
		[TF_CLASS_SPY] = "models/bots/spy/bot_spy.mdl",
	},
	[1] = {	-- GIANTS
		[TF_CLASS_DEMOMAN] = "models/bots/demo_boss/bot_demo_boss.mdl",
		[TF_CLASS_CIVILIAN] = "models/bots/engineer/bot_engineer.mdl",
		[TF_CLASS_ENGINEER] = "models/bots/engineer/bot_engineer.mdl",
		[TF_CLASS_HEAVYWEAPONS] = "models/bots/heavy_boss/bot_heavy_boss.mdl",
		[TF_CLASS_MEDIC] = "models/bots/medic/bot_medic.mdl",
		[TF_CLASS_PYRO] = "models/bots/pyro_boss/bot_pyro_boss.mdl",
		[TF_CLASS_SCOUT] = "models/bots/scout_boss/bot_scout_boss.mdl",
		[TF_CLASS_SNIPER] = "models/bots/sniper/bot_sniper.mdl",
		[TF_CLASS_SOLDIER] = "models/bots/soldier_boss/bot_soldier_boss.mdl",
		[TF_CLASS_SPY] = "models/bots/spy/bot_spy.mdl",
	}
}

ENEMY_TEMPLATES = {
	["T_TFBot_Enemy_Basic"] = {
		Weight = 1,
		Name = "Basic",
		Type = ENEMY_TYPE_COMMON,
		WeaponRestrictions = WEPRST_MELEE_ONLY,
		Skill = AI_EXPERT,
		Class = "Scout",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH,
		DefaultSlot = LOADOUT_POSITION_MELEE,
		Attributes = ATTR_DISABLE_DODGE | ATTR_IGNORE_FLAG,
		Items = {},
		ItemAttributes = {},
		CharacterAttributes = { ["move speed penalty"] = 0.75 },
		Scale = 1,
		BaseCashMult = 1,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["dmg taken increased"] = 0.5 },
				AddConds = {},
				Weight = 0.85,
			},
		},
	},
	["T_TFBot_Enemy_Blocker"] = {
		Weight = 0.65,
		Name = "Blocker",
		Type = ENEMY_TYPE_COMMON,
		WeaponRestrictions = WEPRST_MELEE_ONLY,
		Skill = AI_EXPERT,
		Class = "Heavyweapons",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 2,
		DefaultSlot = LOADOUT_POSITION_MELEE,
		Attributes = ATTR_IGNORE_FLAG,
		Items = {},
		ItemAttributes = {},
		CharacterAttributes = {},
		Scale = 1,
		BaseCashMult = 1,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["dmg taken increased"] = 0.5 },
				AddConds = {},
				Weight = 0.85,
			},
		},
	},
	["T_TFBot_Enemy_Knight"] = {
		Weight = 0.25,
		Name = "Knight",
		Type = ENEMY_TYPE_COMMON,
		WeaponRestrictions = WEPRST_MELEE_ONLY,
		Skill = AI_EXPERT,
		Class = "Demoman",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH,
		DefaultSlot = LOADOUT_POSITION_MELEE,
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE,
		Items = { "Ali Baba's Wee Booties", "The Chargin' Targe", "The Half-Zatoichi" },
		ItemAttributes = {},
		CharacterAttributes = {},
		Scale = 1,
		BaseCashMult = 1,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5, ["mult charging move speed"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Charging ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["charge recharge rate increased"] = 2, ["charge time increased"] = 0.5 },
				AddConds = { TF_COND_SHIELD_CHARGE },
				Weight = 0.5,
			},
			{
				Append_Name = "Enraged ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["fire rate bonus"] = 0.8 },
				AddConds = { TF_COND_CRITBOOSTED },
				Weight = 0.75,
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["dmg taken increased"] = 0.5 },
				AddConds = {},
				Weight = 0.85,
			},
		},
	},
	["T_TFBot_Enemy_Medic"] = {
		Weight = 0.1,
		Name = "Uber Medic",
		Type = ENEMY_TYPE_COMMON,
		WeaponRestrictions = WEPRST_SECONDARY_ONLY,
		Skill = AI_EXPERT,
		Class = "Medic",
		Action = "Medic",
		Health = ENEMY_BASE_HEALTH * 2.4,
		DefaultSlot = LOADOUT_POSITION_SECONDARY,
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_SPAWN_WITH_FULL_CHARGE,
		Items = { "TF_WEAPON_SYRINGEGUN_MEDIC", "TF_WEAPON_MEDIGUN" },
		ItemAttributes = {},
		CharacterAttributes = { ["ubercharge rate bonus"] = 5, ["heal rate bonus"] = 0.1},
		Scale = 1,
		BaseCashMult = 1,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = function( botSpawn, data ) -- Passes botSpawn, data
			local alivebots = #ents.GetAllAliveNonMedicBots()
			local switched
			if switched == nil then switched = false end
			if alivebots <= 0 then
				if switched == false then
					botSpawn:BotCommand( "switch_action Mobber" )
					botSpawn:AcceptInput("$BotCommand","switch_action Mobber")
					botSpawn:RunScriptCode( "activator.ClearAllWeaponRestrictions()", botSpawn, botSpawn )
					botSpawn:WeaponStripSlot( 1 )
					botSpawn:SetActivePlayerWeapon( botSpawn:GetPlayerItemBySlot( 0 ) )
					timer.Simple( 0.5, function()
						switched = false
					end)
				end
			end
		end, 
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 0.5,
			},
			{
				Append_Name = "Bigheal ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["ubercharge rate bonus"] = 0.1, ["heal rate bonus"] = 10 },
				AddConds = {},
				Weight = 1, 
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["dmg taken increased"] = 0.5 },
				AddConds = {},
				Weight = 0.85,
			},
		},
	},
	
	["T_TFBot_Enemy_Shotgunner"] = {
		Weight = 0.075,
		Name = "Shotgunner",
		Type = ENEMY_TYPE_MINIGIANT,
		WeaponRestrictions = WEPRST_SECONDARY_ONLY,
		Skill = AI_EXPERT,
		Class = "Heavyweapons",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 5,
		DefaultSlot = LOADOUT_POSITION_SECONDARY,
		Attributes = ATTR_IGNORE_FLAG | ATTR_HOLD_FIRE_UNTIL_FULL_RELOAD | ATTR_DISABLE_DODGE,
		Items = { "TF_WEAPON_SHOTGUN_HWG" },
		ItemAttributes = { [1] = {
			["Fire rate penalty"] = 2,
			["Damage bonus"] = 1.25,
			["Spread Penalty"] = 1.5,
		} },
		CharacterAttributes = { ["damage force reduction"] = 0.6, ["airblast vulnerability multiplier"] = 0.6 },
		Scale = 1.5,
		BaseCashMult = 1.5,
		AddConds = {},
		VisionRange = 500,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = { [1] = {
					["Fire rate bonus"] = 0.5,
					["reload time increased"] = 0.5, 
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1, 
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.85,
			},
		},
	},
	["T_TFBot_Enemy_Grenadier"] = {
		Weight = 0.05,
		Name = "Grenader",
		Type = ENEMY_TYPE_MINIGIANT,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		Skill = AI_EXPERT,
		Class = "Demoman",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 4,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE,
		Items = {"Magnum Opus"},
		ItemAttributes = {},
		CharacterAttributes = { ["fire rate penalty"] = 2, ["reload time increased"] = 1.5, ["projectile speed increased hidden"] = 0.67, ["damage force reduction"] = 0.6, ["airblast vulnerability multiplier"] = 0.6 },
		Scale = 1.5,
		BaseCashMult = 1.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = { [0] = {
					["Fire rate bonus"] = 0.5,
					["reload time increased"] = 0.5, 
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1, 
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.85,
			},
		},
	},
	["T_TFBot_Enemy_Baseballer"] = {
		Weight = 0.075,
		Name = "Baseballer",
		Type = ENEMY_TYPE_MINIGIANT,
		WeaponRestrictions = WEPRST_MELEE_ONLY,
		DefaultSlot = LOADOUT_POSITION_MELEE,
		Skill = AI_EXPERT,
		Class = "Scout",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 4,
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE,
		Items = {"The Sandman", "Batter's Helmet", "Batter's Bracers"},
		ItemAttributes = { [2] = {
			["effect bar recharge rate increased"] = 0.15,
		} },
		CharacterAttributes = { ["damage force reduction"] = 0.6, ["airblast vulnerability multiplier"] = 0.6 },
		Scale = 1.5,
		BaseCashMult = 1.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Major League ",
				Items = {},
				ItemAttributes = { [2] = {
					["effect bar recharge rate increased"] = 0.05,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Ornament ",
				Items = { "The Wrap Assassin" },
				ItemAttributes = { [2] = {
					["effect bar recharge rate increased"] = 0.25,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 0.85, 
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.85,
			},
		},
	},
	["T_TFBot_Enemy_Launcher"] = {
		Weight = 0.05,
		Name = "Launcher",
		Type = ENEMY_TYPE_MINIGIANT,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Soldier",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 6,
		Attributes = ATTR_IGNORE_FLAG | ATTR_HOLD_FIRE_UNTIL_FULL_RELOAD | ATTR_DISABLE_DODGE,
		Items = {"Tyrantium Helmet"},
		ItemAttributes = { [0] = {
			["fire rate penalty"] = 3,
			["damage bonus"] = 1.25,
			["ignores other projectiles"] = 1,
			["mult projectile count"] = 3,
			["projectile speed decreased"] = 0.65,
			["blast radius increased"] = 1.2,
			["spread angle pattern"] = "0 10 0|0 0 0|0 -10 0",
			["damage force reduction"] = 0.6, 
			["airblast vulnerability multiplier"] = 0.6
		} },
		CharacterAttributes = { ["blast dmg to self increased"] = 0 },
		Scale = 1.5,
		BaseCashMult = 1.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = { [0] = {
					["Fire rate bonus"] = 0.5,
					["reload time increased"] = 0.5, 
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1, 
			},
			{
				Append_Name = "Homing ",
				Items = {},
				ItemAttributes = { [0] = {
					["projectile speed decreased"] = 0.25,
					["mod projectile heat seek power"] = 90, 
					["mod projectile heat aim error"] = 90, 
					["mod projectile heat aim time"] = 6, 
					["mod projectile heat no predict target speed"] = 1, 
					["mod projectile heat aim start time"] = 1, 
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 0.75, 
			},
			{
				Append_Name = "Accelerating ",
				Items = {},
				ItemAttributes = { [0] = {
					["projectile speed decreased"] = 0.1,
					["projectile acceleration"] = 2200, 
					["projectile acceleration time"] = 0.75, 
					["projectile acceleration start time"] = 0.5,  
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 0.75, 
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.85,
			},
		},
	},
	["T_TFBot_Enemy_Buffer"] = {
		Weight = 0.06,
		Name = "Buffer",
		Type = ENEMY_TYPE_MINIGIANT,
		WeaponRestrictions = WEPRST_MELEE_ONLY,
		DefaultSlot = LOADOUT_POSITION_SECONDARY,
		Skill = AI_EXPERT,
		Class = "Soldier",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 4,
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE,
		Items = {"The Buff Banner", "TF_WEAPON_SHOVEL"},
		ItemAttributes = {},
		CharacterAttributes = { ["increase buff duration"] = 10, ["damage force reduction"] = 0.6, ["airblast vulnerability multiplier"] = 0.6 },
		Scale = 1.5,
		BaseCashMult = 1.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = function( botSpawn, data )
			local self = botSpawn
			local cond = TF_COND_OFFENSEBUFF
			local radius = 450 * 1.5
			if string.match( self.m_szNetname, "Conch" ) then
				cond = TF_COND_REGENONDAMAGEBUFF
			elseif string.match( self.m_szNetname, "Battalion" ) then
				cond = TF_COND_DEFENSEBUFF
			end
			for _, player in pairs( ents.FindInSphere( self:GetAbsOrigin(), radius, "player" ) ) do
				if IsValid( player ) and player:IsAlive() and ( player:GetTeam() == self:GetTeam() ) then
					player:AddCond( cond, 0.2 )
				end
			end
		end, -- Passes botSpawn, data
		SpawnFunc = function( botSpawn, data )
			local self = botSpawn
			local snd = "Weapon_BuffBanner.HornBlue"
			if string.match( self.m_szNetname, "Conch" ) then
				snd = "Samurai.Conch"
			elseif string.match( self.m_szNetname, "Battalion" ) then
				snd = "Weapon_BattalionsBackup.HornBlue"
			end
			self:PlaySound( snd )
		end, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.85,
			},
			{
				Append_Name = "Conch ",
				Items = {"The Concheror"},
				ItemAttributes = {},
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Battalion ",
				Items = {"The Battalion's Backup"},
				ItemAttributes = {},
				CharacterAttributes = {},
				AddConds = {},
				Weight = 0.75,
			},
		},
	},
	["T_TFBot_Enemy_Stomper"] = {
		Weight = 0.055,
		Name = "Stomper",
		Type = ENEMY_TYPE_MINIGIANT,
		WeaponRestrictions = WEPRST_MELEE_ONLY,
		DefaultSlot = LOADOUT_POSITION_MELEE,
		Skill = AI_EXPERT,
		Class = "Pyro",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 7,
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_AUTO_JUMP,
		Items = { "The Mantreads" },
		ItemAttributes = { [2] = { ["no_attack"] = 1 }, },
		CharacterAttributes = {
			["kb fall min velocity"] = 600, 
			["kb fall radius"] = 300, 
			["kb fall stun time"] = -5, 
			["kb fall force"] = 400, 
			["kb fall damage"] = 25, 
			["increased jump height"] = 5, 
			["cancel falling damage"] = 1, 
			["damage force reduction"] = 0.6, 
			["airblast vulnerability multiplier"] = 0.6
		},
		Scale = 1.5,
		BaseCashMult = 1.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = function( botSpawn, data )
			botSpawn:AcceptInput( "RunScriptCode", "activator.SetAutoJump( 4, 4 )", botSpawn, botSpawn )
		end, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.85,
			},
			{
				Append_Name = "Stun ",
				Items = {},
				CharacterAttributes = {
					["kb fall stun time"] = 2, 
				},
				CharacterAttributes = {},
				AddConds = {},
				Weight = 0.75,
			},
			{
				Append_Name = "Enraged ",
				Items = {},
				CharacterAttributes = {
					["kb fall damage"] = 75, 
				},
				CharacterAttributes = {},
				AddConds = { TF_COND_CRITBOOSTED },
				Weight = 1,
			},
		},
	},
	["T_TFBot_Enemy_Flamer"] = {
		Weight = 0.06,
		Name = "Flamer",
		Type = ENEMY_TYPE_MINIGIANT,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Pyro",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 6,
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_ALWAYS_FIRE_WEAPON,
		Items = {},
		ItemAttributes = {[0] = {
			["damage bonus"] = 2,
			["flame_drag"] = 10,
		}},
		CharacterAttributes = {["damage force reduction"] = 0.6, ["airblast vulnerability multiplier"] = 0.6},
		Scale = 1.5,
		BaseCashMult = 1.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.85,
			},
		},
	},
	["T_TFBot_Enemy_Cannoneer"] = {
		Weight = 0.06,
		Name = "Cannoneer",
		Type = ENEMY_TYPE_MINIGIANT,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Demoman",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 6,
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_HOLD_FIRE_UNTIL_FULL_RELOAD,
		Items = {"TF_WEAPON_GRENADELAUNCHER", "Treasure Hat 1", "The Bearded Bombardier"},
		ItemAttributes = {[0] = {
			["Projectile speed increased"] = 1.5,
			["grenade launcher mortar mode"] = nil,
			["damage blast push"] = 25,
			["override projectile type"] = 17,
			["grenade not explode on impact"] = 1,
			["cannonball push back"] = 1,
			["fire rate penalty"] = 2,
			["custom item model"] = "models/workshop/weapons/c_models/c_demo_cannon/c_demo_cannon.mdl",
		}},
		CharacterAttributes = {["damage force reduction"] = 0.6, ["airblast vulnerability multiplier"] = 0.6},
		Scale = 1.5,
		BaseCashMult = 1.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = function( botSpawn, data )
			timer.Simple( 1, function() 
				botSpawn:GetPlayerItemBySlot(1):SetAttributeValue( "custom item model", "models/workshop/weapons/c_models/c_demo_cannon/c_demo_cannon.mdl" )
			end)
		end, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = { [0] = {
					["fire rate bonus"] = 0.5,
					["reload time increased"] = 0.5, 
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.85,
			},
		},
	},
	["T_TFBot_Enemy_Protector"] = {
		Weight = 0.05,
		Name = "Protector",
		Type = ENEMY_TYPE_MINIGIANT,
		WeaponRestrictions = WEPRST_SECONDARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_SECONDARY,
		Skill = AI_EXPERT,
		Class = "Medic",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 7,
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE,
		Items = {"Jarate"},
		ItemAttributes = {[1] = {
			["custom item model"] = "models/workshop/weapons/c_models/c_quadball/c_quadball_grenade.mdl",
			["custom item model"] = "models/workshop/weapons/c_models/c_quadball/c_quadball_grenade.mdl",
			["custom projectile model"] = "models/workshop/weapons/c_models/c_quadball/c_quadball_grenade.mdl",
			["override projectile type"] = 3,
			["effect bar recharge rate increased"] = 0.375,
			["effect cond override"] = 12,
			["explosion particle"] = "ExplosionCore_sapperdestroyed",
			["explosion particle on direct hit"] = "ExplosionCore_sapperdestroyed",
			["Projectile speed increased"] = 1.5,
			["fire input on attack"] = "popscript^$ProptectorGrenade^",
		}},
		CharacterAttributes = {["use original class player animations"] = 1, ["damage force reduction"] = 0.6, ["airblast vulnerability multiplier"] = 0.6},
		Scale = 1.5,
		BaseCashMult = 1.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = function( botSpawn, data )
			timer.Simple( 1, function() 
				botSpawn:GetPlayerItemBySlot(1):SetAttributeValue( "custom item model", "models/workshop/weapons/c_models/c_quadball/c_quadball_grenade.mdl" )
				botSpawn:SetAttributeValue( "use original class player animations", 1 )
			end)
		end, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = { [1] = {
					["effect bar recharge rate increased"] = 0.1875,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.85,
			},
		},
	},
	["T_TFBot_Enemy_Sniper"] = {
		Weight = 0.05,
		Name = "Sniper",
		Type = ENEMY_TYPE_MINIGIANT,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Sniper",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 3,
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_ALWAYS_FIRE_WEAPON,
		Items = {"TF_WEAPON_SNIPERRIFLE", "Preventative Measure", "The Aimframe"},
		ItemAttributes = {[0] = {
			["custom projectile model"] = "models/weapons/w_models/w_rocketbullet.mdl",
			["override projectile type"] = 2,
			["projectile trail particle"] = "~drg_bison_projectile",
			["Projectile speed increased"] = 2.72,
			["projectile radius damage"] = 100,
			["projectile radius damage time"] = 0,
			["projectile radius damage radius"] = 48,
			["projectile radius damage hit limit"] = 1,
			["projectile radius knockback radius"] = 48,
			["projectile radius knockback"] = 750,
			["projectile radius knockback hit limit"] = 1,
			["projectile radius knockback time"] = 0,
			["custom projectile size"] = 2,
			["blast radius decreased"] = 0,
			["explosion particle"] = "sapper_flyingembers",
			["explosion particle on direct hit"] = "sapper_flyingembers",
			["projectile lifetime"] = 3,
			["fire rate penalty"] = 2,
			["gesture speed increase"] = 0.5,
			["mod projectile heat seek power"] = 69420,
			["mod projectile heat aim error"] = 30,
			["mod projectile heat aim time"] = 0.05,
			["mod projectile heat no predict target speed"] = 0,
		}},
		CharacterAttributes = {["damage force reduction"] = 0.6, ["airblast vulnerability multiplier"] = 0.6},
		Scale = 1.5,
		BaseCashMult = 1.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = { [1] = {
					["fire rate bonus"] = 0.5,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.85,
			},
		},
	},
	["T_TFBot_Enemy_Harpooner"] = {
		Weight = 0.065,
		Name = "Harpooner",
		Type = ENEMY_TYPE_MINIGIANT,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Sniper",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 3,
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE,
		Items = {"The Fortified Compound", "The Lone Star", "The Birdman of Australiacatraz"},
		ItemAttributes = {[0] = {
			["projectile trail particle"] = "raygun_projectile_blue_crit_trail",
			["override projectile type"] = 26,
			["Projectile speed increased"] = 1,
			["mult grappling hook speed"] = 0,
			["projectile radius damage"] = 0.1,
			["projectile radius damage time"] = 0,
			["projectile radius damage radius"] = 50,
			["apply look velocity on damage"] = -500,
			["apply z velocity on damage"] = -750,
			["add attributes on hit"] = "cancel falling damage|1|0.1",
			["projectile detonate time"] = 3,
			["fire rate penalty"] = 3,
			["gesture speed increase"] = 0.5,
			["mod projectile heat seek power"] = 69420,
			["mod projectile heat aim error"] = 15,
			["mod projectile heat aim time"] = 0.05,
			["mod projectile heat no predict target speed"] = 0,
		}},
		CharacterAttributes = {["damage force reduction"] = 0.6, ["airblast vulnerability multiplier"] = 0.6},
		Scale = 1.5,
		BaseCashMult = 1.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = { [0] = {
					["fire rate bonus"] = 0.5,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Snaring-",
				Items = {},
				ItemAttributes = { [0] = {
					["stun on hit"] = 5,
					["stun on hit type"] = "movement",
					["stun on hit slow"] = 0.85,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Spooking-",
				Items = {},
				ItemAttributes = { [0] = {
					["stun on hit"] = 0.5,
					["stun on hit type"] = "ghost",
					["stun on hit slow"] = 0,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.85,
			},
		},
	},
	
	["T_TFBot_Giant_Enemy_Flank"] = {
		Weight = 0.01,
		Name = "Giant Flank Cannon",
		Type = ENEMY_TYPE_GIANT,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Heavyweapons",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 20, -- 500 base
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_MINIBOSS | ATTR_ALWAYS_FIRE_WEAPON,
		Items = {"TF_WEAPON_MINIGUN", "Air Exchanger", "Pyro Helm"},
		ItemAttributes = {[0] = {
			["custom item model"] = "models/weapons/c_models/c_baikal_boar/c_baikal_boar.mdl",
			["projectile trail particle"] = "~tranq_distortion_trail",
			["override projectile type"] = 2,
			["Projectile speed increased"] = 2.5,
			["projectile detonate time"] = 0.218,
			["proximity bomb"] = 1,
			["mult projectile count"] = 3,
			["ignores other projectiles"] = 1,
			["weapon always gib"] = 1,
			["projectile spread angle penalty"] = 12.5,
			["explosion particle"] = "rd_robot_explosion_smoke_linger",
			["explosion particle on direct hit"] = "rd_robot_explosion_smoke_linger",
			["mod mini-crit airborne"] = 1,
			["damage penalty"] = 0.75,
		}},
		CharacterAttributes = {["is miniboss"] = 1, ["move speed bonus"] = 0.5, ["damage force reduction"] = 0.1, ["airblast vulnerability multiplier"] = 0.1, ["override footstep sound set"] = 2},
		Scale = 1.75,
		BaseCashMult = 2.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = { [0] = {
					["fire rate bonus"] = 0.5,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.75,
			},
		},
	},
	["T_TFBot_Giant_Enemy_Orb"] = {
		Weight = 0.0125,
		Name = "Giant Orb Caster",
		Type = ENEMY_TYPE_GIANT,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Scout",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 15, -- 375 base
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_MINIBOSS,
		Items = {"Orb Caster", "The Cross-Comm Crash Helmet"},
		ItemAttributes = {[0]={["damage bonus"] = 2, ["reload time increased"] = 2}},
		CharacterAttributes = {["is miniboss"] = 1, ["move speed bonus"] = 0.5, ["damage force reduction"] = 0.1, ["airblast vulnerability multiplier"] = 0.1, ["override footstep sound set"] = 5},
		Scale = 1.75,
		BaseCashMult = 2.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = { [0] = {
					["fire rate bonus"] = 0.5,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Homing ",
				Items = {},
				ItemAttributes = { [0] = {
					["mod projectile heat seek power"] = 45,
					["mod projectile heat aim error"] = 15,
					["mod projectile heat no predict target speed"] = 1,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 0.85,
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.75,
			},
		},
	},
	["T_TFBot_Giant_Enemy_Burst"] = {
		Weight = 0.015,
		Name = "Giant Burst Fire Soldier",
		Type = ENEMY_TYPE_GIANT,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Soldier",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 16, -- 400 base
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_MINIBOSS | ATTR_HOLD_FIRE_UNTIL_FULL_RELOAD,
		Items = {"TF_WEAPON_ROCKETLAUNCHER", "The Conquistador"},
		ItemAttributes = {[0] = { 
			["faster reload rate"] = 0.3, 
			["fire rate bonus"] = 0.1, 
			["clip size upgrade atomic"] = 6, 
			["Projectile speed increased"] = 1,
			["mod projectile heat seek power"] = 69420,
			["mod projectile heat aim error"] = 15,
			["mod projectile heat aim time"] = 0.05,
			["mod projectile heat no predict target speed"] = 0,
		}},
		CharacterAttributes = {["is miniboss"] = 1, ["move speed bonus"] = 0.5, ["damage force reduction"] = 0.1, ["airblast vulnerability multiplier"] = 0.1, ["override footstep sound set"] = 3},
		Scale = 1.75,
		BaseCashMult = 2.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = { [0] = {
					["fire rate bonus"] = 0.5,
					["reload time decreased"] = 0.5,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Enraged ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = {},
				AddConds = { TF_COND_CRITBOOSTED },
				Weight = 1,
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.75,
			},
		},
	},
	["T_TFBot_Giant_Enemy_FlarePunch"] = {
		Weight = 0.015,
		Name = "Giant Flare Punch Pyro",
		Type = ENEMY_TYPE_GIANT,
		WeaponRestrictions = WEPRST_SECONDARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_SECONDARY,
		Skill = AI_EXPERT,
		Class = "Pyro",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 20, -- 500 base
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_MINIBOSS | ATTR_ALWAYS_FIRE_WEAPON,
		Items = {"TF_WEAPON_FLAMETHROWER", "TF_WEAPON_SHOTGUN_PYRO", "Dead Heat", "Bushi-Dou"},
		ItemAttributes = {[0] = { 
			["damage bonus"] = 3,
			["flame_drag"] = 4,
			["is_passive_weapon"] = 1,
		},[1] = { 
			["crit vs burning players"] = 1,
			["damage bonus"] = 3,
			["fire rate bonus"] = 0.1,
			["override projectile type"] = 6,
			["mult projectile count"] = 3,
			["projectile spread angle penalty"] = 4,
			["remove damage type"] = 16777216,
			["projectile speed decreased"] = 0.1,
			["projectile acceleration"] = 1800,
			["projectile acceleration time"] = 1,
			["hold fire until full reload"] = 2,
		}},
		CharacterAttributes = {["is miniboss"] = 1, ["move speed bonus"] = 0.5, ["damage force reduction"] = 0.1, ["airblast vulnerability multiplier"] = 0.1, ["override footstep sound set"] = 6},
		Scale = 1.75,
		BaseCashMult = 2.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = { [1] = {
					["fire rate bonus"] = 0.5,
					["reload time decreased"] = 0.5,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Scorching ",
				Items = {},
				ItemAttributes = {[1] = {
					["crits_become_minicrits"] = 1,
					["mod flaregun fires pellets with knockback"] = 3,
				}},
				CharacterAttributes = {},
				AddConds = {},
				Weight = 0.9,
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.75,
			},
		},
	},
	["T_TFBot_Giant_Enemy_Rammer"] = {
		Weight = 0.015,
		Name = "Giant Rammer Demoman",
		Type = ENEMY_TYPE_GIANT,
		WeaponRestrictions = WEPRST_MELEE_ONLY,
		DefaultSlot = LOADOUT_POSITION_MELEE,
		Skill = AI_EXPERT,
		Class = "Demoman",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 25, -- 625 base
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_MINIBOSS,
		Items = {"Ali Baba's Wee Booties", "The Splendid Screen", "War Head", "Bone-Cut Belt", "Road Rage"},
		ItemAttributes = {[1] = {
			["Attack not cancel charge"] = 1,
			["item style override"] = 1
		},[2] = {
			["fire rate penalty"] = 69420
		}},
		CharacterAttributes = {["is miniboss"] = 1, ["Attack not cancel charge"] = 1, ["charge time increased"] = 0.5, ["charge impact damage increased"] = 2, ["charge recharge rate increased"] = 5, ["move speed bonus"] = 0.5, ["mult charging move speed"] = 1.5, ["mult stun resistance"] = 0, ["damage force reduction"] = 0, ["airblast vulnerability multiplier"] = 0, ["override footstep sound set"] = 4},
		Scale = 1.75,
		BaseCashMult = 2.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5, ["mult charging move speed"] = 2.25 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = {["charge recharge rate increased"] = 69420},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.75,
			},
		},
	},
	["T_TFBot_Giant_Enemy_Ranged_Repair"] = {
		Weight = 0.0125,
		Name = "Giant Ranged Repair",
		Type = ENEMY_TYPE_GIANT,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Medic",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 20, -- 500 base
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_MINIBOSS | ATTR_HOLD_FIRE_UNTIL_FULL_RELOAD,
		Items = {"Festive Crusader's Crossbow", "The Crosslinker's Coil", "Practitioner's Processing Mask", "Hazardous Environment Vest"},
		ItemAttributes = {[0] = {
			["faster reload rate"] = 0.2,
			["clip size upgrade atomic"] = 14,
			["dmg penalty vs players"] = 0.25,
			["dmg penalty vs buildings"] = 0.25,
			["fire rate bonus"] = 0.2,
			["projectile penetration"] = 1,
		}},
		CharacterAttributes = {["is miniboss"] = 1, ["move speed bonus"] = 0.5, ["damage force reduction"] = 0.1, ["airblast vulnerability multiplier"] = 0.1},
		Scale = 1.75,
		BaseCashMult = 2.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = { [0] = {
					["fire rate bonus"] = 0.5,
					["reload time decreased"] = 0.5,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Healing ",
				Items = {},
				ItemAttributes = { [0] = {
					["damage bonus"] = 2.5,
					["dmg penalty vs players"] = 0.1,
					["dmg penalty vs buildings"] = 0.1,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.75,
			},
		},
	},
	["T_TFBot_Giant_Enemy_Explosive_Hunter"] = {
		Weight = 0.0125,
		Name = "Giant Explosive Hunter",
		Type = ENEMY_TYPE_GIANT,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Sniper",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 15, -- 375 base
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_MINIBOSS,
		Items = {"Festive Huntsman", "Fused Plates"},
		ItemAttributes = {[0] = {
			["fire input on attack"] = "popscript^$ExplosiveArrows^",
			["arrow hit kill time"] = 2.15,
			["mult projectile count"] = 9,
			["spread angle pattern"] = "0 0 0|0 5 0|0 -5 0|0 10 0|0 -10 0|0 15 0|0 -15 0|0 20 0|0 -20 0",
		}},
		CharacterAttributes = {["is miniboss"] = 1, ["move speed bonus"] = 0.5, ["damage force reduction"] = 0.1, ["airblast vulnerability multiplier"] = 0.1},
		Scale = 1.75,
		BaseCashMult = 2.5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {
			{
				Append_Name = "Speedy ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["move speed bonus"] = 1.5 },
				AddConds = {},
				Weight = 1, -- If we roll the chance for variant, weight of this one to be chosen
			},
			{
				Append_Name = "Frenzied ",
				Items = {},
				ItemAttributes = { [0] = {
					["fire rate bonus"] = 0.5,
					["reload time decreased"] = 0.5,
				} },
				CharacterAttributes = {},
				AddConds = {},
				Weight = 1,
			},
			{
				Append_Name = "Armored ",
				Items = {},
				ItemAttributes = {},
				CharacterAttributes = { ["mult max health"] = 0.67 },
				AddConds = {},
				Weight = 0.75,
			},
		},
	},
	
	["T_TFBot_Giant_Enemy_Corrupted_Launcher"] = {
		Weight = 1,
		Name = "Giant Corrupted Launcher",
		Type = ENEMY_TYPE_BOSS,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Soldier",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 50, -- 1250 base
		Attributes = ATTR_IGNORE_FLAG | ATTR_HOLD_FIRE_UNTIL_FULL_RELOAD | ATTR_DISABLE_DODGE | ATTR_MINIBOSS,
		Items = {"Spine-Chilling Skull 2011 Style 3"},
		ItemAttributes = { [0] = {
			["fire rate penalty"] = 2,
			-- ["reload time increased"] = 1.25,
			["damage bonus"] = 1.33,
			["ignores other projectiles"] = 1,
			["mult projectile count"] = 5,
			["projectile speed decreased"] = 0.5,
			["blast radius increased"] = 1.33,
			["spread angle pattern"] = "0 7.5 0|0 0 0|0 -7.5 0|0 15 0|0 -15 0",
			
			["projectile trail particle"] = "raygun_projectile_blue",
			["explosion particle"] = "bombinomicon_burningdebris_halloween",
			["explosion particle on direct hit"] = "bombinomicon_burningdebris_halloween",
			["add attributes on hit"] = "dmg taken increased|1.5|5|healing received penalty|0.5|5|reduced_healing_from_medics|0.001337|5|move speed penalty|0.8|5|is suicide counter|0|5|hud overlay|yiresahud/antiheal|5",
		} },
		CharacterAttributes = {["is miniboss"] = 1, ["move speed bonus"] = 0.5, ["damage force reduction"] = 0, ["airblast vulnerability multiplier"] = 0},
		Scale = 2,
		BaseCashMult = 5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = function( botSpawn, data )
			for i=0, 10 do
				if IsValid( botSpawn:GetPlayerItemBySlot(i) ) then
					if botSpawn:GetPlayerItemBySlot(i):GetItemName() == "Spine-Chilling Skull 2011 Style 3" then
						botSpawn:GetPlayerItemBySlot(i):SetAttributeValue( "attach particle effect", 258 )
					end
				end
			end
		end, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {},
	},
	["T_TFBot_Giant_Enemy_Corrupted_Minigunner"] = {
		Weight = 0.85,
		Name = "Giant Corrupted Minigunner",
		Type = ENEMY_TYPE_BOSS,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Heavyweapons",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 60, -- 1.5k base
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_MINIBOSS,
		Items = {"Spine-Chilling Skull 2011 Style 3"},
		ItemAttributes = { [0] = {
			["custom projectile model"] = "models/weapons/w_models/w_rocketbullet.mdl",
			["override projectile type"] = 2,
			["Projectile speed increased"] = 1,
			["projectile radius damage"] = 8,
			["projectile radius damage time"] = 0,
			["projectile radius damage radius"] = 48,
			["projectile radius damage hit limit"] = 1,
			["custom projectile size"] = 2,
			["blast radius decreased"] = 0,
			["explosion particle"] = "sapper_flyingembers",
			["explosion particle on direct hit"] = "sapper_flyingembers",
			["projectile lifetime"] = 3,
			
			["projectile trail particle"] = "~raygun_projectile_blue",
			["add attributes on hit"] = "dmg taken increased|1.5|2|healing received penalty|0.5|2|reduced_healing_from_medics|0.001337|2|move speed penalty|0.8|2|is suicide counter|0|2|hud overlay|yiresahud/antiheal|2",
		} },
		CharacterAttributes = {["is miniboss"] = 1, ["move speed bonus"] = 0.5, ["damage force reduction"] = 0, ["airblast vulnerability multiplier"] = 0},
		Scale = 2,
		BaseCashMult = 5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = function( botSpawn, data )
			for i=0, 10 do
				if IsValid( botSpawn:GetPlayerItemBySlot(i) ) then
					if botSpawn:GetPlayerItemBySlot(i):GetItemName() == "Spine-Chilling Skull 2011 Style 3" then
						botSpawn:GetPlayerItemBySlot(i):SetAttributeValue( "attach particle effect", 258 )
					end
				end
			end
		end, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {},
	},
	["T_TFBot_Giant_Enemy_Corrupted_Sniper"] = {
		Weight = 0.5,
		Name = "Giant Corrupted Sniper",
		Type = ENEMY_TYPE_BOSS,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Sniper",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 35, -- 875 base
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_MINIBOSS | ATTR_ALWAYS_FIRE_WEAPON,
		Items = {"Spine-Chilling Skull 2011 Style 3"},
		ItemAttributes = { [0] = {
			["custom projectile model"] = "models/weapons/w_models/w_rocketbullet.mdl",
			["override projectile type"] = 2,
			["projectile trail particle"] = "~drg_bison_projectile",
			["Projectile speed increased"] = 2.72,
			["projectile radius damage"] = 150,
			["projectile radius damage time"] = 0,
			["projectile radius damage radius"] = 48,
			["projectile radius damage hit limit"] = 1,
			["projectile radius knockback radius"] = 48,
			["projectile radius knockback"] = 1500,
			["projectile radius knockback hit limit"] = 1,
			["projectile radius knockback time"] = 0,
			["custom projectile size"] = 2,
			["blast radius decreased"] = 0,
			["explosion particle"] = "sapper_flyingembers",
			["explosion particle on direct hit"] = "sapper_flyingembers",
			["projectile lifetime"] = 3,
			["fire rate penalty"] = 3,
			["gesture speed increase"] = 0.33,
			["mod projectile heat seek power"] = 69420,
			["mod projectile heat aim error"] = 30,
			["mod projectile heat aim time"] = 0.05,
			["mod projectile heat no predict target speed"] = 0,
			
			["add attributes on hit"] = "dmg taken increased|1.5|6|healing received penalty|0.5|6|reduced_healing_from_medics|0.001337|6|move speed penalty|0.8|6|is suicide counter|0|6|hud overlay|yiresahud/antiheal|6",
		} },
		CharacterAttributes = {["is miniboss"] = 1, ["move speed bonus"] = 0.5, ["damage force reduction"] = 0, ["airblast vulnerability multiplier"] = 0},
		Scale = 2,
		BaseCashMult = 5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = function( botSpawn, data )
			for i=0, 10 do
				if IsValid( botSpawn:GetPlayerItemBySlot(i) ) then
					if botSpawn:GetPlayerItemBySlot(i):GetItemName() == "Spine-Chilling Skull 2011 Style 3" then
						botSpawn:GetPlayerItemBySlot(i):SetAttributeValue( "attach particle effect", 258 )
					end
				end
			end
		end, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {},
	},
	["T_TFBot_Giant_Enemy_Fire_Spreader"] = {
		Weight = 0.85,
		Name = "Giant Fire Spreader",
		Type = ENEMY_TYPE_BOSS,
		WeaponRestrictions = WEPRST_SECONDARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_SECONDARY,
		Skill = AI_EXPERT,
		Class = "Pyro",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 55, -- 1375 base
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_MINIBOSS,
		Items = {"The Scorch Shot", "Hellscape", "Demonic Dome"},
		ItemAttributes = { [1] = {
			["burst fire count"] = 3,
			["burst fire rate mult"] = 9,
			["faster reload rate"] = 0.33,
			["spread angle pattern"] = "0 10 0|0 0 0|0 -10 0",
			["proj attribute pattern"] = "projectile speed increased|0.5&projectile speed increased|0.5&projectile speed increased|0.5&projectile speed increased|0.75&projectile speed increased|0.75&projectile speed increased|0.75&projectile speed increased|1.2&projectile speed increased|1.2&projectile speed increased|1.2",
			["shoot pattern reset time"] = 1,
			["fire input on attack"] = "popscript^$MolotovExplode^",
			["mult projectile count"] = 3,
		} },
		CharacterAttributes = {["is miniboss"] = 1, ["move speed bonus"] = 0.5, ["damage force reduction"] = 0, ["airblast vulnerability multiplier"] = 0},
		Scale = 2,
		BaseCashMult = 5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {},
	},
	["T_TFBot_Giant_Enemy_Rocket_Artillery"] = {
		Weight = 1,
		Name = "Giant Rocket Artillery",
		Type = ENEMY_TYPE_BOSS,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Soldier",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 60, -- 1.5k base
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_MINIBOSS | ATTR_HOLD_FIRE_UNTIL_FULL_RELOAD | ATTR_ALWAYS_FIRE_WEAPON,
		Items = {"Armored Authority", "Soldier's Sparkplug", "Fancy Dress Uniform"},
		ItemAttributes = { [0] = {
			["clip size upgrade atomic"] = 46,
			["fire rate bonus"] = 0.1,
			["faster reload rate"] = 0.2,
			["spread angle pattern"] = "-75 0 0",
			["projectile lifetime"] = 5,
			["noclip projectiles"] = 1,
			["fire input on attack"] = "popscript^$OrbitalRocket^",
			["projectile no deflect"] = 1,
			["force fire full clip"] = 1,
			["throwable damage"] = 1.5,
		} },
		CharacterAttributes = {["is miniboss"] = 1, ["move speed bonus"] = 0.5, ["damage force reduction"] = 0, ["airblast vulnerability multiplier"] = 0},
		Scale = 2,
		BaseCashMult = 5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {},
	},
	["T_TFBot_Giant_Enemy_Beamer"] = {
		Weight = 1,
		Name = "Giant Beamer",
		Type = ENEMY_TYPE_BOSS,
		WeaponRestrictions = WEPRST_PRIMARY_ONLY,
		DefaultSlot = LOADOUT_POSITION_PRIMARY,
		Skill = AI_EXPERT,
		Class = "Civilian",
		Action = "Mobber",
		Health = ENEMY_BASE_HEALTH * 50, -- 1250 base
		Attributes = ATTR_IGNORE_FLAG | ATTR_DISABLE_DODGE | ATTR_MINIBOSS | ATTR_HOLD_FIRE_UNTIL_FULL_RELOAD,
		Items = {"The Master Mind", "Iron Lung", "Pip-Boy", "Life Support System", "Roboot", "Contaminated Carryall", "Delldozer", "The Pomson 6000"},
		ItemAttributes = { [0] = {
			["clip size bonus upgrade"] = 20,
			["fire rate bonus"] = 0.02,
			["reload time decreased"] = 0.15,
			["dmg penalty vs players"] = 3,
			["dmg penalty vs buildings"] = 15,
			
			["mod projectile heat seek power"] = 69420,
			["mod projectile heat aim error"] = 30,
			["mod projectile heat aim time"] = 0.05,
			["mod projectile heat no predict target speed"] = 1,
			
			["projectile speed decreased"] = 0.65,
		} },
		CharacterAttributes = {["is miniboss"] = 1, ["move speed bonus"] = 0.5, ["damage force reduction"] = 0, ["airblast vulnerability multiplier"] = 0},
		Scale = 2,
		BaseCashMult = 5,
		AddConds = {},
		VisionRange = -1,
		LogicFunc = nil, -- Passes botSpawn, data
		SpawnFunc = nil, -- Passes botSpawn, data
		DeathFunc = nil, -- Passes botSpawn
		
		Variants = {},
	},
}

--[[----------------+
	FUNCTIONS
+------------------]]--

function removeCallbacks(player, callbacks)
	if not IsValid(player) then
		return
	end

	for _, callbackId in pairs(callbacks) do
		player:RemoveCallback(callbackId)
	end
end

math.WeightedRandom = function( tbl )
	local total = 0
	for i, d in pairs( tbl ) do
		if tostring( type( d ) ) == "table" then
			total = total + d.Weight
		else
			total = total + d
		end
	end
	
	local random = math.randomfloat( 0, total )
	
	local cumulativeProbability = 0
	for key, item in pairs(tbl) do
		if tostring( type( tbl[key] ) ) == "table" then
			cumulativeProbability = cumulativeProbability + tbl[key].Weight
		else
			cumulativeProbability = cumulativeProbability + tbl[key]
		end
		if (cumulativeProbability >= random) then
			return key;
		end
	end
end

math.WeightedRandomEnemy = function( tbl )
	local total = 0
	for i, d in pairs( tbl ) do
		total = total + ( d.Weight * ENEMY_TYPE_CHANCE_MULT[ d.Type ] )
	end
	
	local random = math.randomfloat( 0, total )
	
	local cumulativeProbability = 0
	for key, item in pairs(tbl) do
		cumulativeProbability = cumulativeProbability + ( tbl[key].Weight * ENEMY_TYPE_CHANCE_MULT[ tbl[key].Type ] )
		if (cumulativeProbability >= random) then
			return key;
		end
	end
end

CEntity.GetAttributeValueClean = function(self, attribute, default, slot) -- IDIOT FACE
	if slot == nil then return default end
    if (IsValid(self)) then
		-- print( self, attribute, default, slot, slot == LOADOUT_POSITION_BODY, ( self:GetAttributeValue( tostring( attribute ), true ) or default  ) )
		
		if slot == LOADOUT_POSITION_BODY then
			return ( self:GetAttributeValue( tostring( attribute ), true ) or default )
		else
			if IsValid( self:GetPlayerItemBySlot(slot) ) then
				return ( self:GetPlayerItemBySlot(slot):GetAttributeValue( tostring( attribute ), true ) or default )
			end
		end
    end
	return default
end

CEntity.GetItemBySlotClean = function(self, slot)
    if (IsValid(self)) then
		--print( attribute, default, slot, slot == LOADOUT_POSITION_BODY, ( self:GetAttributeValue( tostring( attribute ), true ) or default  ) )
		--print( slot )
		
		if slot == LOADOUT_POSITION_BODY then
			return self
		elseif slot == LOADOUT_POSITION_PRIMARY_AND_SECONDARY then
			return { self:GetPlayerItemBySlot( 0 ), self:GetPlayerItemBySlot( 1 ) }
		else
			return self:GetPlayerItemBySlot( tonumber(slot) )
		end
    end
end

ents.GetAllAliveBots = function()
	local ply = {}
	for _, player in pairs( ents.GetAllPlayers() ) do
		if player:IsBot() and player:IsAlive() then 
			table.insert( ply, player )
		end
	end
	return ply
end

ents.GetAllAliveNonMedicBots = function()
	local ply = {}
	for _, player in pairs( ents.GetAllPlayers() ) do
		if player:IsBot() and player:IsAlive() and ( player.m_iClass ~= TF_CLASS_MEDIC ) then 
			table.insert( ply, player )
		end
	end
	return ply
end

function GetAllVotes()
	local Votes = 0
	for i = 0, #VOTE_RESULTS do
		if VOTE_RESULTS[i] ~= nil then
			Votes = Votes + #VOTE_RESULTS[i]
		end
	end
	
	return Votes
end

function GetVoteWinner()
	local HighestVote = -100
	local Winners = {}
	for i = 0, #VOTE_RESULTS do
		if VOTE_RESULTS[i] ~= nil then
			if #VOTE_RESULTS[i] > HighestVote then
				HighestVote = #VOTE_RESULTS[i]
				Winners = { i }
			elseif #VOTE_RESULTS[i] == HighestVote then
				table.insert( Winners, i )
			end
		end
	end
	
	if #Winners == 1 then
		return Winners[1]
	else
		return Winners[ math.random( 1, #Winners ) ]
	end
end

function HasTrue( tbl )
	if tostring(type( tbl )) == "table" then
		for i, v in pairs( tbl ) do
			if v == true then
				return true
			end
		end
	else
		return tbl
	end
	return false
end

function WeaponAllowed( weapon, list )
	if ( not weapon ) or ( weapon == nil ) then return false end
	if ( not list ) or ( list == nil ) then return true end
	if ( tostring(type(weapon)) ~= "table" ) and ( weapon:IsPlayer() ) then
		weapon = { weapon:GetPlayerItemBySlot(0), weapon:GetPlayerItemBySlot(1) }
	end
	
	--print( type( list ), type( weapon ) )

	if tostring(type(list)) == "table" then
		if tostring(type(weapon)) == "table" then  
			local result = {}
			for i, wep in pairs( weapon ) do
				-- print( wep:GetItemName(), list[wep:GetClassname()] )
				if list[wep:GetClassname()] ~= nil then
					result[i] = list[wep:GetClassname()] 
				elseif list[ wep:GetItemName() ] ~= nil then
					result[i] = list[wep:GetItemName()] 
				else --failsafe
					result[i] = ( false )
				end
			end
			--PrintTable( result )
			return result
		else
			-- print( weapon:GetItemName(), list[weapon:GetClassname()] )
			--print( list[weapon:GetClassname()] )
			if list[weapon:GetClassname()] ~= nil then
				return ( list[weapon:GetClassname()] ) 
			elseif list[ weapon:GetItemName() ] ~= nil then
				return ( list[weapon:GetItemName()] )
			else --failsafe
				-- print( "Weapon was not found on provided list", weapon:GetItemName(), weapon:GetClassname() ) 
				return false 
			end
		end
	else
		if tostring(type(weapon)) == "table" then  
			local result = {}
			for i, wep in pairs( weapon ) do
				if wep:GetClassname() == list or ( wep:GetItemName() == list ) then
					result[i] = true
				else
					result[i] = false
				end
			end
			return result
		else
			if weapon:GetClassname() == list or ( weapon:GetItemName() == list ) then
				return true
			else
				return false
			end
		end
	end
	
	return false
end

function GetTypeCost( type )
	return math.floor( UPGRADE_COST_TABLE[type] * math.max( ( ( WAVE - 1 )^UPGRADE_COST_RAMP_COEF ), 1 ) ) 
end
function GetEnemyCount()
	return math.floor( ENEMY_BASE_COUNT + ( ( WAVE - 1 )^ENEMY_BASE_COUNT_SCALER ) ) 
end
function GetEnemyHealthMult()
	return WAVE^(ENEMY_BASE_HEALTH_SCALER + ( ( math.floor( (WAVE-1)/7 ) ) * ( ENEMY_BASE_HEALTH_SCALER_PER_PLAYER * #ents.GetAllRealPlayers() ) ) )
end

function BuildVoteMenu( player, dev )
	player = player or dev 
	--print( math.floor( ( WAVE + 1 ) / ( 6 + ( math.floor( ( WAVE + 1.5 ) / 7 ) * 7 ) ) ), ( WAVE + 1 ) / ( 6 + ( math.floor( ( WAVE + 1.5 ) / 7 ) * 7 ) ) )
	local AboutToBeShop = tobool( math.floor( ( WAVE + 1 ) / ( 6 + ( math.floor( ( WAVE + 1.5 ) / 7 ) * 7 ) ) ) )
	-- print( SHOP_WAVE, AboutToBeShop )
	
	if InWave then return end
	
	local function GetVotes( index )
		if VOTE_RESULTS[index] ~= nil then
			return #VOTE_RESULTS[index]
		else
			return 0
		end
	end
	
	if not VOTE_MENU then
	
		VOTE_MENU = {}
		local Categories = {}
		
		for key, val in pairs(UPGRADE_VOTING_MENU) do
			VOTE_MENU[key] = val
		end
		
		local function CategorySelected( cate )
			for i, _ in pairs( Categories ) do
				if Categories[i] == cate then
					return true
				end
			end
			return false
		end
		
		VOTE_MENU["onSelect"] = function( ply, index, value ) Voted( ply,index,value ) end 
		
		if SHOP_WAVE == false and AboutToBeShop == false then
			for i=1, tonumber( VOTE_OPTIONS + ENCOUNTER_MODIFY_STATS[MODIFY_VOTE_OPTIONS] ) do
				local random = math.WeightedRandom( VOTE_CATEGORIES )
				local category = VOTE_CATEGORIES[ random ]
				local name = category.name
				
				if i~=1 then
					while CategorySelected( random ) do
						random = math.WeightedRandom( VOTE_CATEGORIES )
						category = VOTE_CATEGORIES[ random ]
						name = category.name
					end
				end
				
				table.insert( Categories, random )
				
				VOTE_MENU[i] = { text = name, value = random, disabled = false }
			end
		elseif AboutToBeShop and ( not SHOP_WAVE ) then
			VOTE_MENU[1] = { text = VOTE_CATEGORIES[ UPGRADE_CATEGORY_SHOP ].name, value = UPGRADE_CATEGORY_SHOP, disabled = false }
		elseif SHOP_WAVE and ( not AboutToBeShop ) then
			VOTE_MENU[1] = { text = VOTE_CATEGORIES[ UPGRADE_CATEGORY_ELITE_BOSS ].name, value = UPGRADE_CATEGORY_ELITE_BOSS, disabled = false }
		end
	else
		if SHOP_WAVE == false and AboutToBeShop == false then
			for i=1, tonumber( VOTE_OPTIONS + ENCOUNTER_MODIFY_STATS[MODIFY_VOTE_OPTIONS] ) do
				local str = tostring( VOTE_CATEGORIES[tonumber( VOTE_MENU[i].value )].name ) .. " "
				for votes=1, GetVotes( tonumber( VOTE_MENU[i].value ) ) do
					str = str .. "☑"
				end
				VOTE_MENU[i] = { text = str, value = tonumber( VOTE_MENU[i].value ), disabled = false }
			end
		elseif AboutToBeShop and ( not SHOP_WAVE ) then
			local str = tostring( VOTE_CATEGORIES[ UPGRADE_CATEGORY_SHOP ].name ) .. " "
				for votes=1, GetVotes( tonumber( UPGRADE_CATEGORY_SHOP ) ) do
					str = str .. "☑"
				end
			VOTE_MENU[1] = { text = str, value = UPGRADE_CATEGORY_SHOP, disabled = false }
		elseif SHOP_WAVE and ( not AboutToBeShop ) then
			local str = tostring( VOTE_CATEGORIES[ UPGRADE_CATEGORY_ELITE_BOSS ].name ) .. " "
				for votes=1, GetVotes( tonumber( UPGRADE_CATEGORY_ELITE_BOSS ) ) do
					str = str .. "☑"
				end
			VOTE_MENU[1] = { text = str, value = UPGRADE_CATEGORY_ELITE_BOSS, disabled = false }
		end
	end
	
	player:DisplayMenu( VOTE_MENU )
end

function Voted( player, index, value )
	value = tonumber( value )
	
	for i = 0, #VOTE_RESULTS do
		for index, id in pairs( VOTE_RESULTS[i] ) do
			if id == player:GetSteamId() then
				table.remove( VOTE_RESULTS[i], index )
			end
		end
	end
	
	table.insert( VOTE_RESULTS[value], player:GetSteamId() )
end

function BuildUpgradeMenu( player, dev, loot_table )
	player = player or dev
	loot_table = loot_table or UPGRADE_LOOT_COMMON
	
	if player.InMenu == true then return end
	
	local new_menu = {}
	local display_upgrades = player.DisplayedUpgrades
	local discount = player.CostMult
	if loot_table == UPGRADE_LOOT_SHOP then
		display_upgrades = player.DisplayedShopUpgrades
	end
	
	for key, val in pairs(UPGRADE_DEFAULT_MENU) do
		new_menu[key] = val
	end
	--new_menu[itemsPerPage] = player.DisplayedUpgrades
	
	local function UpgradeAlreadySelected( upgrade, table, max_upgrades )
		if ( not upgrade ) or ( not table ) then return false end
		
		local output = false
		
		for i, v in pairs( table ) do
			if ( type(i) == "number" ) and ( i >= 1 ) and ( max_upgrades >= i ) then
				if upgrade == Upgrades[tonumber( v.value )]	then
					output = true
				end
			end
		end
		
		return output
	end
	
	new_menu["onSelect"] = function( ply, index, value ) UpgradeBrought( ply,index,value ) end
	new_menu["onCancel"] = function( ply, reason ) UpgradeSkipped( ply,reason ) end
	
	for i=1, tonumber( display_upgrades ) do
		local loot_upgraded = false 
		local type = table.RandomChance( UPGRADE_LOOT_TABLE[ loot_table ] ) -- type 0-4
		if ( loot_table ~= UPGRADE_LOOT_SHOP ) and ( type ~= UPGRADE_TYPE_GREED ) then
			-- print( player:GetAttributeValueClean( "freaky fair extra attrib1", 0, LOADOUT_POSITION_BODY ), player:GetAttributeValueClean( "freaky fair extra attrib1", 0, LOADOUT_POSITION_BODY ) >= math.random() )
			if player:GetAttributeValueClean( "freaky fair extra attrib1", 0, LOADOUT_POSITION_BODY ) > 0 then
				local chance = player:GetAttributeValueClean( "freaky fair extra attrib1", 0, LOADOUT_POSITION_BODY )
				if chance >= math.random() then
					type = math.min( type + 1, UPGRADE_TYPE_LEGENDARY )
					loot_upgraded = true
				end
			end
		end
		local upgrades_list = GetUpgradesTableFiltered(type)
		local rnd = math.random( 1, #upgrades_list ) 
		local selected_upgrade = Upgrades[ upgrades_list[rnd] ]
		local loops = 0
		local force_disable = false
		
		while IsUpgradeCapped( player, selected_upgrade ) or ( not HasTrue( WeaponAllowed( player:GetItemBySlotClean( selected_upgrade.Attributes[1].slot ), selected_upgrade.WeaponList ) ) ) or ( ( ( UPGRADE_LOOT_CATEGORY ~= UPGRADE_CATEGORY_ALL ) and ( UPGRADE_LOOT_CATEGORY ~= UPGRADE_CATEGORY_EPIC ) and ( UPGRADE_LOOT_CATEGORY ~= UPGRADE_CATEGORY_ELITE_BOSS ) and ( UPGRADE_LOOT_CATEGORY ~= UPGRADE_CATEGORY_GREED ) ) and ( selected_upgrade.Category ~= UPGRADE_LOOT_CATEGORY ) ) or ( UpgradeAlreadySelected( selected_upgrade, new_menu, display_upgrades ) ) do -- TODO: Filter out copies of same upgrade, loop through table of upgrades already selected to make sure it's unique
			rnd = math.random( 1, #upgrades_list )
			selected_upgrade = Upgrades[ upgrades_list[rnd] ]
			
			loops = loops + 1 -- failsafe to avoid stackoverflow
			if loops > 2500 then
				print( "breaking" )
				force_disable = true
				break
			end
		end
		
		local cost = ""
		if player.InShop then
			local cost_num = math.floor( GetTypeCost(type) * discount, 2 )
			cost = "$" .. tostring( cost_num )
			if 1 > discount then
				cost = cost .. " (-" .. tostring( math.round( 1-discount, 2 ) * 100 ) .. "%)"
			end
			-- new_menu["flags"] = MENUFLAG_NO_SOUND
			-- new_menu["onCancel"] = nil
		end
		
		--local str = tostring( UPGRADE_TYPE_TABLE[type] ) .. ": " .. selected_upgrade.Name .. "\n" .. "Description: " .. "\n" ..selected_upgrade.Description
		local str = tostring( UPGRADE_TYPE_TABLE[type] ) .. ": " .. selected_upgrade.Name .. " " .. cost .. "\n" .. selected_upgrade.Description
		if loot_upgraded then
			str = "(UPGRADED) " .. str
		end
		
		new_menu[i] = { text = str, value = upgrades_list[rnd], disabled = ( IsUpgradeCapped( player, selected_upgrade ) or force_disable ) }
	end
	
	local reroll_cost = math.floor( math.max( ( WAVE - 1 ), 1 ) * ( UPGRADE_REROLL_COST * UPGRADE_REROLL_COST_RAMP_COEF ) * ( player.Rerolls + 1 )^UPGRADE_REROLL_COST_RAMP_COEF )
	
	new_menu[display_upgrades + 1] = { text = "Reroll Items $" .. tostring(reroll_cost) .. " " .. tostring(player.Rerolls) .. "/" .. tostring(player.MaxRerolls), value = UPGRADE_REROLL - loot_table, disabled = tobool( player.Rerolls >= player.MaxRerolls ) }
	
	local total = 0
	for i=1, display_upgrades do
		total = total +	GetTypeCost(Upgrades[tonumber(new_menu[i].value)].Type)
	end
	total = math.floor( total / display_upgrades )
	if not player.InShop then
		new_menu["title"] = new_menu["title"] .. "\nSkip for $" .. tostring( total )
	end
	
	--PrintTable( new_menu )
	player.Menu = new_menu
	player.InMenu = true
	player:DisplayMenu( new_menu )
end

function BuildViewUpgradeMenu( player, dev )
	player = player or dev
	
	--if player.InMenu == true then return end
	player.InRoll = false
	
	local new_menu = {}
	
	for key, val in pairs(UPGRADE_VIEW_MENU) do
		new_menu[key] = val
	end
	
	for index, count in pairs( player.Upgrades ) do
		if count > 0 then
			local greed = false
			if Upgrades[index].Type == UPGRADE_TYPE_GREED then greed = true end
			
			local extra_text = ""
			if greed then
				extra_text = "\n**You cannot drop Greed Loot!**"
			end
			table.insert( new_menu, { text = tostring( UPGRADE_TYPE_TABLE[Upgrades[index].Type] ) .. ": " .. Upgrades[index].Name .. " x" .. tostring(count) .. "\n" .. Upgrades[index].Description .. " each" .. extra_text, value = index, disabled = greed } )
		end
	end
	
	new_menu["onCancel"] = function( ply, reason ) 
		player.InRoll = false 
		if player.InMenu then
			player:DisplayMenu( player.Menu )
		end
	end
	
	new_menu["onSelect"] = function( ply, index, value ) 
		local warning_menu = {}
		
		value = tonumber( value )
		
		for k, v in pairs(UPGRADE_WARNING_MENU) do
			warning_menu[k] = v
		end
		
		warning_menu["onSelect"] = function( ply, i, v ) 
			player.InRoll = false 
			if player.InMenu then
				player:DisplayMenu( player.Menu )
			end
		
			UpgradeSalvaged( ply, i, v ) 
		end
		warning_menu["onCancel"] = function( ply, reason ) BuildViewUpgradeMenu( ply, ply ) end
		
		
		warning_menu["title"] = "Salvage " .. tostring( UPGRADE_TYPE_TABLE[Upgrades[value].Type] ) .. ": " .. Upgrades[value].Name .. " x" .. tostring(player.Upgrades[value])
		warning_menu[1] = { text = "Yes. \n" .. Upgrades[value].Description .. "\nYou'll get $" .. tostring( math.floor( GetTypeCost( Upgrades[value].Type ) * 0.5 * player.Upgrades[value] ) ) .. "\nPress back to cancel", value = value, disabled = false } 
		
		player:DisplayMenu( warning_menu )
	end
	
	player:DisplayMenu( new_menu )
end

function UpgradeSalvaged( player, index, value )
	value = tonumber(value)
	local upgrade = Upgrades[value]
	
	player:AddCurrency( math.floor(GetTypeCost( Upgrades[value].Type ) * 0.5 * player.Upgrades[value] ) )
	player:Print( PRINT_TARGET_CENTER, "Salvaged " .. tostring( UPGRADE_TYPE_TABLE[Upgrades[value].Type] ) .. ": " .. Upgrades[value].Name .. " x" .. tostring(player.Upgrades[value]) .. "\nFor $" .. tostring( math.floor(GetTypeCost( Upgrades[value].Type ) * 0.5 * player.Upgrades[value] ) ) )
	
	for i = 1, player.Upgrades[value] do
		for j = 1, #upgrade.Attributes do
			--print( upgrade.ApplyFunction )
			pcall( upgrade.SalvagedFunction, player, tonumber( value ) )
			--if not ( HasTrue( WeaponAllowed( player:GetItemBySlotClean( upgrade.slot ), upgrade.WeaponList ) ) ) then goto skip2 end
			
			if upgrade.Attributes[j].slot == LOADOUT_POSITION_BODY then
			
				local cap = ( upgrade.Attributes[j].cap or ( ( 2^32 ) / 2 ) - 1 )
				
				if tostring( upgrade.Attributes[j].type ) == "add" then
					player:SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_BODY ) - upgrade.Attributes[j].increment	), cap )
				elseif tostring( upgrade.Attributes[j].type ) == "multiply" then
					player:SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_BODY ) / upgrade.Attributes[j].increment ), cap )
				elseif tostring( upgrade.Attributes[j].type ) == "subtract" then
					player:SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_BODY ) + upgrade.Attributes[j].increment ), cap )
				elseif tostring( upgrade.Attributes[j].type ) == "divide" then
					player:SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_BODY ) * upgrade.Attributes[j].increment ), cap ) 
				elseif tostring( upgrade.Attributes[j].type ) == "set" then
					player:SetAttributeValue( tostring( upgrade.Attributes[j].attr ), upgrade.Attributes[j].refund_set ) 
				end
				
			elseif upgrade.Attributes[j].slot == LOADOUT_POSITION_PRIMARY_AND_SECONDARY then
				if tostring( upgrade.Attributes[j].type ) == "add" then
					if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_PRIMARY ) - upgrade.Attributes[j].increment ), cap )
					end
					if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_SECONDARY ) - upgrade.Attributes[j].increment ), cap )
					end
				elseif tostring( upgrade.Attributes[j].type ) == "multiply" then
					if (IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and  WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_PRIMARY ) / upgrade.Attributes[j].increment ), cap )
					end
					if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_SECONDARY ) / upgrade.Attributes[j].increment ), cap )
					end
				elseif tostring( upgrade.Attributes[j].type ) == "subtract" then
					if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_PRIMARY ) + upgrade.Attributes[j].increment ), cap )
					end
					if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_SECONDARY ) + upgrade.Attributes[j].increment ), cap )
					end
				elseif tostring( upgrade.Attributes[j].type ) == "divide" then
					if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_PRIMARY ) * upgrade.Attributes[j].increment ), cap )
					end
					if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_SECONDARY ) * upgrade.Attributes[j].increment ), cap )
					end
				elseif tostring( upgrade.Attributes[j].type ) == "set" then
					if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), upgrade.Attributes[j].refund_set ) 
					end
					if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), upgrade.Attributes[j].default ) 
					end
				end
				
			else
				if ( WeaponAllowed( player:GetPlayerItemBySlot( upgrade.Attributes[j].slot ), upgrade.WeaponList ) ) then
					if tostring( upgrade.Attributes[j].type ) == "add" then
						player:GetPlayerItemBySlot(upgrade.Attributes[j].slot):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, upgrade.Attributes[j].slot ) - upgrade.Attributes[j].increment ), cap )
					elseif tostring( upgrade.Attributes[j].type ) == "multiply" then
						player:GetPlayerItemBySlot(upgrade.Attributes[j].slot):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, upgrade.Attributes[j].slot ) / upgrade.Attributes[j].increment ), cap )
					elseif tostring( upgrade.Attributes[j].type ) == "subtract" then
						player:GetPlayerItemBySlot(upgrade.Attributes[j].slot):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, upgrade.Attributes[j].slot ) + upgrade.Attributes[j].increment ), cap )
					elseif tostring( upgrade.Attributes[j].type ) == "divide" then
						player:GetPlayerItemBySlot(upgrade.Attributes[j].slot):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, upgrade.Attributes[j].slot ) * upgrade.Attributes[j].increment ), cap )
					elseif tostring( upgrade.Attributes[j].type ) == "set" then
						player:GetPlayerItemBySlot(upgrade.Attributes[j].slot):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), upgrade.Attributes[j].refund_set ) 
					end
				end
			end
			
			::skip2::
		end
	end
	
	player.Upgrades[value] = 0
end

function ApplyMissingUpgrades( player )
	for i, v in pairs( player.Upgrades ) do
		local upgrade = Upgrades[i]
		
		if( not Upgrades[i].Attributes ) then
			-- print(i)
		end
		for j = 1, ( #upgrade.Attributes ) do
			if v == 0 then goto skip end
			local unupgraded = false
			if upgrade.Attributes[j].slot == LOADOUT_POSITION_BODY then
				unupgraded = player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_BODY ) == upgrade.Attributes[j].default
			elseif upgrade.Attributes[j].slot == LOADOUT_POSITION_PRIMARY_AND_SECONDARY then
				if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) then
					unupgraded = player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_PRIMARY ) == upgrade.Attributes[j].default
				end
				if not unupgraded then
					unupgraded = player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_SECONDARY ) == upgrade.Attributes[j].default
				end
			else
				unupgraded = player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, upgrade.Attributes[j].slot ) == upgrade.Attributes[j].default
			end
			for k = 1, v do
				
				if upgrade.Attributes[j].slot == LOADOUT_POSITION_BODY then
				
					if unupgraded then
						pcall( upgrade.ApplyFunction, player, tonumber( i ) )
					end
			
					local cap = ( upgrade.Attributes[j].cap or ( ( 2^32 ) / 2 ) - 1 )
					
					if tostring( upgrade.Attributes[j].type ) == "add" then
						player:SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_BODY ) + upgrade.Attributes[j].increment	), cap )
					elseif tostring( upgrade.Attributes[j].type ) == "multiply" then
						player:SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_BODY ) * upgrade.Attributes[j].increment ), cap )
					elseif tostring( upgrade.Attributes[j].type ) == "subtract" then
						player:SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_BODY ) - upgrade.Attributes[j].increment ), cap )
					elseif tostring( upgrade.Attributes[j].type ) == "divide" then
						player:SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_BODY ) / upgrade.Attributes[j].increment ), cap ) 
					elseif tostring( upgrade.Attributes[j].type ) == "set" then
						player:SetAttributeValue( tostring( upgrade.Attributes[j].attr ), upgrade.Attributes[j].increment ) 
					end
					
				elseif upgrade.Attributes[j].slot == LOADOUT_POSITION_PRIMARY_AND_SECONDARY then
					if tostring( upgrade.Attributes[j].type ) == "add" then
						if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
							player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_PRIMARY ) + upgrade.Attributes[j].increment ), cap )
						end
						if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
							player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_SECONDARY ) + upgrade.Attributes[j].increment ), cap )
						end
					elseif tostring( upgrade.Attributes[j].type ) == "multiply" then
						if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
							player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_PRIMARY ) * upgrade.Attributes[j].increment ), cap )
						end
						if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
							player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_SECONDARY ) * upgrade.Attributes[j].increment ), cap )
						end
					elseif tostring( upgrade.Attributes[j].type ) == "subtract" then
						if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
							player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_PRIMARY ) - upgrade.Attributes[j].increment ), cap )
						end
						if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
							player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_SECONDARY ) - upgrade.Attributes[j].increment ), cap )
						end
					elseif tostring( upgrade.Attributes[j].type ) == "divide" then
						if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
							player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_PRIMARY ) / upgrade.Attributes[j].increment ), cap )
						end
						if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
							player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, LOADOUT_POSITION_SECONDARY ) / upgrade.Attributes[j].increment ), cap )
						end
					elseif tostring( upgrade.Attributes[j].type ) == "set" then
						if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
							player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), upgrade.Attributes[j].increment ) 
						end
						if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
							player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), upgrade.Attributes[j].increment ) 
						end
					end
					 
				else
					if ( WeaponAllowed( player:GetPlayerItemBySlot( upgrade.Attributes[j].slot ), upgrade.WeaponList ) ) then
						if tostring( upgrade.Attributes[j].type ) == "add" then
							player:GetPlayerItemBySlot(upgrade.Attributes[j].slot):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, upgrade.Attributes[j].slot ) + upgrade.Attributes[j].increment ), cap )
						elseif tostring( upgrade.Attributes[j].type ) == "multiply" then
							player:GetPlayerItemBySlot(upgrade.Attributes[j].slot):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, upgrade.Attributes[j].slot ) * upgrade.Attributes[j].increment ), cap )
						elseif tostring( upgrade.Attributes[j].type ) == "subtract" then
							player:GetPlayerItemBySlot(upgrade.Attributes[j].slot):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, upgrade.Attributes[j].slot ) - upgrade.Attributes[j].increment ), cap )
						elseif tostring( upgrade.Attributes[j].type ) == "divide" then
							player:GetPlayerItemBySlot(upgrade.Attributes[j].slot):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[j].attr, upgrade.Attributes[j].default, upgrade.Attributes[j].slot ) / upgrade.Attributes[j].increment ), cap )
						elseif tostring( upgrade.Attributes[j].type ) == "set" then
							player:GetPlayerItemBySlot(upgrade.Attributes[j].slot):SetAttributeValue( tostring( upgrade.Attributes[j].attr ), upgrade.Attributes[j].increment ) 
						end
					end
				end
			end
			::skip::
		end
	end
	
	player:SetAttributeValue( "max health additive bonus", player:GetAttributeValueClean( "max health additive bonus", 0, LOADOUT_POSITION_BODY ) + player.HealthGained )
	player:SetAttributeValue( "mult max health", math.max( player:GetAttributeValueClean( "mult max health", 0, LOADOUT_POSITION_BODY ) + player.HealthMultGained, 1 ) )
end

function UpgradeBrought( player, index, value )
	player:PlaySoundToSelf( "ui/buttonrollover.wav" )
	if tonumber( value ) >= 0 then
		local upgrade = Upgrades[ tonumber( value ) ]
		if player.InShop then
			local discount = player.CostMult
			local str = ""
			if player.CanHaggle and ( not player.Haggled ) then
				discount = discount - 0.15
				player.Haggled = true
				str = "\nYou haggled and brought the price down by 15%"
			end
			if ( player.m_nCurrency < ( math.floor(GetTypeCost(upgrade.Type) * discount, 2 ) ) ) then 
				player:PlaySoundToSelf( "mvm/mvm_money_vanish.wav" )
				player:PlaySoundToSelf( "mvm/mvm_money_vanish.wav" )
				player:Print( PRINT_TARGET_CENTER, "Not enough money" )
				timer.Simple( 0.2, function()
					if player.InShop then
						player.Menu["flags"] = MENUFLAG_NO_SOUND | MENUFLAG_BUTTON_EXIT
					end
					player:DisplayMenu( player.Menu )
				end)
				return
			end
			local cost = math.floor(GetTypeCost(upgrade.Type) * discount, 2 )
			player:RemoveCurrency( cost )
			player:Print( PRINT_TARGET_CENTER, "Brought: " .. tostring( UPGRADE_TYPE_TABLE[upgrade.Type] ) .. ": " .. upgrade.Name .. " $" .. tostring(cost) .. "\n" .. upgrade.Description .. str )
			player:PlaySoundToSelf( "MVM.PlayerUpgraded" )
			player:PlaySoundToSelf( "MVM.PlayerUpgraded" )
		else
			player:Print( PRINT_TARGET_CENTER, "Picked up: " .. tostring( UPGRADE_TYPE_TABLE[upgrade.Type] ) .. ": " .. upgrade.Name .. "\n" .. upgrade.Description )
			
			player.Rerolls = 0
			--player.InShop = false
			player.InMenu = false
			player.InRoll = false
			
			player:PlaySoundToSelf( "ui/item_metal_tiny_pickup.wav" )
			player:PlaySoundToSelf( "ui/item_metal_tiny_pickup.wav" )
			player:PlaySoundToSelf( "ui/item_metal_tiny_pickup.wav" )
		end
		
		--print( player, index, value )
		
		for i = 1, #upgrade.Attributes do
			--print( upgrade.ApplyFunction )
			pcall( upgrade.ApplyFunction, player, tonumber( value ) )
			
			if upgrade.Attributes[i].slot == LOADOUT_POSITION_BODY then
			
				local cap = ( upgrade.Attributes[i].cap or ( ( 2^32 ) / 2 ) - 1 )
				
				if tostring( upgrade.Attributes[i].type ) == "add" then
					player:SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_BODY ) + upgrade.Attributes[i].increment	), cap )
				elseif tostring( upgrade.Attributes[i].type ) == "multiply" then
					player:SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_BODY ) * upgrade.Attributes[i].increment ), cap )
				elseif tostring( upgrade.Attributes[i].type ) == "subtract" then
					player:SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_BODY ) - upgrade.Attributes[i].increment ), cap )
				elseif tostring( upgrade.Attributes[i].type ) == "divide" then
					player:SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_BODY ) / upgrade.Attributes[i].increment ), cap ) 
				elseif tostring( upgrade.Attributes[i].type ) == "set" then
					player:SetAttributeValue( tostring( upgrade.Attributes[i].attr ), upgrade.Attributes[i].increment ) 
				end
				
			elseif upgrade.Attributes[i].slot == LOADOUT_POSITION_PRIMARY_AND_SECONDARY then
				if tostring( upgrade.Attributes[i].type ) == "add" then
					if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_PRIMARY ) + upgrade.Attributes[i].increment ), cap )
					end
					if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_SECONDARY ) + upgrade.Attributes[i].increment ), cap )
					end
				elseif tostring( upgrade.Attributes[i].type ) == "multiply" then
					if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_PRIMARY ) * upgrade.Attributes[i].increment ), cap )
					end
					if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_SECONDARY ) * upgrade.Attributes[i].increment ), cap )
					end
				elseif tostring( upgrade.Attributes[i].type ) == "subtract" then
					if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_PRIMARY ) - upgrade.Attributes[i].increment ), cap )
					end
					if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_SECONDARY ) - upgrade.Attributes[i].increment ), cap )
					end
				elseif tostring( upgrade.Attributes[i].type ) == "divide" then
					if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_PRIMARY ) / upgrade.Attributes[i].increment ), cap )
					end
					if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_SECONDARY ) / upgrade.Attributes[i].increment ), cap )
					end
				elseif tostring( upgrade.Attributes[i].type ) == "set" then
					if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) and ( WeaponAllowed( player:GetPlayerItemBySlot( 0 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), upgrade.Attributes[i].increment ) 
					end
					if ( WeaponAllowed( player:GetPlayerItemBySlot( 1 ), upgrade.WeaponList ) ) then
						player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), upgrade.Attributes[i].increment ) 
					end
				end
				
			else
				if ( WeaponAllowed( player:GetPlayerItemBySlot( upgrade.Attributes[i].slot ), upgrade.WeaponList ) ) then
					if tostring( upgrade.Attributes[i].type ) == "add" then
						player:GetPlayerItemBySlot(upgrade.Attributes[i].slot):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, upgrade.Attributes[i].slot ) + upgrade.Attributes[i].increment ), cap )
					elseif tostring( upgrade.Attributes[i].type ) == "multiply" then
						player:GetPlayerItemBySlot(upgrade.Attributes[i].slot):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.min( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, upgrade.Attributes[i].slot ) * upgrade.Attributes[i].increment ), cap )
					elseif tostring( upgrade.Attributes[i].type ) == "subtract" then
						player:GetPlayerItemBySlot(upgrade.Attributes[i].slot):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, upgrade.Attributes[i].slot ) - upgrade.Attributes[i].increment ), cap )
					elseif tostring( upgrade.Attributes[i].type ) == "divide" then
						player:GetPlayerItemBySlot(upgrade.Attributes[i].slot):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), math.max( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, upgrade.Attributes[i].slot ) / upgrade.Attributes[i].increment ), cap )
					elseif tostring( upgrade.Attributes[i].type ) == "set" then
						player:GetPlayerItemBySlot(upgrade.Attributes[i].slot):SetAttributeValue( tostring( upgrade.Attributes[i].attr ), upgrade.Attributes[i].increment ) 
					end
				end
			end
			
			::skip3::
		end
		
		player.Upgrades[ tonumber( value ) ] = player.Upgrades[ tonumber( value ) ] + 1
		
		player.Menu[ tonumber( index) ]["disabled"] = true
		
		timer.Simple( 0.2, function()
			if player.InShop then
				player.Menu["flags"] = MENUFLAG_NO_SOUND | MENUFLAG_BUTTON_EXIT
				player:DisplayMenu( player.Menu )
			end
		end)
	elseif tonumber( value ) <= UPGRADE_REROLL then
		if ( player.m_nCurrency < math.floor( ( math.max( ( WAVE - 1 ), 1 ) * ( UPGRADE_REROLL_COST * UPGRADE_REROLL_COST_RAMP_COEF * ( player.Rerolls + 1 )^UPGRADE_REROLL_COST_RAMP_COEF ) ) ) ) then
			player:PlaySoundToSelf( "mvm/mvm_money_vanish.wav" )
			player:PlaySoundToSelf( "mvm/mvm_money_vanish.wav" )
			player:Print( PRINT_TARGET_CENTER, "Not enough money" )
			timer.Simple( 0.2, function()
				if player.InShop then
					player.Menu["flags"] = MENUFLAG_NO_SOUND | MENUFLAG_BUTTON_EXIT
				end
				player:DisplayMenu( player.Menu )
			end)
			return
		end
		
		player:PlaySoundToSelf( "ui/trade_up_apply_sticker.wav" )
		player:PlaySoundToSelf( "ui/trade_up_apply_sticker.wav" )
		player:RemoveCurrency( math.floor( ( math.max( ( WAVE - 1 ), 1 ) * ( UPGRADE_REROLL_COST * UPGRADE_REROLL_COST_RAMP_COEF * ( player.Rerolls + 1 )^UPGRADE_REROLL_COST_RAMP_COEF ) ) ) )
		
		player.Rerolls = player.Rerolls + 1
		
		player.InMenu = false
		player.InRoll = true
		timer.Simple( 0.2, function()
			BuildUpgradeMenu( player, player, math.abs( tonumber( value ) + 1 ) )
			player.InRoll = false
		end)
	end
end

function UpgradeSkipped( player, reason )
	if reason == MENU_CANCEL_NODISPLAY or reason == MENU_CANCEL_TIMEOUT or reason == MENU_CANCEL_INTERRUPTED then
		--player:DisplayMenu( player.Menu )
	else
		player.InMenu = false
		player.InRoll = false
		--player.InShop = false
		player.Rerolls = 0
	end
	
	if reason == MENU_CANCEL_EXIT then
		if not player.InShop then
			local total = 0
			for i=1, player.DisplayedUpgrades do
				total = total + GetTypeCost(Upgrades[tonumber(player.Menu[i].value)].Type)
			end
			total = math.floor( total / player.DisplayedUpgrades )
			
			player:AddCurrency( total )
			player.InMenu = false
			player.InRoll = false
			--player.InShop = false
			player.Rerolls = 0
			player:PlaySoundToSelf( "MVM.MoneyPickup" )
			player:PlaySoundToSelf( "ui/item_metal_tiny_drop.wav" )
			player:PlaySoundToSelf( "ui/item_metal_tiny_drop.wav" )
		else
			player.InMenu = false
			player.InRoll = false
			player.InShop = false
			player.Rerolls = 0
			
			player:PlaySoundToSelf( "ui/item_metal_tiny_drop.wav" )
			player:PlaySoundToSelf( "ui/item_metal_tiny_drop.wav" )
		end
	end
end	

function GetUpgradesTableFiltered( type )
	local new_tbl = {}
	local cate = UPGRADE_LOOT_CATEGORY
	if cate == UPGRADE_CATEGORY_ELITE_BOSS then cate = UPGRADE_CATEGORY_EPIC end
	-- print( type, UPGRADE_LOOT_CATEGORY )
	
	for index, upgrade in pairs( Upgrades ) do
		if ( cate ~= UPGRADE_CATEGORY_ALL ) and ( cate ~= UPGRADE_CATEGORY_EPIC ) and ( cate ~= UPGRADE_CATEGORY_GREED ) and ( cate ~= UPGRADE_CATEGORY_GREED ) and ( cate ~= UPGRADE_CATEGORY_SHOP ) then
			-- print( upgrade.Type, type, upgrade.Type == type, upgrade.Category, cate, upgrade.Category == cate )
			if ( upgrade.Type == type ) and ( upgrade.Category == cate ) then
				table.insert( new_tbl, index )
			end
		else
			if upgrade.Type == type then
				table.insert( new_tbl, index )
			end
		end
	end
	
	if new_tbl == nil then
		for index, upgrade in pairs( Upgrades ) do
			if upgrade.Type == type then
				table.insert( new_tbl, index )
			end
		end
	end
	
	return new_tbl
end

function IsUpgradeCapped( player, upgrade )
	local capped = false
	for i = 1, #upgrade.Attributes do
		if upgrade.Attributes[i].cap == nil then goto skip end
		-- print( upgrade.Name, upgrade.Attributes[i].cap, upgrade.Attributes[i].slot, upgrade.Attributes[i].type, "\n", player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, upgrade.Attributes[i].slot ), upgrade.Attributes[i].cap, ( ( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, upgrade.Attributes[i].slot ) +0.001) >= upgrade.Attributes[i].cap ) )
		
		if upgrade.Attributes[i].slot == LOADOUT_POSITION_BODY then
	
			if upgrade.Attributes[i].type == "add" or upgrade.Attributes[i].type == "multiply" then
				capped = ( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_BODY ) >= upgrade.Attributes[i].cap )
			elseif upgrade.Attributes[i].type == "subtract" or upgrade.Attributes[i].type == "divide" then
				capped = ( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_BODY ) <= upgrade.Attributes[i].cap )
			elseif upgrade.Attributes[i].type == "set" then
				capped = ( ( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_BODY ) +0.0001) >= upgrade.Attributes[i].cap )
			end
		
		elseif upgrade.Attributes[i].slot == LOADOUT_POSITION_PRIMARY_AND_SECONDARY then
			if upgrade.Attributes[i].type == "add" or upgrade.Attributes[i].type == "multiply" then
				if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) then
					capped = (player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_PRIMARY ) >= upgrade.Attributes[i].cap)
				end
				if capped == false then
					capped = (player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_SECONDARY ) >= upgrade.Attributes[i].cap)
				end
			elseif upgrade.Attributes[i].type == "subtract" or upgrade.Attributes[i].type == "divide" then
				if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) then
					capped = (player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_PRIMARY ) <= upgrade.Attributes[i].cap )
				end
				if capped == false then
					capped = (player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_SECONDARY ) <= upgrade.Attributes[i].cap )
				end
			elseif upgrade.Attributes[i].type == "set" then
				if IsValid(player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY)) then
					capped = ( ( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_PRIMARY ) +0.001) >= upgrade.Attributes[i].cap )
				end
				if capped == false then
					capped = ( ( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, LOADOUT_POSITION_SECONDARY ) +0.001) >= upgrade.Attributes[i].cap )
				end
			end
		else
			if upgrade.Attributes[i].type == "add" or upgrade.Attributes[i].type == "multiply" then
				capped = (player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, upgrade.Attributes[i].slot ) >= upgrade.Attributes[i].cap)
			elseif upgrade.Attributes[i].type == "subtract" or upgrade.Attributes[i].type == "divide" then
				capped = (player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, upgrade.Attributes[i].slot ) <= upgrade.Attributes[i].cap )
			elseif upgrade.Attributes[i].type == "set" then
				capped = ( ( player:GetAttributeValueClean( upgrade.Attributes[i].attr, upgrade.Attributes[i].default, upgrade.Attributes[i].slot ) ) == upgrade.Attributes[i].cap )
			end
		end
		
		::skip::
	end
	return capped
end

function SetUpPlayerInfo( player )
	player.DisplayedUpgrades = UPGRADE_DEFAULT_COUNT
	player.DisplayedShopUpgrades = UPGRADE_DEFAULT_COUNT
	player.Rerolls = 0
	player.MaxRerolls = UPGRADE_DEFAULT_MAX_REROLLS
	player.CostMult = 1
	player.CashMult = 1
	player.CanHaggle = false
	player.VoteMenu = nil
	player.IncomeDelay = 0
	player.AdderanlineTime = 0
	
	if not player.Upgrades then
		
		player.Upgrades = {}
		
		
		for index, upgrade in pairs( Upgrades ) do
			player.Upgrades[index] = 0
		end
		
		player.InMenu = false
		player.InRoll = false
		player.InShop = false
		player.Haggled = false
		
		player.HealthGained = 0
		player.HealthMultGained = 0
		
		player.DamageCallback = player:AddCallback( ON_DAMAGE_RECEIVED_PRE, function( ent, dmginfo )
			if IsValid( ent:GetPlayerItemBySlot( LOADOUT_POSITION_PDA ) ) then
				local disguise = ent:GetPlayerItemBySlot( LOADOUT_POSITION_PDA )
				local attr = disguise:GetAttributeValue( "disguise damage reduction" ) or 1
				
				if ent:InCond( TF_COND_DISGUISED ) then
					dmginfo.Damage = dmginfo.Damage * attr
					return true
				end
			end
		end)
		
	end
end

function ResetPlayerInfo( player,dev )
	player = dev or player
	player.DisplayedUpgrades = UPGRADE_DEFAULT_COUNT
	player.DisplayedShopUpgrades = UPGRADE_DEFAULT_COUNT
	player.Rerolls = 0
	player.MaxRerolls = UPGRADE_DEFAULT_MAX_REROLLS
	player.Upgrades = {}
	player.CostMult = 1
	player.CashMult = 1
	player.CanHaggle = false
	player.VoteMenu = nil
	player.IncomeDelay = 0
	player.MaxIncome = 100
	player.IncomeThisWave = 0
	player.AdderanlineTime = 0
	
	for index, upgrade in pairs( Upgrades ) do
		player.Upgrades[index] = 0
	end
	
	player.InMenu = false
	player.InRoll = false
	player.InShop = false
	player.TurretMode = false
	player.TankMode = false
	player.Haggled = false
	
	player.HealthGained = 0
	player.HealthMultGained = 0
	
	player.DamageCallback = player:AddCallback( ON_DAMAGE_RECEIVED_PRE, function( ent, dmginfo )
		if IsValid( ent:GetPlayerItemBySlot( LOADOUT_POSITION_PDA ) ) then
			local disguise = ent:GetPlayerItemBySlot( LOADOUT_POSITION_PDA )
			local attr = disguise:GetAttributeValue( "disguise damage reduction" ) or 1
			
			if ent:InCond( TF_COND_DISGUISED ) then
				dmginfo.Damage = dmginfo.Damage * attr
				return true
			end
		end
	end)
end

function OnPlayerChat( player, text )
	--print( text )
	for s,_ in pairs(COMMANDS_TABLE) do
		--print( s, string.lower(COMMANDS_TABLE[s]), string.lower(text), string.match(string.lower(text), string.lower(COMMANDS_TABLE[s]))	)
		if ( string.match(string.lower(text), string.lower(COMMANDS_TABLE[s])) ) then
			BuildViewUpgradeMenu( player, player )
			player.InRoll = true
		end
	end
end

function OnAttackLogic(projectile,activator,weapon)
	-- print( activator )
	if IsValid(activator) and activator:IsAlive() and IsValid(weapon) and ( weapon ~= activator:GetPlayerItemBySlot(2) ) then
		if weapon:GetAttributeValue("airblast vulnerability multiplier hidden") ~= nil then
			local val = weapon:GetAttributeValue("airblast vulnerability multiplier hidden")
			local velo = activator:GetPlayerVelocity() - ( Vector( val, val, 0 ) * activator:GetEyeAngles():GetForward() )
			activator:SetPlayerVelocity( velo )
		end
		-- print( ( weapon:GetAttributeValue("tag__summer2014") ~= nil ) )
		if ( weapon:GetAttributeValue("tag__summer2014") ~= nil ) and ( IsValid( projectile ) ) then
			ExplosiveArrows(projectile,activator,weapon)
		end
	end
end

function OnKillLogic(projectile,activator,caller) 
	if( activator:GetAttributeValue("kill eater user 2") or 0 ) > 0 then
		activator.AdderanlineTime = CurTime() + 3
	end
	
	if ( activator:GetAttributeValue( "unlimited quantity" ) or 0 ) > 0 then
		local amount = ENEMY_BASE_CASH * caller.CashMult * ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GLOBALCASH] * ( activator:GetAttributeValue( "unlimited quantity" ) or 1 )
		
		local Ent_DataTable = {
			model = "models/items/currencypack_large.mdl",
			solid = 0
		}
		local cash = ents.CreateWithKeys( "prop_dynamic", Ent_DataTable, true, true )
		cash:SetAbsOrigin( caller:GetAbsOrigin() )
		
		cash.Amount = amount
		cash.Reward = activator
		cash.DieTime = CurTime() + 11
		cash.ThinkTimer = timer.Create( 0.1, function()
			if ( not IsValid( cash ) ) then
				return false
			end
			
			cash:SetAbsAngles( cash:GetAbsAngles() + Vector(0,6,0 ) )
			for _, player in pairs( ents.FindInSphere( cash:GetAbsOrigin(), 64, "player" ) ) do 
				if IsValid(player) and (player == cash.Reward) then
					cash.Reward:AddCurrency( cash.Amount )
					cash:PlaySound( "MVM.MoneyPickup" )
					
					pcall( timer.Stop, cash.ThinkTimer )
					cash:Kill()
				end
			end
			
			local pi = math.pi
			local timedif = cash.DieTime - CurTime()
			local blink = tobool( math.floor( math.sin( ( 2*pi * ( timedif ) ) - pi ) + 1 ) )
			
			if timedif <= 5 then
				if blink then
					cash:Disable()
				else
					cash:Enable()
				end
			end
			if ( timedif <= 0 ) then
				util.ParticleEffect( "mvm_cash_explosion", cash:GetAbsOrigin() )
				cash:PlaySound( "MVM.MoneyVanish" )
				
				pcall( timer.Stop, cash.ThinkTimer )
				cash:Kill()
				
				return false
			end
		end, 0 )
	end
	
	if caller.MarkForHealth then
		activator:SetAttributeValue( "max health additive bonus", ( activator:GetAttributeValue( "max health additive bonus" ) or 0 ) + ( activator:GetPlayerItemBySlot(2):GetAttributeValue( "duckstreaks active" ) or 0 ) )
		activator.HealthGained = activator.HealthGained + ( activator:GetPlayerItemBySlot(2):GetAttributeValue("duckstreaks active") or 2 )
	end
end

function StartTurretMode( player )
	player.TurretMode = true
end
function StopTurretMode( player )
	player.TurretMode = false
end

function StartTankMode(player)
	player.TankMode = true
end
function StopTankMode(player)
	player.TankMode = false
end

function OnBuildingCreated(entity, classname)
	timer.Simple( 0.1, function()
		if entity:IsValid() and (IsValid( entity:GetBuilder() ) ) then
			local ply = entity:GetBuilder()
			local pda = ply:GetPlayerItemBySlot( LOADOUT_POSITION_PDA )
			
			if ( ( pda:GetAttributeValue( "merasmus hat level display ONLY" ) ) ~= nil ) and ( not tobool( entity.m_bDisposableBuilding ) ) then
				entity.m_iHighestUpgradeLevel = ( pda:GetAttributeValue( "merasmus hat level display ONLY" ) + 1 )
			end
			if ( ( pda:GetAttributeValue( "building instant upgrade" ) ) ~= nil ) and ( not tobool( entity.m_bDisposableBuilding ) ) then
				entity.m_iUpgradeMetal = 200 * ( pda:GetAttributeValue( "building instant upgrade" ) )
			end
		end
	end)
end

function ChanceGoldenChance( decrease, upgrade )
	local mult = 1
	if decrease then mult = -1 end
	ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] = ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] + ( upgrade.Attributes[1].increment * mult )
end

function ProptectorGrenade(projectile,activator,weapon)
	projectile.RemovedCallback = projectile:AddCallback( ON_REMOVE, function( ent )
		local vectors = { Vector( 0, 192, 0 ), Vector( 0, -192, 0 ), Vector( 192, 0, 0 ), Vector( -192, 0, 0 ), }
		local angles = { Vector( 0, 90, 0 ), Vector( 0, 270, 0 ), Vector( 0, 0, 0 ), Vector( 0, 180, 0 ), }
		for index, vec in pairs( vectors ) do
			local Ent_data = {
				spawnflags = 1,
				skin = 1,
				teamnum = 3
			}
			local shield = ents.CreateWithKeys( "entity_medigun_shield", Ent_data, true, true )
			shield:SetAbsOrigin( ent:GetAbsOrigin() + vec )
			shield:SetAbsAngles( angles[index] )
			shield.m_nRenderMode = 1
			
			shield.DieTime = CurTime() + 5
			shield.ThinkTimer = timer.Create( 0.1, function()
				if ( not IsValid( shield ) )  then
					return false
				end
				
				local pi = math.pi
				local timedif = shield.DieTime - CurTime()
				local blink = tobool( math.floor( math.sin( ( 2*pi * ( timedif ) ) - pi ) + 1 ) )
				
				if ( timedif <= 0 )then
					pcall( timer.Stop, shield.ThinkTimer )
					shield:Kill()
					return false
				end
				
				if ( timedif <= 3 ) then
					if blink then
						shield:Alpha( 125 )
					else
						shield:Alpha( 255 )
					end
				end
			end, 0 )
		end
		
		ent:RemoveCallback( ON_REMOVE, ent.RemovedCallback )
	end)
end

function ExplosiveArrows(projectile, activator, weapon)
	projectile.Owner = activator
	projectile.CollidedCallback = projectile:AddCallback( ON_START_TOUCH, function( ent, other, hitPos, hitNormal )
		local function Explode( self, owner )
			util.ParticleEffect( "mvm_loot_explosion", self:GetAbsOrigin() )
			self:PlaySound("Weapon_LooseCannon.Explode")
			self:PlaySound("Weapon_LooseCannon.Explode")
			self:PlaySound("Weapon_LooseCannon.Explode")
			for _, others in pairs(ents.FindInSphere(self:GetAbsOrigin(),150)) do
				if others:IsRealPlayer() and ( others:GetTeam() ~= owner:GetTeam() ) then
					local BlastDamage = 30 + ( ( ( others.m_iMaxHealth + others:GetAttributeValueByClass("add_maxhealth", 0) ) * others:GetAttributeValueClean( "mult max health", 1, LOADOUT_POSITION_BODY ) ) * 0.3 )
					others:TakeDamage({Damage = BlastDamage, Attacker = owner, DamageType = DMG_BLAST})
				elseif others:IsBot() and ( others:GetTeam() ~= owner:GetTeam() ) then
					-- local BlastDamage = 150 + ( ( ( others.m_iMaxHealth + others:GetAttributeValueByClass("add_maxhealth", 0) ) * others:GetAttributeValueClean( "mult max health", 1, LOADOUT_POSITION_BODY ) ) * 0.05 )
					local BlastDamage = 250 * owner:GetAttributeValueByClass( "mult_dmg", 1 ) * owner:GetAttributeValueByClass( "mult_dmg_vs_players", 1 )
					others:TakeDamage({Damage = BlastDamage, Attacker = owner, DamageType = DMG_BLAST})
				end
			end	
		end
		
		if other:IsWorld() then
			timer.Simple( 2, function()
				Explode( ent, ent.Owner )
			end)
		elseif other:IsPlayer() then
			Explode( ent, ent.Owner )
		end
		
		ent:RemoveCallback( ON_START_TOUCH, ent.CollidedCallback )
	end)
end

function MolotovExplode(projectile, activator, weapon)
	projectile.Owner = activator
	projectile.RemovedCallback = projectile:AddCallback( ON_REMOVE, function( ent )
		util.ParticleEffect( "mvm_hatch_destroy_burn", ent:GetAbsOrigin() + Vector(0, 0, 256) )
		util.ParticleEffect( "mvm_hatch_destroy_smolderembers", ent:GetAbsOrigin() + Vector(0, 0, 192) )
		-- util.ParticleEffect( "mvm_hatch_destroy_smolder", ent:GetAbsOrigin() + Vector(0, 0, 128) )
		
		local DieTime = CurTime() + 10
		local pos = ent:GetAbsOrigin()
		local owner = ent.Owner
		local ownerTeam = owner:GetTeam()
		
		timer.Create( 0.1, function()
			if CurTime() >= DieTime then
				return false
			end
			for _, player in pairs( ents.FindInSphere( pos, 96, "player" ) ) do
				if IsValid( player ) and ( player:GetTeam() ~= ownerTeam ) then
					local damage = ( ( ( player.m_iMaxHealth + player:GetAttributeValueByClass("add_maxhealth", 0) ) * player:GetAttributeValueClean( "mult max health", 1, LOADOUT_POSITION_BODY ) ) ) / 25
					player:TakeDamage({Damage = damage, Attacker = owner, DamageType = DMG_BURN, DamageCustom = TF_DMG_CUSTOM_DRAGONS_FURY_BONUS_BURNING })
					player:IgnitePlayerDuration( 10, owner )
				end
			end
		end, 0 )
		
		ent:RemoveCallback( ON_REMOVE, ent.RemovedCallback )
	end)
end

function RecountPlayers( teamnum )
	PlayerCount = 0
	for i,v in pairs(PlayerTable) do
		PlayerTable[i] = nil
	end
	if teamnum == nil or ( not teamnum ) then
		for index, player in pairs(ents.GetAllPlayers()) do
			if ( player:IsRealPlayer() ) then
				PlayerTable[PlayerCount] = player
				PlayerCount = PlayerCount + 1	
			end
		end
	else
		for index, player in pairs(ents.GetAllPlayers()) do
			if ( player.m_iTeamNum ~= teamnum ) and ( player.m_iTeamNum ~= 1 ) and ( player:IsAlive() ) then
				PlayerTable[PlayerCount] = player
				PlayerCount = PlayerCount + 1	
			end
		end
	end
end

function OrbitalRocket(projectile,activator,weapon)
	RecountPlayers( activator.m_iTeamNum )
	local RandomPlayer = PlayerTable[math.random(0,#PlayerTable)]
	OrbitalRocketMain(RandomPlayer,activator,projectile:GetNetIndex(), ( activator:InCond(34) ) or ( activator:InCond(11) ) )
end

function OrbitalRocketMain(target,attacker,index,critboosted)
	if (target:IsValid()) and (attacker:IsValid()) then
		timer.Simple(3, function()
			local KeyValues = {
				model = "models/props_mvm/indicator/indicator_circle_long.mdl",
				skin = 1,
				origin = target:GetAbsOrigin(),
				disableshadows = 1,
				targetname = 'indicator ' .. tostring(index)
			}
			local KeyValues2 = {
				origin = target:GetAbsOrigin() + Vector(0, 0, 1100),
				angles = "90 0 0",
				Crits = 0,
				SpreadAngle = 0,
				targetname = 'shooter ' .. tostring(index),
				teamnum = attacker.m_iTeamNum
			}
			
			local mimic = ents.CreateWithKeys("tf_point_weapon_mimic", KeyValues2, true, true)
			mimic["$weaponname"] = "Orbital Strike Rocket"
			mimic["$AddWeaponAttribute"] = "dmg penalty vs players|" .. tostring( ( attacker.m_hActiveWeapon:GetAttributeValue( "throwable damage" ) ) or 1 )
			
			if critboosted then
				mimic["Crits"] = 1
			end
			
			local ring = ents.CreateWithKeys("prop_dynamic", KeyValues, true, true)
			ring:AcceptInput("SetAnimation","start")
			
			timer.Create(0.1, function()
				-- util.StartLagCompensation(target)
				local Trace = util.Trace({
					start = target:GetAbsOrigin() + Vector(0, 0, 16),
					mask = MASK_PLAYERSOLID,
					angles = Vector(90, 0, 0),
					mins = Vector(-16, -16, 0),
					maxs = Vector(16, 16, 0),
					filter = ents.GetAllPlayers()
				})
				-- util.FinishLagCompensation(target)
				ring:SetAbsOrigin(Trace.HitPos + Vector(0, 0, 8))
				mimic:SetAbsOrigin(Trace.HitPos + Vector(0, 0, 1100))
			end, 2.5 / 0.1)
			
			timer.Simple(2.7, function()
				ring:AcceptInput("Skin", 0)
			end)
			
			timer.Simple(3.7, function()
				mimic:AcceptInput("FireOnce")
			end)
			
			timer.Simple(4.7, function()
				ring:AcceptInput("SetAnimation","end")
			end)
			timer.Simple(5.2, function()
				ents.FindByName('indicator ' .. tostring(index)):AcceptInput("kill")
				mimic:AcceptInput("kill")
			end)
		end)
	end
end

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

function findFreeBot()
	local chosen

	for _, bot in pairs(ents.GetAllPlayers()) do
		if
			not bot:IsRealPlayer()
			and not bot:IsAlive()
			and (bot.m_iTeamNum == 1 or bot.m_iTeamNum == 0)
			and bot:GetPlayerName() ~= "Demo-Bot"
		then
			chosen = bot
			break
		end
	end

	return chosen
end

function ApplyName( bot, data )
	local displayName = data.Name
	bot.m_szNetname = displayName
	bot:SetFakeClientConVar("name", displayName)
end

function SpawnEnemy( data )
	local callbacks = {}
	local botSpawn = findFreeBot()
	
	if not botSpawn then
		print( "GLOBAL BOT LIMIT REACHED" )
		return
	end
	
	local Possible_Spawns = {}
	for index, data in pairs( ARENA_SPAWNS[ ARENA ] ) do
		if data.teamnum == 3 then
			table.insert( Possible_Spawns, data )
		end
	end
	
	local pos = Possible_Spawns[ math.random( 1, #Possible_Spawns ) ].pos + Vector( 0, 0, 16 )
	
	ApplyName( botSpawn, data )
	botSpawn:SetAbsOrigin( pos )
	botSpawn:SetAbsOrigin( pos )
	botSpawn:SwitchClassInPlace( data.Class )
	botSpawn:SwitchClassInPlace( data.Class )
	-- botSpawn.m_iTeamNum = 3
	-- botSpawn:SetFakeSendProp( "m_iTeamNum", 3 )
	botSpawn:RunScriptCode( "activator.ForceChangeTeam(3, true)", botSpawn, botSpawn )
	botSpawn:RunScriptCode( "activator.ForceChangeTeam(3, true)", botSpawn, botSpawn )
	botSpawn.m_iszClassIcon = ""
	botSpawn.CashMult = data.BaseCashMult
	botSpawn:SetCustomModelWithClassAnimations( ENEMY_MODEL_TABLE[ 0 ][botSpawn.m_iClass] )
	if data.Class == "Civilian" then
		botSpawn:SetCustomModelWithClassAnimations( "models/bots/engineer/bot_engineer.mdl" )
	end
	botSpawn.DeathFunction = data.DeathFunc
	
	botSpawn.MarkForHealth = false
	botSpawn.IsGiant = false
	
	if data.Type == ENEMY_TYPE_GIANT then
		ENEMY_CURRENT_NUMBER_OF_GIANTS = ENEMY_CURRENT_NUMBER_OF_GIANTS + 1
		botSpawn.IsGiant = true
	end
	
	if( ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] /100 ) > math.random() then
		-- print( "GOLDEN" )
		botSpawn.CashMult = botSpawn.CashMult * 5
		botSpawn:SetAttributeValue( "attach particle effect static", 3083 ) -- Golden Glimmer
	end
	
	callbacks.died = botSpawn:AddCallback(ON_DEATH, function()
		for name, _ in pairs(botSpawn:GetAllAttributeValues()) do
			botSpawn:SetAttributeValue(name, nil)
		end
		botSpawn:ResetFakeSendProp("m_iTeamNum")
		botSpawn.m_iTeamNum = 1
		botSpawn:SetAttributeValue( "attach particle effect static", nil )
		
		if botSpawn.IsGiant then
			ENEMY_CURRENT_NUMBER_OF_GIANTS = ENEMY_CURRENT_NUMBER_OF_GIANTS - 1
		end
		
		removeCallbacks(botSpawn, callbacks)
		pcall( timer.Stop, botSpawn.logicLoop )
		pcall( botSpawn.DeathFunction, botSpawn )
		
		-- print( botSpawn.CashMult )
		for _, player in pairs( ents.GetAllRealPlayers() ) do
			if ( player:GetAttributeValue( "unlimited quantity" ) or 0 ) <= 0 then 
				player:AddCurrency( ENEMY_BASE_CASH * botSpawn.CashMult * player.CashMult * ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GLOBALCASH] )
			end
		end
	end)
	
	timer.Simple(0, function()
		
		-- if not ( botSpawn:IsAlive() and IsValid( botSpawn ) and botSpawn:OnTeam( 3 ) ) then
			-- return
		-- end
		
		botSpawn:RunScriptCode( "activator.ForceChangeTeam(3, true)", botSpawn, botSpawn )
		botSpawn:SetAbsOrigin( pos )
		botSpawn:SetAbsOrigin( pos )
		botSpawn:SwitchClassInPlace( data.Class )
		botSpawn:SwitchClassInPlace( data.Class )
		botSpawn:SetAttributeValue("hidden maxhealth non buffed", ( data.Health - botSpawn.m_iHealth ) )
		botSpawn:SetAttributeValue("SET BONUS: max health additive bonus", ( data.Health * GetEnemyHealthMult() ) - data.Health )
		botSpawn:SetAttributeValue("rage giving scale", ( 1 / GetEnemyHealthMult() ) )
		
		for i=0, 2 do -- Remove unused items, save on edicts/networked entities
			if i ~= data.DefaultSlot and ( data.Items[i] == nil ) then
				botSpawn:WeaponStripSlot( i )
			end
		end
		botSpawn:SetActivePlayerWeapon( botSpawn:GetPlayerItemBySlot( data.DefaultSlot ) )
		
		for i, name in pairs( data.Items ) do
			-- print( tostring( name ), botSpawn:GiveItem( tostring( name ), nil, false, true ) )
			botSpawn:GiveItem( tostring( name ), nil, false, true )
		end
		
		timer.Simple( 0.1, function() 
		
			botSpawn:SetCustomModelWithClassAnimations( ENEMY_MODEL_TABLE[ 0 ][botSpawn.m_iClass] )
			if data.Class == "Civilian" then
				botSpawn:SetCustomModelWithClassAnimations( "models/bots/engineer/bot_engineer.mdl" )
			end
			
			for name, value in pairs(data.CharacterAttributes) do
				botSpawn:SetAttributeValue(name, value)
			end
			
			for i = 0, 10 do
				if IsValid( botSpawn:GetPlayerItemBySlot( i ) ) and ( data.ItemAttributes[i] ~= nil ) then
					for name, value in pairs(data.ItemAttributes[i]) do
						botSpawn:GetPlayerItemBySlot(i):SetAttributeValue(name, value)
					end
				end
			end
			
			for cond, _ in pairs( data.AddConds ) do
				botSpawn:AddCond( cond ) 
			end
			
			botSpawn:RunScriptCode( "activator.ForceChangeTeam(3, true)", botSpawn, botSpawn )
			botSpawn:RunScriptCode( "activator.ClearBehaviorFlag(1023)", botSpawn, botSpawn )
			botSpawn:RunScriptCode( "activator.ClearAllWeaponRestrictions()", botSpawn, botSpawn )
			botSpawn:RunScriptCode( "activator.ClearAllBotAttributes()", botSpawn, botSpawn )
			botSpawn:RunScriptCode( "activator.ClearAllBotTags()", botSpawn, botSpawn )
			botSpawn:RunScriptCode( "activator.ClearAttentionFocus()", botSpawn, botSpawn )
			
			if ( data.Variants ) and ( data.Variants[1] ) then
				if math.random() <= ( VARIANT_CHANCE * ENCOUNTER_MODIFY_STATS[MODIFY_VARIANT_CHANCE] ) then
					local variant = data.Variants[ math.WeightedRandom( data.Variants ) ]
					
					local displayName = variant.Append_Name .. data.Name 
					botSpawn.m_szNetname = displayName
					botSpawn:SetFakeClientConVar("name", displayName)
					
					for name, value in pairs(variant.CharacterAttributes) do
						botSpawn:SetAttributeValue(name, value)
					end
					
					for i = 0, 10 do
						if IsValid( botSpawn:GetPlayerItemBySlot( i ) ) and ( variant.ItemAttributes[i] ) then
							for name, value in pairs(variant.ItemAttributes[i]) do
								botSpawn:SetAttributeValue(name, value)
							end
						end
					end
					
					for i, name in pairs( variant.Items ) do
						-- print( tostring( name ), botSpawn:GiveItem( tostring( name ), nil, false, true ) )
						botSpawn:GiveItem( tostring( name ), nil, false, true )
					end
					
					for cond, _ in pairs( variant.AddConds ) do
						botSpawn:AddCond( cond ) 
					end
				end
			end
			
			--print( botSpawn.m_nBotSkill ) 
			
			botSpawn:RunScriptCode( "activator.AddBotAttribute(" .. tostring( data.Attributes ) .. ")", botSpawn, botSpawn )
			botSpawn:RunScriptCode( "activator.AddWeaponRestriction(" .. tostring( data.WeaponRestrictions ) .. ")", botSpawn, botSpawn )
			botSpawn:RunScriptCode( "activator.SetDifficulty(" .. tostring( data.Skill ) .. ")", botSpawn, botSpawn )
			botSpawn:RunScriptCode( "activator.SetMaxVisionRangeOverride(" .. tostring( data.VisionRange ) .. ")", botSpawn, botSpawn )
			botSpawn:RunScriptCode( "activator.SetScaleOverride(" .. tostring( data.Scale ) .. ")", botSpawn, botSpawn )
			
			-- print( botSpawn.m_bIsMiniBoss, botSpawn.m_iClass, ENEMY_MODEL_TABLE )
			
			botSpawn:SetCustomModelWithClassAnimations( ENEMY_MODEL_TABLE[ botSpawn.m_bIsMiniBoss ][botSpawn.m_iClass] )
			
			--botSpawn:RunScriptCode( "printl( activator.HasBotAttribute( 16 ) )", botSpawn, botSpawn )
			
			botSpawn:BotCommand( "switch_action Mobber" )
			botSpawn:BotCommand( "switch_action " .. tostring( data.Action ) )
		end)
		
		util.ParticleEffect( "teleportedin_blue", botSpawn:GetAbsOrigin() )
		
		timer.Create( 0.1, function()
			botSpawn:BotCommand( "switch_action " .. tostring( data.Action ) )
			botSpawn:SetAbsOrigin( pos )
			botSpawn:SetActivePlayerWeapon( botSpawn:GetPlayerItemBySlot( data.DefaultSlot ) )
			
			if data.Class == "Civilian" then
				botSpawn:SetCustomModelWithClassAnimations( "models/bots/engineer/bot_engineer.mdl" )
			end
		end, 3 )
		
		botSpawn.logicLoop = timer.Create(0.1, function()
			if ( not botSpawn:IsAlive() ) or ( not IsValid( botSpawn ) ) or ( not botSpawn:OnTeam( 3 ) ) then
				-- print( botSpawn, "stopping logic loop" )
				pcall( timer.stop, botSpawn.logicLoop )
				return false
			end
			pcall( data.LogicFunc, botSpawn, data )
		end, 0 )
		
		pcall( data.SpawnFunc, botSpawn, data )
	end)
	return botSpawn
end

--[[----------------+
	WAVES
+------------------]]--

function SetWaveCount( count )
	WAVE = tonumber(count)
end

function ResetEncounterModifiers()
	ENCOUNTER_MODIFY_STATS[MODIFY_VARIANT_CHANCE] = 1
	ENCOUNTER_MODIFY_STATS[MODIFY_VOTE_OPTIONS] = 0
	
	ENEMY_TYPE_CHANCE_MULT = {
		[ENEMY_TYPE_COMMON] = 1,
		[ENEMY_TYPE_MINIGIANT] = 1,
		[ENEMY_TYPE_GIANT] = 1,
		[ENEMY_TYPE_BOSS] = 0,
	}
end

function HardResetEncounterModifiers()
	ENCOUNTER_MODIFY_STATS[MODIFY_VARIANT_CHANCE] = 1
	ENCOUNTER_MODIFY_STATS[MODIFY_VOTE_OPTIONS] = 0
	ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GLOBALCASH] = 1
	ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_MULT] = 1
	ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] = 0
	ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_MAX_GIANTS] = 1
	
	ENEMY_TYPE_CHANCE_MULT = {
		[ENEMY_TYPE_COMMON] = 1,
		[ENEMY_TYPE_MINIGIANT] = 1,
		[ENEMY_TYPE_GIANT] = 1,
		[ENEMY_TYPE_BOSS] = 0,
	}
end

function InitWave()
	pcall( timer.Stop, SpawnTimer )
	HardResetEncounterModifiers()
	WAVE = 0
	TotalCount = 0
	SpawnTimer = nil
	WaveStarted = false
	InWave = false 
	SHOP_WAVE = false
	ARENA = 1
	ents.FindByClass('tf_objective_resource').m_nMannVsMachineMaxWaveCount = 0
	ents.FindByClass('tf_objective_resource').m_nMannVsMachineWaveCount = 0
	
	UPGRADE_LOOT_CATEGORY = UPGRADE_CATEGORY_ALL
	
	VOTING = false
	VOTE_OPTIONS = 3
	VOTE_RESULTS = {}
	VOTE_MENU = nil
	
	for _, player in pairs( ents.GetAllRealPlayers() ) do
		ResetPlayerInfo( player )
	end
end

function StartWave() 
	VOTE_MENU = nil
	WaveStarted = true
	for i = 0, #VOTE_CATEGORIES do
		VOTE_RESULTS[i] = {}
	end
	WAVE = WAVE + 1
	WAVE_DURATION = CurTime() + WAVE_HORDE_DURATION + 5
	ents.FindByClass('tf_objective_resource').m_nMannVsMachineWaveCount = WAVE
	InWave = true
	WAVE_TYPE_CURRENT = math.WeightedRandom( WAVE_TYPE_CHANCE_TABLE )
	SHOP_WAVE = tobool( math.floor( WAVE / ( 6 + ( math.floor( ( WAVE + 0.5 ) / 7 ) * 7 ) ) ) )
	TotalCount = math.floor( GetEnemyCount() )
	ARENA = math.random( 1, #ARENA_SPAWNS )
	StartDelay = nil
	LastWholeNumber = nil
	ResetEncounterModifiers()
	ENEMY_CURRENT_NUMBER_OF_GIANTS = 0
	ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_MAX_GIANTS] = math.ceil( WAVE/7 )
	
	for _, player in pairs( ents.GetAllRealPlayers() ) do
		if ( not IsValid( player ) ) or ( not player:OnTeam( 2 ) ) then goto continue end
		player:ForceRespawnDead()
		for i=0, 2 do
			if( IsValid(player:GetPlayerItemBySlot(i)) ) then
				player:GetPlayerItemBySlot(i):SetAttributeValue( "fire input on attack", "popscript^$OnAttackLogic^" )
				player:GetPlayerItemBySlot(i):SetAttributeValue( "fire input on kill", "popscript^$OnKillLogic^" )
			end
		end
		
		player.InShop = false
		player.InMenu = false
		player.InRoll = false
		
		::continue::
	end
	
	local Modif = math.floor( WAVE/7 ) * 7
	
	if UPGRADE_LOOT_CATEGORY == UPGRADE_CATEGORY_EPIC then
		ENEMY_TYPE_CHANCE_MULT = {
			[ENEMY_TYPE_COMMON] = 0.9,
			[ENEMY_TYPE_MINIGIANT] = 1.5,
			[ENEMY_TYPE_GIANT] = 1.15,
			[ENEMY_TYPE_BOSS] = 0,
		}
		ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_MAX_GIANTS] = ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_MAX_GIANTS] + 1
	elseif UPGRADE_LOOT_CATEGORY == UPGRADE_CATEGORY_ELITE_BOSS then
		ENEMY_TYPE_CHANCE_MULT = {
			[ENEMY_TYPE_COMMON] = 0,
			[ENEMY_TYPE_MINIGIANT] = 0,
			[ENEMY_TYPE_GIANT] = 0,
			[ENEMY_TYPE_BOSS] = 1,
		}
		TotalCount = math.min( math.max( math.floor( WAVE/7 ) - 1, 1 ), 5 )
		WAVE_TYPE_CURRENT = WAVE_TYPE_STANDARD
	elseif UPGRADE_LOOT_CATEGORY == UPGRADE_CATEGORY_GREED then
		ENCOUNTER_MODIFY_STATS[MODIFY_VARIANT_CHANCE] = 5
	else
		ENEMY_TYPE_CHANCE_MULT = {
			[ENEMY_TYPE_COMMON] = 1,
			[ENEMY_TYPE_MINIGIANT] = 1,
			[ENEMY_TYPE_GIANT] = 1,
			[ENEMY_TYPE_BOSS] = 0,
		}
	end
	
	if WAVE_TYPE_CURRENT == WAVE_TYPE_HORDE then
		ENEMY_TYPE_CHANCE_MULT = {
			[ENEMY_TYPE_COMMON] = 1,
			[ENEMY_TYPE_MINIGIANT] = 0.33,
			[ENEMY_TYPE_GIANT] = 0.15,
			[ENEMY_TYPE_BOSS] = 0,
		}
	end
	
	-- print( "Before Chance", ENEMY_TYPE_CHANCE_MULT[ENEMY_TYPE_COMMON], ENEMY_TYPE_CHANCE_MULT[ENEMY_TYPE_MINIGIANT] )
	
	for i=1, #ENEMY_TYPE_CHANCE_MULT do
		ENEMY_TYPE_CHANCE_MULT[i] = ENEMY_TYPE_CHANCE_MULT[i] * ENEMY_TYPE_CHANCE_SCALE_MULT[ WAVE - Modif ][i]
	end
	
	-- print( WAVE - Modif, "After Chance", ENEMY_TYPE_CHANCE_MULT[ENEMY_TYPE_COMMON], ENEMY_TYPE_CHANCE_MULT[ENEMY_TYPE_MINIGIANT] )
	
	if SHOP_WAVE == false then
		local Possible_Spawns = {}
		for index, data in pairs( ARENA_SPAWNS[ ARENA ] ) do
			if data.teamnum == 2 then
				table.insert( Possible_Spawns, data )
			end
		end
		
		for _, player in pairs( ents.GetAllRealPlayers() ) do
			if ( not IsValid( player ) ) or ( not player:OnTeam( 2 ) ) then goto continue end
			
			player:HideMenu()
			player.InShop = false
			player.IncomeThisWave = 0
			
			player:AcceptInput( "RunScriptCode", "ScreenFade( !activator, 255, 255, 255, 255, 1, 0.5, 2 )", player, player )
			player:AddCond( 87, 2 )
			timer.Simple( 1, function()
				player:SetAbsOrigin( Possible_Spawns[ math.random( 1, #Possible_Spawns ) ].pos + Vector( 0, 0, 16 ) )
				player:AcceptInput( "RunScriptCode", "ScreenFade( !activator, 255, 255, 255, 255, 1, 0, 1 )", player, player )
				
				player:Print( 2, "Loot on Victory: " .. VOTE_CATEGORIES[ UPGRADE_LOOT_CATEGORY ].name .. "!"  )
			end)
			timer.Simple( 2, function()
				player:RemoveCond( 87 )
				if( player:GetAttributeValue("kill eater user 1") or 0 ) > 0 then
					player:AddCond( TF_COND_RUNE_HASTE, 6 )
				end
			end)
			
			::continue::
		end
		
		local BaseEnemies = TotalCount
		local SpawnedCount = 0
		local SpawnDelay = 0
		local StillSpawning = true
		
		TotalCount = math.floor( TotalCount * ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_MULT] )
		
		-- print( math.WeightedRandomEnemy( ENEMY_TEMPLATES ), GetEnemyCount(), GetEnemyHealthMult() )
		
		timer.Simple( 1, function()
			SpawnTimer = timer.Create( 0.1, function()
				if WAVE_TYPE_CURRENT == WAVE_TYPE_STANDARD then
				
					if CurTime() >= SpawnDelay and ( #ents.GetAllAliveBots() < ENEMY_BASE_MAXACTIVE_COUNT ) then
						SpawnDelay = CurTime() + math.randomfloat( 1, 2 )
						for i=1, math.random( math.clamp(math.floor( TotalCount / 12 ),1, 8), math.clamp(math.floor( TotalCount / 6 ), 1, 10) ) do
							if ( #ents.GetAllAliveBots() >= ENEMY_BASE_MAXACTIVE_COUNT ) then
								break
							end
							if SpawnedCount >= TotalCount then
								StillSpawning = false
								break
							end
							SpawnedCount = SpawnedCount + 1
							local template = ENEMY_TEMPLATES[math.WeightedRandomEnemy( ENEMY_TEMPLATES )]
							while ( template.Type == ENEMY_TYPE_GIANT ) and ( ENEMY_CURRENT_NUMBER_OF_GIANTS >= ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_MAX_GIANTS] ) do
								template = ENEMY_TEMPLATES[math.WeightedRandomEnemy( ENEMY_TEMPLATES )]
							end
							local bot = SpawnEnemy( template )
							bot.CashMult = bot.CashMult / ( TotalCount / BaseEnemies )
						end
					end
					
					-- print( StillSpawning, TotalCount, SpawnedCount, SpawnedCount >= TotalCount, #ents.GetAllAliveBots() ) 
					
					if StillSpawning == false and ( #ents.GetAllAliveBots() <= 0 ) then
						pcall( timer.Stop, SpawnTimer )
						timer.Simple( 1, function()
							EndWave()
						end)
						return
					end
				
				elseif WAVE_TYPE_CURRENT == WAVE_TYPE_HORDE then
					
					if CurTime() >= SpawnDelay and ( #ents.GetAllAliveBots() < ENEMY_BASE_MAXACTIVE_COUNT ) then
						SpawnDelay = CurTime() + 1
						for i=1, math.random( 1, 3 ) do
							if ( #ents.GetAllAliveBots() >= ENEMY_BASE_MAXACTIVE_COUNT ) then
								break
							end
							SpawnedCount = SpawnedCount + 1
							local template = ENEMY_TEMPLATES[math.WeightedRandomEnemy( ENEMY_TEMPLATES )]
							while ( template.Type == ENEMY_TYPE_GIANT ) and ( ENEMY_CURRENT_NUMBER_OF_GIANTS >= ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_MAX_GIANTS] ) do
								template = ENEMY_TEMPLATES[math.WeightedRandomEnemy( ENEMY_TEMPLATES )]
							end
							local bot = SpawnEnemy( template )
							if BaseEnemies <= SpawnedCount then
								bot.CashMult = 0
							end
						end
					end
					
					if CurTime() > WAVE_DURATION then
						pcall( timer.Stop, SpawnTimer )
						timer.Simple( 1, function()
							EndWave()
						end)
						return
					end
					
				end
				
			end, 0)
		end)
	else
		for _, player in pairs( ents.GetAllRealPlayers() ) do
			if ( not IsValid( player ) ) or ( not player:OnTeam( 2 ) ) then goto continue end
			
			UPGRADE_LOOT_CATEGORY = UPGRADE_CATEGORY_ALL
			player:HideMenu()
			player.InShop = true
			player.Haggled = false
			player.IncomeThisWave = 0
			
			player:AcceptInput( "RunScriptCode", "ScreenFade( !activator, 255, 255, 255, 255, 1, 0.5, 2 )", player, player )
			player:AddCond( 87, 2 )
			timer.Simple( 1, function()
				player:SetAbsOrigin( Vector( 1088, -3623, 64 ) )
				player:AcceptInput( "RunScriptCode", "ScreenFade( !activator, 255, 255, 255, 255, 1, 0, 1 )", player, player )
				
				player:Print( 2, "Shop Time" )
			end)
			timer.Simple( 2, function() 
				InWave = false
				player:RemoveCond( 87 )
				BuildUpgradeMenu( player, player, UPGRADE_LOOT_SHOP )
			end)
			
			::continue::
		end
	end
end

function EndWave()
	pcall( timer.Stop, SpawnTimer )
	SpawnTimer = nil
	TotalCount = 0
	
	for _, bot in pairs( ents.GetAllAliveBots() ) do
		bot:Suicide()
	end
	
	for _, player in pairs( ents.GetAllRealPlayers() ) do
	
		if ( not IsValid( player ) ) or ( not player:OnTeam( 2 ) ) then goto continue end
	
		player:ForceRespawnDead()
		player:HideMenu()
		
		local loot = UPGRADE_LOOT_COMMON
		
		if UPGRADE_LOOT_CATEGORY == UPGRADE_CATEGORY_GREED then
			loot = UPGRADE_LOOT_GREED
		elseif UPGRADE_LOOT_CATEGORY == UPGRADE_CATEGORY_EPIC or UPGRADE_LOOT_CATEGORY == UPGRADE_CATEGORY_ELITE_BOSS then
			loot = UPGRADE_LOOT_EPIC
		end
		
		BuildUpgradeMenu( player, player, loot )
		
		if player.TankMode then
			player:SetAttributeValue( "mult max health", ( player:GetAttributeValue( "mult max health" ) or 0 ) + ( player:GetAttributeValue("sapper health bonus") or 0.05 ) )
			player.HealthMultGained = player.HealthMultGained + ( player:GetAttributeValue("sapper health bonus") or 0.05 )
		end
		if ( player:GetAttributeValue("sapper health penalty") or 0 ) > 0 then
			player:SetAttributeValue( "max health additive bonus", ( player:GetAttributeValue( "max health additive bonus" ) or 0 ) + ( player:GetAttributeValue("sapper health penalty") or 5 ) )
			player.HealthGained = player.HealthGained + ( player:GetAttributeValue("sapper health penalty") or 5 )
		end
		
		if( ( player:GetAttributeValue("currency bonus") or 0 ) > 0 ) then
			player.MaxIncome = ( player:GetAttributeValue("currency bonus") or 0 ) * 100
			if ( player.MaxIncome >= player.IncomeThisWave ) then
				player:AddCurrency( player.MaxIncome - player.IncomeThisWave )
			end
		end
		
		::continue::
	end
	
	InWave = false
end

function WaveThink()

	if not StartDelay then 
		StartDelay = 0 
	end
	if not LastWholeNumber then
		LastWholeNumber = 0
	end
	--print( ( not InWave ), ( WAVE > 0 ) )
	
	if ( not InWave and ( WAVE > 0 ) ) or ( SHOP_WAVE == true ) then
		
		for _, player in pairs( ents.GetAllRealPlayers() ) do
			if ( not IsValid( player ) ) or ( not player:OnTeam( 2 ) ) then goto continue end
			-- print( player.InMenu, player.InRoll )
			if ( not player.InMenu ) and ( not player.InRoll ) then
				BuildVoteMenu( player ) 
			end
			if StartDelay and ( StartDelay > CurTime() ) and ( LastWholeNumber ~= math.ceil( StartDelay - CurTime() ) ) then
				LastWholeNumber = math.ceil( StartDelay - CurTime() )
				player:Print( PRINT_TARGET_HINT, "Next Wave Starts In: " .. tostring( math.ceil( StartDelay - CurTime() ) ) )
			end
			::continue::
		end
		
		if GetAllVotes() >= #ents.GetAllRealPlayers() then
			if ( StartDelay == 0 ) or ( StartDelay > ( CurTime() + 10.005 ) ) then
				StartDelay = CurTime() + 10
			end
		end
		if GetAllVotes() >= 1 then
			if ( StartDelay == 0 ) then
				if SHOP_WAVE == true then
					StartDelay = CurTime() + 60
				else
					StartDelay = CurTime() + 30
				end
			end
			
			if CurTime() >= StartDelay then
				UPGRADE_LOOT_CATEGORY = GetVoteWinner()
				StartWave()
			end
		end
	end
	
	if ( InWave and ( WAVE > 0 ) ) and ( SHOP_WAVE == false ) then
		for _, player in pairs( ents.GetAllRealPlayers() ) do
			if ( not IsValid( player ) ) or ( not player:OnTeam( 2 ) ) then goto continue end
			if( ( player:GetAttributeValue("currency bonus") or 0 ) > 0 ) then
				player.MaxIncome = ( player:GetAttributeValue("currency bonus") or 0 ) * 100
				if CurTime() >= player.IncomeDelay and ( player.MaxIncome >= player.IncomeThisWave ) then
					player.IncomeDelay = CurTime() + 1
					player:AddCurrency( ( player:GetAttributeValue( "currency bonus" ) or 0 ) )
					player.IncomeThisWave = player.IncomeThisWave + ( player:GetAttributeValue( "currency bonus" ) or 0 )
				end
			end
			::continue::
		end
	end
	
	for _, player in pairs( ents.GetAllRealPlayers() ) do
		if ( not IsValid( player ) ) or ( not player:OnTeam( 2 ) ) then goto continue end
		if( player.TurretMode ) then
			player:SetAttributeValue( "weapon spread bonus", player:GetAttributeValue("throwable fire speed") )
			player:SetAttributeValue( "move accuracy mult", player:GetAttributeValue("throwable fire speed") * 2 )
			if ( player.m_hActiveWeapon:GetAttributeValue("spread penalty") or 1 ) > 1.1 then 
				player:SetAttributeValue( "fire rate bonus HIDDEN", player:GetAttributeValue("throwable fire speed") * 2 )
			else
				player:SetAttributeValue( "fire rate bonus HIDDEN", player:GetAttributeValue("throwable fire speed") )
			end
		end
		if ( player:GetAttributeValue("kill eater user 2") or 0 ) > 0 then
			if player.AdderanlineTime >= CurTime() then
				player:SetAttributeValue( "fire rate penalty HIDDEN", player:GetAttributeValue("kill eater user 2") )
			else
				player:SetAttributeValue( "fire rate penalty HIDDEN", nil )
			end
		end
		if( player:InCond( 113 ) ) and ( player:GetAttributeValueClean( "add cond when active", 0, LOADOUT_POSITION_BODY ) == 113 ) then
			for _, others in pairs( ents.FindInSphere( player:GetAbsOrigin(), 350, "player" ) ) do
				if IsValid( others ) and ( others:GetTeam() == player:GetTeam() ) and ( others ~= player ) then
					others:AddCond( 113, 0.15 )
				end
			end
		end
		if( player.m_iClass == TF_CLASS_SPY ) then
			if( IsValid( player:GetPlayerItemBySlot( LOADOUT_POSITION_PDA2 ) ) ) and ( player:GetAttributeValueClean("move speed bonus resource level", 1, LOADOUT_POSITION_PDA2 ) > 1 ) then
				local val = player:GetAttributeValueClean("move speed bonus resource level", 1, LOADOUT_POSITION_PDA2 )
				local str = "major move speed bonus|" .. tostring( val )
				player:SetAttributeValue( "effect add attributes", str )
			end
		end
		if( WeaponAllowed( player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY), WEAPONS_LIST_ENERGYWEAPON ) ) then
			player:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue( "clip size bonus upgrade", 1 * ( player:GetAttributeValueClean( "clip size bonus", 1, LOADOUT_POSITION_PRIMARY ) ) * ( player:GetAttributeValueClean( "clip size penalty", 1, LOADOUT_POSITION_PRIMARY ) ) * ( player:GetAttributeValueClean( "clip size bonus", 1, LOADOUT_POSITION_BODY ) ) * ( player:GetAttributeValueClean( "clip size penalty", 1, LOADOUT_POSITION_BODY ) ) )
		end
		if( WeaponAllowed( player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY), WEAPONS_LIST_ENERGYWEAPON ) ) then
			player:GetPlayerItemBySlot(LOADOUT_POSITION_SECONDARY):SetAttributeValue( "clip size bonus upgrade", 1 * ( player:GetAttributeValueClean( "clip size bonus", 1, LOADOUT_POSITION_SECONDARY ) ) * ( player:GetAttributeValueClean( "clip size penalty", 1, LOADOUT_POSITION_SECONDARY ) ) * ( player:GetAttributeValueClean( "clip size bonus", 1, LOADOUT_POSITION_BODY ) ) * ( player:GetAttributeValueClean( "clip size penalty", 1, LOADOUT_POSITION_BODY ) ) )
		end
		player:SetAttributeValue( "is australium item", ENCOUNTER_MODIFY_STATS[MODIFY_ENEMY_GOLDEN_CHANCE] )
		::continue::
	end
	
	if InWave and ( WAVE_TYPE_CURRENT == WAVE_TYPE_HORDE ) then 
		for _, player in pairs( ents.GetAllRealPlayers() ) do
			if ( not IsValid( player ) ) or ( not player:OnTeam( 2 ) ) then goto continue end
			if WAVE_DURATION and ( WAVE_DURATION > CurTime() ) and ( LastWholeNumber ~= math.ceil( WAVE_DURATION - CurTime() ) ) then
				LastWholeNumber = math.ceil( WAVE_DURATION - CurTime() )
				player:Print( PRINT_TARGET_HINT, "¡HORDE! Time Left: " .. tostring( math.ceil( WAVE_DURATION - CurTime() ) ) .. " Seconds" )
			end
			::continue::
		end
	end
	
	timer.Simple( 0.1, function()
		WaveThink()
	end)
end

--[[----------------+
	HOOKS
+------------------]]--

local hooks = {}
hooks.Add = function( name, event, callback )
	--print( name, event, callback )
	hooks[ tostring( name ) ] = AddEventCallback( tostring( event ), callback )
	--PrintTable( hooks )
end

hooks.Add( "ON_SPAWN", "player_spawn", function( event )
	local userid = event.userid
	local class = event.class
	local player = ents.GetPlayerByUserId( tonumber( userid ) )
	
	--print(class, player.OldClass)
	if player:IsRealPlayer() then
		SetUpPlayerInfo( player )
		
		if WaveStarted and ( not SHOP_WAVE ) then
			local Possible_Spawns = {}
			for index, data in pairs( ARENA_SPAWNS[ ARENA ] ) do
				if data.teamnum == 2 then
					table.insert( Possible_Spawns, data )
				end
			end
			
			player:SetAbsOrigin( Possible_Spawns[ math.random( 1, #Possible_Spawns ) ].pos + Vector( 0, 0, 16 ) )
			
			player:AddCond( TF_COND_INVULNERABLE_CARD_EFFECT, 3 )
			player:AddCond( TF_COND_INVULNERABLE_WEARINGOFF, 3 )
		end
		
		timer.Simple( 0.015, function() 
		
			-- local items = {}
			-- table.insert( items, player:GetPlayerItemBySlot(0):GetItemName() )
			-- table.insert( items, player:GetPlayerItemBySlot(1):GetItemName() )
			-- table.insert( items, player:GetPlayerItemBySlot(2):GetItemName() )
			
			for i=0, 6 do
				player:WeaponStripSlot( i )
			end
			
			-- for _, weapon in pairs( items ) do
				-- player:GiveItem( weapon )
			-- end
			
			for attr, val in pairs( player:GetAllAttributeValues() ) do 
				player:SetAttributeValue( attr, nil )
			end
			
			timer.Simple( 0.015, function() 
				player:Regenerate()
				-- if ( ( player.OldClass ~= nil ) and ( class ~= player.OldClass ) ) then
					ApplyMissingUpgrades( player )
				-- end
				
				-- player.OldClass = class
			end)
		end)
	end
	-- if player:IsValid() then
		-- player.ArmorPlates = 0
		-- player.MaxArmorPlates = 6
	-- end
end)

hooks.Add( "ON_TAKE_DAMAGE", "player_hurt", function( event )
	local victim = ents.GetPlayerByUserId( tonumber( event.userid ) )
	local attacker = ents.GetPlayerByUserId( ( tonumber( event.attacker ) or 0 ) )
	local weapon = nil
	local melee = nil
	if IsValid( attacker ) then
		weapon = attacker.m_hActiveWeapon
		melee = attacker:GetPlayerItemBySlot(2)
	end
	
	if IsValid( victim ) and victim:IsBot() and IsValid( attacker ) and attacker:IsRealPlayer() and IsValid( weapon ) and ( victim ~= attacker ) then
		if ( weapon:GetAttributeValue( "throwable damage" ) or 0 ) > 0 then
			local amount = ( weapon:GetAttributeValue( "throwable damage" ) or 0 ) / 100
			if amount >= math.random() then
				victim:AddCond( TF_COND_URINE, 3 )
			end
		end
		if ( weapon:GetAttributeValue( "throwable healing" ) or 0 ) > 0 then
			local amount = ( weapon:GetAttributeValue( "throwable healing" ) or 0 ) / 100
			if amount >= math.random() then
				victim:AddCond( TF_COND_MAD_MILK, 2 )
			end
		end
		if IsValid( melee ) and ( weapon == melee ) and ( ( melee:GetAttributeValue( "duckstreaks active" ) or 0 ) > 0 ) then
			victim.MarkForHealth = true
		end
		if ( attacker:GetAttributeValue( "expiration date" ) or 0 ) > 0 then
			local amount = ( attacker:GetAttributeValue( "expiration date" ) or 0 )
			attacker:AddCurrency( amount )
		end
	end
	
	if IsValid( victim) and victim:IsRealPlayer() then
		if (victim:GetAttributeValue("sapper health bonus") or 0 ) > 0 then
			victim:SetAttributeValue( "max health additive bonus", ( victim:GetAttributeValue("max health additive bonus") or 0 ) - ( 1 + ( math.floor( victim.m_iMaxHealth / 300 ) ) ) )
		end
	end
end)

--[[----------------+
	SETUP
+------------------]]--

WaveThink()

for i = 0, #VOTE_CATEGORIES do
	VOTE_RESULTS[i] = {}
end

for ent, _ in pairs(buildings) do
	ents.AddCreateCallback(ent, OnBuildingCreated)
end
print( "hippopotamus-shit" )