//-----note to character makers-----------//
//if forever reason you need to make it so you're character can't 
// change angle/aim please consider setting player.lockaim to true

freeslot("MT_ZTARGET",
"S_ZTAR0","S_ZTAR1","S_ZTAR2","S_ZTAR3",
"SPR_ZTRG"
)

mobjinfo[MT_ZTARGET] = {
	doomednum = -1,
	spawnhealth = 1000,
	spawnstate = S_ZTAR0,
	radius = 24*FRACUNIT,
	height = 32*FRACUNIT,
	damage = 1,
	speed = 100*FRACUNIT,
	flags = MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_SCENERY
}

//-------- Lock On console commands ---------------//
local lockonbuttonset = 2
COM_AddCommand("lockon_button", function(player, argument)
		
		if lockonbuttonset == nil
			lockonbuttonset = 2
		end
		local choice = lockonbuttonset
		if argument
			if argument == "1" or argument == "one"
				if lockonbuttonset == 1 then CONS_Printf(player, "lockon_button is already on Custom Button 1") return end
				lockonbuttonset = 1
				print("lock on is now set to Custom Button 1")
			elseif argument == "2" or argument == "two"
				if lockonbuttonset == 2 then CONS_Printf(player, "lockon_button is already on Custom Button 2") return end
				lockonbuttonset = 2
				print("lock on is now set to Custom Button 2")
			elseif argument == "3" or argument == "three"
				if lockonbuttonset == 3 then CONS_Printf(player, "lockon_button is already on Custom Button 3") return end
				lockonbuttonset = 3
				print("lock on is now set to Custom Button 3")
			else
				CONS_Printf(player, "sets the lock on to a Custom Button, valid arguments are 1, 2, 3 .Currently ".. choice)
			end
		else
			CONS_Printf(player, "sets the lock on to a Custom Button, valid arguments are 1, 2, 3 .Currently ".. choice)
		end
end, 0)

addHook("PreThinkFrame", function()
	for player in players.iterate do
		
		local mbj = player.mo
		if player.mo and player.mo.valid and player.locknontarget and player.locknontarget.valid and player.locknontarget.health then
		local t = player.locknontarget
		player.locknocheck = R_PointToAngle2(mbj.x, mbj.y, t.x, t.y)
		player.returntocenter = player.mo.angle
		end

	end
end)

