--[[Global variables 
    MenuCapacity - How many upgrades can be stored in the menu, keep as integer
	Note that the sourcemod menu has a 512 byte limit, try to keep names/descriptions short
	Byte limit as opposed to a character limit means that inserting unicode characters which contain more than 1 byte
	will use up more of the limit
	
	You can use special characters like \n in sourcemod menus
	
	If you go above 7 selections (6+1 reroll selections) the sourcemod menu will display the Next and Previous buttons
	Personally I find this to be a bit clunky so I would stick with using a MenuCapacity of 6, 7 if you want to
	prevent accidental rerolls
	
TotalUpgradePoints - Determines the starting amount of upgrade points on wave 1, and for any late joiners, keep as integer

TotalRerollPoints - Determines the starting amount of upgrade points on wave 1, and for any late joiners, keep as integer]]

MenuCapacity = 6 -- 상점에 팝업되는 메뉴의 수 6 = 5개의 항목 + 리롤
TotalUpgradePoints = 999 -- 웨이브 1 에 지급되는 선택 횟수
TotalRerollPoints = 999 -- 웨이브 1에 지급되는 리롤 횟수


--[[AllShops is a table that controls what upgrades are shown to players, based on what class they are
	Note that it uses the game's interal reference for classes, which is different from their class selection screen order
	
	Each class can have any number of subtables or sub categories, I use this to define four different rarities
	
	You can also go for a shared upgrade pool between all classes, or Demo and Soldier etc.]]

--attributes are defined as text on menu, attribute name, min, increment, max

--[[The 1st field is actually the most important, as it used to uniquely identify upgrades, this allows the second field
	to exist beyond just attributes, and you can utilize "custom" to write a function that can do anything, as shown in
	Max Ammo and Mixed Concotion On Hit
	
	Note that max is typicallly optional for attributes, and if you're using "custom", min increment and max are also optional
	and can be defined in the AddUpgrade function instead]]
	
--	어트리뷰트 문법 {"상점 표기 업그레이드 이름", "어트리뷰트 이름" 최소 수치, 상승/하락폭, 최대 수치} 최대 수치는 적지않으면 MAX 없음
--  어트리뷰트 이름 작성시 "," 가 들어갈시 오류발생함 / 로 바꾸는것을 추천
--  어트리뷰트 이름이 길시 상점 메뉴 아래부분이 글자깨짐 발생가능.

