-- Morshu's Stuff --
if not srb2p return end

-- Stats
charStats["pmorshu"] = {
	-- GENERAL
	name = "Morshu", -- Only for bots/enemies
	basehp = 60, -- Base HP/SP at level 1
	basesp = 40,
	persona = "rubyn", -- Determines actual stats
	melee_natk = "morshu_atk1", -- Normal melee attack
	wep = "morshu_weapon1", -- Default weapon
	weptype = WPT_PSYGLOVES, -- Equippable weapon type(s)
	atk = 30, -- Attack power of physical attacks
	acc = 85, -- Accuracy of physical attacks
	crit = 7, -- Critical rate of physical attacks
	supercolor_start = SKINCOLOR_SUPERGOLD1, -- If Super Form is applicable, will use this flash
	-- ANIMS
	anim_stand = {SPR_PLAY, A, 8, "SPR2_STND"}, -- Standing
	anim_stand_hurt = {SPR_PLAY, A, 1, "SPR2_STND"}, -- Standing (Low HP)
	anim_stand_bored = {SPR_PLAY, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, 8, "SPR2_WAIT"}, -- Standing (Rare)
	anim_guard = {SPR_PLAY, D, 1, "SPR2_RUN_"}, -- Guarding
	anim_move = {SPR_PLAY, A, B, C, D, E, F, 2, "SPR2_WALK"}, -- Moving
	anim_run = {SPR_PLAY, A, B, C, D, E, F, 2, "SPR2_RUN_"}, -- Running
	anim_atk = {SPR_PLAY, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 2, "SPR2_ROLL"}, -- Attacking
	anim_aoa_end = {SPR_PLAY, Z, Y, X, W, V, U, T, S, R, Q, P, O, N, M, L, K, J, I, H, G, F, E, D, C, B, A, 2, "SPR2_ROLL"}, -- Jumping out from All Out Attack
	anim_hurt = {SPR_PLAY, A, 35, "SPR2_PAIN"}, -- Taking damage
	anim_getdown = {SPR_PLAY, C, 1, "SPR2_PAIN"}, -- Knocked down from weakness/crit
	anim_downloop = {SPR_PLAY, C, 1, "SPR2_PAIN"}, -- Is down
	anim_getup = {SPR_PLAY, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 1, "SPR2_ROLL"}, -- Gets up from down
	anim_death = {SPR_PLAY, A, 30, "SPR2_DEAD"}, -- Dies
	anim_revive = {SPR_PLAY, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 1, "SPR2_ROLL"}, -- Gets revived
	anim_evoker = {SPR_PLAY, Q, 1, "SPR2_DASH"}, -- Uses evoker
	-- VOICES
	vfx_summon = {"sfx_morsum"},
    vfx_skill = {"sfx_morskl"},
    vfx_item = {"sfx_morsum", "sfx_morskl", "sfx_morcrt"},
    vfx_die = {"sfx_morhel"},
    vfx_heal = {"sfx_morhel"},
    vfx_healself = {"sfx_morhsf"},
    vfx_kill = {"sfx_morcrt"},
    vfx_1more = {"sfx_morhsf"},
    vfx_crit = {"sfx_morcrt"},
    vfx_aoaask = {"sfx_morsum"},
    vfx_aoado = {"sfx_moraoa"},
    vfx_aoarelent = {"sfx_morskl"},
    vfx_miss = {"sfx_morhel"},
    vfx_dodge = {"sfx_mordod"},
    vfx_win = {"sfx_morwin"},
    vfx_levelup = {"sfx_morcrt", "sfx_morhsf"},
	-- HUD/UI
	hudaoa = "H_MORAOA", -- Patch for All Out Attack hud
	hudbust = "H_MORBAR", -- Patch to draw on the stat hud
	icon = "ICO_MORS", -- Icon for net select and other menus
	hudcutin = "MORS_A", -- Cut in
	aoa_quote = "Come back when \nyou're a little \nMMMMM... skilled!", -- Something to say when in a Hold-Up
	tip = "Learns Expel, Fire, and Bless. A burly support oriented around saving others in need with Patra, Recarm, and defensive options. Use Lamp Oil to make way for his Fire skills which do fixed damage, but have higher Burn chances." -- A brief description of how the character generally plays in battle
}

VFX_freeslotC("pmorshu")

-- Persona
personaList["rubyn"] = {
	-- GENERAL
	name = "Rubyn",
	arcana = ARCANA_FORTUNE,
	sprite = SPR_RUBY,
	startframe = 0,
	anim_idle = {SPR_RUBY, A, 10},
	anim_atk = {SPR_RUBY, B, C, D, E, E, E, E, 2},
	-- STATS (At level 10)
	strength = 4,
	magic = 10,
	endurance = 9,
	luck = 11,
	agility = 6,
	-- AFFINITIES
	resist = bionis and ATK_FIRE|ATK_BLESS|ATK_EARTH or ATK_FIRE|ATK_BLESS,
	weak = bionis and ATK_CURSE|ATK_POISON or ATK_CURSE,
	-- SKILLSET
	skills = {
		{"mor_wares 1", 1}, {"kouha", 4},
		{"makakaja", 14}, {"patra", 15},
		{"makarakarn", 16}, {"recarm", 19},
		{"tetrakarn", 21}, {"mor_wandbreaker", 25},
		
		{"mor_wares 2", 28, "mor_wares 1"}, {"kouga", 34, "kouha"},
		{"mamakakaja", 37, "makakaja"}, {"me patra", 40, "patra"},
		{"samarecarm", 45, "recarm"}, {"tetraja", 49, "makarakarn"},
		{"mor_wares 3", 52, "mor_wares 2"}, {"kougaon", 57, "kouga"},
		
		{"mor_insta-heal", 62, "me patra"}, {"mor_discount wares", 66, "mor_wares 3"},
		{"mor_doublakarn", 70, "tetrakarn"}, {bionis and "divine judgement" or "mor_eternal light", 81, "kougaon"},
		
		// Wares I > Wares 2 > Wares 3 > Discount Wares
		// Kouha > Kouga > Kougaon > Eternal Light/Divine Judgement
		// Makakaja > Mamakakaja
		// Patra > Me Patra > Insta-Heal
		// Makarakarn > Tetraja
		// Recarm > Samarecarm
		// Tetrakarn > Doublakarn
		// Wandbreaker
	},
}

-- Dungeon Ability
DNG_Abilities["pmorshu"] = {
	jfunc = 	function(p)
					local mo = p.mo
					local bomb = P_SPMAngle(mo, MT_JUMPBOMB, mo.angle)
					S_StartSound(bomb, sfx_bombs)
				end,
	func =		function(p)
					local mo = p.mo
					if mo.p_abl
						if ((mo.eflags & MFE_VERTICALFLIP) and mo.momz < 0)
						or (not (mo.eflags & MFE_VERTICALFLIP) and mo.momz > 0)
						else
							mo.state = S_PLAY_FALL
							p.pflags = $ & ~PF_JUMPED
							mo.p_abl = false
						end
					end
				end,
}

-- Weapons
weaponsList["morshu_weapon1"] = {
	name = "Magic Hands",
	type = WPT_PSYGLOVES,
	rarity = 1,
	element = nil,
	atk = 300,
	acc = 85,
	crit = 7,
	desc = "Morshu's starting weapon. \nA pair of magician's gloves that somehow \nended up in Morshu's Lost and Found bin.",
	slot = "expel boost",
}

weaponsList["morshu_weapon2"] = {
	name = "Heated Hands",
	type = WPT_PSYGLOVES,
	rarity = 3,
	element = nil,
	atk = 900,
	acc = 85,
	crit = 7,
	desc = "Morshu's 2nd tier weapon. \nA pair of magician's gloves that works best \nwhen performing fire-based tricks.",
	ma = 1,
	lu = 1,
	slot = "burn boost",
}

weaponsList["morshu_weapon3"] = {
	name = "Luminous Hands",
	type = WPT_PSYGLOVES,
	rarity = 5,
	element = nil,
	atk = 1500,
	acc = 85,
	crit = 7,
	desc = "Morshu's 3rd tier weapon. \nA pair of magician's gloves that shine \nbrightly when the spotlight is on, bringing \neven more attention to the performer.",
	ma = 3,
	lu = 3,
	slot = "bless amp",
}

-- Velvet Shop
table.insert(shopList["velvet_shop_mp1"].weapons, {makeWeapon("morshu_weapon1", 10), 800, nil, 4})
table.insert(shopList["velvet_shop_mp1"].weapons, {makeWeapon("morshu_weapon2"), 4000, 3})
table.insert(shopList["velvet_shop_mp1"].weapons, {makeWeapon("morshu_weapon3"), 12500, 6})

-- Void Shop
table.insert(shopList["void_shop"].weapons, {makeWeapon("morshu_weapon1", 10), 700, nil, 6})
table.insert(shopList["void_shop"].weapons, {makeWeapon("morshu_weapon2"), 1500, 6, 12})
table.insert(shopList["void_shop"].weapons, {makeWeapon("morshu_weapon3"), 2000, 12})

-- Bionis Shop
if bionis
	table.insert(shopList["shop_bionis"].weapons, {makeWeapon("morshu_weapon1", 10), 800, nil, 4})
	table.insert(shopList["shop_bionis"].weapons, {makeWeapon("morshu_weapon2"), 4000, 3})
	table.insert(shopList["shop_bionis"].weapons, {makeWeapon("morshu_weapon3"), 12500, 6})
	table.insert(shopList["shop_ameno"].weapons, {makeWeapon("morshu_weapon2", 10), 8000, 3})
	table.insert(shopList["shop_ameno"].weapons, {makeWeapon("morshu_weapon3", 10), 25000, 6})
end

