Emerald Hunt Lua help

Status
Not open for further replies.

Latius

Hybrid Kart Mapper/Porter
As some of you might know, I am currently trying to create a Lua script which randomises the looks of the Emeralds you can find in a Hunt map. I have given the new sprites states like S_EMERALD1, S_EMERALD2 and so on (although those aren't the names I'm using in the final version of the Lua) and have a plan as to how to do it. The problem is that I only want to randomise the Hunt Emeralds which are chosen by the game, or to instead override how the game does it and randomise the spawn points in the Lua script (which in turn can mean using more or less Emeralds if the map maker wants to, but never more than the number of Emerald states - although if I did that, then I would need to alter the HUD to cater for up to 7 Emeralds) and give them a random sprite which would not be the same as any other Emerald in the Hunt map.

Can anyone help me out here with what I need to do? I've checked the source code and the Wiki, but so far I have come up empty.

----------

Edit as of 09-09-2017 at 09:28AM BST:

I have decided to try and make them as a new Thing for the time being, and I have started work on the Lua script. The main problem now is that I've hit a stumbling block with regards to the spawning of them (and as a result, also regarding collecting them and completing the level if all of them have been collected)

Below is my current Lua code for the script in total:

Code:
-- This deals with the Ideya/Emerald Hunt levels

-- Make free slots for all Emeralds and/or Ideya (excluding the temp ones) plus use our own Hunt Emeralds
freeslot("SPR_IDEY","S_IDEYA00","S_IDEYA01","S_IDEYA02","S_IDEYA03","S_IDEYA04","S_IDEYA05",
"S_IDEYA06","S_IDEYA07","S_IDEYA08","S_IDEYA09","S_IDEYA10",
"S_IDEYA11","S_IDEYA12","S_IDEYA13","S_IDEYA14","S_IDEYA15",
"S_IDEYA16","S_IDEYA17","S_IDEYA18","S_IDEYA19","S_IDEYA20","S_IDEYA21","S_IDEYA22","S_IDEYA23","S_IDEYA24","S_IDEYA25",
"MT_HUNT_IDEYA")

-- Set states for the Ideyas/Emeralds

-- State for any Ideyas during map loading
states[S_IDEYA00] = {SPR_NULL, A, -1,nil,0,0,S_IDEYA00}

-- Original Ideyas and first 5 Emeralds
states[S_IDEYA01] = {SPR_IDEY, A, -1,nil,0,0,S_IDEYA01} //Red Ideya or Green Emerald
states[S_IDEYA02] = {SPR_IDEY, B, -1,nil,0,0,S_IDEYA02} //White Ideya or Purple Emerald
states[S_IDEYA03] = {SPR_IDEY, C, -1,nil,0,0,S_IDEYA03} //Yellow Ideya or Blue Emerald
states[S_IDEYA04] = {SPR_IDEY, D, -1,nil,0,0,S_IDEYA04} //Green Ideya or Light Blue Emerald
states[S_IDEYA05] = {SPR_IDEY, E, -1,nil,0,0,S_IDEYA05} //Blue Ideya or Orange Emerald

-- Extended Ideyas and remaining Emeralds
//states[S_IDEYA06] = {SPR_IDEY, F, -1,nil,0,0,S_IDEYA06}
//states[S_IDEYA07] = {SPR_IDEY, G, -1,nil,0,0,S_IDEYA07}