AllShops =
{
	[1] = --Scout Shop [참조 하는 배열][주석 1]
	{
		CommonAttribute =
		{
			{"피해량 +25%", "damage bonus",1,0.25},
			{"장탄수 +50%", "clip size bonus",1,0.5},
			{"공격 속도 +10%", "fire rate bonus",1,-0.1,0.1},
 			{"재장전 속도 +20%", "faster reload rate",1,-0.2,0.1},
			{"처치 시 체력 25 회복", "heal on kill",0,25},
			{"최대 체력 +25", "max health additive bonus",0,25},
			{"모든 탄약수 +50%", "custom",1,0.5},
			{"이동 속도 +10%", "move speed bonus",1,0.1},
			{"점프 높이 +20%", "increased jump height",1,0.2},
			{"무기 전환 속도 +35%", "deploy time decreased",1,-0.35,0},
			{"재충전 속도 [공/우유/음료] +15%", "effect bar recharge rate increased",1,-0.15,0.1},
			{"화염 피해 저항력 +25%", "dmg taken from fire reduced",1,-0.25,0.1},
			{"치명타 피해 저항력 +30%", "dmg taken from crit reduced",1,-0.3,0.1},
			{"탄환 피해 저항력 +25%", "dmg taken from bullets reduced",1,-0.25,0.1},
			{"폭발 피해 저항력 +25%", "dmg taken from blast reduced",1,-0.25,0.1},
			{"근거리 피해 저항력 +25%", "dmg from melee increased",1,-0.25,0.1},
			{"초당 체력 회복량 +2", "health regen",0,2},
			{"5초 마다 최대 탄약의 20% 보급", "ammo regen",0,0.2,1},
			{"적중 시 체력 15 회복", "heal on hit for rapidfire",0,15},
			{"밀어내기 저항력 +30%", "damage force reduction",1,-0.3,0},
		},
		RareAttribute =
		{
			{"( R ) 처치 시: 소형 치료제 드롭", "drop health pack on kill",0,1,1},
			{"( R ) 투사체 관통 [탄환]", "projectile penetration",0,1,1},
			{"( R ) 우유 적중시 대상 이동 속도 감소", "applies snare effect",1,-0.35,0.65},
			{"( R ) 추가 점프 횟수 +1", "air dash count",0,1},
		},
		EpicAttribute =
		{
			{"( SR ) 발사 당 탄환수 +50%", "bullets per shot bonus",1,0.5},
			{"( SR ) 전차 대상 피해량 +50%", "mult dmg vs tanks",1,0.5},
			{"( SR ) 사망 시 귀환 확률 +25%", "teleport instead of die",0,0.25,1},
			{"( SR ) 폭주 미터/우유 지속시간 +50%", "mult effect duration",1,0.5},
			{"( SR ) 처치 시 5초간 이동속도 증진", "speed_boost_on_kill",0,5,5},
		},
		LegendaryAttribute =
		{
			{"【 SSR 】 처치 시 3초간 치명타 증진", "critboost on kill",0,3},
			{"【 SSR 】 소형 치명타 발생시 크리티컬로 전환", "minicrits become crits",0,1,1},
			{"【 SSR 】 모든 받는 치료량 +100%", "healing received bonus",1,1},
			{"【 SSR 】 적중 시 죽음의 표식 부착", "mark for death",0,1,1},
		}
	},
	[3] = --Soldier Shop
	{
		CommonAttribute =
		{
			{"피해량 +25%", "damage bonus",1,0.25},
			{"주무기: 장탄수 +2", "clip size upgrade atomic",1,2},
			{"장탄수 +50%", "clip size bonus",1,0.5},
			{"공격 속도 +10%", "fire rate bonus",1,-0.1,0.1},
			{"재장전 속도 +20%", "faster reload rate",1,-0.2,0.1},
			{"처치 시 체력 25 회복", "heal on kill",0,25},
			{"최대 체력 +25", "max health additive bonus",0,25},
			{"모든 탄약수 +50%", "custom",1,0.5},
			{"이동 속도 +10%", "move speed bonus",1,0.1},
			{"점프 높이 +20%", "increased jump height",1,0.2},
			{"무기 전환 속도 +35%", "deploy time decreased",1,-0.35,0},
			{"화염 피해 저항력 +25%", "dmg taken from fire reduced",1,-0.25,0.1},
			{"치명타 피해 저항력 +30%", "dmg taken from crit reduced",1,-0.3,0.1},
			{"탄환 피해 저항력 +25%", "dmg taken from bullets reduced",1,-0.25,0.1},
			{"폭발 피해 저항력 +25%", "dmg taken from blast reduced",1,-0.25,0.1},
			{"근거리 피해 저항력 +25%", "dmg from melee increased",1,-0.25,0.1},
			{"초당 체력 회복량 +2", "health regen",0,2},
			{"5초 마다 최대 탄약의 20% 보급", "ammo regen",0,0.2,1},
			{"적중 시 체력 15 회복", "heal on hit for rapidfire",0,15},
			{"폭발 반경 +25%", "Blast radius increased",1,0.25},
			{"투사체 비행 속도 +25%", "Projectile speed increased",1,0.25},
			{"깃발: 증진 지속시간 +25%", "increase buff duration",1,0.25},
			{"깃발: 분노 획득량 +25%", "rage giving scale",1,0.25},
			{"고지 도약기: 무한 재사용", "parachute redeploy",0,1,1},
		},
		RareAttribute =
		{
			{"( R ) 처치 시: 소형 치료제 드롭", "drop health pack on kill",0,1,1},
			{"( R ) 로켓 특화", "rocket specialist",0,1,1},
			{"( R ) 추가 점프 횟수 +1", "air dash count",0,1},
			{"( R ) 낙하 피해 무시", "cancel falling damage",0,1,1},
			{"( R ) 폭발로 공중에 뜬 대상 소형 치명타", "mod mini-crit airborne",0,1,1},
		},
		EpicAttribute =
		{
			{"( SR ) 깃발: 증진 반경 +25%", "mod soldier buff range",1,0.25},
			{"( SR ) 전차 대상 피해량 +50%", "mult dmg vs tanks",1,0.5},
			{"( SR ) 사망 시 귀환 확률 +25%", "teleport instead of die",0,0.25,1},
			{"( SR ) 처치 시 5초간 이동속도 증진", "speed_boost_on_kill",0,5,5},
			{"( SR ) 투사체 반사/파괴 불가", "projectile no deflect",0,1,1},
		},
		LegendaryAttribute =
		{
			{"【 SSR 】 처치 시 3초간 치명타 증진", "critboost on kill",0,3},
			{"【 SSR 】 소형 치명타 발생시 크리티컬로 전환", "minicrits become crits",0,1,1},
			{"【 SSR 】 모든 받는 치료량 +100%", "healing received bonus",1,1},
			{"【 SSR 】 적중 시 죽음의 표식 부착", "mark for death",0,1,1},
		}
	},
	[7] = --Pyro Shop
	{
		CommonAttribute =
		{
			{"피해량 +25%", "damage bonus",1,0.25},
			{"산탄총: 장탄수 +50%", "clip size bonus",1,0.5},
			{"산탄총/조명총: 공격 속도 +10%", "fire rate bonus",1,-0.1,0.1},
			{"산탄총/조명총: 재장전 속도 +20%", "faster reload rate",1,-0.2,0.1},
			{"처치 시 체력 25 회복", "heal on kill",0,25},
			{"최대 체력 +25", "max health additive bonus",0,25},
			{"모든 탄약수 +50%", "custom",1,0.5},
			{"이동 속도 +10%", "move speed bonus",1,0.1},
			{"점프 높이 +20%", "increased jump height",1,0.2},
			{"무기 전환 속도 +35%", "deploy time decreased",1,-0.35,0},
			{"화염 피해 저항력 +25%", "dmg taken from fire reduced",1,-0.25,0.1},
			{"치명타 피해 저항력 +30%", "dmg taken from crit reduced",1,-0.3,0.1},
			{"탄환 피해 저항력 +25%", "dmg taken from bullets reduced",1,-0.25,0.1},
			{"폭발 피해 저항력 +25%", "dmg taken from blast reduced",1,-0.25,0.1},
			{"근거리 피해 저항력 +25%", "dmg from melee increased",1,-0.25,0.1},
			{"초당 체력 회복량 +2", "health regen",0,2},
			{"5초 마다 최대 탄약의 20% 보급", "ammo regen",0,0.2,1},
			{"적중 시 체력 2 회복", "heal on hit for rapidfire",0,2},
			{"초당 화염 방사기 탄약 소모량 -25%", "flame ammopersec decreased",1,-0.25,0},
			{"화상 피해 +100%", "weapon burn dmg increased",1,1},
			{"밀어내기 저항력 +30%", "damage force reduction",1,-0.3,0},
			{"조명총: 투사체 비행 속도 +25%", "Projectile speed increased",1,0.25},
			{"가열 가속기: 공중 재사용", "thermal_thruster_air_launch",0,1,1},
			{"가열 가속기: 착륙 시 주변 대상 기절", "falling_impact_radius_stun",0,1,1},
			{"용의 격노/제트팩/가스 재충전 대기 시간 -15%", "mult_item_meter_charge_rate",1,-0.15,0.55},
			{"팀원 압축 공기 분사 시 이동속도 증진", "airblast_give_teammate_speed_boost",0,1,1},
		},
		RareAttribute =
		{
			{"( R ) 처치 시: 소형 치료제 드롭", "drop health pack on kill",0,1,1},
			{"( R ) 추가 점프 횟수 +1", "air dash count",0,1},
			{"( R ) 반사 시킨 투사체 속도 +100%", "mult reflect velocity",1,1},
			{"( R ) 화염 비거리 +25%", "flame_drag",0,-1,-4},
			{"( R ) 조명총/반사 시킨 투사체: 폭발 반경 +40%", "Blast radius increased",1,0.4},
			{"( R ) 압축 공기 분사 탄약 소모량 -25%", "airblast cost decreased",1,-0.25,0},
			{"( R ) 적중 시 대상 이동속도 감소", "slow enemy on hit",0,1,1},
		},
		EpicAttribute =
		{
			{"( SR ) 전차 대상 피해량 +50%", "mult dmg vs tanks",1,0.5},
			{"( SR ) 사망 시 귀환 확률 +25%", "teleport instead of die",0,0.25,1},
			{"( SR ) 처치 시 5초간 이동속도 증진", "speed_boost_on_kill",0,5,5},
			{"( SR ) 주무기: 후방 공격 시 치명타", "mod flamethrower back crit",0,1,1},
			{"( SR ) 압축 공기 분사 재사용 대기 시간 -50%", "mult airblast refire time",1,-0.5,0},
		},
		LegendaryAttribute =
		{
			{"【 SSR 】 처치 시 3초간 치명타 증진", "critboost on kill",0,3},
			{"【 SSR 】 적중 시 죽음의 표식 부착", "mark for death",0,1,1},
			{"【 SSR 】 모든 받는 치료량 +100%", "healing received bonus",1,1},
			{"【 SSR 】 불타는 적에게 300% 추가 피해", "damage bonus vs burning",1,2,3},
		},
		Contraband =
		{
			{"【 UR 】적중 시 가스 상태 부여", "add cond on hit",0,123,123},
		}
	},
	[4] = --Demoman Shop
	{
		CommonAttribute =
		{
			{"피해량 +25%", "damage bonus",1,0.25},
			{"주무기: Clip Size +2", "clip size upgrade atomic",1,2},
			{"장탄수 +50%", "clip size bonus",1,0.5},
			{"공격 속도 +10%", "fire rate bonus",1,-0.1,0.1},
			{"재장전 속도 +20%", "faster reload rate",1,-0.2,0.1},
			{"처치 시 체력 25 회복", "heal on kill",0,25},
			{"최대 체력 +25", "max health additive bonus",0,25},
			{"모든 탄약수 +50%", "custom",1,0.5},
			{"이동 속도 +10%", "move speed bonus",1,0.1},
			{"점프 높이 +20%", "increased jump height",1,0.2},
			{"무기 전환 속도 +35%", "deploy time decreased",1,-0.35,0},
			{"방패: 돌격 재충전 속도 +100%", "charge recharge rate increased",1,1},
			{"방패: 돌격 충돌 피해 +100%", "charge impact damage increased",1,1},
			{"화염 피해 저항력 +25%", "dmg taken from fire reduced",1,-0.25,0.1},
			{"치명타 피해 저항력 +30%", "dmg taken from crit reduced",1,-0.3,0.1},
			{"탄환 피해 저항력 +25%", "dmg taken from bullets reduced",1,-0.25,0.1},
			{"폭발 피해 저항력 +25%", "dmg taken from blast reduced",1,-0.25,0.1},
			{"근거리 피해 저항력 +25%", "dmg from melee increased",1,-0.25,0.1},
			{"초당 체력 회복량 +2", "health regen",0,2},
			{"5초 마다 최대 탄약의 20% 보급", "ammo regen",0,0.2,1},
			{"적중 시 체력 15 회복", "heal on hit for rapidfire",0,15},
			{"폭발 반경 +25%", "Blast radius increased",1,0.25},
			{"투사체 비행 속도 +25%", "Projectile speed increased",1,0.25},
			{"밀어내기 저항력 +30%", "damage force reduction",1,-0.3,0},
			{"점착 폭탄 최대 설치량 +2", "max pipebombs increased",1,2},
			{"점착 폭탄: 충전 대기 시간 -25%", "stickybomb charge rate",1,-0.25,0},
			{"점착 폭탄: 폭파 대기 시간 -0.2초", "sticky arm time bonus",0,-0.2,-0.8},
			{"고지 도약기: 무한 재사용", "parachute redeploy",0,1,1},
		},
		RareAttribute =
		{
			{"( R ) 처치 시: 소형 치료제 드롭", "drop health pack on kill",0,1,1},
			{"( R ) 근거리 공격 너비 +50%", "melee bounds multiplier",1,0.5},
			{"( R ) 근거리 공격 사거리 +25%", "melee range multiplier",1,0.25},
			{"( R ) 추가 점프 횟수 +1", "air dash count",0,1},
			{"( R ) 낙하 피해 무시", "cancel falling damage",0,1,1},
			{"( R ) 폭발로 공중에 뜬 대상 소형 치명타", "mod mini-crit airborne",0,1,1},
			{"( R ) 방패: 돌격 유지 시간 +1 초", "charge time increased",1,1},
			{"( R ) 유탄 발사기: 벽/지면 충돌시 폭발", "grenade explode on impact",0,1,1},
		},
		EpicAttribute =
		{
			{"( SR ) 전차 대상 피해량 +50%", "mult dmg vs tanks",1,0.5},
			{"( SR ) 사망 시 귀환 확률 +25%", "teleport instead of die",0,0.25,1},
			{"( SR ) 처치 시 5초간 이동속도 증진", "speed_boost_on_kill",0,5,5},
			{"( SR ) 방패: 돌격 중 방향 완전 제어", "full charge turn control",0,50,50},
			{"( SR ) 점착 폭탄: 충전 비례 피해량 +35%", "stickybomb_charge_damage_increase",1,0.35},
			{"( SR ) 근거리 공격 시 범위 내 모든 적 타격", "melee cleave attack",0,1,1},
			{"( SR ) 투사체 반사/파괴 불가", "projectile no deflect",0,1,1},
		},
		LegendaryAttribute =
		{
			{"【 SSR 】 처치 시 3초간 치명타 증진", "critboost on kill",0,3},
			{"【 SSR 】 소형 치명타 발생시 크리티컬로 전환", "minicrits become crits",0,1,1},
			{"【 SSR 】 모든 받는 치료량 +100%", "healing received bonus",1,1},
			{"【 SSR 】 적중 시 죽음의 표식 부착", "mark for death",0,1,1},
		}
	},
	[6] = --Heavy Shop
	{
		CommonAttribute =
		{
			{"산탄총: 장탄수 +50%", "clip size bonus",1,0.5},
			{"공격 속도 +10%", "fire rate bonus",1,-0.1,0.1},
			{"산탄총: 재장전 속도 +20%", "faster reload rate",1,-0.2,0.1},
			{"도시락 재충전 속도 +15%", "charge recharge rate increased",1,-0.15,0},
			{"처치 시 체력 25 회복", "heal on kill",0,25},
			{"최대 체력 +25", "max health additive bonus",0,25},
			{"모든 탄약수 +50%", "custom",1,0.5},
			{"이동 속도 +10%", "move speed bonus",1,0.1},
			{"점프 높이 +20%", "increased jump height",1,0.2},
			{"무기 전환 속도 +35%", "deploy time decreased",1,-0.35,0},
			{"화염 피해 저항력 +25%", "dmg taken from fire reduced",1,-0.25,0.1},
			{"치명타 피해 저항력 +30%", "dmg taken from crit reduced",1,-0.3,0.1},
			{"탄환 피해 저항력 +25%", "dmg taken from bullets reduced",1,-0.25,0.1},
			{"폭발 피해 저항력 +25%", "dmg taken from blast reduced",1,-0.25,0.1},
			{"근거리 피해 저항력 +25%", "dmg from melee increased",1,-0.25,0.1},
			{"초당 체력 회복량 +2", "health regen",0,2},
			{"5초 마다 최대 탄약의 20% 보급", "ammo regen",0,0.2,1},
			{"적중 시 체력 2 회복", "heal on hit for rapidfire",0,2},
			{"밀어내기 저항력 +30%", "damage force reduction",1,-0.3,0},
			{"사격 준비 속도 +15%", "minigun spinup time decreased",1,-0.15,0},
			{"총열 회전 중 이동 속도 +20%", "aiming movespeed increased",1,0.20},
		},
		RareAttribute =
		{
			{"( R ) 피해량 +25%", "damage bonus",1,0.25},
			{"( R ) 처치 시: 소형 치료제 드롭", "drop health pack on kill",0,1,1},
			{"( R ) 추가 점프 횟수 +1", "air dash count",0,1},
			{"( R ) 투사체 관통", "projectile penetration",0,1,1},
			{"( R ) 투사체 파괴", "attack projectiles",0,1,2},
			{"( R ) 밀침 분노", "generate rage on damage",0,1,3},
			{"( R ) 총열 회전 중 무기 교체", "mod minigun can holster while spinning",0,1,1},
			{"( R ) 적중 시 대상 이동속도 감소", "slow enemy on hit",0,1,1},
		},
		EpicAttribute =
		{
			{"( SR ) 전차 대상 피해량 +50%", "mult dmg vs tanks",1,0.5},
			{"( SR ) 사망 시 귀환 확률 +25%", "teleport instead of die",0,0.25,1},
			{"( SR ) 처치 시 5초간 이동속도 증진", "speed_boost_on_kill",0,5,5},
			{"( SR ) 총열 회전 시 화염 고리 생성", "ring of fire while aiming",0,1,1},
			{"( SR ) 발사 당 탄환수 +25%", "bullets per shot bonus",1,0.25},
		},
		LegendaryAttribute =
		{
			{"【 SSR 】 처치 시 3초간 치명타 증진", "critboost on kill",0,3},
			{"【 SSR 】 소형 치명타 발생시 크리티컬로 전환", "minicrits become crits",0,1,1},
			{"【 SSR 】 모든 받는 치료량 +100%", "healing received bonus",1,1},
			{"【 SSR 】 적중 시 죽음의 표식 부착", "mark for death",0,1,1},
		}
	},
	[9] = --Engineer Shop
	{
		CommonAttribute =
		{
 			{"무기: 피해량 +25%", "damage bonus",1,0.25},
			{"무기: 장탄수 +50%", "clip size bonus",1,0.5},
			{"무기: 공격 속도 +10%", "fire rate bonus",1,-0.1,0.1},
			{"무기: 재장전 속도 +20%", "faster reload rate",1,-0.2,0.1},
			{"처치 시 체력 25 회복", "heal on kill",0,25},
			{"최대 체력 +25", "max health additive bonus",0,25},
			{"무기: 모든 탄약수 +50%", "custom",1,0.5},
			{"이동 속도 +10%", "move speed bonus",1,0.1},
			{"점프 높이 +20%", "increased jump height",1,0.2},
			{"무기 전환 속도 +70%", "deploy time decreased",1,-0.70,0},
			{"화염 피해 저항력 +25%", "dmg taken from fire reduced",1,-0.25,0.1},
			{"치명타 피해 저항력 +30%", "dmg taken from crit reduced",1,-0.3,0.1},
			{"탄환 피해 저항력 +25%", "dmg taken from bullets reduced",1,-0.25,0.1},
			{"폭발 피해 저항력 +25%", "dmg taken from blast reduced",1,-0.25,0.1},
			{"근거리 피해 저항력 +25%", "dmg from melee increased",1,-0.25,0.1},
			{"초당 체력 회복량 +2", "health regen",0,2},
			{"5초 마다 최대 탄약의 20% 보급", "ammo regen",0,0.2,1},
			{"적중 시 체력 15 회복", "heal on hit for rapidfire",0,3},
			{"최대 금속 보유량 +50%", "maxammo metal increased",1,0.50},
			{"구조물 최대 내구도 +100%", "engy building health bonus",1,1},
			{"센트리 건 공격 속도 +10%", "engy sentry fire rate increased",1,-0.1,0},
			{"디스펜서 효과 범위 +100%", "engy dispenser radius increased",1,1},
			{"일회용 센트리 건설 수 +1", "engy disposable sentries",0,1},
			{"양방향 텔레포터r", "bidirectional teleport",0,1,1},
			{"5초 마다 금속 100 보급", "metal regen",0,100},
			{"센트리 건 최대 탄약량 +50%", "mvm sentry ammo",1,0.50},
			{"건설 속도 +25%", "build rate bonus",1,-0.25,0},
			{"렌치 타격 시 건설 속도 +30%", "Construction rate increased",1,0.3},
			{"수리 효율 +20%", "Repair rate increased",1,0.2},
			{"업그레이드 효율 +20%", "upgrade rate decrease",1,0.2},
			{"탄약 상자/디스펜서 에서 얻는 금속량 +25%", "metal_pickup_decreased",1,0.25},
		},
		RareAttribute =
		{
			{"( R ) 처치 시: 소형 치료제 드롭", "drop health pack on kill",0,1,1},
			{"( R ) 추가 점프 횟수 +1", "air dash count",0,1},
			{"( R ) 투사체 관통[무기]", "projectile penetration",0,1,1},
			{"( R ) 센트리 건 피해량 +25%", "engy sentry damage bonus",1,0.25},
			{"( R ) 센트리 건 사정거리 +50%", "engy sentry radius increased",1,0.5},
			{"( R ) 디스펜서 회복/보급 효율 +50%", "mult dispenser rate",1,0.5},
		},
		EpicAttribute =
		{
			{"( SR ) 전차 대상 피해량 +50%", "mult dmg vs tanks",1,0.5},
			{"( SR ) 사망 시 귀환 확률 +25%", "teleport instead of die",0,0.25,1},
			{"( SR ) 처치 시 5초간 이동속도 증진", "speed_boost_on_kill",0,5,5},
			{"( SR ) 무기: 발사 당 탄환수 +50%", "bullets per shot bonus",1,0.5},
			{"( SR ) 센트리 건 로켓 발사 속도 +25%", "mult firerocket rate",1,-0.25,0},
			{"( SR ) 텔레포터 재충전 속도 +50%", "mult teleporter recharge rate",1,-0.5,0},
			{"( SR ) 텔레포터 사용 후 이동속도 증진", "mod teleporter speed boost",0,1,1},
			{"( SR ) 센트리 건 목표 대상 피해량 +50%", "damage bonus bullet vs sentry target",1,0.25},
		},
		LegendaryAttribute =
		{
			{"【 SSR 】 처치 시 3초간 치명타 증진", "critboost on kill",0,3},
			{"【 SSR 】 소형 치명타 발생시 크리티컬로 전환", "minicrits become crits",0,1,1},
			{"【 SSR 】 모든 받는 치료량 +100%", "healing received bonus",1,1},
			{"【 SSR 】 적중 시 죽음의 표식 부착", "mark for death",0,1,1},
			{"【 SSR 】 구조물 건설 금속 소모 -80%", "building cost reduction",1,-0.8,0.2},
		}
	},
	[5] = --Medic Shop
	{
		CommonAttribute =
		{
			{"피해량 +25%", "damage bonus",1,0.25},
			{"장탄수 +50%", "clip size bonus",1,0.5},
			{"십자군의 쇠뇌: 장탄수 +2", "clip size upgrade atomic",1,2},
			{"공격 속도 +10%", "fire rate bonus",1,-0.1,0.1},
			{"재장전 속도 +20%", "faster reload rate",1,-0.2,0.1},
			{"처치 시 체력 25 회복", "heal on kill",0,25},
			{"최대 체력 +25", "max health additive bonus",0,25},
			{"모든 탄약수 +50%", "custom",1,0.5},
			{"이동 속도 +10%", "move speed bonus",1,0.1},
			{"점프 높이 +20%", "increased jump height",1,0.2},
			{"무기 전환 속도 +70%", "deploy time decreased",1,-0.70,0},
			{"화염 피해 저항력 +25%", "dmg taken from fire reduced",1,-0.25,0.1},
			{"치명타 피해 저항력 +30%", "dmg taken from crit reduced",1,-0.3,0.1},
			{"탄환 피해 저항력 +25%", "dmg taken from bullets reduced",1,-0.25,0.1},
			{"폭발 피해 저항력 +25%", "dmg taken from blast reduced",1,-0.25,0.1},
			{"근거리 피해 저항력 +25%", "dmg from melee increased",1,-0.25,0.1},
			{"초당 체력 회복량 +2", "health regen",0,2},
			{"5초 마다 최대 탄약의 20% 보급", "ammo regen",0,0.2,1},
			{"적중 시 체력 6 회복", "heal on hit for rapidfire",0,3},
			{"우버 충전율 +25%", "ubercharge rate bonus",1,0.25},
			{"우버차지 지속시간 +2 초", "uber duration bonus",0,2},
			{"치료 속도/회복 속도/자가 치료량 +25%", "healing mastery",0,1},
			{"과치료량 +25% / 과치료 지속시간 +50%", "overheal expert",0,1},
			{"치료율 +25%", "heal rate bonus",1,0.25},
			{"과치료 최대량 +25%", "overheal bonus",1,0.25},
			{"과치료 유지 시간 +50%", "overheal bonus",1,0.25},
			{"소생 속도 +25%", "revive rate",1,0.25},
			{"밀어내기 저항력 +30%", "damage force reduction",1,-0.3,0},
		},
		RareAttribute =
		{
			{"( R ) 투사체 보호막", "generate rage on heal",0,1,2},
			{"( R ) 추가 점프 횟수 +1", "air dash count",0,1},
			{"( R ) 적중 시 우버 충전률 +1%", "add uber charge on hit",0,0.01},
			{"( R ) 미치광이 우유 주사기/볼트", "mad milk syringes",0,1,1},
			{"( R ) 메디건 사정거리 +25%", "mult medigun range",1,0.25},
		},
		EpicAttribute =
		{
			{"( SR ) 사망 시 귀환 확률 +25%", "teleport instead of die",0,0.25,1},
			{"( SR ) 처치 시 2초간 치명타 증진", "critboost on kill",0,2},
			{"( SR ) 적중 시 혼합 상태이상 부여", "custom",0,1,1},
			{"( SR ) 치료율 의 50% 만큼 구조물 치유", "medic machinery beam",0,5},
			{"( SR ) 근거리 공격 시 범위 내 모든 적 타격", "melee cleave attack",0,1,1},
			{"( SR ) 처치 시 5초간 이동속도 증진", "speed_boost_on_kill",0,5,5},
		},
		LegendaryAttribute =
		{
			{"【 SSR 】 소형 치명타 발생시 크리티컬로 전환", "minicrits become crits",0,1,1},
			{"【 SSR 】 모든 받는 치료량 +100%", "healing received bonus",1,1},
			{"【 SSR 】 피격 시 3 초간 무적이 될 확률 +10%", "uber on damage taken",0,0.1,0.1},
		}
	},
	[2] = --Sniper Shop
	{
		CommonAttribute =
		{
			{"피해량 +25%", "damage bonus",1,0.25},
			{"기관단총: 장탄수 +50%", "clip size bonus",1,0.5},
			{"공격 속도 +10%", "fire rate bonus",1,-0.1,0.1},
			{"재장전 속도 +20%", "faster reload rate",1,-0.2,0.1},
			{"처치 시 체력 25 회복", "heal on kill",0,25},
			{"최대 체력 +25", "max health additive bonus",0,25},
			{"모든 탄약수 +50%", "custom",1,0.5},
			{"이동 속도 +10%", "move speed bonus",1,0.1},
			{"점프 높이 +20%", "increased jump height",1,0.2},
			{"무기 전환 속도 +35%", "deploy time decreased",1,-0.35,0},
			{"재충전 속도 [병수도/레이저백] +15%", "effect bar recharge rate increased",1,-0.15,0.1},
			{"화염 피해 저항력 +25%", "dmg taken from fire reduced",1,-0.25,0.1},
			{"치명타 피해 저항력 +30%", "dmg taken from crit reduced",1,-0.3,0.1},
			{"탄환 피해 저항력 +25%", "dmg taken from bullets reduced",1,-0.25,0.1},
			{"폭발 피해 저항력 +25%", "dmg taken from blast reduced",1,-0.25,0.1},
			{"근거리 피해 저항력 +25%", "dmg from melee increased",1,-0.25,0.1},
			{"초당 체력 회복량 +2", "health regen",0,2},
			{"5초 마다 최대 탄약의 20% 보급", "ammo regen",0,0.2,1},
			{"적중 시 체력 15 회복", "heal on hit for rapidfire",0,3},
			{"활: 화살 통달", "arrow mastery",0,1},
			{"저격소총: 충전 속도 +25%", "SRifle Charge rate increased",1,0.25},
			{"적중 시 5 초간 출혈", "bleeding duration",0,5},
		},
		RareAttribute =
		{
			{"( R ) 처치 시: 소형 치료제 드롭", "drop health pack on kill",0,1,1},
			{"( R ) 추가 점프 횟수 +1", "air dash count",0,1},
			{"( R ) 투사체 관통", "projectile penetration",0,1,1},
			{"( R ) 병수도 적중시 대상 이동 속도 감소", "applies snare effect",1,-0.35,0.65},
			{"( R ) 메디건 치료 광선이 연결된 모든 대상 타격", "damage all connected",0,1,1},
			{"( R ) 조준 시 조준선이 흔들리지 않음", "no damage view flinch",0,1,1},
			{"( R ) 저격소총: 완전 충전 시 피해량 +35%", "sniper full charge damage bonus",1,0.35},
			{"( R ) 기관단총: 집탄율 +100%", "weapon spread bonus",1,-1,0},
			{"( R ) 기관단총: 헤드샷 가능", "can headshot",0,1,1},
		},
		EpicAttribute =
		{
			{"( SR ) 전차 대상 피해량 +50%", "mult dmg vs tanks",1,0.5},
			{"( SR ) 사망 시 귀환 확률 +25%", "teleport instead of die",0,0.25,1},
			{"( SR ) 집중력/젠장/병수도 지속시간 +50%", "mult effect duration",1,0.5},
			{"( SR ) 헤드샷 폭발", "explosive sniper shot",0,1},
			{"( SR ) 폭발 탄환 개조", "explosive bullets",0,147,147},
			{"( SR ) 처치 시 5초간 이동속도 증진", "speed_boost_on_kill",0,5,5},
		},
		LegendaryAttribute =
		{
			{"【 SSR 】 소형 치명타 발생시 크리티컬로 전환", "minicrits become crits",0,1,1},
			{"【 SSR 】 모든 받는 치료량 +100%", "healing received bonus",1,1},
			{"【 SSR 】 적중 시 죽음의 표식 부착", "mark for death",0,1,1},
		}
	},
	[8] = --Spy Shop
	{
		CommonAttribute =
		{
			{"피해량 +25%", "damage bonus",1,0.25},
			{"장탄수 +50%", "clip size bonus",1,0.5},
			{"공격 속도 +10%", "fire rate bonus",1,-0.1,0.1},
			{"재장전 속도 +20%", "faster reload rate",1,-0.2,0.1},
			{"처치 시 체력 25 회복", "heal on kill",0,25},
			{"최대 체력 +25", "max health additive bonus",0,25},
			{"모든 탄약수 +50%", "custom",1,0.5},
			{"이동 속도 +10%", "move speed bonus",1,0.1},
			{"점프 높이 +20%", "increased jump height",1,0.2},
			{"무기 전환 속도 +35%", "deploy time decreased",1,-0.35,0},
			{"전자 교란기 재충전 속도 +15%", "charge recharge rate increased",1,0.15},
			{"화염 피해 저항력 +25%", "dmg taken from fire reduced",1,-0.25,0.1},
			{"치명타 피해 저항력 +30%", "dmg taken from crit reduced",1,-0.3,0.1},
			{"탄환 피해 저항력 +25%", "dmg taken from bullets reduced",1,-0.25,0.1},
			{"폭발 피해 저항력 +25%", "dmg taken from blast reduced",1,-0.25,0.1},
			{"근거리 피해 저항력 +25%", "dmg from melee increased",1,-0.25,0.1},
			{"초당 체력 회복량 +2", "health regen",0,2},
			{"5초 마다 최대 탄약의 20% 보급", "ammo regen",0,0.2,1},
			{"적중 시 체력 15 회복", "heal on hit for rapidfire",0,3},
			{"전자 교란기 동력 강화", "robo sapper",0,1,3},
			{"거대 로봇 백스탭 피해량 +25%", "armor piercing",0,25,100},
			{"은폐 지속시간 +20%", "cloak consume rate decreased",1,-0.2},
			{"은폐 재생량 +50%", "mult cloak meter regen rate",1,0.5},
			{"적중 시 은폐 에너지 +15%", "add cloak on hit",0,15},
			{"처치 시 은폐 에너지 +30%", "add cloak on kill",0,30},
		},
		RareAttribute =
		{
			{"( R ) 처치 시: 소형 치료제 드롭", "drop health pack on kill",0,1,1},
			{"( R ) 추가 점프 횟수 +1", "air dash count",0,1},
			{"( R ) 투사체 관통", "projectile penetration",0,1,1},
			{"( R ) 메디건 치료 광선이 연결된 모든 대상 타격", "damage all connected",0,1,1},
			{"( R ) 리볼버: 집탄율 +100%", "weapon spread bonus",1,-1,0},
			{"( R ) 헤드샷 가능", "can headshot",0,1,1},
			{"( R ) 은폐 해제 대기 시간 -50%", "mult decloak rate",1,-0.5,0.01},
		},
		EpicAttribute =
		{
			{"( SR ) 사망 시 귀환 확률 +25%", "teleport instead of die",0,0.25,1},
			{"( SR ) 전자 교란기: 디버프 지속시간 +50%", "mult effect duration",1,0.5},
			{"( SR ) 처치 시 5초간 이동속도 증진", "speed_boost_on_kill",0,1,1},
			{"( SR ) 마지막 장탄 항상 치명타", "last shot crits",0,1,1},
			{"( SR ) 병수도/자라테 면역", "wet immunity",0,1,1},
			{"( SR ) 화상 면역", "afterburn immunity",0,1,1},
			{"( SR ) 리볼버: 변장 시 피해량 +50%", "damage bonus while disguised",1,0.5},
		},
		LegendaryAttribute =
		{
 			{"【 SSR 】 모든 받는 치료량 +100%", "healing received bonus",1,1},
			{"【 SSR 】 전차 대상 피해량 +300%", "mult dmg vs tanks",1,3},
			{"【 SSR 】 리볼버 사격 시 변장 유지", "keep disguise on attack",0,1,1},
			{"【 SSR 】 백스탭 처치 시 변장", "disguise on backstab",0,1,1},
			{"【 SSR 】 백스탭 및 건물 새핑 시 치명타 누적", "sapper kills collect crits",0,1,1},
		}
	}
}

