-- Rebirth --

Base_Rebirth = Base_Object:New({

	Scale = 1,
	Type = "Rebirth",
	TierAttribute = "RebirthTier",
	GrowthAttribute = "RiteGrowth",
	IntroText = "Sacrifice everything to rebirth anew",
	ForfeitText = "Forfeit all items, unlocks, keys, gold, experience and learned skills for:",
	InteractText = "rebirths",
	UpgradeSuffix = "%",

	GetRiteLevel = function(self, Source, Value)
		if self.Type == "Evolve" then
			return math.min(Source.Transforms * TRANSFORM_RITE_SCALE + Source.Evolves + Source.RiteEvolution + 1, Value)
		elseif self.Type == "Transform" then
			return math.min((Source.Transforms + 1) * TRANSFORM_RITE_SCALE, Value)
		end

		return Value
	end,

	GetBonus = function(self, Source, MoreInfo)
		local Value = Source[self.TierAttribute]
		if self.GrowthAttribute then
			Value = Value * (1 + Source[self.GrowthAttribute])
		end

		Value = Value * self.Scale

		return MoreInfo and Value or math.floor(Value)
	end,

	GetBonusText = function(self, Source, MoreInfo)
		local Bonus = self:GetBonus(Source, MoreInfo)
		local Existing = Source[self.Attribute] * self.Scale
		local Increase = 100 * (Bonus + Existing) / Existing - 100
		local ExistingText = (Existing ~= 0 and Bonus ~= 0) and "([c green]+" .. FormatSI(Increase, true) .. "%[c white]) " or ""
		local Value
		if MoreInfo then
			Value = Bonus
		else
			Value = FormatSI(Bonus)
		end

		return Value .. self.UpgradeSuffix .. "[c white] " .. ExistingText
	end,

	CanUse = function(self, Level, Source)
		return Source[self.TierAttribute] > 0
	end,

	Use = function(self, Level, Duration, Source, Target, Result, Priority)
		Result.Target[self.Type] = 1
		Result.Target[self.Attribute] = Source[self.TierAttribute]

		return Result
	end,

	GetInfo = function(self, Source, Item)

		-- Get new rite levels
		local RiteWisdom = self:GetRiteLevel(Source, Source.RiteWisdom) + 1
		local RiteWealth = self:GetRiteLevel(Source, Source.RiteWealth)
		local RiteKnowledge = self:GetRiteLevel(Source, Source.RiteKnowledge)
		local RitePrivilege = self:GetRiteLevel(Source, Source.RitePrivilege)
		local RiteEnchantment = self:GetRiteLevel(Source, Source.RiteEnchantment)
		local RitePassage = self:GetRiteLevel(Source, Source.RitePassage)

		-- Get new rebirth numbers
		local Rebirths = Source.Rebirths
		local Evolves = Source.Evolves
		local Transforms = Source.Transforms
		local PainDifficulty = 0
		if self.Type == "Rebirth" then
			Rebirths = Rebirths + 1 + Source.RiteGrowth
			PainDifficulty = Source.EternalPain
		elseif self.Type == "Evolve" then
			Evolves = Evolves + 1 + Source.RiteEvolution
			Rebirths = 0
		elseif self.Type == "Transform" then
			Transforms = Transforms + 1
			Evolves = 0
			Rebirths = 0
		end

		-- Calculate new difficulty
		local NewDifficulty = 100 + Rebirths * REBIRTH_DIFFICULTY + Evolves * EVOLVE_DIFFICULTY + Transforms * TRANSFORM_DIFFICULTY + PainDifficulty
		if Item == Item_EternalPain then
			NewDifficulty = NewDifficulty + Item:GetBonus(Source)
		end

		-- Get text
		local GoldPercent = RiteWealth * Item_RiteWealth.Multiplier
		local Gold = math.min(math.floor(GoldPercent * 0.01 * Source.Experience), MAX_GOLD)
		local WisdomPlural = RiteWisdom ~= 1 and "s" or ""
		local PassagePlural = RitePassage ~= 1 and "s" or ""
		local PrivilegePlural = RitePrivilege ~= 1 and "s" or ""
		local PrivilegeText = RitePrivilege > 0 and "[c green]" .. RitePrivilege .. "[c white] item" .. PrivilegePlural .. " in your trade bag\n\n" or "\n"
		local UpgradeText = self.UpgradeText or self:GetUpgradeText(Source, Item)
		local KeyText = RitePassage > 0 and " ([c green]" .. Item_RitePassage.Keys[RitePassage][1] .. "[c white])" or ""

		-- Set text
		return
			"[c gray]" .. self.IntroText .. "\n\n" ..
			self.ForfeitText .. "\n\n" ..
			"Permanent [c green]" .. self:GetBonusText(Source, Item.MoreInfo) .. UpgradeText ..
			"\n\n[c yellow]You will keep\n" ..
			"[c green]" .. RiteKnowledge .. "[c white] of your highest level skills\n" ..
			PrivilegeText ..
			"[c yellow]You will start with\n" ..
			"[c green]" .. RiteEnchantment .. "[c white] extra max skill levels\n" ..
			"[c green]" .. FormatSI(NewDifficulty) .. "%[c white] difficulty\n" ..
			"[c green]" .. RiteWisdom .. "[c white] character level" .. WisdomPlural .. "\n" ..
			"[c green]" .. RitePassage .. "[c white] key" .. PassagePlural .. KeyText .. "\n" ..
			"[c green]" .. FormatSI(Gold) .. "[c white] gold ([c green]" .. GoldPercent .. "%[c white])\n\n" ..
			"[c yellow]Warning\nYou will only be able to interact with players that have the same number of " .. self.InteractText
	end,

	PlaySound = function(self)
		Audio.Play("rebirth.ogg")
	end,
})