-- These ones are only for the extended Ideyas
//states[S_IDEYA08] = {SPR_IDEY, H, -1,nil,0,0,S_IDEYA08}
//states[S_IDEYA09] = {SPR_IDEY, I, -1,nil,0,0,S_IDEYA09}
//states[S_IDEYA10] = {SPR_IDEY, J, -1,nil,0,0,S_IDEYA10}
//states[S_IDEYA11] = {SPR_IDEY, K, -1,nil,0,0,S_IDEYA11}
//states[S_IDEYA12] = {SPR_IDEY, L, -1,nil,0,0,S_IDEYA12}
//states[S_IDEYA13] = {SPR_IDEY, M, -1,nil,0,0,S_IDEYA13}
//states[S_IDEYA14] = {SPR_IDEY, N, -1,nil,0,0,S_IDEYA14}
//states[S_IDEYA15] = {SPR_IDEY, O, -1,nil,0,0,S_IDEYA15}
//states[S_IDEYA16] = {SPR_IDEY, P, -1,nil,0,0,S_IDEYA16}
//states[S_IDEYA17] = {SPR_IDEY, Q, -1,nil,0,0,S_IDEYA17}
//states[S_IDEYA18] = {SPR_IDEY, R, -1,nil,0,0,S_IDEYA18}
//states[S_IDEYA19] = {SPR_IDEY, S, -1,nil,0,0,S_IDEYA19}
//states[S_IDEYA20] = {SPR_IDEY, T, -1,nil,0,0,S_IDEYA20}
//states[S_IDEYA21] = {SPR_IDEY, U, -1,nil,0,0,S_IDEYA21}
//states[S_IDEYA22] = {SPR_IDEY, V, -1,nil,0,0,S_IDEYA22}
//states[S_IDEYA23] = {SPR_IDEY, W, -1,nil,0,0,S_IDEYA23}
//states[S_IDEYA24] = {SPR_IDEY, X, -1,nil,0,0,S_IDEYA24}
//states[S_IDEYA25] = {SPR_IDEY, Y, -1,nil,0,0,S_IDEYA25}

-- Local values for number of Ideyas/Emeralds

local numbideya = 5 //The maximun number of Ideya
local MAXHUNTIDEYA = 64 //The maximun number of Hunt Ideya to consider
local MAXSPAWNIDEYA = 5 //Soft cap for maximun nunber of spawnable Ideyas
local mapideyas //Local value of how many Ideya Spawns there are on the map which are valid
local ideyalocations = {} //Current Ideya Locations
local allideyalocations = {} //All valid spawnable Ideya Locations
local spawnideyas //Local value for how many Ideyas to spawn

-- 

-- Time to make the Thing
mobjinfo[MT_HUNT_IDEYA] = {
	doomednum = 3219, //Hopefully this number isn't used by other Things...
    spawnstate = S_IDEYA00,
    spawnhealth = 1000,
    seestate = S_NULL,
    seesound = sfx_None,
    reactiontime = 0,
    attacksound = sfx_None,
    painstate = S_NULL,
    painchance = 0,
    painsound = sfx_None,
    meleestate = S_NULL,
    missilestate = S_NULL,
    deathstate = S_SPRK1,
    xdeathstate = S_NULL,
	deathsound = sfx_None, //Would be replaced with custom SFX sound
	speed = 10,
	radius = 16*FRACUNIT,
	height = 32*FRACUNIT,
	dispoffset = 0,
	mass = 4,
	damage = 0,
	activesound = sfx_None,
	flags = MF_SPECIAL|MF_NOGRAVITY,
	raisestate = S_NULL
}