addHook("ThinkFrame", function()
	for player in players.iterate do
	
	if player.mo.valid and player.mo and player.mo.skin == "sms" or
	player.mo.skin == "samus" or player.mo.skin == "basesamus" then
		return // dont lock on if your playing certain characters	
	end
	
	if lockonbuttonset == nil or lockonbuttonset == 2 then // default to BT_CUSTOM2
			player.lockonbutton = (player.cmd.buttons & BT_CUSTOM2)
	elseif lockonbuttonset == 1 then
			player.lockonbutton = (player.cmd.buttons & BT_CUSTOM1)
	elseif lockonbuttonset == 3 then
			player.lockonbutton = (player.cmd.buttons & BT_CUSTOM3)
	end
	
		// grdualy snape back to center
		if player.returntocenter != nil and player.mo.angle >= player.returntocenter-(ANG1/2900) and player.mo.angle <= player.returntocenter+(ANG1/2900)
		player.movetocenter = ANG1
		end
		if player.movetocenter and player.movetocenter != 0 then
		player.movetocenter = $+ANG2
		end
	
		if not player.lockonbutton then ---// BT_CUSTOM2 is default
			player.locktapready = true
			player.locktapping = false
		elseif player.locktapready then
			player.locktapping = true
			player.locktapready = false
		else
			player.locktapping = false
		end -- End new lines
				
		local mbj = player.mo
		
		if player.locktapping then // lock on by a function
			player.movetocenter = 0
			player.lockodelay = 1
			player.angeloverflow = 0
			player.angelaim = 0
			player.centeraim = 0
				if player.targetmark and player.targetmark.valid then
				player.targetmark.state = S_NULL
				end
			if player.locknontarget and player.locknontarget.valid and player.locknontarget then // remove old target to look for new one
			player.locknontarget = false
			else
			player.locknontarget = LO_LockOnToEnemies(mbj, player, 3990*mbj.scale)
				if player.locknontarget and player.locknontarget.valid
					player.targetmark = P_SpawnMobj(player.locknontarget.x, player.locknontarget.y, player.locknontarget.z, MT_ZTARGET)
					player.targetmark.target = player.locknontarget
					player.targetmark.creator = player
				end
			end
		end
				
		 if player.mo and player.mo.valid and player.locknontarget and player.locknontarget.valid and player.locknontarget.health
		 and not player.lockaim then // prevent some exploits
			local t = player.locknontarget
			player.locknonangle = R_PointToAngle2(mbj.x, mbj.y, t.x, t.y)
			player.aiming = R_PointToAngle2(0, 0, R_PointToDist2(mbj.x, mbj.y, t.x, t.y), ((t.z+(t.height/5)) - mbj.z)	)
			if player.aiming >= 518011616 then // limits how far the player will look vertically
				player.aiming = 518011615
			elseif player.aiming <= -518011616 then
				player.aiming = -518011615
			end
				if player.locknocheck and player.mo.angle != player.locknocheck then
				player.angeloverflow = (player.mo.angle - player.locknocheck)
				player.targetdistance = R_PointToDist2(t.x, t.y, mbj.x, mbj.y)
					if player.angeloverflow > 670240 and player.lockodelay >= 4 and player.centeraim >= 0 then
					player.angelaim = player.angeloverflow-player.movetocenter
					player.centeraim = 1 // snap to the center when moving camera back twards the target
						if player.angeloverflow > 1050571070 then 
						player.angelaim = 1050571070
						end
					elseif player.angeloverflow < -670240 and player.lockodelay >= 5 and player.centeraim <= 0 then
					player.angelaim = player.angeloverflow+player.movetocenter
					player.centeraim = -1
						if player.angeloverflow < -1050571070 then 
						player.angelaim = -1050571070
						end
					else
						if player.lockodelay and player.lockodelay <= 6 then 
							player.lockodelay = $+1
						end
						player.angelaim = FixedAngle(0)
						player.movetocenter = 0
						if player.centeraim != 0 then
							player.lockodelay = 1
							player.centeraim = 0
						end
					end
	
				end
				if player.pflags&PF_ANALOGMODE then
					player.angelaim = FixedAngle(0) // angle aim not needed for simple controls
				end
				if player.climbing <= 0 then // sets the angle after all calculations
				player.mo.angle = player.locknonangle+player.angelaim 
				player.thinkangle = player.locknonangle+player.angelaim
				end
			player.anglemod = player.angle
			player.locknonreset = true
			player.angeloverflow = 0
			player.angelaim = 0
		elseif player.locknonreset then
			player.aiming = 0
			player.lockodelay = 1
			player.angeloverflow = 0
			player.angelaim = 0
			player.locknonreset = false
			//player.targetmark.state = S_NULL //
		end
		player.angeloverflow = 0
		player.angelaim = 0
		
	end
end)

addHook("MobjThinker", function(mo)
	
	if mo.valid and mo.target and mo.target.valid  and mo.target.health then // setpostion if target is alive
	local heightadd = (mo.target.height/2)
		P_TeleportMove(mo, mo.target.x, mo.target.y, mo.target.z+heightadd)
	elseif mo.valid then
		mo.state = S_NULL 
	end
	
	if mo.valid and mo.creator.valid and mo.creator then
		local mbj = mo.creator.mo
		if mo.creator.centeraim == 1 then
			mo.state = S_ZTAR2
		elseif mo.creator.centeraim == -1 then
			mo.state = S_ZTAR3
		else
			mo.state = S_ZTAR1
		end
		if mo.creator.locknontarget.valid and mo.creator.valid and mbj.valid and (mbj.state == S_PLAY_DEAD or mbj.state == S_PLAY_DRWN) then 
		mo.creator.locknontarget = false
		mo.state = S_NULL
		end
		if mo ~= displayplayer.targetmark
			mo.flags2 = $ | MF2_DONTDRAW
		end
	elseif mo.valid then
		mo.state = S_NULL 
	end

end, MT_ZTARGET)

states[S_ZTAR0] = {SPR_NULL, 0|FF_FULLBRIGHT|TR_TRANS30, 1, none, 0, 0, S_ZTAR1}
states[S_ZTAR1] = {SPR_ZTRG, 0|FF_FULLBRIGHT|TR_TRANS30, 1, none, 0, 0, S_ZTAR1}
states[S_ZTAR2] = {SPR_ZTRG, 1|FF_FULLBRIGHT|TR_TRANS30, 1, none, 0, 0, S_ZTAR2}
states[S_ZTAR3] = {SPR_ZTRG, 2|FF_FULLBRIGHT|TR_TRANS30, 1, none, 0, 0, S_ZTAR3}