// Maps Format

// 0: Floor
// 1: Wall
// 2: Sword Chest
// 3: Shield Chest
// 4: Potion Chest
// 5: Trap Chest
// 8: Ladder
// 9: Player Spawn Location

local map1 = {
9,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,1,1,1,0,2,0,1,0,1,0,0,4,1,0,0,0,1,0,1,0,1,1,1,0,0,1,1,0,1,0,0,0,1,5,0,1,0,0,1,1,1,0,1,1,0,0,0,1,1,0,0,0,0,8,0,1,0,1,5,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,
}

local map2 = {
8,0,0,0,0,0,0,0,0,4,1,1,1,1,1,1,1,0,1,1,0,0,0,1,0,0,0,0,0,0,0,9,0,1,0,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,1,0,1,1,1,1,1,5,1,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1,0,1,4,3,0,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,
}

local map3 = {
0,0,0,0,0,0,0,0,0,9,0,1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,3,1,1,1,0,1,4,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,1,1,1,5,1,1,1,0,1,2,0,0,0,0,0,0,0,0,0,0,8,1,0,1,0,1,0,1,1,1,
}

local map4 = {
9,0,0,0,0,0,0,0,0,0,1,1,1,1,1,5,1,1,1,0,0,0,0,8,1,0,0,0,0,0,0,1,4,1,1,0,1,1,1,1,0,1,1,1,1,0,1,0,2,0,0,0,0,0,1,0,1,0,1,0,5,1,1,0,1,0,1,0,1,0,0,0,0,0,1,0,1,4,3,0,0,1,1,1,1,0,1,1,1,5,0,0,0,0,0,0,5,0,5,0,
}

local map5 = {
2,1,8,1,1,1,1,1,1,1,0,1,0,1,5,0,0,0,0,0,0,1,0,1,1,1,1,0,1,0,0,0,0,1,1,0,0,0,1,0,1,1,0,1,1,0,1,1,1,0,0,0,0,1,9,0,1,0,0,0,0,1,1,1,1,1,1,0,1,0,0,1,0,0,0,4,1,4,1,0,0,1,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
}

local map6 = {
9,0,0,0,0,0,0,0,1,4,0,1,1,1,1,5,1,1,1,0,0,1,0,0,0,0,0,0,1,0,0,1,0,1,1,0,1,0,1,0,0,5,0,0,0,0,1,0,1,0,0,1,0,1,8,0,0,0,0,0,0,1,0,1,0,1,1,0,1,0,0,1,0,0,0,0,0,2,1,0,0,1,1,1,5,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
}

local map7 = {
3,0,0,0,0,0,0,0,0,8,0,1,0,1,1,1,1,1,1,1,0,0,0,1,0,0,0,1,4,0,0,1,1,1,0,9,0,1,0,0,0,0,0,1,0,0,0,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,4,0,0,0,0,1,0,0,0,1,1,1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,
}

local map8 = {
0,0,0,0,0,0,0,0,0,8,0,0,0,0,1,1,0,0,0,0,0,0,1,5,0,0,5,1,0,0,0,0,5,0,0,0,0,5,0,0,0,1,0,0,1,3,0,0,1,0,0,1,0,0,4,1,0,0,1,0,0,0,5,0,0,0,0,5,0,0,0,0,1,5,0,0,5,1,0,0,0,0,0,0,1,1,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,
}

local map9 = {
8,0,0,0,1,1,0,0,0,4,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,0,0,1,0,0,0,0,1,0,0,1,5,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,2,0,0,5,1,1,0,0,0,9,
}

local maps = {map1, map2, map3, map4, map5, map6, map7, map8, map9}

// Swords Format
// "X": Name of the weapon.
// X: Damage of the weapon.

local dagger = {"Dagger", 1}
local smallsword = {"Small Sword", 2}
local broadsword = {"Broadsword", 4}
local greatsword = {"Greatsword", 8}
local mastersword = {"Master Sword", 16}

local swords = {dagger, smallsword, broadsword, greatsword, mastersword}

// Shields format, same as swords except damage is now defense.

local potlid = {"Pot Lid", 10}
local smallshield = {"Small Shield", 20}
local shield = {"Shield", 35}
local metalshield = {"Metal Shield", 50}
local mirrorshield = {"Mirror Shield", 100}

local shields = {potlid, smallshield, shield, metalshield, mirrorshield}