-- Base Rebirth Token --

Base_RebirthToken = Base_Object:New({

	Difficulty = REBIRTH_DIFFICULTY,
	Tiers = 1,
	Type = "rebirth",
	TierAttribute = "RebirthTier",
	TierText = "character levels",

	GetTier = function(self, Source, MoreInfo)
		if MoreInfo then
			return Source[self.TierAttribute]
		else
			return FormatSI(Source[self.TierAttribute])
		end
	end,

	GetTierDivisor = function(self, Source)
		return REBIRTH_PROGRESS_START - Source.RiteProgress * REBIRTH_PROGRESS_SCALE
	end,

	GetExtraTierText = function(self, Source)
		return ""
	end,

	GetResetText = function(self, Source)
		return ""
	end,

	GetInfo = function(self, Source, Item)
		return
			"You are in " .. self.Type .. " tier [c green]" .. self:GetTier(Source, Item.MoreInfo) .. "\n\n" ..
			"Every [c green]" .. self:GetTierDivisor(Source) .. "[c white] " .. self.TierText .. " gives [c green]" .. self.Tiers .. "[c white] tier, which increases your " .. self.Type .. " stat bonus\n\n" ..
			self:GetExtraTierText(Source) ..
			self:GetResetText(Source)
	end,
})

-- Rebirth Token --

Item_RebirthToken = Base_RebirthToken:New({

	GetExtraTierText = function(self, Source)
		return
			"Rebirthing increases:\n" ..
			"Difficulty by [c green]" .. self.Difficulty .. "%\n"
	end,
})

-- Evolve Token --