-- Skills
attackDefs["morshu_atk1"] = {
	name = "Pickpocket",
	type = ATK_PIERCE,
	power = 30,
	accuracy = 85,
	critical = 7,
	target = TGT_ENEMY,
	cost = CST_HP,
	cost = 0,
	desc = "Miniscule Pierce damage to \none enemy. \nSteals SP, EP, and Macca.",
	anim_norepel = true,
	physical = true,
	norandom = true,
	anim = 	function(mo, targets, hittargets, timer)
				local target = targets[1]
				local atarget = hittargets[1]
				if timer == 1
					ANIM_set(mo, mo.anim_run, true)
					mo.reachedtarget = false
					local cx = target.x + 168*cos(target.angle + ANG1*20)
					local cy = target.y + 168*sin(target.angle + ANG1*20)
					CAM_goto(server.P_BattleStatus[mo.battlen].cam, cx, cy, target.z + FRACUNIT*30, 70*FRACUNIT)
					CAM_angle(server.P_BattleStatus[mo.battlen].cam, R_PointToAngle2(cx, cy, target.x, target.y))
					S_StartSound(mo, sfx_zoom)
				end
				if not mo.reachedtarget
					mo.angle = R_PointToAngle2(mo.x, mo.y, target.x, target.y)
					P_InstaThrust(mo, mo.angle, FRACUNIT*36)
					if R_PointToDist2(mo.x, mo.y, target.x, target.y) < FRACUNIT*36
						ANIM_set(mo, mo.anim_atk, true)
						P_StartQuake(FRACUNIT*8, 4)
						mo.reachedtarget = true
						P_InstaThrust(mo, mo.angle, -FRACUNIT*6)
						mo.momz = 7*FRACUNIT
						playSound(mo.battlen, sfx_phys)
						for i = 1, 2
							createSplat(mo)
						end
					end
				else
					if P_IsObjectOnGround(mo)
					and not mo.momz
					and not mo.damagetime
						mo.damagetime = 1
						mo.momz = FRACUNIT
						P_InstaThrust(mo, mo.angle, FRACUNIT*90)
						S_StartSound(mo, sfx_spin)
					elseif mo.damagetime
						local trail = P_SpawnMobj(mo.x, mo.y, mo.z, MT_DUMMY)
						trail.color = mo.color
						mo.damagetime = $+1
						if mo.damagetime == 2
							damageObject(atarget)
							damageSP(atarget, 10)
							P_StartQuake(FRACUNIT*7, 4)
							playSound(mo.battlen, sfx_phys)
							for i = 1, 2
								createSplat(mo)
							end
						end
						if mo.damagetime == 10
						and atarget ~= mo
							mo.atk_attacker = mo
							damageSP(mo, -10)
							playSound(mo.battlen, sfx_heal)
							fillEmeraldGauge(mo, 20, true)
							playSound(mo.battlen, sfx_buff2)
							if not target.plyr
								local btl = server.P_BattleStatus[mo.battlen]
								btl.r_money = $+10
								BTL_logMessage(targets[1].battlen, "Earned +10 Macca!")
							end
						elseif mo.damagetime == 50
							mo.reachedtarget = nil
							mo.damagetime = nil
							return true
						end
					end
				end
			end,
	critanim = 	function(mo, targets, hittargets, timer)
					local target = targets[1]
					local atarget = hittargets[1]
					if timer == 1
						ANIM_set(mo, mo.anim_run, true)
						mo.reachedtarget = false
						local cx = target.x + 168*cos(target.angle + ANG1*20)
						local cy = target.y + 168*sin(target.angle + ANG1*20)
						CAM_goto(server.P_BattleStatus[mo.battlen].cam, cx, cy, target.z + FRACUNIT*30, 70*FRACUNIT)
						CAM_angle(server.P_BattleStatus[mo.battlen].cam, R_PointToAngle2(cx, cy, target.x, target.y))
						S_StartSound(mo, sfx_zoom)
					end
					if not mo.reachedtarget
						mo.angle = R_PointToAngle2(mo.x, mo.y, target.x, target.y)
						P_InstaThrust(mo, mo.angle, FRACUNIT*36)
						if R_PointToDist2(mo.x, mo.y, target.x, target.y) < FRACUNIT*36
							ANIM_set(mo, mo.anim_atk, true)
							P_StartQuake(FRACUNIT*8, 4)
							mo.reachedtarget = true
							P_InstaThrust(mo, mo.angle, -FRACUNIT*7)
							mo.momz = 8*FRACUNIT
							playSound(mo.battlen, sfx_phys)
							for i = 1, 2
								createSplat(mo)
							end
						end
					else
						if P_IsObjectOnGround(mo)
						and not mo.momz
						and not mo.damagetime
							local cam = server.P_BattleStatus[mo.battlen].cam
							local cx = mo.x + 128*cos(mo.angle - ANG1*25)
							local cy = mo.y + 128*sin(mo.angle - ANG1*25)
							P_TeleportMove(cam, cx, cy, mo.z + FRACUNIT*16)
							server.P_BattleStatus[mo.battlen].cam.angle = R_PointToAngle2(cam.x, cam.y, mo.x, mo.y)
							CAM_goto(cam, cam.x-24*cos(cam.angle), cam.y-24*sin(cam.angle), cam.z+FRACUNIT*5, 1*FRACUNIT)
							mo.damagetime = 1
							mo.momx, mo.momy, mo.momz = 0, 0, 0
							ANIM_set(mo, mo.anim_special1, true)
							S_StartSound(mo, sfx_spndsh)
						elseif mo.damagetime
							mo.damagetime = $+1
							if mo.damagetime == 13 or mo.damagetime == 21 or mo.damagetime == 28
								mo.rev = $ and $+1 or 1
								S_StartSound(mo, sfx_spndsh)
								ANIM_set(mo, mo.rev == 3 and mo.anim_special2 or mo.anim_special1, true)
							end
							if mo.damagetime >= 35
								if mo.damagetime == 35
									local cx = target.x + 512*cos(target.angle + ANG1*20)
									local cy = target.y + 512*sin(target.angle + ANG1*20)
									CAM_goto(server.P_BattleStatus[mo.battlen].cam, cx, cy, target.z + FRACUNIT*30, 128*FRACUNIT)
									CAM_angle(server.P_BattleStatus[mo.battlen].cam, R_PointToAngle2(cx, cy, target.x, target.y), ANG1*16)
									S_StartSound(mo, sfx_zoom)
									P_InstaThrust(mo, mo.angle, FRACUNIT*120)
									ANIM_set(mo, mo.anim_atk, true)
								else
									local trail = P_SpawnMobj(mo.x, mo.y, mo.z, MT_DUMMY)
									trail.color = mo.color
									if mo.damagetime == 36
										damageObject(atarget)
										damageSP(atarget, 20)
										P_SetObjectMomZ(atarget, 5*FRACUNIT)
										P_StartQuake(FRACUNIT*12, 7)
										playSound(mo.battlen, sfx_phys)
										for i = 1, 4
											createSplat(mo)
										end
									end
									if mo.damagetime == 40
									and atarget ~= mo
										mo.atk_attacker = mo
										damageSP(mo, -20)
										playSound(mo.battlen, sfx_heal)
										fillEmeraldGauge(mo, 40, true)
										playSound(mo.battlen, sfx_buff2)
										if not target.plyr
											local btl = server.P_BattleStatus[mo.battlen]
											btl.r_money = $+20
											BTL_logMessage(targets[1].battlen, "Earned +20 Macca!")
										end
									elseif mo.damagetime == 85
										mo.rev = nil
										mo.reachedtarget = nil
										mo.damagetime = nil
										return true
									end
								end
							end
						end
					end
				end,
}

attackDefs["mor_wares 1"] = {
	name = "Morshu's Wares I",
	type = ATK_PASSIVE,
	desc = "A set of tools that \nare essential for \nadventuring.",
	norogue = true,
	norandom = true,
	implicit = "mor_rope 1",
}

attackDefs["mor_rope 1"] = {
	name = "Rope I",
	type = ATK_BLESS,
	power = 100,
	accuracy = 25,
	costtype = CST_SP,
	instakill = true,
	luckbased = true,
	cost = 10,
	desc = "YEET that enemy outta \nthere! (Low chance)",
	target = TGT_ENEMY,
	implicit = "mor_bomb 1",
	norepel = true,
	norogue = true,
	norandom = true,
	anim = function(mo, targets, hittargets, timer)
		if timer == 1
			playSound(mo.battlen, sfx_rope)
		end
		local target = hittargets[1]
		if timer == 10
			local x = target.x + 48*cos(target.angle)
			local y = target.y + 48*sin(target.angle)
			playSound(mo.battlen, sfx_ropego)
			target.mudo_dum = P_SpawnMobj(x, y, target.z + FRACUNIT*32, MT_DUMMY)
			target.mudo_dum.state = S_INVISIBLE
			target.mudo_dum.tics = -1
			target.mudo_dum.angle = target.angle
		elseif timer == 25
			local m = P_SpawnMobj(target.mudo_dum.x, target.mudo_dum.y, target.z + FRACUNIT*32, MT_DUMMY)
			m.sprite = SPR_ROPE
			m.frame = A|FF_PAPERSPRITE
			m.angle = target.angle + ANG1*90
			m.tics = -1
			m.scale = FRACUNIT*3/2
			target.mudo = m
			m = P_SpawnMobj(target.mudo_dum.x, target.mudo_dum.y, target.z + FRACUNIT*32, MT_DUMMY)
			m.sprite = SPR_ROPE
			m.frame = A|FF_PAPERSPRITE
			m.angle = mo.angle + ANG1*90
			m.destscale = FRACUNIT*8
			m.scalespeed = FRACUNIT/6
			m.tics = 8
			m = P_SpawnMobj(target.mudo_dum.x, target.mudo_dum.y, target.z + FRACUNIT*32, MT_DUMMY)
			m.sprite = SPR_ROPE
			m.frame = B|FF_TRANS30|FF_PAPERSPRITE
			m.angle = mo.angle + ANG1*90
			m.destscale = FRACUNIT*8
			m.scalespeed = FRACUNIT/6
			m.tics = 8
		elseif timer == 50
			target.mudo.destscale = 1
			target.mudo.tics = 20
		elseif timer == 70
			damageObject(target)
			target.mudo = nil
			P_RemoveMobj(target.mudo_dum)
			target.mudo_dum = nil
		elseif timer == 110
			return true
		end
	end,
}