// Healing format, same as the last two.

local smallhppotion = {"Small HP Potion", 35}
local hppotion = {"HP Potion", 75}
local bighppotion = {"Big HP Potion", 125}

local potions = {smallhppotion, hppotion, bighppotion}

// Thanks LJ Sonic, this is very useful.
local function blockToSector(x, y)
    return R_PointInSubsector(x * 64*FRACUNIT - FRACUNIT, y * 64*FRACUNIT - FRACUNIT).sector
end

local function P_BuildMap(p)
	if p.rpg
		p.rpg.map = maps[p.rpg.floor]
		for r=1,10
			for c=1,10
				local block = blockToSector(c, r)
				block.floorheight = 0
				for s in sectors.iterate
					if p.rpg.floor < #maps - ((#maps/2) + (#maps/4))
						local floor = "GFZFLR01"
						local texture = 1495
						s.floorpic = floor
						s.ceilingpic = floor
						for i=0,3
							local l = s.lines[i]
							l.frontside.bottomtexture = texture
							if l.backside
								l.backside.bottomtexture = texture
							end
						end
					elseif p.rpg.floor < #maps - (#maps/4)
						local floor = "THZFLR24"
						local texture = 2290
						s.floorpic = floor
						s.ceilingpic = floor
						for i=0,3
							local l = s.lines[i]
							l.frontside.bottomtexture = texture
							if l.backside
								l.backside.bottomtexture = texture
							end
						end
					elseif p.rpg.floor < #maps
						local floor = "CEZFLR06"
						local texture = 3100
						s.floorpic = floor
						s.ceilingpic = floor
						for i=0,3
							local l = s.lines[i]
							l.frontside.bottomtexture = texture
							if l.backside
								l.backside.bottomtexture = texture
							end
						end
					else
						local floor = "ERZRCKF1"
						local texture = 2500
						s.floorpic = floor
						s.ceilingpic = floor
						for i=0,3
							local l = s.lines[i]
							l.frontside.bottomtexture = texture
							if l.backside
								l.backside.bottomtexture = texture
							end
						end
					end
				end
				if p.rpg.map[block.tag] == 1
					block.floorheight = 64*FRACUNIT
				elseif p.rpg.map[block.tag] == 2
					P_SpawnMobj(c*(64*FRACUNIT)-32*FRACUNIT, r*(64*FRACUNIT)-32*FRACUNIT, 0, MT_ARMAGEDDON_BOX)
				elseif p.rpg.map[block.tag] == 3
					P_SpawnMobj(c*(64*FRACUNIT)-32*FRACUNIT, r*(64*FRACUNIT)-32*FRACUNIT, 0, MT_FORCE_BOX)
				elseif p.rpg.map[block.tag] == 4
					P_SpawnMobj(c*(64*FRACUNIT)-32*FRACUNIT, r*(64*FRACUNIT)-32*FRACUNIT, 0, MT_RING_BOX)
				elseif p.rpg.map[block.tag] == 5
					P_SpawnMobj(c*(64*FRACUNIT)-32*FRACUNIT, r*(64*FRACUNIT)-32*FRACUNIT, 0, MT_EGGMAN_BOX)
				elseif p.rpg.map[block.tag] == 8
					P_SpawnMobj(c*(64*FRACUNIT)-32*FRACUNIT, r*(64*FRACUNIT)-32*FRACUNIT, 0, MT_YELLOWSPRING)
				elseif p.rpg.map[block.tag] == 9
					P_TeleportMove(p.mo, c*(64*FRACUNIT)-32*FRACUNIT, r*(64*FRACUNIT)-32*FRACUNIT, 0)
				elseif p.rpg.map[block.tag] == 0
					if p.rpg.floor < #maps - ((#maps/2) + (#maps/4))
						if P_RandomRange(1,8) == 7
							P_SpawnMobj(c*(64*FRACUNIT)-32*FRACUNIT, r*(64*FRACUNIT)-32*FRACUNIT, 0, MT_REDCRAWLA)
						elseif P_RandomRange(1,8) == 3
							P_SpawnMobj(c*(64*FRACUNIT)-32*FRACUNIT, r*(64*FRACUNIT)-32*FRACUNIT, 0, MT_BLUECRAWLA)
						end
					elseif p.rpg.floor < #maps - (#maps/4)
						if P_RandomRange(1,10) == 1
							P_SpawnMobj(c*(64*FRACUNIT)-32*FRACUNIT, r*(64*FRACUNIT)-32*FRACUNIT, 0, MT_JETTGUNNER)
						elseif P_RandomRange(1,10) == 5
							P_SpawnMobj(c*(64*FRACUNIT)-32*FRACUNIT, r*(64*FRACUNIT)-32*FRACUNIT, 0, MT_SPINCUSHION)
						end
					elseif p.rpg.floor < #maps
						if P_RandomRange(1,12) == 2
							P_SpawnMobj(c*(64*FRACUNIT)-32*FRACUNIT, r*(64*FRACUNIT)-32*FRACUNIT, 0, MT_EGGGUARD)
						elseif P_RandomRange(1,12) == 8
							P_SpawnMobj(c*(64*FRACUNIT)-32*FRACUNIT, r*(64*FRACUNIT)-32*FRACUNIT, 0, MT_FACESTABBER)
						end
					end
				end
			end
		end
		
		if p.rpg.floor < #maps - ((#maps/2) + (#maps/4))
			S_ChangeMusic("lowflr", true, p)
		elseif p.rpg.floor < #maps - (#maps/4)
			S_ChangeMusic("midflr", true, p)
		elseif p.rpg.floor < #maps
			S_ChangeMusic("hiflr", true, p)
		else
			S_ChangeMusic("topflr", true, p)
		end
	end	