addHook("MapLoad", do
	-- First, we need to reset some bits
	
	mapideyas = 0 
	allideyalocations = {}
	ideyalocations = {}
	spawnideyas = 0
	
	-- Next, let's get the valid Ideya Locations, and add them to the table of all spawnable locations.
	
	for mobj in thinkers.iterate("mobj")
		if mobj and mobj.type == MT_HUNT_IDEYA
			if mobj.valid and mapideyas < MAXHUNTIDEYA
				table.insert(allideyalocations, mobj)
				mapideyas = mapideyas + 1
				print("Added Ideya Location #"..mapideyas)
			end
		end
	end

	-- Now set the number of spawnable Ideyas
	
	if not mapheaderinfo[gamemap].numideyas //If not set in the map header, set to default value
		spawnideyas = 3
	end
	if mapheaderinfo[gamemap].numideyas
		spawnideyas = mapheaderinfo[gamemap].numideyas
	end
	if spawnideyas > MAXSPAWNIDEYA //If the value is too high, cap it
		spawnideyas = MAXSPAWNIDEYA
	end

	if mapideyas >= spawnideyas //Only do the next block if enough Ideya Spawn Points were placed on the map
		-- Now, we go through the table and randomly pick a number of them dependant on how many Ideyas were chosen to be spawn, then add them to the spawned table
		
		-- Next, we spawn the chosen Ideyas after making sure each one has a different sprite
	
		-- Finally, we need to do some HUD stuff regarding the Ideya Radar, due to there being a variable number of Ideyas
		
		// If only one, then it is positioned in the middle.
		// If two, then they are positioned such that there's a gap between them where the middle is.
		// If three, the central one is in the middle, with the outer two straddling it.
		// And so on...
	end	

	if spawnideyas > mapideyas and mapideyas > 0 //You didn't add enough Spawn points.
		print("Not enough Ideya Spawn points!")
	end
end)
 
Last edited:
I've made some progress - in fact, I would say I just need to sort out the HUD, and then I'm done - but now I'm hitting an Access Violation when my code wasn't before.

Here's the code I've gotten so far - can someone tell me what's causing it, as I can't troubleshoot it?

Code:
-- This deals with the Ideya/Emerald Hunt levels

-- Make free slots for all Emeralds and/or Ideya (excluding the temp ones) plus use our own Hunt Emeralds
freeslot("SPR_IDEY","S_IDEYA00","S_IDEYA01","S_IDEYA02","S_IDEYA03","S_IDEYA04","S_IDEYA05",
"S_IDEYA06","S_IDEYA07","S_IDEYA08","S_IDEYA09","S_IDEYA10",
"S_IDEYA11","S_IDEYA12","S_IDEYA13","S_IDEYA14","S_IDEYA15",
"S_IDEYA16","S_IDEYA17","S_IDEYA18","S_IDEYA19","S_IDEYA20","S_IDEYA21","S_IDEYA22","S_IDEYA23","S_IDEYA24","S_IDEYA25",
"MT_HUNT_IDEYA")

-- Set states for the Ideyas/Emeralds

-- State for any Ideyas during map loading
states[S_IDEYA00] = {SPR_NULL, A, -1,nil,0,0,S_IDEYA00}

-- Original Ideyas and first 5 Emeralds
states[S_IDEYA01] = {SPR_IDEY, A, -1,nil,0,0,S_IDEYA01} //Red Ideya or Green Emerald
states[S_IDEYA02] = {SPR_IDEY, B, -1,nil,0,0,S_IDEYA02} //White Ideya or Purple Emerald
states[S_IDEYA03] = {SPR_IDEY, C, -1,nil,0,0,S_IDEYA03} //Yellow Ideya or Blue Emerald
states[S_IDEYA04] = {SPR_IDEY, D, -1,nil,0,0,S_IDEYA04} //Green Ideya or Light Blue Emerald
states[S_IDEYA05] = {SPR_IDEY, E, -1,nil,0,0,S_IDEYA05} //Blue Ideya or Orange Emerald

-- Extended Ideyas and remaining Emeralds
//states[S_IDEYA06] = {SPR_IDEY, F, -1,nil,0,0,S_IDEYA06}
//states[S_IDEYA07] = {SPR_IDEY, G, -1,nil,0,0,S_IDEYA07}