Item_EvolveToken = Base_RebirthToken:New({

	Type = "evolve",
	TierAttribute = "EvolveTier",
	TierText = "rebirths",
	Difficulty = EVOLVE_DIFFICULTY,

	GetTierDivisor = function(self, Source)
		return 10
	end,

	GetExtraTierText = function(self, Source)
		return
			"Evolving increases:\n" ..
			"Rebirth tier by [c green]" .. EVOLVE_REBIRTH_TIERS ..  "[c white]\n" ..
			"Rite of Power increase amount by [c green]" .. RITE_POWER_EVOLVE_SCALE .. "[c white]\n" ..
			"Starting rite level cap by [c green]" .. EVOLVE_RITE_SCALE .. "\n" ..
			"Rite of Growth max by [c green]" .. Item_RiteGrowth.EvolveScale .. "[c white]\n" ..
			"Difficulty by [c green]" .. self.Difficulty .. "%\n"
	end,

	GetResetText = function(self, Source)
		local RiteLevel = Source.Transforms * TRANSFORM_RITE_SCALE + Source.Evolves + Source.RiteEvolution + 1

		return "\n[c yellow]Evolving resets your rebirths\n[c yellow]All rites will be reduced to level [c green]" .. RiteLevel
	end,
})

-- Transform Token --

Item_TransformToken = Base_RebirthToken:New({

	Type = "transform",
	TierAttribute = "TransformTier",
	TierText = "evolves",
	Difficulty = TRANSFORM_DIFFICULTY,

	GetTierDivisor = function(self, Source)
		return 10
	end,

	GetExtraTierText = function(self, Source)
		return
			"Transforming increases:\n" ..
			"Rebirth tier by [c green]" .. TRANSFORM_REBIRTH_TIERS .. "[c white]\n" ..
			"Evolve tier by [c green]" .. TRANSFORM_EVOLVE_TIERS .. "[c white]\n" ..
			"Rite of Power increase amount by [c green]" .. RITE_POWER_TRANSFORM_SCALE .. "[c white]\n" ..
			"Rite of Growth max by [c green]" .. Item_RiteGrowth.TransformScale .. "[c white]\n" ..
			"Rite of Evolution max by [c green]" .. Item_RiteEvolution.TransformScale .. "[c white]\n" ..
			"Starting rite level cap by [c green]" .. TRANSFORM_RITE_SCALE .. "\n" ..
			"Difficulty by [c green]" .. self.Difficulty .. "%\n"
	end,

	GetResetText = function(self, Source)
		local RiteLevels = (Source.Transforms + 1) * TRANSFORM_RITE_SCALE

		return "\n[c yellow]Transforming resets your evolves/rebirths\n[c yellow]All rites will be reduced to level [c green]" .. RiteLevels
	end,
})

-- Eternal Strength

Item_EternalStrength = Base_Rebirth:New({

	Attribute = "EternalStrength",
	UpgradeText = "damage power bonus",
})

-- Eternal Guard

Item_EternalGuard = Base_Rebirth:New({

	Attribute = "EternalGuard",
	UpgradeSuffix = "",

	GetUpgradeText = function(self, Source, Item)
		local DamageBlock
		local Armor
		if Item.MoreInfo then
			DamageBlock = self:GetBonus(Source, true)
			Armor = RoundDown1(self:GetBonus(Source, true) / ETERNAL_GUARD_DIVISOR)
		else
			DamageBlock = FormatSI(self:GetBonus(Source, false))
			Armor = FormatSI(math.floor((self:GetBonus(Source, true) / ETERNAL_GUARD_DIVISOR)))
		end

		return "damage block and [c green]" .. Armor .. "[c white] armor bonus"
	end,
})

-- Eternal Fortitude

Item_EternalFortitude = Base_Rebirth:New({

	Attribute = "EternalFortitude",
	UpgradeText = "max health and heal power bonus",
})

-- Eternal Spirit

Item_EternalSpirit = Base_Rebirth:New({

	Attribute = "EternalSpirit",
	UpgradeText = "max mana and mana power bonus",
})

-- Eternal Wisdom

Item_EternalWisdom = Base_Rebirth:New({

	Attribute = "EternalWisdom",
	UpgradeText = "experience bonus",
})

-- Eternal Wealth