--Used for returning the class name  [주석 1]
classIndices_Internal = {
    [1] = "스카웃",
    [3] = "솔저",
    [7] = "파이로",
    [4] = "데모맨",
    [6] = "헤비",
    [9] = "엔지니어",
    [5] = "메딕",
    [2] = "스나이퍼",
    [8] = "스파이",
}


--[[This table is essential, it will store the SteamID3 of a player and act as a "save file" for the player,
		Things that are stored in here for each player:
			UpgradePoints - how many upgrade points the player has, persists between classes
			RerollPoints - how many rerolls the player has, persists between classes

			An index from [1] to [9] which will represent the player's class
			Inside the index, each class has its own
				hasRolled - boolean, used as a flag if the player has rolled for upgrades on that class
				PurchasedUpgrades - table, which upgrades have been purchased for that player on that class
				MaxedUpgrades - table, which upgrades are maxed for that player on that class
				UpgradeMenu - table, show a unique upgrade menu for that player on that class
			]]
UniqueAccountIDs = {}

--[[Also very important, this table is akin to an emulator's "save state" where it will copy everything from
	UniqueAccountIDs, TotalUpgradePoints, and TotalRerollPoints. In the case that players lose a wave, this table is used
	to store save states]]
WaveState = {}

--[[Finds all func_upgradestation's on the map and lets the player interact with them for bringing up the menu]]
function EnableUpgradeStations()
	for _, v in pairs(ents.FindAllByClass("func_upgradestation")) do
		v:AddCallback(ON_START_TOUCH,
		function(_,player)
		    if player:IsRealPlayer() then
				RollUpgrades(player)
				ShowUpgradeMenu(player)
				--player:Print(2, "Weclome to the Randomizer Upgrade Station!") --없어도 되지 않을까요
			end
		end)
		v:AddCallback(ON_END_TOUCH,
		function(_,player)
		    if player:IsRealPlayer() then
				CloseUpgradeMenu(player) --probably redundnant
				--player:Print(2, "You have left the Randomizer Upgrade Station.")-- 없어도 되지 않을까요
			end
		end)
	end
end

--[[Adds the OnSpawn callback so that everytime a player spawns their upgrades are reapplied]]
function OnPlayerConnected(player)
    if player:IsRealPlayer() then
        player:AddCallback(ON_SPAWN, function(player)
			InitUserId(player)
			ReAddPurchasedUpgrades(player)
		end)
    end
end

--[[If the player joins the server for the first time, their SteamID3 is added to UniqueAccountIDs
	Note that the function for pruchasing upgrades is stored here]]
function InitUserId(activator)
	local player = (ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]
	if UniqueAccountIDs[player] == nil then
		UniqueAccountIDs[player] =
		{
			UpgradePoints = TotalUpgradePoints,
			RerollPoints = TotalRerollPoints,
		}
	end

	local class = activator:DumpProperties().m_iClass
	if UniqueAccountIDs[player][class] == nil then
		UniqueAccountIDs[player][class] =
		{
			hasRolled = false,
			PurchasedUpgrades = {}, --Stored as key [Upgrade name] with value equal to how many times it was purchased
			MaxedUpgrades = {}, --Used a temporary table, similar to PurchasedUpgrades, probably not needed in style2
			UpgradeMenu =
			{
				timeout = 0,
				title = "Select an upgrade - ",
				itemsPerPage = nil,
				flags = MENUFLAG_BUTTON_EXIT,
				onSelect = function(activator, index, value) --Responsible for subtracting upgrade/reroll points, disabling purchased upgrades
					local player = UniqueAccountIDs[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
					local class = activator:DumpProperties().m_iClass
					local purchased = player[class].PurchasedUpgrades
					local menu = player[class].UpgradeMenu
					local playername = activator:DumpProperties().m_szNetname[1]

					if value ~= "reroll" then
						if purchased[value] == nil then
							purchased[value] = 1
						else
							purchased[value] = purchased[value] + 1
						end

						menu[index].disabled = true
						AddUpgrade(activator, value)

						local upgradetable = {}
						for i in (string.gmatch(value, "[^,]+")) do
							upgradetable[#upgradetable + 1] = i
						end
						local upgrade = upgradetable[1]

						if string.find(upgrade, "( R )",1,true) then -- 루아 string.sub (참조 문자열,시작 문자열 위치,끝 문자열 위치) \x074B69FF = 색상코드 \x07RRGGBB
							util.PrintToChatAll("\x07ff3d3d"  .. playername .." " .. "\x074B69FF".. string.sub(upgrade,1,5) .. "\x07FFD700".. string.sub(upgrade,6,#upgrade) .. "\x07fbeccb Level " .. purchased[value] .. "\x07fbeccb 을 구입 하였습니다. ")
						elseif string.find(upgrade, "( SR )",1,true) then
							util.PrintToChatAll("\x07ff3d3d"  .. playername .. " " .. "\x078847FF".. string.sub(upgrade,1,6) .. "\x07FFD700".. string.sub(upgrade,7,#upgrade) .. "\x07fbeccb Level " .. purchased[value] .. "\x07fbeccb 을 구입 하였습니다. ")
						elseif string.find(upgrade, "【 SSR 】",1,true) then
							util.PrintToChatAll("\x07ff3d3d"  .. playername .. " " .. "\x07EB4B4B".. string.sub(upgrade,1,11) .. "\x07FFD700".. string.sub(upgrade,12,#upgrade) .. "\x07fbeccb Level " .. purchased[value] .. "\x07fbeccb 을 구입 하였습니다. ")
						else
						util.PrintToChatAll("\x07ff3d3d"  .. playername .. " "  .. "\x07FFD700" .. upgrade .. "\x07fbeccb Level " .. purchased[value] .. "\x07fbeccb 을 구입 하였습니다. ")
						end

						player.UpgradePoints = player.UpgradePoints - 1

						player[class].hasRolled = false
						RollUpgrades(activator) --after purchasing an upgrade, reroll for new set of upgrades

					else
						RerollUpgrades(activator)
					end

					ShowUpgradeMenu(activator)
				end,
				onCancel = nil
			}
		}
	end
end

--[[Your random number generator, returns a float to allow for decimal probabilities
	In this example, it rolls for rarity first, then rolls a second time to pick an upgrade
	So the probability of a specific upgrade is based on two rng rolls]]
function UpgradeRoulette(activator)
	local number = math.random() --returns float from 0 to 1
	local class = activator:DumpProperties().m_iClass
	local shop = AllShops[class]
	local pool = {}

	if number < 0.80 then
		pool = shop.CommonAttribute
	elseif (number >= 0.80 and number < 0.95) then
		pool = shop.RareAttribute
	elseif (number >= 0.95 and number < 0.99) then
		pool = shop.EpicAttribute
	elseif number >= 0.99 then --probably should be less than 1%
		pool = shop.LegendaryAttribute
	end

	local index = math.random(1,(#pool)) --returns integer from 1 to number of upgrades in pool
	local upgrade = pool[index]

	return upgrade
end

--[[This function calls UpgradeRoulette and sends the chosen upgrades to the upgrade menu]]
function RollUpgrades(activator)
	local player = UniqueAccountIDs[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
	local class = activator:DumpProperties().m_iClass
	local menu = player[class].UpgradeMenu
	local purchased = player[class].PurchasedUpgrades
	local maxed = player[class].MaxedUpgrades

	if player[class].hasRolled ~= true then
		for index = 1, MenuCapacity, 1 do
			menu[index] = {}
			maxed = {}
		end

		for index = 1, MenuCapacity, 1 do
			local upgrade = UpgradeRoulette(activator)
			local upgradestring = table.concat(upgrade,",")

			--[[Used to prevent maxed out upgrades from reappearing in the shop
				Note that this is possibly bugged in style2, will fix later]]
			function CheckMaxed(upgrade)
				local min = upgrade[3]
				local increment = upgrade[4]
				local max = upgrade[5]
				if max ~= nil then
					if maxed[upgradestring] == nil then
						if purchased[upgradestring] == nil then
							maxed[upgradestring] = 0
						else
							maxed[upgradestring] = purchased[upgradestring]
						end
					else
						maxed[upgradestring] = maxed[upgradestring] + 1
					end
					local value = min + maxed[upgradestring] * increment
					if increment > 0 then
						return (tostring(value) >= tostring(max))  --floating point issue
					else
						return (tostring(value) <= tostring(max))
					end
				end
			end

			if CheckMaxed(upgrade) == true then --If upgrade is maxed, reroll
				while CheckMaxed(upgrade) == true do
					upgrade = UpgradeRoulette(activator)
				end
			end

			for i = 1, MenuCapacity, 1 do --If upgrade is duplicate, reroll
				if menu[i].text == upgrade[1] then
					while menu[i].text == upgrade[1] do
						upgrade = UpgradeRoulette(activator)
					end
				end
			end

			menu[index] = {text = upgrade[1], value = table.concat(upgrade,","), disabled = false} --value can't accept tables, only strings/numbers
		end
		player[class].hasRolled = true
	end
end

--Called when the reroll option is selected, subtracts a reroll point
function RerollUpgrades(activator)
	local player = UniqueAccountIDs[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
	local class = activator:DumpProperties().m_iClass

	player.RerollPoints = player.RerollPoints - 1
	player[class].hasRolled = false
	RollUpgrades(activator)
end

--Sets hasRolled to false for all players in the game, usually called on wave end
function ResetRolls()
	for _, v in pairs(UniqueAccountIDs) do
		for i = 1, 9, 1 do
			if v[i] ~= nil then
				v[i].hasRolled = false
			end
		end
	end
end

--[[Apply upgrades to players
	using "custom" allows you do anything you define in the function as an upgrade
	meaning PointTemplate upgrades are possible]]
function AddUpgrade(activator, value)
	local player = UniqueAccountIDs[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
	local class = activator:DumpProperties().m_iClass
	local purchased = player[class].PurchasedUpgrades
	local upgradetable = {}

	for i in string.gmatch(value, "[^,]+") do
		upgradetable[#upgradetable + 1] = i
	end
	local upgrade = upgradetable[1]
	local attributename = upgradetable[2]
	local min = tonumber(upgradetable[3])
	local increment = tonumber(upgradetable[4])
	local max = tonumber(upgradetable[5])

	if attributename == "custom" then
		if upgrade == "모든 탄약수 +50%" then
			activator:SetAttributeValue("maxammo primary increased",min+increment*purchased[value])
			activator:SetAttributeValue("maxammo secondary increased",min+increment*purchased[value])
			activator:SetAttributeValue("maxammo grenades1 increased",min+increment*2*purchased[value])
		elseif upgrade == "( SR ) 적중 시 혼합 상태이상 부여" then
			activator:SetAttributeValue("add cond on hit",123 + 27*256 + 24*65536) --123 = gas, 27 = milk, 24 = jarate, total is 1579899
			activator:SetAttributeValue("add cond on hit duration",10)
			activator:SetAttributeValue("bleeding duration",10)
		end
	elseif attributename ~= "custom" then
		if max ~= nil then
			if increment > 0 then
				activator:SetAttributeValue(attributename,math.min(min+increment*purchased[value],max))
			else
				activator:SetAttributeValue(attributename,math.max(min+increment*purchased[value],max))
			end
		else
			activator:SetAttributeValue(attributename,min+increment*purchased[value])
		end
	end
end

--Give all players specified amount of upgrade points, adds running total to TotalUpgradePoints for late joiners
function AddUpgradePoints(number)
	for _, v in pairs(UniqueAccountIDs) do
		v.UpgradePoints = v.UpgradePoints + number
	end
	TotalUpgradePoints = TotalUpgradePoints + number
end

--Give all players specified amount of rerolls, adds running total to TotalRerollPoints for late joiners
function AddRerollPoints(number)
	for _, v in pairs(UniqueAccountIDs) do
		v.RerollPoints = v.RerollPoints + number
	end
	TotalRerollPoints = TotalRerollPoints + number
end

--Set all players's upgrade points to specified value without adding or subtracting to TotalUpgradePoints
function SetUpgradePoints(number)
	for _, v in pairs(UniqueAccountIDs) do
		v.UpgradePoints = number
	end
end

--Set all players's rerolls to specified value without adding or subtracting to TotalRerollPoints
function SetRerollPoints(number)
	for _, v in pairs(UniqueAccountIDs) do
		v.RerollPoints = number
	end
end

--Iterates upon PurchasedUpgrades table and calls AddUpgrade for each upgrade, called OnSpawn of every player
function ReAddPurchasedUpgrades(activator)
	local player = UniqueAccountIDs[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
	local class = activator:DumpProperties().m_iClass
	local purchased = player[class].PurchasedUpgrades

	for k, _ in pairs(purchased) do
		AddUpgrade(activator, k)
	end
	activator:RefillAmmo()
end

--[[This function will display the shop menu
	It shows how many upgrade levels were purchased and the max if it exists
	It will also show the corresponding class you are playing as in the title
	Shows how many upgrade points are remaining
	Always adds the reroll option to the bottom of the list
	Will disable the shop if the player has no more upgrade points]]
function ShowUpgradeMenu(activator)
	local player = UniqueAccountIDs[(ents.FindByClass("tf_player_manager", nil)):DumpProperties().m_iAccountID[activator:GetNetIndex()+1]]
	local class = activator:DumpProperties().m_iClass
	local menu = player[class].UpgradeMenu
	local purchased = player[class].PurchasedUpgrades

	menu[MenuCapacity+1] = {text= classIndices_Internal[class] .. " 상점 새로고침\n    새로고침 " .. player.RerollPoints .. " 번 남음", value="reroll"}
	if player.RerollPoints == 1 then
		menu[MenuCapacity+1] = {text= classIndices_Internal[class] .. " 상점 새로고침\n    새로고침 "  .. player.RerollPoints .. " 번 남음", value="reroll"}
	elseif player.RerollPoints <= 0 then
		menu[MenuCapacity+1] = {text= classIndices_Internal[class] .. " 상점 새로고침\n    새로고침 "  .. player.RerollPoints .. " 번 남음", value="reroll", disabled = true}
	end

	menu.title = classIndices_Internal[class] .. " 상점\n" ..  player.UpgradePoints .. " 업그레이드 포인트 남음\n "
	if player.UpgradePoints == 1 then
		menu.title = classIndices_Internal[class] .. " 상점\n" .. player.UpgradePoints .. " 업그레이드 포인트 남음\n "
	elseif player.UpgradePoints <= 0 then
		for i = 1, MenuCapacity+1, 1 do
			menu[i].disabled = true
		end
	end

	for i = 1, MenuCapacity, 1 do
		local value = menu[i].value
		local upgradetable = {}
		for k in string.gmatch(value, "[^,]+") do
			upgradetable[#upgradetable + 1] = k
		end
		local min = upgradetable[3]
		local increment = upgradetable[4]
		local max = upgradetable[5]

		if purchased[value] ~= nil then
			menu[i].text = menu[i].text .. "\n    #: " .. purchased[value]
		else
			menu[i].text = menu[i].text .. "\n    #: 0"
		end
		if max ~= nil then
			menu[i].text = menu[i].text .. "          Max: " .. math.ceil((max-min)/increment) --big brain math
		end
	end

	activator:DisplayMenu(menu)

	for i = 1, MenuCapacity, 1 do
		local value = menu[i].value
		local upgradetable = {}
		for k in string.gmatch(value, "[^,]+") do
			upgradetable[#upgradetable + 1] = k
		end
		upgrade = upgradetable[1]

		menu[i].text = upgrade
	end
end

function CloseUpgradeMenu(activator) --probably redundnant
	activator:HideMenu()
end

function deepCopy(original) --special thx to https://developer.roblox.com
	local copy = {}
	for k, v in pairs(original) do
		if type(v) == "table" then
			v = deepCopy(v)
		end
		copy[k] = v
	end
	return copy
end

function OnWaveSuccess(wave) --adds however many upgrade points every wave, can also be edited to do other things
	AddUpgradePoints(2)
	AddRerollPoints(1)
end

function OnWaveReset(wave) --on wave reset, load save state from WaveState
	if WaveState[wave] ~= nil then
		TotalUpgradePoints = WaveState[wave].TotalUpgradePoints
		TotalRerollPoints = WaveState[wave].TotalRerollPoints
		UniqueAccountIDs = deepCopy(WaveState[wave].UniqueAccountIDs)
	end
end

function OnWaveInit(wave) --on wave init, create save state in WaveState, reset rolls
	EnableUpgradeStations() --for wave 1
	if WaveState[wave] == nil then
		WaveState[wave] =
		{
			TotalUpgradePoints = TotalUpgradePoints,
			TotalRerollPoints = TotalRerollPoints,
			UniqueAccountIDs = deepCopy(UniqueAccountIDs)
		}
	end
	ResetRolls()
end