-- These ones are only for the extended Ideyas
//states[S_IDEYA08] = {SPR_IDEY, H, -1,nil,0,0,S_IDEYA08}
//states[S_IDEYA09] = {SPR_IDEY, I, -1,nil,0,0,S_IDEYA09}
//states[S_IDEYA10] = {SPR_IDEY, J, -1,nil,0,0,S_IDEYA10}
//states[S_IDEYA11] = {SPR_IDEY, K, -1,nil,0,0,S_IDEYA11}
//states[S_IDEYA12] = {SPR_IDEY, L, -1,nil,0,0,S_IDEYA12}
//states[S_IDEYA13] = {SPR_IDEY, M, -1,nil,0,0,S_IDEYA13}
//states[S_IDEYA14] = {SPR_IDEY, N, -1,nil,0,0,S_IDEYA14}
//states[S_IDEYA15] = {SPR_IDEY, O, -1,nil,0,0,S_IDEYA15}
//states[S_IDEYA16] = {SPR_IDEY, P, -1,nil,0,0,S_IDEYA16}
//states[S_IDEYA17] = {SPR_IDEY, Q, -1,nil,0,0,S_IDEYA17}
//states[S_IDEYA18] = {SPR_IDEY, R, -1,nil,0,0,S_IDEYA18}
//states[S_IDEYA19] = {SPR_IDEY, S, -1,nil,0,0,S_IDEYA19}
//states[S_IDEYA20] = {SPR_IDEY, T, -1,nil,0,0,S_IDEYA20}
//states[S_IDEYA21] = {SPR_IDEY, U, -1,nil,0,0,S_IDEYA21}
//states[S_IDEYA22] = {SPR_IDEY, V, -1,nil,0,0,S_IDEYA22}
//states[S_IDEYA23] = {SPR_IDEY, W, -1,nil,0,0,S_IDEYA23}
//states[S_IDEYA24] = {SPR_IDEY, X, -1,nil,0,0,S_IDEYA24}
//states[S_IDEYA25] = {SPR_IDEY, Y, -1,nil,0,0,S_IDEYA25}

-- Local values for number of Ideyas/Emeralds

local numbideya = 5 //The max number of Ideya
local MAXHUNTIDEYA = 64 //The max number of Hunt Ideya to consider
local MAXSPAWNIDEYA = 5 //Soft cap for max nunber of spawnable Ideyas
local mapideyas //Local value of how many Ideya Spawns there are on the map which are valid
local ideyalocations = {} //Current Ideya Locations
local allideyalocations = {} //All valid spawnable Ideya Locations
local spawnideyas //Local value for how many Ideyas to spawn
local ideyastate = {} //Used to refrence the state of the current Ideya locations
local ideyacollected = {} //Used to tell if an Ideya is collected
local ideyanum = {} //Used to make sure an Ideya isn't chosen twice
local numideyascollected //Number of Ideyas collected

-- 

-- Time to make the Thing
mobjinfo[MT_HUNT_IDEYA] = {
	doomednum = 3219, //Hopefully this number isn't used by other Things...
    spawnstate = S_IDEYA00,
    spawnhealth = 1000,
    seestate = S_NULL,
    seesound = sfx_None,
    reactiontime = 0,
    attacksound = sfx_None,
    painstate = S_NULL,
    painchance = 0,
    painsound = sfx_None,
    meleestate = S_NULL,
    missilestate = S_NULL,
    deathstate = S_SPRK1,
    xdeathstate = S_NULL,
	deathsound = sfx_None, //Would be replaced with custom SFX sound
	speed = 10,
	radius = 16*FRACUNIT,
	height = 32*FRACUNIT,
	dispoffset = 0,
	mass = 4,
	damage = 0,
	activesound = sfx_None,
	flags = MF_SPECIAL|MF_NOGRAVITY,
	raisestate = S_NULL
}