Item_EternalWealth = Base_Rebirth:New({

	Attribute = "EternalWealth",
	UpgradeText = "gold bonus",
})

-- Eternal Knowledge

Item_EternalKnowledge = Base_Rebirth:New({

	Attribute = "EternalKnowledge",
	Scale = 1.0 / ETERNAL_KNOWLEDGE_DIVISOR,
	UpgradeSuffix = "",

	GetUpgradeText = function(self, Source, Item)
		local Plural = self:GetBonus(Source) ~= 1 and "s" or ""

		return "extra skill point" .. Plural
	end,
})

-- Eternal Pain

Item_EternalPain = Base_Rebirth:New({

	Attribute = "EternalPain",
	UpgradeText = "difficulty increase",
})

-- Eternal Protection

Item_EternalProtection = Base_Rebirth:New({

	Attribute = "EternalProtection",
	UpgradeText = "resistance bonus",
	Scale = 1.0 / ETERNAL_PROTECTION_DIVISOR,
})

-- Evolve --

Base_Evolve = Base_Rebirth:New({

	Type = "Evolve",
	TierAttribute = "EvolveTier",
	GrowthAttribute = "RiteEvolution",
	IntroText = "Evolve into a higher form",
	ForfeitText = "Forfeit all rebirths, items, unlocks, keys, gold, experience and learned skills for:",
	InteractText = "evolves and rebirths",

	PlaySound = function(self)
		Audio.Play("sparkle0.ogg")
	end,
})

-- Eternal Alacrity

Item_EternalAlacrity = Base_Evolve:New({

	Attribute = "EternalAlacrity",
	Scale = ETERNAL_ALACRITY_SCALE,
	UpgradeText = "battle speed bonus\n\n[c yellow]Max battle speed is " .. MAX_BATTLE_SPEED .. "%",
})

-- Eternal Command

Item_EternalCommand = Base_Evolve:New({

	Attribute = "EternalCommand",
	Scale = ETERNAL_COMMAND_SCALE,
	UpgradeText = "summon battle speed bonus\n\n[c yellow]Max summon battle speed is " .. MAX_BATTLE_SPEED .. "%",
})

-- Eternal Ward

Item_EternalWard = Base_Evolve:New({

	Attribute = "EternalWard",
	Scale = ETERNAL_WARD_SCALE,
	UpgradeText = "max resistance bonus\n\n[c yellow]Applies to summons\n[c yellow]Max resistance is " .. MAX_RESISTANCE .. "%",
})

-- Eternal Impatience

Item_EternalImpatience = Base_Evolve:New({

	Attribute = "EternalImpatience",
	Scale = ETERNAL_IMPATIENCE_SCALE,
	UpgradeText = "cooldown reduction bonus\n\n[c yellow]Minimum cooldown is " .. MIN_COOLDOWN .. " seconds",
})

-- Eternal Charisma

Item_EternalCharisma = Base_Evolve:New({

	Attribute = "EternalCharisma",
	Scale = ETERNAL_CHARISMA_SCALE,
	UpgradeText = "vendor discount bonus\n\n[c yellow]Max vendor discount is " .. MAX_VENDOR_DISCOUNT .. "%",
})

-- Transform --

Base_Transform = Base_Rebirth:New({

	Type = "Transform",
	TierAttribute = "TransformTier",
	GrowthAttribute = false,
	IntroText = "Transform into a higher being",
	ForfeitText = "Forfeit all rebirths, evolves, items, unlocks, keys, gold, experience and learned skills for:",
	InteractText = "transforms, evolves, and rebirths",

	PlaySound = function(self)
		Audio.Play("warp0.ogg")
	end,
})

-- Eternal Hell

Item_EternalHell = Base_Transform:New({

	Attribute = "EternalHell",
	Scale = ETERNAL_HELL_SCALE,
	UpgradeText = "difficulty multiplier bonus",
	UpgradeSuffix = "",
})

