Page 1 of 1

LUA Script File - Help Requested

Posted: Tue Jun 04, 2019 3:16 pm
by Wilmatron
Hi All,

I could really use a hand with this one! It's been baffling me for a while now!

Please find attached zip file, which is my attempt at scripting the very last NOD mission for CNC Tiberian Dawn (this is a work in progress as I am learning LUA language on the job!). I appear to be getting the following LUA exception error "attempt to call global 'Build' (a nil value)" when my NOD Barracks is given a command that overlaps its "in-progress" build routine. For the full error please see contents of the attached zip.

You'll notice I have the following in my LUA script file:

1. Global Variables - An array of production buildings and unit types to produce for NOD attack waves
2. Build functions - that take care of building from either of my 2 Barracks or 2 Factories (named 'BuildFromBarracks' and 'BuildFromFactory')
3. Attack Wave functions - that specify what to build, which path to follow and attacking strategy
4. World Loaded - Triggers that define when the attack waves should initialise

Just to clarify; if I spread my attack wave intervals far enough apart so that they don't overlap the production queue, I do not run into this exception.

For example; this is fine...

Trigger.AfterDelay(DateTime.Seconds(90), AttackPlayerWave1)
Trigger.AfterDelay(DateTime.Seconds(150), AttackPlayerWave2)
Trigger.AfterDelay(DateTime.Seconds(210), AttackPlayerWave3)
Trigger.AfterDelay(DateTime.Seconds(270), AttackPlayerWave4)
Trigger.AfterDelay(DateTime.Seconds(330), AttackPlayerWave5)
Trigger.AfterDelay(DateTime.Seconds(450), AttackPlayerRandom)

But if I shorten the interval times that's when the problem occurs. Ideally I'd like to specify whatever interval time I like without it breaking, and have the barracks (or factory) queue the next attack wave behind the first one.

I'd appreciate it if one of you LUA experts could take a gander at the code and let me know how to achieve this, or perhaps insert the code required with some comments for me to learn from.

Thank you for taking the time to read this.

Cheers,
Dave

Re: LUA Script File - Help Requested

Posted: Wed Jun 05, 2019 11:26 am
by abcdefg30
The problem is in the following part:

Code: Select all

BuildFromFactory = function(factory, units, action)                                                 --Declare factory build function
	if factory.IsDead or factory.Owner ~= enemy then
		return
	end

	if not factory.Build(units, action) then
		Trigger.AfterDelay(DateTime.Seconds(2), function()
			Build(factory, units, action)
		end)
	end
end

BuildFromBarracks = function(barracks, units, action)                                               --Declare barracks build function
	if barracks.IsDead or barracks.Owner ~= enemy then
		return
	end
  
  if not barracks.Build(units, action) then
		Trigger.AfterDelay(DateTime.Seconds(2), function()
			Build(barracks, units, action)
		end)
	end
end
You are calling a method named "Build" in the Trigger.AfterDelay functions inside the production callbacks, which does not exist (what the error says).
Change the first "Build" to "BuildFromFactory" and the second to "BuildFromBarracks".

The new code should look like:

Code: Select all

BuildFromFactory = function(factory, units, action)                                                 --Declare factory build function
	if factory.IsDead or factory.Owner ~= enemy then
		return
	end

	if not factory.Build(units, action) then
		Trigger.AfterDelay(DateTime.Seconds(2), function()
			BuildFromFactory(factory, units, action)
		end)
	end
end

BuildFromBarracks = function(barracks, units, action)                                               --Declare barracks build function
	if barracks.IsDead or barracks.Owner ~= enemy then
		return
	end
  
  if not barracks.Build(units, action) then
		Trigger.AfterDelay(DateTime.Seconds(2), function()
			BuildFromBarracks(barracks, units, action)
		end)
	end
end

Re: LUA Script File - Help Requested

Posted: Wed Jun 05, 2019 3:22 pm
by Wilmatron
Many thanks for clearing that up! I can't believe it was that simple - but of course, now that you point it out, it makes sense why it was crashing before.

Thanks again.