end

local function P_RPGVars(p)
	if p.rpg == nil
		p.rpg = {}
		
		p.rpg.floor = 1
		p.rpg.map = maps[p.rpg.floor]
		
		p.rpg.level = 1
		p.rpg.xp = 0
		p.rpg.nextxp = 100
		p.rpg.maxhp = 90
		
		p.rpg.swordnum = 1
		p.rpg.shieldnum = 1
		p.rpg.inventory = {potions[1]}
	end
		
	p.rpg.hp = p.rpg.maxhp 
	p.mo.scale = FRACUNIT/4
	
end

local function P_LoadArray(p, filename)
	local thing = io.openlocal(filename, "r+")
	local stringy = thing:read("*a")
	print(stringy)
	local maparray = {}
	for i=0,10
		local array = {}
		for k=0,20
			if string.sub(stringy, k, k) ~= ","
				table.insert(maparray, tonumber(string.sub(stringy, k+(20*i), k+(20*i))))
			end
		end
	end
	table.insert(maps, maparray)
	p.rpg.floor = #maps
	thing:close()
end

COM_AddCommand("addgamefloor", function(p, arg)
	local testfile = io.openlocal(arg, "r+")
	
	if testfile ~= nil
		P_LoadArray(p, arg)
	else
		CONS_Printf(p, "There is no file with this filename!")
	end
end)

COM_AddCommand("loadgamefloor", function(p, arg)
	if maps[tonumber(arg)] ~= nil
		p.rpg.floor = tonumber(arg)
		for mob in mobjs.iterate()
			if (mob.type == MT_YELLOWSPRING) or (mob.type == MT_EGGMAN_BOX) or (mob.type == MT_ARMAGEDDON_BOX) or (mob.type == MT_FORCE_BOX) or (mob.type == MT_RING_BOX) or (mob.flags & MF_ENEMY)
				P_RemoveMobj(mob)
			end
		end
		P_BuildMap(p)
		return false
	else
		CONS_Printf(p, "Invalid floor number!")
	end
end)

addHook("PlayerSpawn", function(p)
	if mapheaderinfo[gamemap].lvlttl == "Dungeon Crawler"
	
		P_RPGVars(p)
		
		P_BuildMap(p)
	
	end
end)