-- Eternal Malice

Item_EternalMalice = Base_Transform:New({

	Attribute = "EternalMalice",
	Scale = ETERNAL_MALICE_SCALE,
	UpgradeText = "target count bonus",
	UpgradeSuffix = "",
})

-- Eternal Deceit

Item_EternalDeceit = Base_Transform:New({

	Attribute = "EternalDeceit",
	Scale = ETERNAL_DECEIT_SCALE,
	UpgradeText = "set requirement bonus",
	UpgradeSuffix = "",
})

-- Eternal Rest

Item_EternalRest = Base_Transform:New({

	Attribute = "EternalRest",
	Scale = ETERNAL_REST_SCALE,
	UpgradeSuffix = "",

	GetUpgradeText = function(self, Source, Item)
		local EvolveBonusText
		if Item.MoreInfo then
			EvolveBonusText = self:GetBonus(Source, true) * ETERNAL_REST_EVOLVE_SCALE
		else
			EvolveBonusText = FormatSI(math.floor(self:GetBonus(Source, false) * ETERNAL_REST_EVOLVE_SCALE))
		end

		return
			"base eternal strength, guard, fortitude, spirit, wisdom, wealth, protection, and knowledge bonus\n\nand\n\n" ..
			"Permanent [c green]".. EvolveBonusText .. "[c white] base eternal alacrity, command, ward, impatience, and charisma bonus"
	end,
})

-- Rites --

Base_Rite = Base_Object:New({

	ExponentScale = 0.0,
	LinearScale = 1.0,
	Max = 0,

	GetRiteText = function(self, UpgradeText)
		return "Permanently " .. UpgradeText
	end,

	PlaySound = function(self)
		Audio.Play("unlock" .. Random.GetInt(0, 1) .. ".ogg", 0.85)
	end,

	GetUpgradedCost = function(self, Source, Level)
		local Index = Level - 1
		local Cost = self.Item.Cost ^ (1 + Index * self.ExponentScale) + self.Item.Cost * (Index * self.LinearScale)
		if Cost > MAX_GOLD then
			return MAX_GOLD
		end

		-- Round to nearest 1000
		return math.floor(Cost / 1000) * 1000
	end,

	GetPrice = function(self, Source, Count, VendorScale)
		local Total = 0
		local Amount = 0
		for i = 1, Count do

			-- Check if item can be used
			if self.GetMax and Source[self.AttributeName] + i > self:GetMax(Source) then
				break
			end

			-- Get base cost of item
			local Cost = self:GetUpgradedCost(Source, Source[self.AttributeName] + i)

			-- Apply player's vendor discount
			if Source.VendorDiscount > 0 then
				local Multiplier = (100 - Source.VendorDiscount) * 0.01
				Cost = math.max(Cost * Multiplier, 1)
			end

			-- Apply vendor multiplier
			Cost = Cost * VendorScale

			-- Only return the amount the player can afford
			if Amount > 0 and Total + Cost > Source.Gold then
				break
			end

			-- Update totals
			Total = Total + Cost
			Amount = Amount + 1
		end

		return Total, Amount
	end,

	GetMax = function(self, Source)
		return self.Max
	end,

	CanBuy = function(self, Source)
		return self:UsesLeft(Level, Source) > 0
	end,

	CanUse = function(self, Level, Source)
		return self:CanBuy(Source)
	end,

	UsesLeft = function(self, Level, Source)
		return self.GetMax and self:GetMax(Source) - Source[self.AttributeName] or 1
	end,

	Use = function(self, Level, Duration, Source, Target, Result, Priority)
		if self:CanBuy(Source) then
			Result.Target[self.AttributeName] = Level
		end

		return Result
	end,

})

-- Rite of Wealth

