More NiGHTS Lua troubles

Status
Not open for further replies.

Latius

Hybrid Kart Mapper/Porter
I've been trying to code a NiGHTS boss which follows the same Axis as NiGHTS Super Sonic (using FuriousFox's GHZ boss as a baseline) but whenever I try to test it out, this happens:

srb20027.gif



Here's the current code I'm using as well:

Code:
/*
Latius' NiGHTS Boss Template

Based on the script used for FuriousFox's GHZ Eggman, but modified to work with NiGHTS
*/

freeslot("MT_NIGHTSBOSS", "S_NIGHTSBOSS", "S_NIGHTSBOSSCHASE", "S_NIGHTSBOSSSTUNNED", "S_NIGHTSBOSSPAIN", "S_NIGHTSBOSSTURN", "S_NIGHTSBOSSDIE", "S_NIGHTSBOSSFLEE")

mobjinfo[MT_NIGHTSBOSS] = {
doomednum = 3221,
spawnstate = S_NIGHTSBOSS,
seestate = S_NIGHTSBOSS,
seesound = sfx_None,
attacksound = sfx_None,
painstate = S_NIGHTSBOSSPAIN,
painsound = sfx_dmpain,
deathstate = S_EGGMOBILE_DIE1,
xdeathstate = S_EGGMOBILE_FLEE1,
deathsound = sfx_cybdth,
spawnhealth = 9,
reactiontime = 256,
speed = 1*FRACUNIT,
radius = 24*FRACUNIT,
height = 76*FRACUNIT,
mass = sfx_None,
damage = 8*FRACUNIT,
flags = MF_SPECIAL|MF_SHOOTABLE|MF_FLOAT|MF_NOGRAVITY|MF_BOSS
}

states[S_NIGHTSBOSS] = {SPR_EGGM, A, 1, nil, 0, 0, S_NIGHTSBOSS}
states[S_NIGHTSBOSSPAIN] = {SPR_EGGM, V, 35, A_Pain, 0, 0, S_NIGHTSBOSS}
states[S_NIGHTSBOSSTURN] = {SPR_EGGM, A, 1, nil, 0, 0, S_NIGHTSBOSSTURN}
states[S_NIGHTSBOSSSTUNNED] = {SPR_EGGM, X, 70, nil, 0, 0, S_NIGHTSBOSS} //Also uses sprite Y as well
states[S_NIGHTSBOSSCHASE] = {SPR_EGGM, A, 1, nil, 0, 0, S_NIGHTSBOSSCHASE}

local axismo //Axis to use
local bossdir = 1 //Variable for the direction of the boss. 1 means Anticlockwise, -1 means Clockwise and 0 means pausing. Would be increased by x1 in Pinch Mode for every hit
local lastbossdir = 0 //Variable for storing the old bossdir when changing directions
local pinchmode = false //Bool for checking if the boss is in Pinch Mode (3HP or less)
local pinchmod = false //Checks if Pinch Mode has modified the dir value
local turntimer //How long before turning around
local oldangle //The old angle of the boss, used to check when the boss has turned 180 or when recovering from being hit or stunned
local chasetimer //How long the Boss would chase after a Player before stopping
local stunswitch //How long to show the two frames of the stunned animation7
local chasecooldown = 0 //Cooldown for chasing
local chaserange = 1024 * FRACUNIT //Chase Range
local targetdir //Direction of target along axis if chasing (1 is Anticlockwise, -1 is clockwise)
local targetzdir //Z direction of target if chasing

local function bosschasecheck(bossmo, playermo)
	if bossmo.valid and playermo.valid
		local xydist = R_PointToDist2(bossmo.x, bossmo.y, playermo.x, playermo.y)
		local zdist = abs(bossmo.z - playermo.z)
		local dist = FixedHypot(xydist, zdist)
		if dist <= chaserange then return true else return false end
	else
		return false
	end
end

local function gettargetzdir(bossmo, playermo)
	local xydist = R_PointToDist2(bossmo.x, bossmo.y, playermo.x, playermo.y)
	local zdist = abs(bossmo.z - playermo.z)
	if bossmo.z == playermo.z or zdist < xydist/2 then return 0
	elseif bossmo.z > playermo.z then return -1
	else return 1 end
end

local function anglecheck(bossmo, playermo)
	if R_PointToDist2(bossmo.x, bossmo.y, playermo.x, playermo.y) < 16*FRACUNIT then return 0
	else
		local bossang = FixedAngle(R_PointToAngle2(axismo.x, axismo.y, bossmo.x, bossmo.y))
		local playerang = FixedAngle(R_PointToAngle2(axismo.x, axismo.y, playermo.x, playermo.y))
		local checkangle = bossang - playerang
		
		if checkangle > FixedAngle(ANGLE_180) then return -1
		elseif checkangle > 0 then return 1
		elseif checkangle > -FixedAngle(ANGLE_180) then return -1
		else return 1 end
	end
end