addHook("MapLoad", do
	-- First, we need to reset some bits
	
	mapideyas = 0 
	allideyalocations = {}
	ideyalocations = {}
	spawnideyas = 0
	ideyastate = {}
	ideyacollected = {}
	ideyanum = {}
	numideyascollected = 0
	
	-- Next, let's get the valid Ideya Locations, and add them to the table of all spawnable locations.
	
	for mobj in thinkers.iterate("mobj")
		if mobj and mobj.type == MT_HUNT_IDEYA
			if mobj.valid and mapideyas < MAXHUNTIDEYA
				table.insert(allideyalocations, mobj)
				mapideyas = mapideyas + 1
				print("Added Ideya Location #"..mapideyas)
			end
		end
	end

	-- Now set the number of spawnable Ideyas
	
	if not mapheaderinfo[gamemap].numideyas //If not set in the map header, set to default value
		spawnideyas = 3
	elseif mapheaderinfo[gamemap].numideyas
		spawnideyas = mapheaderinfo[gamemap].numideyas
	end
	if spawnideyas > MAXSPAWNIDEYA //If the value is too high, cap it
		spawnideyas = MAXSPAWNIDEYA
	end

	if mapideyas >= spawnideyas //Only do the next block if enough Ideya Spawn Points were placed on the map
		-- Now, we go through the table and randomly pick a number of them dependant on how many Ideyas were chosen to be spawn, then add them to the spawned table
		local tempflag
		local tempval
		for i = 1,spawnideyas //We do this as many times as spawnideyas states
			repeat
				tempval = P_RandomKey(mapideyas) + 1 //This gives a value between 1 and mapideyas
				tempflag = true //It could be okay
				if i != 1 //IS this not the first Ideya to be spawned?
					for j = 1,i-1 //No, so check the list.
						if ideyanum[j] == tempval //We have a match...
							tempflag = false //So don't use it
						end
					end
				end
			until tempflag == true //It's okay, so it can be used.
			
			table.insert(ideyalocations, allideyalocations[tempval]) //Insert the Ideya into the table
			table.insert(ideyanum, tempval) //And add the value to the table
			print("Spawn #"..tempval.." has been chosen for Ideya #"..i..".") //Debugging
			
			-- Next, we spawn the chosen Ideyas after making sure each one has a different sprite
			repeat
				tempval = P_RandomKey(numbideya) + 1
				tempflag = true //It could be okay
				if i != 1 //IS this not the first Ideya to be spawned?
					for j = 1,i-1 //No, so check the list.
						if ideyastate[j] == tempval //We have a match...
							tempflag = false //So don't use it
						end
					end
				end
			until tempflag == true
			
			//Need to spawn the Ideya using the value to determine the spawn state
			P_SetMobjStateNF(ideyalocations[i], ideyalocations[i].state + tempval)
			table.insert(ideyacollected, 0)
			table.insert(ideyastate, tempval)
			print("State Number "..tempval.." has been chosen for Ideya #"..i..".")
		end
		
		
	
		-- Finally, we need to do some HUD stuff regarding the Ideya Radar, due to there being a variable number of Ideyas
		
		// If only one, then it is positioned in the middle.
		// If two, then they are positioned such that there's a gap between them where the middle is.
		// If three, the central one is in the middle, with the outer two straddling it.
		// And so on...
		
	elseif mapideyas > 0 //You didn't add enough Spawn points.
		print("Not enough Ideya Spawn points!")
	end
end)

-- This hook deals with collecting the Ideyas/Emeralds

addHook("TouchSpecial", do
	
	-- Check to see if this is in a collectable state.
	if mobj.state != S_IDEYA00 //It can be collected.
		//Play Ideya Collection sound
		for i = 1,spawnideyas //Find out which Ideya was collected
			if ideyalocations[i] == mobj //This is the one
				ideyacollected[i] = 1 //Set the Ideya as collected
			end
		end
		
		numideyacollected = numideyacollected + 1 //One less Ideya to collect
		if numideyacollected == spawnideya //All Ideya collected?
			for p in players.iterate
				if not p.mo continue end
				P_DoPlayerExit(p.mo) //Yes, so end the level for everyone.
			end
		end
	end
end, MT_HUNT_IDEYA)
 
Status
Not open for further replies.

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

Back
Top