Item_RiteWealth = Base_Rite:New({

	AttributeName = "RiteWealth",
	Multiplier = REBIRTH_WEALTH_MULTIPLIER,
	ExponentScale = 0.01,
	LinearScale = 1.0,
	GetMax = false,

	GetInfo = function(self, Source, Item)
		return self:GetRiteText("increase the amount of experience converted into gold after rebirth by [c green]" .. self:GetPercent(Item.Level) .. "%[c white]")
	end,

	GetPercent = function(self, Level)
		return Level * self.Multiplier
	end,
})

-- Rite of Wisdom

Item_RiteWisdom = Base_Rite:New({

	AttributeName = "RiteWisdom",
	ExponentScale = 0.01,
	LinearScale = 1.0,
	Max = MAX_LEVEL - 1,

	GetInfo = function(self, Source, Item)
		local AddedText = ""
		if not self:CanBuy(Source) then
			AddedText = "\n\n[c red]Max wisdom attained"
		end

		return self:GetRiteText("increase the starting level after rebirth by [c green]" .. Item.Level .. "[c white]" .. AddedText)
	end,
})

-- Rite of Knowledge

Item_RiteKnowledge = Base_Rite:New({

	AttributeName = "RiteKnowledge",
	ExponentScale = 0.05,
	LinearScale = 1.0,
	Max = MAX_SKILLS,

	GetInfo = function(self, Source, Item)
		local AddedText = ""
		if not self:CanBuy(Source) then
			AddedText = "\n\n[c red]Max knowledge attained"
		end

		return self:GetRiteText(
			"increase the number of learned skills carried over after rebirth by [c green]" .. Item.Level .. "\n\n" ..
			"Skills will have a max level of [c green]" .. Source.RiteEnchantment + DEFAULT_MAX_SKILL_LEVEL .. AddedText)
	end,
})

-- Rite of Power

Item_RitePower = Base_Rite:New({

	AttributeName = "RitePower",
	ExponentScale = 0.01,
	LinearScale = 1.0,
	GetMax = false,

	GetInfo = function(self, Source, Item)
		return self:GetRiteText("increase your rebirth tier by [c green]" .. Source.GetRitePowerScale() .. "[c white]")
	end,
})

-- Rite of Progress

Item_RiteProgress = Base_Rite:New({

	AttributeName = "RiteProgress",
	ExponentScale = 0.022,
	LinearScale = 1.0,
	Max = 49,

	GetInfo = function(self, Source, Item)
		local AddedText = ""
		if not self:CanBuy(Source) then
			AddedText = "\n\n[c red]Max progress attained"
		end

		return self:GetRiteText("reduce the character levels required for a rebirth tier by [c green]" .. REBIRTH_PROGRESS_SCALE .. "[c white]" .. AddedText)
	end,
})

-- Rite of Girth

Item_RiteGirth = Base_Rite:New({

	AttributeName = "RiteGirth",
	ExponentScale = 0.12,
	LinearScale = 4.0,
	Max = MAX_BELT_SIZE - DEFAULT_BELTSIZE,

	GetInfo = function(self, Source, Item)
		local AddedText = ""
		if not self:CanBuy(Source) then
			AddedText = "\n\n[c red]Max girth attained"
		end

		return self:GetRiteText("increase the belt size after rebirth by [c green]" .. Item.Level .. "[c white]" .. AddedText)
	end,
})

-- Rite of Proficiency

Item_RiteProficiency = Base_Rite:New({

	AttributeName = "RiteProficiency",
	ExponentScale = 0.05,
	LinearScale = 2.0,
	Max = MAX_SKILLBAR_SIZE - DEFAULT_SKILLBARSIZE,

	GetInfo = function(self, Source, Item)
		local AddedText = ""
		if not self:CanBuy(Source) then
			AddedText = "\n\n[c red]Max proficiency attained"
		end

		return self:GetRiteText("increase the skill bar size after rebirth by [c green]" .. Item.Level .. "[c white]" .. AddedText)
	end,
})

-- Rite of Insight