local function boss(bossmo)
	
	if axismo == nil or axismo.valid == false
		//Kill the boss! We can't use them here!
		print("No Axis for the boss to use!")
		P_KillMobj(bossmo)
	else
		if bossmo.state == S_NIGHTSBOSS //Normal, needs fixing
			if pinchmod == true then pinchmod = false end //reset this flag
			if bossdir > 0 then
				local x = axismo.x + axismo.spawnpoint.angle*cos(bossmo.angle-ANGLE_90)
				local y = axismo.y + axismo.spawnpoint.angle*sin(bossmo.angle-ANGLE_90)
			else
				local x = axismo.x + axismo.spawnpoint.angle*cos(bossmo.angle+ANGLE_90)
				local y = axismo.y + axismo.spawnpoint.angle*sin(bossmo.angle+ANGLE_90)
			end
			bossmo.angle = $1 + bossdir*FixedAngle(bossmo.info.speed)
			P_TeleportMove(bossmo, x, y, bossmo.z*FRACUNIT)
			//Check if a NiGHTS Super Sonic is within range, and the cooldown is finished
			P_BossTargetPlayer(bossmo, true)
			if bosschasecheck(bossmo, bossmo.target) and chasecooldown <= 0
				//The nearest one is in range! After them!
				bossmo.state = S_NIGHTSBOSSCHASE
				//Get the Axis and Z drection of the Player relative to the Boss
				targetdir = anglecheck(bossmo, bossmo.target)
				targetzdir = gettargetzdir(bossmo, bossmo.target)
				bossdir = abs(bossdir)*targetdir
				//Finally, set the Chase Timer.
				chasetimer = 35*3
			else
				//None in range, or cooldown not expired, so get ready to turn (and also lower the Cooldown timer)
				if chasecooldown > 0 then chasecooldown = $-1 end
				turntimer = $-1
				if turntimer <= 0
					bossmo.state = S_NIGHTSBOSSTURN
					oldangle = bossmo.angle
					lastbossdir = bossdir
					bossdir = 0
				end
			end
			
		elseif bossmo.state == S_NIGHTSBOSSTURN //Turning around, needs fixing
			if pinchmod == true then pinchmod = false end //reset this flag
			bossmo.angle = $1 - FixedAngle(lastbossdir*6*FRACUNIT)
			if bossmo.angle == oldangle-FixedAngle(ANGLE_180) or bossmo.angle == oldangle+FixedAngle(ANGLE_180) //Done a 180?
				bossmo.state = S_NIGHTSBOSS //Return to normal
				bossdir = $-lastbossdir
				lastbossdir = 0
				turntimer = P_RandomRange(70,350) //Sets the new turn timer
			end
			
		elseif bossmo.state == S_NIGHTSBOSSPAIN //I'm hit! (Needs fixing?)
			if not pinchmode and bossmo.health <= 3 then pinchmode = true end //Turn on Pinch Mode
			if pinchmod == false and pinchmode //In Pinch Mode?
				pinchmod = true //set flag
				if lastbossdir > 0 //Stopped, but was heading Anticlockwise
					lastbossdir = $+1
				elseif lastbossdir < 0 //Stopped, but was heading Anticlockwise
					lastbossdir = $-1
				else
					if bossdir > 0 //Heading anticlockwise
						bossdir = $+1
					else //Heading clockwise
						bossdir = $-1
					end
				end
			end
			if chasecooldown <= 0 then chasecooldown = 35 end
			if bossdir == 0 //Was turning before being hit
				bossmo.angle = oldangle-FixedAngle(ANGLE_180)
				bossdir = $-lastbossdir
				lastbossdir = 0
				turntimer = P_RandomRange(70,350) //Sets the new turn timer
			end
			
		elseif bossmo.state == S_NIGHTSBOSSCHASE //After that NiGHTS! Needs fixing
			if pinchmod == true then pinchmod = false end //reset this flag
			if targetdir > 0 then
				local x = axismo.x + axismo.spawnpoint.angle*cos(bossmo.angle-ANGLE_90)
				local y = axismo.y + axismo.spawnpoint.angle*sin(bossmo.angle-ANGLE_90)
			else
				local x = axismo.x + axismo.spawnpoint.angle*cos(bossmo.angle+ANGLE_90)
				local y = axismo.y + axismo.spawnpoint.angle*sin(bossmo.angle+ANGLE_90)
			end
			local z = bossmo.z + targetzdir*abs(bossdir)*bossmo.info.speed
			
			bossmo.angle = $1 + targetdir*abs(bossdir)*FixedAngle(bossmo.info.speed)
			P_TeleportMove(bossmo, x, y, z)
			
			chasetimer = $-1
			if chasetimer <= 0 then bossmo.state = S_NIGHTSBOSSSTUNNED end
			
			
		elseif bossmo.state == S_NIGHTSBOSSSTUNNED //Damn, missed! (Needs fixing?)
			if pinchmod == true then pinchmod = false end //reset this flag
			if chasecooldown <= 0 then chasecooldown = 35 end
		end
	end
end

local function bossDead(bossmo)
	bossmo.state = bossmo.info.xdeathstate
	//Set players to start to exit, but don't spin them or anything until after the Boss is fleeing
end

addHook("MobjSpawn", function(mobj)
	turntimer = P_RandomRange(70,350)
	axismo = P_GetClosestAxis(mobj)
end, MT_NIGHTSBOSS)
addHook("MobjThinker", boss, MT_NIGHTSBOSS)
addHook("BossDeath", bossDead, MT_NIGHTSBOSS)
 
It looks like the code has a failsafe in place on the anglecheck that uses a value not handled properly by the code if the boss is less than 16 units away from the axis. Are you placing the boss that close in the map? That might be the issue.

(Also, I don't know if that's how it was in FF's original script, but all of those local script variables are going to make it impossible to spawn more than one boss or join a netgame mid-map. I'd try to convert everything to mobj variables and function-scope variables.)
 
The angle check is for when the boss is near to the player, not regarding the boss movement at all. And... Ah, that's a good point. It's also something I should most likely add to EHA to allow netgame capabilities. Then again, I've never done that kind of stuff before - adding them to the Mobj, that is.

And yeah, FF's old code didn't have any local variables.
 
Last edited:
Finally fixed most of the bugs. Going to showcase it in my workshop thread now.
 
Status
Not open for further replies.

Who is viewing this thread (Total: 1, Members: 0, Guests: 1)

Back
Top