addHook("PlayerThink", function(p)
	if p.mo and p.mo.valid
		if p.rpg
			p.powers[pw_shield] = SH_NONE
			p.rings = 1		
			if (p.mo.eflags & MFE_SPRUNG)
				if maps[p.rpg.floor+1] == nil
					G_ExitLevel(1100, 0)
					return true
				end
				for mob in mobjs.iterate()
					if (mob.type == MT_YELLOWSPRING) or (mob.type == MT_EGGMAN_BOX) or (mob.type == MT_ARMAGEDDON_BOX) or (mob.type == MT_FORCE_BOX) or (mob.type == MT_RING_BOX) or (mob.flags & MF_ENEMY)
						P_RemoveMobj(mob)
					end
				end
				p.rpg.floor = $ + 1
				P_RPGVars(p)
				P_BuildMap(p)
			end
			if p.rpg.xp >= p.rpg.nextxp
				p.rpg.level = $ + 1
				p.rpg.xp = 0
				p.rpg.nextxp = $ + (P_RandomRange(75,100) * p.rpg.level)
				p.rpg.maxhp = $ + (P_RandomRange(4,7) * p.rpg.level)
				p.rpg.hp = p.rpg.maxhp
			end
			if not (p.cmd.buttons & BT_CUSTOM3)
				p.c3ready = true
				p.c3tap = false
			elseif p.c3ready
				p.c3ready = false
				p.c3tap = true
			else
				p.c3tap = false
			end
			
			p.rpg.sword = swords[p.rpg.swordnum]
			p.rpg.shield = shields[p.rpg.shieldnum]
			
			if p.c3tap
				if p.rpg.hp < p.rpg.maxhp
					local inv = p.rpg.inventory
					if #inv > 0
						local item = inv[#inv]
						p.rpg.hp = $+item[2]
						table.remove(inv, #inv)
					else
						S_StartSound(p.mo, sfx_lose, p)
					end
				else
					S_StartSound(p.mo, sfx_lose, p)
				end
			end
			
			if p.rpg.maxhp > 999
				p.rpg.maxhp = 999
			end
			
			if p.rpg.hp > p.rpg.maxhp
				p.rpg.hp = p.rpg.maxhp
			end
			if p.rpg.hp < 1
				p.rpg.hp = 0
				P_DamageMobj(p.mo, nil, nil, 100, DMG_INSTAKILL)
			end
		end
	end
end)

addHook("MobjSpawn", function(mo)
	if (mo.flags & MF_ENEMY)
		for p in players.iterate
			if p.rpg
				mo.scale = FRACUNIT/4
				mo.color = P_RandomRange(1,68)
				mo.customhp = P_RandomRange(p.rpg.floor, p.rpg.floor*3)
			end
		end
	end
end)

addHook("MobjDamage", function(mo, inf, src, dmg, dmgtype)
	if mo and mo.valid
		if src and src.valid
			if mo.player
				if mo.player.rpg
					if (src.flags & MF_ENEMY)
						if ((P_RandomRange(10*src.health,25*src.health) * mo.player.rpg.floor) - mo.player.rpg.shield[2]) > 0
							mo.player.rpg.hp = $ - ((P_RandomRange(10*src.health,25*src.health) * mo.player.rpg.floor) - mo.player.rpg.shield[2])
						end
					else
						if dmgtype == DMG_INSTAKILL
							return true
						else
							mo.player.rpg.hp = $ - (P_RandomRange(10, 25) * mo.player.rpg.floor)
						end
					end
				end
			end
		end
	end
end, MT_PLAYER)

addHook("MobjDeath", function(mo, inf, src)
	if (mo.flags & MF_ENEMY)
		if src and src.valid
			if src.type == MT_PLAYER
				if src.player
					if src.player.rpg
						src.player.rpg.xp = $ + (P_RandomRange(10,15) * src.player.rpg.floor)
					end
				end
			end
		end
	end
end)

addHook("MobjDamage", function(mo, inf, src)
	if (mo.flags & MF_ENEMY)
		if src and src.valid
			if src.type == MT_PLAYER
				if src.player
					if src.player.rpg
						mo.customhp = $ - src.player.rpg.sword[2]
						
						if mo.customhp < 1
							mo.health = $-1
							
							if mo.health == 0
								P_KillMobj(mo, inf, src)
							end
						end
						
						return true
					end
				end
			end
		end
	end
end)

addHook("MobjDeath", function(mo, inf, src)
	if src and src.valid
		if src.type == MT_PLAYER
			if src.player and src.player.valid
				if src.player.rpg
					if src.player.rpg.swordnum < #swords
						src.player.rpg.swordnum = $ + 1
					end
					
					local block = blockToSector(mo.x, mo.y)
					src.player.rpg.map[block.tag] = 0		
				end
			end
		end
	end
end, MT_ARMAGEDDON_BOX)

addHook("MobjDeath", function(mo, inf, src)
	if src and src.valid
		if src.type == MT_PLAYER
			if src.player and src.player.valid
				if src.player.rpg
					local inv = src.player.rpg.inventory
					if #inv < 3
						if src.player.rpg.floor < 3
							table.insert(inv, potions[P_RandomRange(1,2)])
						else
							table.insert(inv, potions[P_RandomRange(1,3)])
						end
					end
							
					local block = blockToSector(mo.x, mo.y)
					src.player.rpg.map[block.tag] = 0		
				end
			end
		end
	end
end, MT_RING_BOX)

addHook("MobjDeath", function(mo, inf, src)
	if src and src.valid
		if src.type == MT_PLAYER
			if src.player and src.player.valid
				if src.player.rpg
					if src.player.rpg.shieldnum < #shields
						src.player.rpg.shieldnum = $ + 1
					end
					
					local block = blockToSector(mo.x, mo.y)
					src.player.rpg.map[block.tag] = 0	
				end
			end
		end
	end
end, MT_FORCE_BOX)

addHook("MobjDeath", function(mo, inf, src)
	if src and src.valid
		if src.type == MT_PLAYER
			if src.player and src.player.valid
				if (src.skin == "speccy") or (src.skin == "sspeccy")
					if src.player.spec
						if src.player.rpg
							src.player.rpg.hp = $ - P_RandomRange(10,35)
						end
					end
				end
			end
		end
	end
end, MT_EGGMAN_BOX)

hud.add(function(v, p)
		if mapheaderinfo[gamemap].lvlttl == "Dungeon Crawler"
			if p.rpg
				hud.disable("lives")
				hud.disable("score")
				hud.disable("rings")
				hud.disable("time")
				
				v.drawString(4, 4, "\x85HP: \x80"+p.rpg.hp+"/"+p.rpg.maxhp+" \x83Lives: \x80"+p.lives)
				v.drawFill(4, 14, ((90*p.rpg.maxhp/p.rpg.maxhp*90)/90)+4, 8, 44)
				v.drawFill(6, 16, (p.rpg.hp*90/p.rpg.maxhp*90)/90, 4, 33)
				v.drawString(4, 23, "LV. "+p.rpg.level, nil, "small")
				v.drawFill(4, 27, (100*p.rpg.nextxp/p.rpg.nextxp*100)/100, 2, 8)
				v.drawFill(4, 27, (p.rpg.xp*100/p.rpg.nextxp*100)/100, 2, 129)
				
				v.drawFill((320-64),16,4*12,4*12,0)
				
				for r=1,10
					for c=1,10
						local block = blockToSector(c, r)
						if (p.rpg.map[block.tag] == 0) or (p.rpg.map[block.tag] == 9)
							v.drawFill((320-64)+c*4,(5*12)-r*4,4,4,31)
						elseif p.rpg.map[block.tag] == 1
							v.drawFill((320-64)+c*4,(5*12)-r*4,4,4,0)
						elseif p.rpg.map[block.tag] == 2
							v.drawFill((320-64)+c*4,(5*12)-r*4,4,4,54)
						elseif p.rpg.map[block.tag] == 3
							v.drawFill((320-64)+c*4,(5*12)-r*4,4,4,153)
						elseif p.rpg.map[block.tag] == 4
							v.drawFill((320-64)+c*4,(5*12)-r*4,4,4,115)
						elseif p.rpg.map[block.tag] == 5
							v.drawFill((320-64)+c*4,(5*12)-r*4,4,4,35)
						elseif p.rpg.map[block.tag] == 8
							v.drawFill((320-64)+c*4,(5*12)-r*4,4,4,182)
						end
						v.drawFill((320-64)+(((p.mo.x/FRACUNIT/64)+1)*4),(5*12)-(((p.mo.y/FRACUNIT/64)+1)*4),4,4,73)
					end
				end
				
				v.drawFill(0, 200-64, 84, 64, 0)
				v.drawFill(0, 200-62, 82, 62, 31)
				v.drawString(2, 140, "WPN: "+p.rpg.sword[1], nil, "thin")
				v.drawString(2, 150, "SHD: "+p.rpg.shield[1], nil, "thin")
				v.drawFill(0, 159, 84, 2, 0)
				
				for i=1,3
					if p.rpg.inventory[i] ~= nil
						local item = p.rpg.inventory[i]
						v.drawString(4, 152+(i*12), item[1], nil, "thin") 
					end
				end
			end
		else
			hud.enable("lives")
		end
end)