Item_RiteInsight = Base_Rite:New({

	AttributeName = "RiteInsight",
	ExponentScale = 0.03,
	LinearScale = 1.0,
	Max = MAX_SKILL_UNLOCKS,

	GetInfo = function(self, Source, Item)
		local AddedText = ""
		if not self:CanBuy(Source) then
			AddedText = "\n\n[c red]Max insight attained"
		end

		return self:GetRiteText("increase the starting skill point unlocks after rebirth by [c green]" .. Item.Level .. "[c white]" .. AddedText)
	end,
})

-- Rite of Passage

Item_RitePassage = Base_Rite:New({

	AttributeName = "RitePassage",
	Keys = {
		{ "Crab Key",         1.0e05 },
		{ "Graveyard Key",    2.5e05 },
		{ "Storage Key",      5.0e05 },
		{ "Witch Key",        7.5e05 },
		{ "Library Key",      1.0e06 },
		{ "Cellar Key",       2.5e06 },
		{ "Hideout Key",      5.0e06 },
		{ "Dungeon Key",      7.5e06 },
		{ "Tower Key",        1.0e07 },
		{ "Lighthouse Key",   2.5e07 },
		{ "Passage Key",      5.0e07 },
		{ "City Key",         7.5e07 },
		{ "Building Key",     1.0e08 },
		{ "Bridge Key",       2.5e08 },
		{ "Prisoner Key",     5.0e08 },
		{ "Lost Key",         7.5e08 },
		{ "Swamp Key",        1.0e09 },
		{ "Spider Key",       2.5e09 },
		{ "Chamber Key",      5.0e09 },
		{ "Ancient Key",      7.5e09 },
		{ "Timeless Key",     1.0e10 },
		{ "Black Runestone",  2.5e10 },
		{ "Blue Runestone",   5.0e10 },
		{ "Red Runestone",    7.5e10 },
		{ "Green Runestone",  1.0e11 },
		{ "Icy Key",          1.0e12 },
		{ "Frozen Key",       1.0e13 },
		{ "Eternal Key",      1.0e14 },
		{ "Dark Chamber Key", 1.0e15 },
		{ "Dead Key",         1.0e16 },
		{ "Chore Key",        1.0e18 },
	},

	GetInfo = function(self, Source, Item)
		local AddedText = ""
		if not self:CanBuy(Source) then
			AddedText = "\n\n[c red]Max passage attained"
		else
			AddedText = "\n\n[c yellow]Start with the " .. self.Keys[Source.RitePassage + 1][1]
		end

		return self:GetRiteText("increase the number of keys unlocked after rebirth by [c green]" .. Item.Level .. AddedText)
	end,

	GetMax = function(self, Source)
		return #self.Keys
	end,

	GetUpgradedCost = function(self, Source, Level)
		local Index = math.max(1, math.min(Level, #self.Keys))

		return self.Keys[Index][2]
	end,
})

-- Rite of Enchantment

Item_RiteEnchantment = Base_Rite:New({

	AttributeName = "RiteEnchantment",
	ExponentScale = 0.015,
	LinearScale = 1.0,
	Max = MAX_SKILL_LEVEL - DEFAULT_MAX_SKILL_LEVEL,

	GetInfo = function(self, Source, Item)
		local AddedText = ""
		if not self:CanBuy(Source) then
			AddedText = "\n\n[c red]Max enchantment attained"
		end

		return self:GetRiteText("increase the max level for starting skills after rebirth by [c green]" .. Item.Level .. "[c white]" .. AddedText)
	end,
})

-- Rite of Privilege

Item_RitePrivilege = Base_Rite:New({

	AttributeName = "RitePrivilege",
	ExponentScale = 0.05,
	LinearScale = 2.0,
	Max = MAX_TRADE_ITEMS,

	GetInfo = function(self, Source, Item)
		local Level = math.min(Source.RitePrivilege + 1, self:GetMax())
		local ItemStack = REBIRTH_PRIVILEGE_ITEM_STACK * Level
		local EquipmentStack = REBIRTH_PRIVILEGE_EQUIPMENT_STACK * Level
		local AddedText = ""
		if not self:CanBuy(Source) then
			AddedText = "\n\n[c red]Max privilege attained"
		end

		return self:GetRiteText(
			"increase the number of items and summons carried over after rebirth by [c green]" .. Item.Level ..
			"[c white]" .. AddedText .. "\n\n" ..
			"[c yellow]Items must be placed in your trade bag\n\n" ..
			"[c yellow]Items limited to a stack size of " .. ItemStack .. "\n" ..
			"[c yellow]Equipment limited to a stack size of " .. EquipmentStack
		)
	end,
})

-- Rite of Soul

Item_RiteSoul = Base_Rite:New({

	AttributeName = "RiteSoul",
	Max = 100,

	GetInfo = function(self, Source, Item)
		local AddedText = ""
		if not self:CanUse(1, Source) then
			AddedText = "\n\n[c red]Max soul attained"
		end

		return self:GetRiteText("decrease boss cooldowns by [c green]" .. Item.Level .. "%[c white]" .. AddedText)
	end,
})

-- Rite of Growth

Item_RiteGrowth = Base_Rite:New({

	AttributeName = "RiteGrowth",
	ExponentScale = 0.04,
	LinearScale = 10.0,
	EvolveScale = 1,
	TransformScale = 50,

	GetInfo = function(self, Source, Item)
		local AddedText = ""
		if not self:CanBuy(Source) then
			AddedText = "\n\n[c red]Max growth attained"
		else
			AddedText = "\n\n[c yellow]Max growth is " .. self:GetMax(Source)
		end

		return self:GetRiteText("increase the number of rebirths per rebirth by [c green]" .. Item.Level .. AddedText)
	end,

	GetMax = function(self, Source)
		return MAX_GROWTH + Source.Evolves * self.EvolveScale + Source.Transforms * self.TransformScale
	end,
})

-- Rite of Evolution

Item_RiteEvolution = Base_Rite:New({

	AttributeName = "RiteEvolution",
	TransformScale = 1,

	GetInfo = function(self, Source, Item)
		local AddedText = ""
		if not self:CanUse(1, Source) then
			AddedText = "\n\n[c red]Max evolution attained"
		else
			AddedText = "\n\n[c yellow]Max evolution is " .. self:GetMax(Source)
		end

		return self:GetRiteText("increase the number of evolves per evolve by [c green]" .. Item.Level .. AddedText)
	end,

	GetMax = function(self, Source)
		return MAX_EVOLUTION + Source.Transforms * self.TransformScale
	end,
})

-- Rite of Traversal

Item_RiteTraversal = Base_Rite:New({

	AttributeName = "RiteTraversal",
	Items = {
		{ "Dimensionality",     5^0 * 1e14 },
		{ "Flippers",           5^1 * 1e14 },
		{ "Mountain Climbers",  5^2 * 1e14 },
		{ "Winged Shoes",       5^3 * 1e14 },
		{ "Fire Walkers",       5^4 * 1e14 },
		{ "Ice Walkers",        5^5 * 1e14 },
	},

	GetInfo = function(self, Source, Item)
		local AddedText = ""
		if not self:CanBuy(Source) then
			AddedText = "\n\n[c red]Max traversal attained"
		else
			AddedText = "\n\n[c yellow]Start with " .. self.Items[Source.RiteTraversal + 1][1]
		end

		return self:GetRiteText("increase the number of starting relics after rebirth by [c green]" .. Item.Level .. AddedText)
	end,

	GetMax = function(self, Source)
		return #self.Items
	end,

	GetUpgradedCost = function(self, Source, Level)
		local Index = math.max(1, math.min(Level, #self.Items))

		return self.Items[Index][2]
	end,
})