attackDefs["mor_bomb 1"] = {
	name = "Bomb I",
	type = ATK_FIRE,
	power = 50,
	accuracy = 999,
	costtype = CST_SP,
	cost = 20,
	status = COND_BURN,
	statuschance = 10,
	desc = "50 points of fire dmg \nto all enemies. \nMay inflict burn.",
	target = TGT_ALLENEMIES,
	implicit = "mor_lamp oil a",
	norogue = true,
	norandom = true,
	anim = function(mo, targets, hittargets, timer)
		if timer == 1
			playSound(mo.battlen, sfx_bombs)
		end
		for k,e in ipairs(hittargets)
			local target = e
			if timer >= 20 and timer <= 40
				if timer == 20
				or timer == 30
				or timer == 40
					playSound(mo.battlen, sfx_fire1)
				end
				if not (leveltime%3)
					local boom = P_SpawnMobj(target.x+P_RandomRange(-20, 20)*FRACUNIT, target.y+P_RandomRange(-20, 20)*FRACUNIT, target.z+P_RandomRange(-20, 20)*FRACUNIT, MT_BOSSEXPLODE)
					boom.scale = FRACUNIT*3/2
					boom.state = S_QUICKBOOM1
					for	 i = 1, 4
						local smoke = P_SpawnMobj(boom.x, boom.y, boom.z, MT_SMOKE)
						smoke.momx = P_RandomRange(-4, 4)*FRACUNIT
						smoke.momy = P_RandomRange(-4, 4)*FRACUNIT
						smoke.momz = P_RandomRange(2, 5)*FRACUNIT
					end
				end
				if timer == 30
					local sm = P_SpawnMobj(target.x, target.y, target.z, MT_SMOLDERING)
					sm.fuse = TICRATE
					if target.damagestate == DMG_DRAIN
						damageObject(target, -50)
					else
						damageObject(target, 50)
					end
				end
			end
		end
		if timer == 70 + (#targets-1)*10
			return true
		end
	end,
}

attackDefs["mor_lamp oil a"] = {
	name = "Lamp Oil",
	type = ATK_SUPPORT,
	costtype = CST_SP,
	cost = 5,
	desc = "Lower all enemies's Fire \nresistance to average \nfor 3 turns.",
	target = TGT_ALLENEMIES,
	debuff = true,
	norogue = true,
	norandom = true,
	anim = function(mo, targets, hittargets, timer)
		if timer == 1
			playSound(mo.battlen, sfx_lmpoil)
		end
		for i = 1, #hittargets
			local target = hittargets[i]
			local time = timer - (i-1)*6
			if time == 20
				playSound(mo.battlen, sfx_debuff)
				local orb = P_SpawnMobj(target.x, target.y, target.z, MT_DUMMY)
				orb.sprite = SPR_DBUF
				orb.frame = A|TR_TRANS30
				orb.scale = FRACUNIT*2
				orb.scalespeed = FRACUNIT/32
				orb.destscale = FRACUNIT/6
				orb.tics = 2*TICRATE-15
				orb.color = SKINCOLOR_LIME
			elseif time == 5+2*TICRATE
				buffStat(target, ATK_FIRE, -1)
				playSound(mo.battlen, sfx_bufu6)
				for i = 1, 64
					local m = P_SpawnMobj(target.x, target.y, target.z, MT_DUMMY)
					m.sprite = SPR_THOK
					m.frame = A
					m.tics = TICRATE
					m.fuse = TICRATE
					m.destscale = 1
					m.color = SKINCOLOR_LIME
					m.flags = MF_NOCLIPTHING|MF_NOCLIPHEIGHT
					m.momx = P_RandomRange(-64, 64)*FRACUNIT
					m.momy = P_RandomRange(-64, 64)*FRACUNIT
					m.momz = P_RandomRange(0, 64)*FRACUNIT
				end
			end
		end
		if timer == TICRATE*3 + (#hittargets-1)
			return true
		end
	end,
}

local regaffinities2 = ATK_PASSIVE|ATK_FIRE|ATK_ICE|ATK_WIND|ATK_ELEC|ATK_PSY|ATK_NUCLEAR|ATK_BLESS|ATK_CURSE
local bioaffinities2 = bionis and ATK_PASSIVE|ATK_FIRE|ATK_ICE|ATK_WIND|ATK_ELEC|ATK_PSY|ATK_NUCLEAR|ATK_BLESS|ATK_CURSE|ATK_EARTH|ATK_WATER|ATK_FOREST|ATK_POISON|ATK_METAL|ATK_GRAVITY
attackDefs["mor_wandbreaker"] = {
	name = "Wandbreaker",
	type = bioaffinities2 or regaffinities2,
	passive = PSV_SWORDBREAKER,
	desc = "25% chance to reduce Magical \ndamage against the party \nby 50%.",
	power = 50,
	accuracy = 25,
	norogue = true,
	norandom = true,
}

attackDefs["mor_wares 2"] = {
	name = "Morshu's Wares II",
	type = ATK_PASSIVE,
	desc = "A set of tools that \nare essential for \nadventuring.",
	norogue = true,
	norandom = true,
	implicit = "mor_rope 2",
}

attackDefs["mor_rope 2"] = {
	name = "Rope II",
	type = ATK_BLESS,
	power = 100,
	accuracy = 50,
	costtype = CST_SP,
	instakill = true,
	luckbased = true,
	cost = 10,
	desc = "YEET that enemy outta \nthere! (Medium chance)",
	target = TGT_ENEMY,
	implicit = "mor_bomb 2",
	norepel = true,
	norogue = true,
	norandom = true,
	anim = function(mo, targets, hittargets, timer)
		if timer == 1
			playSound(mo.battlen, sfx_rope)
		end
		local target = hittargets[1]
		if timer == 10
			local x = target.x + 48*cos(target.angle)
			local y = target.y + 48*sin(target.angle)
			playSound(mo.battlen, sfx_ropego)
			target.mudo_dum = P_SpawnMobj(x, y, target.z + FRACUNIT*32, MT_DUMMY)
			target.mudo_dum.state = S_INVISIBLE
			target.mudo_dum.tics = -1
			target.mudo_dum.angle = target.angle
		elseif timer == 25
			local m = P_SpawnMobj(target.mudo_dum.x, target.mudo_dum.y, target.z + FRACUNIT*32, MT_DUMMY)
			m.sprite = SPR_ROPE
			m.frame = A|FF_PAPERSPRITE
			m.angle = target.angle + ANG1*90
			m.tics = -1
			m.scale = FRACUNIT*3/2
			target.mudo = m
			m = P_SpawnMobj(target.mudo_dum.x, target.mudo_dum.y, target.z + FRACUNIT*32, MT_DUMMY)
			m.sprite = SPR_ROPE
			m.frame = A|FF_PAPERSPRITE
			m.angle = mo.angle + ANG1*90
			m.destscale = FRACUNIT*8
			m.scalespeed = FRACUNIT/6
			m.tics = 8
			m = P_SpawnMobj(target.mudo_dum.x, target.mudo_dum.y, target.z + FRACUNIT*32, MT_DUMMY)
			m.sprite = SPR_ROPE
			m.frame = B|FF_TRANS30|FF_PAPERSPRITE
			m.angle = mo.angle + ANG1*90
			m.destscale = FRACUNIT*8
			m.scalespeed = FRACUNIT/6
			m.tics = 8
		elseif timer == 50
			target.mudo.destscale = 1
			target.mudo.tics = 20
		elseif timer == 70
			damageObject(target)
			target.mudo = nil
			P_RemoveMobj(target.mudo_dum)
			target.mudo_dum = nil
		elseif timer == 110
			return true
		end
	end,
}

attackDefs["mor_bomb 2"] = {
	name = "Bomb II",
	type = ATK_FIRE,
	power = 100,
	accuracy = 999,
	costtype = CST_SP,
	cost = 20,
	status = COND_BURN,
	statuschance = 20,
	desc = "100 points of fire dmg \nto all enemies. \nMay inflict burn.",
	target = TGT_ALLENEMIES,
	implicit = "mor_lamp oil a",
	norogue = true,
	norandom = true,
	anim = function(mo, targets, hittargets, timer)
		if timer == 1
			playSound(mo.battlen, sfx_bombs)
		end
		for k,e in ipairs(hittargets)
			local target = e
			if timer == 10
			or timer == 14
				local boom = P_SpawnMobj(target.x+P_RandomRange(-20, 20)*FRACUNIT, target.y+P_RandomRange(-20, 20)*FRACUNIT, target.z+P_RandomRange(-20, 20)*FRACUNIT, MT_BOSSEXPLODE)
				boom.scale = FRACUNIT*3
				boom.state = S_QUICKBOOM1
				playSound(mo.battlen, sfx_fire1)
			elseif timer == 30
				local boom = P_SpawnMobj(target.x, target.y, target.z+20*FRACUNIT, MT_BOSSEXPLODE)
				boom.scale = FRACUNIT*4
				boom.state = S_PFIRE1
				playSound(mo.battlen, sfx_fire2)
				playSound(mo.battlen, sfx_fire1)
				if target.damagestate == DMG_DRAIN
					damageObject(target, -100)
				else
					damageObject(target, 100)
				end
				localquake(mo.battlen, FRACUNIT*32, 8)
				for i = 1, 8
					local smoke = P_SpawnMobj(boom.x, boom.y, boom.z, MT_SMOKE)
					smoke.scale = FRACUNIT*6
					smoke.momx = P_RandomRange(-5, 5)*FRACUNIT
					smoke.momy = P_RandomRange(-5, 5)*FRACUNIT
					smoke.momz = P_RandomRange(3, 6)*FRACUNIT
				end
				local sm = P_SpawnMobj(target.x, target.y, target.z, MT_SMOLDERING)
				sm.fuse = TICRATE/2
				sm.scale = target.scale*3/2
			end
		end
		if timer == 71 + (#targets-1)*10
			return true
		end
	end,
}

attackDefs["mor_wares 3"] = {
	name = "Morshu's Wares III",
	type = ATK_PASSIVE,
	desc = "A set of tools that \nare essential for \nadventuring.",
	norogue = true,
	norandom = true,
	implicit = "mor_rope 3a",
}

attackDefs["mor_rope 3a"] = {
	name = "Rope III",
	type = ATK_BLESS,
	power = 100,
	accuracy = 75,
	costtype = CST_SP,
	instakill = true,
	luckbased = true,
	cost = 10,
	desc = "YEET that enemy outta \nthere! (High chance)",
	target = TGT_ENEMY,
	implicit = "mor_bomb 3a",
	norepel = true,
	norogue = true,
	norandom = true,
	anim = function(mo, targets, hittargets, timer)
		if timer == 1
			playSound(mo.battlen, sfx_rope)
		end
		local target = hittargets[1]
		if timer == 10
			local x = target.x + 48*cos(target.angle)
			local y = target.y + 48*sin(target.angle)
			playSound(mo.battlen, sfx_ropego)
			target.mudo_dum = P_SpawnMobj(x, y, target.z + FRACUNIT*32, MT_DUMMY)
			target.mudo_dum.state = S_INVISIBLE
			target.mudo_dum.tics = -1
			target.mudo_dum.angle = target.angle
		elseif timer == 25
			local m = P_SpawnMobj(target.mudo_dum.x, target.mudo_dum.y, target.z + FRACUNIT*32, MT_DUMMY)
			m.sprite = SPR_ROPE
			m.frame = A|FF_PAPERSPRITE
			m.angle = target.angle + ANG1*90
			m.tics = -1
			m.scale = FRACUNIT*3/2
			target.mudo = m
			m = P_SpawnMobj(target.mudo_dum.x, target.mudo_dum.y, target.z + FRACUNIT*32, MT_DUMMY)
			m.sprite = SPR_ROPE
			m.frame = A|FF_PAPERSPRITE
			m.angle = mo.angle + ANG1*90
			m.destscale = FRACUNIT*8
			m.scalespeed = FRACUNIT/6
			m.tics = 8
			m = P_SpawnMobj(target.mudo_dum.x, target.mudo_dum.y, target.z + FRACUNIT*32, MT_DUMMY)
			m.sprite = SPR_ROPE
			m.frame = B|FF_TRANS30|FF_PAPERSPRITE
			m.angle = mo.angle + ANG1*90
			m.destscale = FRACUNIT*8
			m.scalespeed = FRACUNIT/6
			m.tics = 8
		elseif timer == 50
			target.mudo.destscale = 1
			target.mudo.tics = 20
		elseif timer == 70
			damageObject(target)
			target.mudo = nil
			P_RemoveMobj(target.mudo_dum)
			target.mudo_dum = nil
		elseif timer == 110
			return true
		end
	end,
}

attackDefs["mor_bomb 3a"] = {
	name = "Bomb III",
	type = ATK_FIRE,
	power = 200,
	accuracy = 999,
	costtype = CST_SP,
	cost = 20,
	status = COND_BURN,
	statuschance = 30,
	desc = "200 points of fire dmg \nto all enemies. \nMay inflict burn.",
	target = TGT_ALLENEMIES,
	implicit = "mor_lamp oil a",
	norogue = true,
	norandom = true,
	anim = function(mo, targets, hittargets, timer)
		if timer == 1
			playSound(mo.battlen, sfx_bombs)
			mo.fangle = 0
			mo.fdist = 400
			mo.columns = {}
		end
		local j = #mo.columns
		while j
			local m = mo.columns[j]
			if not m or not m.valid
				j = $-1
				continue
			end
			for i = 1, 5
				local boom = P_SpawnMobj(m.x + P_RandomRange(-48, 48)*FRACUNIT, m.y + P_RandomRange(-48, 48)*FRACUNIT, m.z, MT_DUMMY)
				boom.state = S_QUICKBOOM1
				boom.momz = P_RandomRange(0, 48)*FRACUNIT
				boom.scale = FRACUNIT*3/2
			end
			localquake(mo.battlen, FRACUNIT*8, 1)
			j = $-1
		end
		for k,e in ipairs(hittargets)
			local target = e
			if timer == 17
				DoExplosion(target)
				if target.damagestate == DMG_DRAIN
					damageObject(target, -200)
				else
					damageObject(target, 200)
				end
				playSound(mo.battlen, sfx_megi5)
				if not target.plyr
					createSplat(mo)
					createSplat(mo)
				end
				localquake(mo.battlen, FRACUNIT*20, 20)
				for i=1,20
					local b = P_SpawnMobj(target.x, target.y, target.z+20*FRACUNIT, MT_DUMMY)
					b.momx = P_RandomRange(-8, 8)*FRACUNIT
					b.momy = P_RandomRange(-8, 8)*FRACUNIT
					b.momz = P_RandomRange(-8, 8)*FRACUNIT
					b.state = S_QUICKBOOM1
					b.scale = FRACUNIT*3
				end
			elseif timer >= 17 and timer < 45
				for i = 1, 12
					local boom = P_SpawnMobj(target.x + P_RandomRange(-64, 64)*FRACUNIT, target.y + P_RandomRange(-64, 64)*FRACUNIT, target.z, MT_DUMMY)
					boom.state = S_QUICKBOOM1
					boom.momz = P_RandomRange(0, 80)*FRACUNIT
					boom.scale = FRACUNIT*5
				end
			elseif timer == 30
				mo.fangle = (R_PointToAngle(target.x, target.y)) + ANG1*180
				mo.columns = {}
				local a = mo.fangle - ANG1*80
				for i = 1, 16
					local m = P_SpawnMobj(target.x, target.y, target.z, MT_DUMMY)
					P_InstaThrust(m, a, FRACUNIT*48)
					mo.columns[#mo.columns+1] = m
					m.state = S_INVISIBLE
					m.tics = TICRATE
					a = $+ ANG1*10
				end
			end
		end
		if timer == 45 + (#targets-1)*10
			mo.fangle = nil
			mo.columns = nil
			return true
		end
	end,
}

attackDefs["mor_insta-heal"] = {
	name = "Insta-Heal",
	type = ATK_PASSIVE,
	target = TGT_ALLALLIES,
	desc = "Remove status conditions \nfrom the party each \nturn.",
	passive = PSV_STARTTURN,
	norogue = true,
	norandom = true,
	anim = function(mo, targets, hittargets, timer)
		local colors = {SKINCOLOR_ORANGE, SKINCOLOR_LAVENDER, SKINCOLOR_EMERALD}
		for i = 1, #mo.allies do
			local target = mo.allies[i]
			if timer == 1
				if target.status_condition and target.status_condition < COND_HYPER
					cureStatus(target)
					playSound(mo.battlen, sfx_status)
					for j = 1, 16
						local orb = P_SpawnMobj(target.x, target.y, target.z, MT_DUMMY)
						orb.momx = P_RandomRange(-16, 16)<<FRACBITS
						orb.momy = P_RandomRange(-16, 16)<<FRACBITS
						orb.momz = P_RandomRange(-16, 16)<<FRACBITS
						orb.destscale = 0
						orb.frame = A
						orb.color = colors[P_RandomRange(1, #colors)]
					end
				end
			end
		end
		if timer == 20
			return true
		end
	end,
}

attackDefs["mor_discount wares"] = {
	name = "Discount Wares",
	type = ATK_PASSIVE,
	desc = "A set of adventuring tools \nthat are now less \ncostly to use.",
	norogue = true,
	norandom = true,
	implicit = "mor_rope 3b",
}

attackDefs["mor_rope 3b"] = {
	name = "Rope III",
	type = ATK_BLESS,
	power = 100,
	accuracy = 75,
	costtype = CST_SP,
	instakill = true,
	luckbased = true,
	cost = 5,
	desc = "YEET that enemy outta \nthere! (High chance)",
	target = TGT_ENEMY,
	implicit = "mor_bomb 3b",
	norepel = true,
	norogue = true,
	norandom = true,
	anim = function(mo, targets, hittargets, timer)
		if timer == 1
			playSound(mo.battlen, sfx_rope)
		end
		local target = hittargets[1]
		if timer == 10
			local x = target.x + 48*cos(target.angle)
			local y = target.y + 48*sin(target.angle)
			playSound(mo.battlen, sfx_ropego)
			target.mudo_dum = P_SpawnMobj(x, y, target.z + FRACUNIT*32, MT_DUMMY)
			target.mudo_dum.state = S_INVISIBLE
			target.mudo_dum.tics = -1
			target.mudo_dum.angle = target.angle
		elseif timer == 25
			local m = P_SpawnMobj(target.mudo_dum.x, target.mudo_dum.y, target.z + FRACUNIT*32, MT_DUMMY)
			m.sprite = SPR_ROPE
			m.frame = A|FF_PAPERSPRITE
			m.angle = target.angle + ANG1*90
			m.tics = -1
			m.scale = FRACUNIT*3/2
			target.mudo = m
			m = P_SpawnMobj(target.mudo_dum.x, target.mudo_dum.y, target.z + FRACUNIT*32, MT_DUMMY)
			m.sprite = SPR_ROPE
			m.frame = A|FF_PAPERSPRITE
			m.angle = mo.angle + ANG1*90
			m.destscale = FRACUNIT*8
			m.scalespeed = FRACUNIT/6
			m.tics = 8
			m = P_SpawnMobj(target.mudo_dum.x, target.mudo_dum.y, target.z + FRACUNIT*32, MT_DUMMY)
			m.sprite = SPR_ROPE
			m.frame = B|FF_TRANS30|FF_PAPERSPRITE
			m.angle = mo.angle + ANG1*90
			m.destscale = FRACUNIT*8
			m.scalespeed = FRACUNIT/6
			m.tics = 8
		elseif timer == 50
			target.mudo.destscale = 1
			target.mudo.tics = 20
		elseif timer == 70
			damageObject(target)
			target.mudo = nil
			P_RemoveMobj(target.mudo_dum)
			target.mudo_dum = nil
		elseif timer == 110
			return true
		end
	end,
}

attackDefs["mor_bomb 3b"] = {
	name = "Bomb III",
	type = ATK_FIRE,
	power = 200,
	accuracy = 999,
	costtype = CST_SP,
	cost = 10,
	status = COND_BURN,
	statuschance = 30,
	desc = "200 points of fire dmg \nto all enemies. \nMay inflict burn.",
	target = TGT_ALLENEMIES,
	implicit = "mor_lamp oil b",
	norogue = true,
	norandom = true,
	anim = function(mo, targets, hittargets, timer)
		if timer == 1
			playSound(mo.battlen, sfx_bombs)
			mo.fangle = 0
			mo.fdist = 400
			mo.columns = {}
		end
		local j = #mo.columns
		while j
			local m = mo.columns[j]
			if not m or not m.valid
				j = $-1
				continue
			end
			for i = 1, 5
				local boom = P_SpawnMobj(m.x + P_RandomRange(-48, 48)*FRACUNIT, m.y + P_RandomRange(-48, 48)*FRACUNIT, m.z, MT_DUMMY)
				boom.state = S_QUICKBOOM1
				boom.momz = P_RandomRange(0, 48)*FRACUNIT
				boom.scale = FRACUNIT*3/2
			end
			localquake(mo.battlen, FRACUNIT*8, 1)
			j = $-1
		end
		for k,e in ipairs(hittargets)
			local target = e
			if timer == 17
				DoExplosion(target)
				if target.damagestate == DMG_DRAIN
					damageObject(target, -200)
				else
					damageObject(target, 200)
				end
				playSound(mo.battlen, sfx_megi5)
				if not target.plyr
					createSplat(mo)
					createSplat(mo)
				end
				localquake(mo.battlen, FRACUNIT*20, 20)
				for i=1,20
					local b = P_SpawnMobj(target.x, target.y, target.z+20*FRACUNIT, MT_DUMMY)
					b.momx = P_RandomRange(-8, 8)*FRACUNIT
					b.momy = P_RandomRange(-8, 8)*FRACUNIT
					b.momz = P_RandomRange(-8, 8)*FRACUNIT
					b.state = S_QUICKBOOM1
					b.scale = FRACUNIT*3
				end
			elseif timer >= 17 and timer < 45
				for i = 1, 12
					local boom = P_SpawnMobj(target.x + P_RandomRange(-64, 64)*FRACUNIT, target.y + P_RandomRange(-64, 64)*FRACUNIT, target.z, MT_DUMMY)
					boom.state = S_QUICKBOOM1
					boom.momz = P_RandomRange(0, 80)*FRACUNIT
					boom.scale = FRACUNIT*5
				end
			elseif timer == 30
				mo.fangle = (R_PointToAngle(target.x, target.y)) + ANG1*180
				mo.columns = {}
				local a = mo.fangle - ANG1*80
				for i = 1, 16
					local m = P_SpawnMobj(target.x, target.y, target.z, MT_DUMMY)
					P_InstaThrust(m, a, FRACUNIT*48)
					mo.columns[#mo.columns+1] = m
					m.state = S_INVISIBLE
					m.tics = TICRATE
					a = $+ ANG1*10
				end
			end
		end
		if timer == 45 + (#targets-1)*10
			mo.fangle = nil
			mo.columns = nil
			return true
		end
	end,
}

attackDefs["mor_lamp oil b"] = {
	name = "Lamp Oil",
	type = ATK_SUPPORT,
	costtype = CST_SP,
	cost = 1,
	desc = "Lower all enemies's Fire \nresistance to average \nfor 3 turns.",
	target = TGT_ALLENEMIES,
	debuff = true,
	norogue = true,
	norandom = true,
	anim = function(mo, targets, hittargets, timer)
		if timer == 1
			playSound(mo.battlen, sfx_lmpoil)
		end
		for i = 1, #hittargets
			local target = hittargets[i]
			local time = timer - (i-1)*6
			if time == 20
				playSound(mo.battlen, sfx_debuff)
				local orb = P_SpawnMobj(target.x, target.y, target.z, MT_DUMMY)
				orb.sprite = SPR_DBUF
				orb.frame = A|TR_TRANS30
				orb.scale = FRACUNIT*2
				orb.scalespeed = FRACUNIT/32
				orb.destscale = FRACUNIT/6
				orb.tics = 2*TICRATE-15
				orb.color = SKINCOLOR_LIME
			elseif time == 5+2*TICRATE
				buffStat(target, ATK_FIRE, -1)
				playSound(mo.battlen, sfx_bufu6)
				for i = 1, 64
					local m = P_SpawnMobj(target.x, target.y, target.z, MT_DUMMY)
					m.sprite = SPR_THOK
					m.frame = A
					m.tics = TICRATE
					m.fuse = TICRATE
					m.destscale = 1
					m.color = SKINCOLOR_LIME
					m.flags = MF_NOCLIPTHING|MF_NOCLIPHEIGHT
					m.momx = P_RandomRange(-64, 64)*FRACUNIT
					m.momy = P_RandomRange(-64, 64)*FRACUNIT
					m.momz = P_RandomRange(0, 64)*FRACUNIT
				end
			end
		end
		if timer == TICRATE*3 + (#hittargets-1)
			return true
		end
	end,
}

attackDefs["mor_doublakarn"] = {
	name = "Doublakarn",
	type = ATK_SUPPORT,
	costtype = CST_SP,
	cost = 32,
	target = TGT_ALLY,
	desc = "Give a barrier that \nrepels physical and magic \nattacks to one ally.",
	superbuff = true,
	makarakarn = true,
	tetrakarn = true,
	norogue = true,
	norandom = true,
	anim = 	function(mo, targets, hittargets, timer)
				local target = hittargets[1]
				if timer >= 10 and timer <= 40
					if leveltime%2 == 0
						local s = P_SpawnMobj(target.x, target.y, target.z, MT_DUMMY)
						s.sprite = SPR_MAGN
						s.tics = 1
					end
				elseif timer == 41
					local thok = P_SpawnMobj(target.x, target.y, target.z+5*FRACUNIT, MT_DUMMY)
					thok.state = S_INVISIBLE
					thok.tics = 1
					A_OldRingExplode(thok, MT_SUPERSPARK)
					playSound(mo.battlen, sfx_mirror)
					BTL_logMessage(targets[1].battlen, target.name.." has \na physical and magic barrier")
					target.makarakarn = true
					target.tetrakarn = true
				end
				if timer == 60
					return true
				end
			end,
}

if not bionis
	attackDefs["mor_eternal light"] = {
		name = "Eternal Light",
		type = ATK_BLESS,
		power = 800,
		accuracy = 95,
		costtype = CST_SP,
		cost = 32,
		desc = "Severe Bless dmg to one enemy.",
		target = TGT_ENEMY,
		norogue = true,
		norandom = true,
		hudfunc = 	function(v, mo, timer)
						if timer > 70
						and timer < 120
							local t = timer-70
							local p = "H_ATR"..t/2
							if v.patchExists(p)
								drawScreenwidePatch(v, v.cachePatch(p))
							end
						end
					end,
		anim = function(mo, targets, hittargets, timer)
			local target = hittargets[1]
			if timer == 15
				playSound(mo.battlen, sfx_zio5)
			end
			if timer >= 16
			and timer <= 20
				local s = P_SpawnMobj(target.x, target.y, target.z + target.height/2, MT_THOK)
				s.tics = -1
				s.sprite = SPR_NTHK
				s.frame = A|FF_FULLBRIGHT|FF_TRANS70
				s.scale = mo.scale/2
				s.destscale = mo.scale*16
				s.scalespeed = mo.scale/(12-((timer-16)*2))
				s.blendmode = AST_ADD
				s.fuse = 70 - timer
				local l = P_SpawnMobj(target.x, target.y, target.z, MT_THOK)
				l.tics = -1
				l.sprite = SPR_LRAY
				l.frame = A|FF_FULLBRIGHT|FF_TRANS90
				l.color = SKINCOLOR_PEACHY
				l.scale = mo.scale*5
				l.fuse = 70 - timer
			end
			if timer >= 16
			and timer <= 70
			and leveltime%3 == 0
				local range = 60
				if timer >= 50
					range = 100
				end
				local s = P_SpawnMobj(target.x + P_RandomRange(-range, range)*mo.scale, target.y + P_RandomRange(-range, range)*mo.scale, target.z + P_RandomRange(0, 100)*mo.scale, MT_SUPERSPARK)
			end
			if timer == 50
			or timer == 70
				for i = 1, #server.playerlist[mo.battlen]
					if server.playerlist[mo.battlen][i]
						P_FlashPal(server.playerlist[mo.battlen][i], 1, 2)
					end
				end
				localquake(mo.battlen, FRACUNIT*(timer == 50 and 16 or 32), 10)
			end
			if timer == 70
				damageObject(target)
				playSound(mo.battlen, sfx_hamas2)
				local r = P_SpawnMobj(target.x, target.y, target.z, MT_THOK)
				r.tics = -1
				r.sprite = SPR_LRAY
				r.frame = D|FF_FULLBRIGHT
				r.color = SKINCOLOR_PEACHY
				r.scale = mo.scale*5
				r.fuse = 120 - timer
				for i = 1, 10
					local range = 1024
					local z1 = P_SpawnMobj(target.x + P_RandomRange(-range, range)*mo.scale, target.y + P_RandomRange(-range, range)*mo.scale, target.z, MT_DUMMY)
					z1.sprite, z1.scale, z1.color = SPR_LRAY, target.scale*9/4, SKINCOLOR_PEACHY
					z1.frame = A|FF_FULLBRIGHT
					z1.blendmode = AST_ADD
					z1.destscale = target.scale
					z1.tics = $ + P_RandomRange(-1, 12)
				end
			elseif timer == 120
				return true
			end
		end,
	}
end

-- Fusion Skills
local MorshuFusions_BTL_splitSkills = BTL_splitSkills
BTL_splitSkills = function(v)
	if server.gamemode ~= GM_PVP 
	and server.gamemode ~= GM_VOIDRUN
		if v.skin == "pmorshu" 
		and #v.allies_noupdate
			if bionis and v.level >= 28
				for i = 1, #v.allies_noupdate
					if not v.allies_noupdate[i] or not v.allies_noupdate[i].valid then continue end
					if v.allies_noupdate[i].skin == "ember"
						table.insert(v.skills, "slush fund m")
					end
				end
			end
			if v.level >= 52
				for i = 1, #v.allies_noupdate
					if not v.allies_noupdate[i] or not v.allies_noupdate[i].valid then continue end
					if v.allies_noupdate[i].skin == "motobug"
						table.insert(v.skills, "mad inferno mor")
					end
				end
			end
			if v.level >= 81
				for i = 1, #v.allies_noupdate
					if not v.allies_noupdate[i] or not v.allies_noupdate[i].valid then continue end
					if v.allies_noupdate[i].skin == "link"
						table.insert(v.skills, "seraph lore m")
					end
				end
			end
		end
		if v.skin == "link" 
		and #v.allies_noupdate
			if v.level >= 81
				for i = 1, #v.allies_noupdate
					if not v.allies_noupdate[i] or not v.allies_noupdate[i].valid then continue end
					if v.allies_noupdate[i].skin == "pmorshu"
						table.insert(v.skills, "seraph lore l")
					end
				end
			end
		end
	end
	MorshuFusions_BTL_splitSkills(v)
end

attackDefs["slush fund m"] = {
	name = "Slush Fund",
	type = ATK_SUPPORT,
	power = 0,
	accuracy = 999,
	statuschance = 999,
	status = COND_BURN,
	costtype = CST_SP,
	luckbased = true,
	cost = 24,
	desc = "Fusion (w/ Ember) - \nInflicts Burn on all enemies. \nDeploys Aquaverse field.",
	target = TGT_ALLENEMIES,
	norogue = true,
	norandom = true,
	nometronome = true,
	norepel = true,
	nocast = function(targets, n, mo)
		local tgt = targets[n]
		local battlen = tgt.battlen
		local skincheck = "ember"
		local checkteam = tgt.enemies
		local found
		mo.fusionpartner = false
		local fusioncost = ATK_getSkillCost(mo, attackDefs["slush fund m"])
		local can_afford
		local incapacitated
		for i = 1, #checkteam do
			if checkteam[i].skin == skincheck
				found = true
				mo.fusionpartner = checkteam[i]
				if mo.fusionpartner.sp and mo.fusionpartner.sp >= fusioncost
					can_afford = true
				end
				if mo.fusionpartner.down 
				or mo.fusionpartner.status_condition == COND_SHOCK 
				or mo.fusionpartner.status_condition == COND_BRAINWASH 
				or mo.fusionpartner.status_condition == COND_SLEEP 
				or mo.fusionpartner.status_condition == COND_RAGE
					incapacitated = true
					break
				end
			end
		end
		if not found
			BTL_logMessage(battlen, "Ember is not alive.")
			playSound(battlen, sfx_not)
			return true
		elseif not can_afford
			BTL_logMessage(battlen, mo.fusionpartner.name.." has insufficient SP.")
			playSound(battlen, sfx_not)
			return true
		elseif incapacitated
			BTL_logMessage(battlen, mo.fusionpartner.name.." can't think for themselves right now.")
			playSound(battlen, sfx_not)
			return true
		end
	end,
	hudfunc = function(v, mo, timer)
		for i = 1, #mo.allies do
			local target = mo.allies[i]
			local firstt = TICRATE - timer
			local t = (TICRATE - (firstt*2))
			local t2 = (t<<FRACBITS)/3
			local t3 = t2
			local scale = t*FRACUNIT/6
			local trflag = V_70TRANS
			if firstt < 15
				trflag = V_90TRANS - (V_10TRANS)
			end
			if scale > 0
			and timer < TICRATE
				v.drawScaled(160<<FRACBITS, 100<<FRACBITS, scale, v.cachePatch("H_1M_B"), trflag)
				v.drawScaled(160<<FRACBITS, 100<<FRACBITS, scale, v.cachePatch("H_1M_C"))
			end
			t3 = FixedMul(t3, t3)
			t3 = $+ FixedMul(t3, t2)
			local pp = v.cachePatch(charStats[mo.skin] and charStats[mo.skin].hudaoa or "")
			if mo.status_condition == COND_SUPER
			and charStats[mo.skin] and charStats[mo.skin].hudsaoa
				pp = v.cachePatch(charStats[mo.skin].hudsaoa)
			end
			if timer <100
				v.drawScaled((150)<<FRACBITS + t3/3, (80)<<FRACBITS +t3/8, FRACUNIT/2, pp, V_SNAPTOLEFT, v.getColormap(TC_DEFAULT, mo.color))
				pp = v.cachePatch(charStats["ember"] and charStats["ember"].hudaoa or "pmorshu")
				if target.skin == "ember"
					if target.status_condition == COND_SUPER
					and charStats[target.skin] and charStats[target.skin].hudsaoa
						pp = v.cachePatch(charStats[target.skin].hudsaoa)
					end
					v.drawScaled((150)<<FRACBITS - t3/3, (80)<<FRACBITS -t3/7, FRACUNIT/2, pp, V_SNAPTOLEFT, v.getColormap(TC_DEFAULT, target.color))
				end
			end
		end
	end,
	anim = function(mo, targets, hittargets, timer)
			for i = 1, #mo.allies do
				local target = mo.allies[i]
				if timer == 1
					if target.skin == "ember"
						VFX_Play(target, VFX_AOADO)
						local fusioncost = ATK_getSkillCost(mo, attackDefs["slush fund m"])
						damageSP(target, fusioncost)
					end
				elseif timer >= 1
					if target.skin == "pmorshu"
						summonAura(target, SKINCOLOR_TEAL)
					end
					if target.skin == "ember"
						summonAura(target, SKINCOLOR_TEAL)
					end
				end
			end
			if timer == 1
				mo.fangle = 0
				mo.fdist = 400
				mo.columns = {}
				playSound(mo.battlen, sfx_aoado)
				VFX_Play(target, VFX_AOADO)
			end
			for i = 1, #hittargets
				local target = hittargets[i]
				local t = timer - (i-1)*6
				if t == 10
					playSound(mo.battlen, sfx_absorb)
				end
				if t <= 30
					local thok = P_SpawnMobj(target.x+P_RandomRange(-70, 70)*FRACUNIT, target.y+P_RandomRange(-70, 70)*FRACUNIT, target.z+P_RandomRange(0, 50)*FRACUNIT, MT_DUMMY)
					thok.state = S_CDUST1
					thok.momz = P_RandomRange(3, 10)*FRACUNIT
					thok.color = SKINCOLOR_ORANGE
					thok.tics = P_RandomRange(10, 35)
					thok.scale = FRACUNIT*3/2
				end
				if t == 20
					damageObject(target)
					startField(target, FLD_AQUAVERSE, 4)
				end
			end
			if timer == 42 + (#hittargets-1)*6
				return true
			end
		end,
}

attackDefs["mad inferno mor"] = {
	name = "Mad Inferno",
	type = ATK_FIRE,
	power = 1260,
	accuracy = 95,
	costtype = CST_SP,
	cost = 16,
	status = COND_BURN,
	statuschance = 9999,
	desc = "Fusion (w/ Motobug) - \nx3 Medium Fire dmg to one enemy. \nGuarantees Burn if Morshu initiates.",
	target = TGT_ENEMY,
	hits = 3,
	norogue = true,
	norandom = true,
	nometronome = true,
	nocast = function(targets, n, mo)
		local tgt = targets[n]
		local battlen = tgt.battlen
		local skincheck = "motobug"
		local checkteam = tgt.enemies
		local found
		mo.fusionpartner = false
		local fusioncost = ATK_getSkillCost(mo, attackDefs["mad inferno mor"])
		local can_afford
		local incapacitated
		for i = 1, #checkteam do
			if checkteam[i].skin == skincheck
				found = true
				mo.fusionpartner = checkteam[i]
				if mo.fusionpartner.sp and mo.fusionpartner.sp >= fusioncost
					can_afford = true
				end
				if mo.fusionpartner.down 
				or mo.fusionpartner.status_condition == COND_SHOCK 
				or mo.fusionpartner.status_condition == COND_BRAINWASH 
				or mo.fusionpartner.status_condition == COND_SLEEP 
				or mo.fusionpartner.status_condition == COND_RAGE
					incapacitated = true
					break
				end
			end
		end
		if not found
			BTL_logMessage(battlen, "Motobug is not alive.")
			playSound(battlen, sfx_not)
			return true
		elseif not can_afford
			BTL_logMessage(battlen, mo.fusionpartner.name.." has insufficient SP.")
			playSound(battlen, sfx_not)
			return true
		elseif incapacitated
			BTL_logMessage(battlen, mo.fusionpartner.name.." can't think for themselves right now.")
			playSound(battlen, sfx_not)
			return true
		end
	end,
	hudfunc = function(v, mo, timer)
		for i = 1, #mo.allies do
			local target = mo.allies[i]
			local firstt = TICRATE - timer
			local t = (TICRATE - (firstt*2))
			local t2 = (t<<FRACBITS)/3
			local t3 = t2
			local scale = t*FRACUNIT/6
			local trflag = V_70TRANS
			if firstt < 15
				trflag = V_90TRANS - (V_10TRANS)
			end
			if scale > 0
			and timer < TICRATE
				v.drawScaled(160<<FRACBITS, 100<<FRACBITS, scale, v.cachePatch("H_1M_B"), trflag)
				v.drawScaled(160<<FRACBITS, 100<<FRACBITS, scale, v.cachePatch("H_1M_C"))
			end
			t3 = FixedMul(t3, t3)
			t3 = $+ FixedMul(t3, t2)
			local pp = v.cachePatch(charStats[mo.skin] and charStats[mo.skin].hudaoa or "")
			if mo.status_condition == COND_SUPER
			and charStats[mo.skin] and charStats[mo.skin].hudsaoa
				pp = v.cachePatch(charStats[mo.skin].hudsaoa)
			end
			if timer <100
				v.drawScaled((150)<<FRACBITS + t3/3, (80)<<FRACBITS +t3/8, FRACUNIT/2, pp, V_SNAPTOLEFT, v.getColormap(TC_DEFAULT, mo.color))
				pp = v.cachePatch(charStats["motobug"] and charStats["motobug"].hudaoa or "pmorshu")
				if target.skin == "motobug"
					if target.status_condition == COND_SUPER
					and charStats[target.skin] and charStats[target.skin].hudsaoa
						pp = v.cachePatch(charStats[target.skin].hudsaoa)
					end
					v.drawScaled((150)<<FRACBITS - t3/3, (80)<<FRACBITS -t3/7, FRACUNIT/2, pp, V_SNAPTOLEFT, v.getColormap(TC_DEFAULT, target.color))
				end
			end
		end
		if timer > 80
		and timer < 90
			local t = timer-80
			local p = "H_ATR"..t/2
			if v.patchExists(p)
				drawScreenwidePatch(v, v.cachePatch(p))
			end
		end
	end,
	anim = function(mo, targets, hittargets, timer)
		for i = 1, #mo.allies do
			local target = mo.allies[i]
			if timer == 1
				if target.skin == "motobug"
					VFX_Play(target, VFX_AOADO)
					local fusioncost = ATK_getSkillCost(mo, attackDefs["mad inferno mor"])
					damageSP(target, fusioncost)
				end
			elseif timer >= 1
				if target.skin == "pmorshu"
					summonAura(target, SKINCOLOR_TEAL)
				end
				if target.skin == "motobug"
					summonAura(target, SKINCOLOR_TEAL)
				end
			end
		end
		if timer == 1
			mo.fangle = 0
			mo.fdist = 400
			mo.columns = {}
			playSound(mo.battlen, sfx_aoado)
			VFX_Play(target, VFX_AOADO)
		end
		local target = hittargets[1]
		if timer == 1
			mo.fangle = 0
			mo.fdist = 400
			mo.columns = {}
		elseif timer == 15 
			local cx = target.x + 90*cos(target.angle)
			local cy = target.y + 90*sin(target.angle)
			local h = P_SpawnMobj(cx, cy, target.z, MT_DUMMY)
			h.state = S_INVISIBLE
			h.tics = -1
			mo.columns[#mo.columns+1] = h
		elseif timer == 30 
			local cx = target.x - 90*cos(target.angle + ANGLE_45)
            local cy = target.y - 90*sin(target.angle + ANGLE_45)
			local h = P_SpawnMobj(cx, cy, target.z, MT_DUMMY)
			h.state = S_INVISIBLE
			h.tics = -1
			mo.columns[#mo.columns+1] = h
		elseif timer == 45 
			local cx = target.x - 90*cos(target.angle - ANGLE_45)
            local cy = target.y - 90*sin(target.angle - ANGLE_45)
			local h = P_SpawnMobj(cx, cy, target.z, MT_DUMMY)
			h.state = S_INVISIBLE
			h.tics = -1
			mo.columns[#mo.columns+1] = h
		elseif timer == 60 
			damageObject(target)
			playSound(mo.battlen, sfx_s3k4e)
			local cx = target.x + 90*cos(target.angle)
			local cy = target.y + 90*sin(target.angle)
			local boom = P_SpawnMobj(cx, cy, target.z+20*FRACUNIT, MT_BOSSEXPLODE)
            boom.scale = FRACUNIT*2
            boom.state = S_FBOMB_EXPL1
			mo.columns[#mo.columns-1] = boom
		elseif timer == 75 
			damageObject(target)
			playSound(mo.battlen, sfx_s3k4e)
			local cx = target.x - 90*cos(target.angle + ANGLE_45)
			local cy = target.y - 90*sin(target.angle + ANGLE_45)
			local boom = P_SpawnMobj(cx, cy, target.z+20*FRACUNIT, MT_BOSSEXPLODE)
            boom.scale = FRACUNIT*2
            boom.state = S_FBOMB_EXPL1
			mo.columns[#mo.columns-1] = boom
		elseif timer == 90 
			damageObject(target)
			playSound(mo.battlen, sfx_s3k4e)
			local cx = target.x - 90*cos(target.angle - ANGLE_45)
			local cy = target.y - 90*sin(target.angle - ANGLE_45)
			local boom = P_SpawnMobj(cx, cy, target.z+20*FRACUNIT, MT_BOSSEXPLODE)
            boom.scale = FRACUNIT*2
            boom.state = S_FBOMB_EXPL1
			mo.columns = {}
		end
		local j = #mo.columns
		while j
			local m = mo.columns[j]
			if not m or not m.valid
				j = $-1
				continue
			end
			for i = 1, 12
				local boom = P_SpawnMobj(m.x + P_RandomRange(-48, 48)*FRACUNIT, m.y + P_RandomRange(-48, 48)*FRACUNIT, m.z, MT_DUMMY)
				boom.state = S_QUICKBOOM1
				boom.momz = P_RandomRange(0, 48)*FRACUNIT
				boom.scale = FRACUNIT*3/2
			end
			localquake(mo.battlen, FRACUNIT*8, 1)
			if timer%4 == 0
				playSound(mo.battlen, sfx_fire1)
			end
			j = $-1
		end
		if timer == 120
			mo.fangle = nil
			mo.columns = nil
			return true
		end
	end,
}

attackDefs["seraph lore m"] = {
	name = "Seraph Lore",
	type = ATK_BLESS,
	power = 850,
	accuracy = 999,
	costtype = CST_SP,
	cost = 48,
	desc = "Fusion (w/ Link) - \nReduce HP of all foes by 4/5. \nInsta-kills if weak.",
	target = TGT_ALLENEMIES,
	norogue = true,
	norandom = true,
	nometronome = true,
	nocast = function(targets, n, mo)
		local tgt = targets[n]
		local battlen = tgt.battlen
		local skincheck = "link"
		local checkteam = tgt.enemies
		local found
		mo.fusionpartner = false
		local fusioncost = ATK_getSkillCost(mo, attackDefs["seraph lore m"])
		local can_afford
		local incapacitated
		for i = 1, #checkteam do
			if checkteam[i].skin == skincheck
				found = true
				mo.fusionpartner = checkteam[i]
				if mo.fusionpartner.sp and mo.fusionpartner.sp >= fusioncost
					can_afford = true
				end
				if mo.fusionpartner.down 
				or mo.fusionpartner.status_condition == COND_SHOCK 
				or mo.fusionpartner.status_condition == COND_BRAINWASH 
				or mo.fusionpartner.status_condition == COND_SLEEP 
				or mo.fusionpartner.status_condition == COND_RAGE
					incapacitated = true
					break
				end
			end
		end
		if not found
			BTL_logMessage(battlen, "Link is not alive.")
			playSound(battlen, sfx_not)
			return true
		elseif not can_afford
			BTL_logMessage(battlen, mo.fusionpartner.name.." has insufficient SP.")
			playSound(battlen, sfx_not)
			return true
		elseif incapacitated
			BTL_logMessage(battlen, mo.fusionpartner.name.." can't think for themselves right now.")
			playSound(battlen, sfx_not)
			return true
		end
	end,
	hudfunc = function(v, mo, timer)
		for i = 1, #mo.allies do
			local target = mo.allies[i]
			local firstt = TICRATE - timer
			local t = (TICRATE - (firstt*2))
			local t2 = (t<<FRACBITS)/3
			local t3 = t2
			local scale = t*FRACUNIT/6
			local trflag = V_70TRANS
			if firstt < 15
				trflag = V_90TRANS - (V_10TRANS)
			end
			if scale > 0
			and timer < TICRATE
				v.drawScaled(160<<FRACBITS, 100<<FRACBITS, scale, v.cachePatch("H_1M_B"), trflag)
				v.drawScaled(160<<FRACBITS, 100<<FRACBITS, scale, v.cachePatch("H_1M_C"))
			end
			t3 = FixedMul(t3, t3)
			t3 = $+ FixedMul(t3, t2)
			local pp = v.cachePatch(charStats[mo.skin] and charStats[mo.skin].hudaoa or "")
			if mo.status_condition == COND_SUPER
			and charStats[mo.skin] and charStats[mo.skin].hudsaoa
				pp = v.cachePatch(charStats[mo.skin].hudsaoa)
			end
			if timer <100
				v.drawScaled((150)<<FRACBITS + t3/3, (80)<<FRACBITS +t3/8, FRACUNIT/2, pp, V_SNAPTOLEFT, v.getColormap(TC_DEFAULT, mo.color))
				pp = v.cachePatch(charStats["link"] and charStats["link"].hudaoa or "pmorshu")
				if target.skin == "link"
					v.drawScaled((150)<<FRACBITS - t3/3, (80)<<FRACBITS -t3/7, FRACUNIT/2, pp, V_SNAPTOLEFT, v.getColormap(TC_DEFAULT, target.color))
				end
			end
		end
		if timer > 80
		and timer < 90
			local t = timer-80
			local p = "H_ATR"..t/2
			if v.patchExists(p)
				drawScreenwidePatch(v, v.cachePatch(p))
			end
		end
	end,
	anim = function(mo, targets, hittargets, timer)
		for i = 1, #mo.allies do
			local target = mo.allies[i]
			if timer == 1
				if target.skin == "link"
					VFX_Play(target, VFX_AOADO)
					local fusioncost = ATK_getSkillCost(mo, attackDefs["seraph lore m"])
					damageSP(target, fusioncost)
				end
			elseif timer >= 1
				if target.skin == "pmorshu"
					summonAura(target, SKINCOLOR_TEAL)
				end
				if target.skin == "link"
					summonAura(target, SKINCOLOR_TEAL)
				end
			end
		end
		if timer == 1
			mo.fangle = 0
			mo.fdist = 400
			mo.columns = {}
			playSound(mo.battlen, sfx_aoado)
			VFX_Play(target, VFX_AOADO)
		end
		if timer == 20
			local s = P_SpawnMobj(mo.x - 100*FRACUNIT, mo.y, mo.z + mo.scale*64, MT_DUMMY)
			s.color = SKINCOLOR_WHITE
			s.state = S_MEGISTAR1
			s.scale = FRACUNIT*4
			playSound(mo.battlen, sfx_hamas2)
		elseif timer == 30
			local a = P_SpawnMobj(mo.x - 100*FRACUNIT, mo.y, mo.z, MT_DUMMY)
			a.state = S_ARLE1
			a.colorize = true
			a.color = SKINCOLOR_PEACHY
			a.blendmode = AST_ADD
		elseif timer == 40
			local a = P_SpawnMobj(mo.x - 100*FRACUNIT, mo.y, mo.z, MT_DUMMY)
			a.state = S_ARLE3
			a.fuse = 40
			a.colorize = true
			a.color = SKINCOLOR_PEACHY
			a.blendmode = AST_ADD
			mo.megido2 = {}
			mo.megisphere = P_SpawnMobj(mo.x - 100*FRACUNIT, mo.y, mo.z + 300*FRACUNIT, MT_DUMMY)
			mo.megisphere.sprite = SPR_NTHK
			mo.megisphere.frame = A|FF_FULLBRIGHT
			mo.megisphere.tics = 40
			mo.megisphere.fuse = 40
			mo.megisphere.scale = $/64
			mo.megisphere.destscale = FRACUNIT*24
			mo.megisphere.scalespeed = $*2
			mo.megisphere.color = SKINCOLOR_PEACHY
		elseif timer > 40 and timer < 80
			if timer%3 == 0
				playSound(mo.battlen, sfx_hamas1)
			end
		elseif timer == 80
			local a = P_SpawnMobj(mo.x - 100*FRACUNIT, mo.y, mo.z, MT_DUMMY)
			a.state = S_ARLE5
			a.colorize = true
			a.color = SKINCOLOR_PEACHY
			a.blendmode = AST_ADD
			for k,v in ipairs(hittargets)
				local target = v
				lightningblast(target, SKINCOLOR_PEACHY, FRACUNIT*3/2)
				localquake(mo.battlen, FRACUNIT*8, 8)
				playSound(mo.battlen, sfx_hamas2)
				if not target.boss
					if target.damagestate == DMG_WEAK
						damageObject(target, 9999)
					elseif target.damagestate == DMG_RESIST
						damageObject(target, target.hp*1/2)
					elseif target.damagestate == DMG_DRAIN
						damageObject(target, 0)
					else
						damageObject(target, target.hp*4/5)
					end
				else
					damageObject(target)
				end
			end
		end
		if timer == 100
			return true
		end
	end,
}

attackDefs["seraph lore l"] = {
	name = "Seraph Lore",
	type = ATK_BLESS,
	power = 850,
	accuracy = 999,
	costtype = CST_SP,
	cost = 48,
	desc = "Fusion (w/ Morshu) - \nReduce HP of all foes by 4/5. \nInsta-kills if weak.",
	target = TGT_ALLENEMIES,
	norogue = true,
	norandom = true,
	nometronome = true,
	nocast = function(targets, n, mo)
		local tgt = targets[n]
		local battlen = tgt.battlen
		local skincheck = "pmorshu"
		local checkteam = tgt.enemies
		local found
		mo.fusionpartner = false
		local fusioncost = ATK_getSkillCost(mo, attackDefs["seraph lore l"])
		local can_afford
		local incapacitated
		for i = 1, #checkteam do
			if checkteam[i].skin == skincheck
				found = true
				mo.fusionpartner = checkteam[i]
				if mo.fusionpartner.sp and mo.fusionpartner.sp >= fusioncost
					can_afford = true
				end
				if mo.fusionpartner.down 
				or mo.fusionpartner.status_condition == COND_SHOCK 
				or mo.fusionpartner.status_condition == COND_BRAINWASH 
				or mo.fusionpartner.status_condition == COND_SLEEP 
				or mo.fusionpartner.status_condition == COND_RAGE
					incapacitated = true
					break
				end
			end
		end
		if not found
			BTL_logMessage(battlen, "Morshu is not alive.")
			playSound(battlen, sfx_not)
			return true
		elseif not can_afford
			BTL_logMessage(battlen, mo.fusionpartner.name.." has insufficient SP.")
			playSound(battlen, sfx_not)
			return true
		elseif incapacitated
			BTL_logMessage(battlen, mo.fusionpartner.name.." can't think for themselves right now.")
			playSound(battlen, sfx_not)
			return true
		end
	end,
	hudfunc = function(v, mo, timer)
		for i = 1, #mo.allies do
			local target = mo.allies[i]
			local firstt = TICRATE - timer
			local t = (TICRATE - (firstt*2))
			local t2 = (t<<FRACBITS)/3
			local t3 = t2
			local scale = t*FRACUNIT/6
			local trflag = V_70TRANS
			if firstt < 15
				trflag = V_90TRANS - (V_10TRANS)
			end
			if scale > 0
			and timer < TICRATE
				v.drawScaled(160<<FRACBITS, 100<<FRACBITS, scale, v.cachePatch("H_1M_B"), trflag)
				v.drawScaled(160<<FRACBITS, 100<<FRACBITS, scale, v.cachePatch("H_1M_C"))
			end
			t3 = FixedMul(t3, t3)
			t3 = $+ FixedMul(t3, t2)
			local pp = v.cachePatch(charStats[mo.skin] and charStats[mo.skin].hudaoa or "")
			if mo.status_condition == COND_SUPER
			and charStats[mo.skin] and charStats[mo.skin].hudsaoa
				pp = v.cachePatch(charStats[mo.skin].hudsaoa)
			end
			if timer <100
				v.drawScaled((150)<<FRACBITS + t3/3, (80)<<FRACBITS +t3/8, FRACUNIT/2, pp, V_SNAPTOLEFT, v.getColormap(TC_DEFAULT, mo.color))
				pp = v.cachePatch(charStats["pmorshu"] and charStats["pmorshu"].hudaoa or "link")
				if target.skin == "pmorshu"
					v.drawScaled((150)<<FRACBITS - t3/3, (80)<<FRACBITS -t3/7, FRACUNIT/2, pp, V_SNAPTOLEFT, v.getColormap(TC_DEFAULT, target.color))
				end
			end
		end
		if timer > 80
		and timer < 90
			local t = timer-80
			local p = "H_ATR"..t/2
			if v.patchExists(p)
				drawScreenwidePatch(v, v.cachePatch(p))
			end
		end
	end,
	anim = function(mo, targets, hittargets, timer)
		for i = 1, #mo.allies do
			local target = mo.allies[i]
			if timer == 1
				if target.skin == "pmorshu"
					VFX_Play(target, VFX_AOADO)
					local fusioncost = ATK_getSkillCost(mo, attackDefs["seraph lore l"])
					damageSP(target, fusioncost)
				end
			elseif timer >= 1
				if target.skin == "link"
					summonAura(target, SKINCOLOR_TEAL)
				end
				if target.skin == "pmorshu"
					summonAura(target, SKINCOLOR_TEAL)
				end
			end
		end
		if timer == 1
			mo.fangle = 0
			mo.fdist = 400
			mo.columns = {}
			playSound(mo.battlen, sfx_aoado)
			VFX_Play(target, VFX_AOADO)
		end
		if timer == 20
			local s = P_SpawnMobj(mo.x - 100*FRACUNIT, mo.y, mo.z + mo.scale*64, MT_DUMMY)
			s.color = SKINCOLOR_WHITE
			s.state = S_MEGISTAR1
			s.scale = FRACUNIT*4
			playSound(mo.battlen, sfx_hamas2)
		elseif timer == 30
			local a = P_SpawnMobj(mo.x - 100*FRACUNIT, mo.y, mo.z, MT_DUMMY)
			a.state = S_ARLE1
			a.colorize = true
			a.color = SKINCOLOR_PEACHY
			a.blendmode = AST_ADD
		elseif timer == 40
			local a = P_SpawnMobj(mo.x - 100*FRACUNIT, mo.y, mo.z, MT_DUMMY)
			a.state = S_ARLE3
			a.fuse = 40
			a.colorize = true
			a.color = SKINCOLOR_PEACHY
			a.blendmode = AST_ADD
			mo.megido2 = {}
			mo.megisphere = P_SpawnMobj(mo.x - 100*FRACUNIT, mo.y, mo.z + 300*FRACUNIT, MT_DUMMY)
			mo.megisphere.sprite = SPR_NTHK
			mo.megisphere.frame = A|FF_FULLBRIGHT
			mo.megisphere.tics = 40
			mo.megisphere.fuse = 40
			mo.megisphere.scale = $/64
			mo.megisphere.destscale = FRACUNIT*24
			mo.megisphere.scalespeed = $*2
			mo.megisphere.color = SKINCOLOR_PEACHY
		elseif timer > 40 and timer < 80
			if timer%3 == 0
				playSound(mo.battlen, sfx_hamas1)
			end
		elseif timer == 80
			local a = P_SpawnMobj(mo.x - 100*FRACUNIT, mo.y, mo.z, MT_DUMMY)
			a.state = S_ARLE5
			a.colorize = true
			a.color = SKINCOLOR_PEACHY
			a.blendmode = AST_ADD
			for k,v in ipairs(hittargets)
				local target = v
				lightningblast(target, SKINCOLOR_PEACHY, FRACUNIT*3/2)
				localquake(mo.battlen, FRACUNIT*8, 8)
				playSound(mo.battlen, sfx_hamas2)
				if not target.boss
					if target.damagestate == DMG_WEAK
						damageObject(target, 9999)
					elseif target.damagestate == DMG_RESIST
						damageObject(target, target.hp*1/2)
					elseif target.damagestate == DMG_DRAIN
						damageObject(target, 0)
					else
						damageObject(target, target.hp*4/5)
					end
				else
					damageObject(target)
				end
			end
		end
		if timer == 100
			return true
		end
	end,
}

-- Trait
personaList["rubyn"].trait = "wealth of koridai"

attackDefs["wealth of koridai"] = {
	name = "Wealth of Koridai",
	type = ATK_PASSIVE,
	desc = "Increase the amount of Macca earned \nat the end of the battle by 20%.",
	passive = PSV_ENDBATTLE,
	norogue = true,
	norandom = true,
	anim = function(mo, targets, hittargets, timer)
		local btl = server.P_BattleStatus[mo.battlen]
		btl.r_money = $*120/100
	end,
}

-- Jump Bomb Hook
addHook("MobjCollide", function(thing, tmthing)
	if thing and thing.valid and tmthing and tmthing.valid
	and tmthing.player 
	and thing.state == S_JUMPBOMB3	
	and thing.state != S_JUMPDETONATE
		thing.state = S_JUMPDETONATE
	end
end, MT_JUMPBOMB)