Page 1 of 1

Map crashes

Posted: Tue Nov 14, 2017 8:14 pm
by SethXXX
Dear community, it's me again, probably with a similarly easily fixable problem, but I cannot find the solution.

My custom map crashes with the following error in its Lua script:

Code: Select all

Fatal Lua Error&#58; Error parsing rollingthunder.lua. Reason&#58; &#91;string "rollingthunder.lua"&#93;&#58;245&#58; 'end' expected &#40;to close 'function' at line 221&#41; near '<eof>'
  at OpenRA.Scripting.ScriptContext.FatalError &#40;System.String message&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at System.Reflection.MonoMethod.InternalInvoke &#40;System.Reflection.MonoMethod , System.Object , System.Object&#91;&#93; , System.Exception& &#41; &#91;0x00000&#93; in <73ee1b14c2fa4d61b481096ff3d8d6d7>&#58;0 
  at System.Reflection.MonoMethod.Invoke &#40;System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object&#91;&#93; parameters, System.Globalization.CultureInfo culture&#41; &#91;0x00032&#93; in <73ee1b14c2fa4d61b481096ff3d8d6d7>&#58;0 
  at System.Reflection.MethodBase.Invoke &#40;System.Object obj, System.Object&#91;&#93; parameters&#41; &#91;0x00000&#93; in <73ee1b14c2fa4d61b481096ff3d8d6d7>&#58;0 
  at Eluant.LuaRuntime+MethodWrapper.Invoke &#40;System.Object&#91;&#93; parms&#41; &#91;0x00000&#93; in <c8bc0b4612b543268b8307855c69585a>&#58;0 
  at Eluant.LuaRuntime.MakeManagedCall &#40;System.IntPtr state, Eluant.LuaRuntime+MethodWrapper wrapper&#41; &#91;0x00000&#93; in <c8bc0b4612b543268b8307855c69585a>&#58;0 
  at Eluant.LuaRuntime.MethodWrapperCallCallback &#40;System.IntPtr state&#41; &#91;0x00000&#93; in <c8bc0b4612b543268b8307855c69585a>&#58;0 
  at Eluant.LuaRuntime.MethodWrapperCallCallbackWrapper &#40;System.IntPtr state&#41; &#91;0x00000&#93; in <c8bc0b4612b543268b8307855c69585a>&#58;0 
  at Eluant.LuaApi.lua_pcall &#40;System.IntPtr , System.Int32 , System.Int32 , System.Int32 &#41; &#91;0x00000&#93; in <c8bc0b4612b543268b8307855c69585a>&#58;0 
  at Eluant.LuaRuntime.Call &#40;System.Collections.Generic.IList`1&#91;T&#93; args&#41; &#91;0x00000&#93; in <c8bc0b4612b543268b8307855c69585a>&#58;0 
  at Eluant.LuaRuntime.Call &#40;Eluant.LuaFunction fn, System.Collections.Generic.IList`1&#91;T&#93; args&#41; &#91;0x00000&#93; in <c8bc0b4612b543268b8307855c69585a>&#58;0 
  at Eluant.LuaFunction.Call &#40;System.Collections.Generic.IList`1&#91;T&#93; args&#41; &#91;0x00000&#93; in <c8bc0b4612b543268b8307855c69585a>&#58;0 
  at Eluant.LuaFunction.Call &#40;Eluant.LuaValue&#91;&#93; args&#41; &#91;0x00000&#93; in <c8bc0b4612b543268b8307855c69585a>&#58;0 
  at OpenRA.Scripting.ScriptContext..ctor &#40;OpenRA.World world, OpenRA.Graphics.WorldRenderer worldRenderer, System.Collections.Generic.IEnumerable`1&#91;T&#93; scripts&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at OpenRA.Mods.Common.Scripting.LuaScript.WorldLoaded &#40;OpenRA.World world, OpenRA.Graphics.WorldRenderer worldRenderer&#41; &#91;0x0001d&#93; in <873ffb3d96084d8eb6211bef70b4ce72>&#58;0 
  at OpenRA.World.LoadComplete &#40;OpenRA.Graphics.WorldRenderer wr&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at OpenRA.Game.StartGame &#40;System.String mapUID, OpenRA.WorldType type&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at OpenRA.Network.UnitOrders.ProcessOrder &#40;OpenRA.Network.OrderManager orderManager, OpenRA.World world, System.Int32 clientId, OpenRA.Order order&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at OpenRA.Network.OrderManager.TickImmediate &#40;&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at OpenRA.Sync+<CheckSyncUnchanged>c__AnonStorey0.<>m__0 &#40;&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at OpenRA.Sync.CheckSyncUnchanged&#91;T&#93; &#40;OpenRA.World world, System.Func`1&#91;TResult&#93; fn&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at OpenRA.Sync.CheckSyncUnchanged &#40;OpenRA.World world, System.Action fn&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at OpenRA.Game.InnerLogicTick &#40;OpenRA.Network.OrderManager orderManager&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at OpenRA.Game.LogicTick &#40;&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at OpenRA.Game.Loop &#40;&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at OpenRA.Game.Run &#40;&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at OpenRA.Program.Run &#40;System.String&#91;&#93; args&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
  at OpenRA.Program.Main &#40;System.String&#91;&#93; args&#41; &#91;0x00000&#93; in <771c3876cf2a484a81272dd7e11c4f46>&#58;0 
The map's Lua file is:

Code: Select all

--VARIABLEN

SovietInfantryTypes = &#123; "e1", "e1", "e1", "e2", "e2", "e4", "e4", "shok" &#125;
SovietArmorTypes = &#123; "3tnk", "3tnk", "3tnk", "3tnk", "v2rl", "4tnk", "ttnk" &#125;
SovietAircraftType = &#123; "yak", "yak", "yak", "mig" &#125;
SovietHeliType = &#123; "hind" &#125;

RadarDome = &#123; RadarDome &#125;
SubPens = &#123; SubPen1, SubPen2, SubPen3, SubPen4 &#125;
AirFacilities = &#123; Airfield1, Airfield2, Airfield3, Helipad1, Helipad2, Helipad3 &#125;
ForwardCommand = &#123; SovietForwardCommand &#125;

IdlingUnits = &#123; &#125;
--AttackGroupSize = 3

SovietAttackPathGround = &#123; &#123; Rallypoint, AttackMoveSouth1, AlliedBaseEast, AlliedBaseWest &#125;, &#123; Rallypoint, AttackMoveNorth1, AlliedBaseWest, AlliedBaseEast &#125; &#125;
SovietAttackAir = &#123; &#123; AlliedBaseWest, AlliedBaseEast &#125;, &#123; AlliedBaseEast, AlliedBaseWest &#125; &#125;

InfAttack = &#123; &#125;
TankAttack = &#123; &#125;
AirAttack = &#123; &#125;
HeliAttack = &#123; &#125;

MCVReinforcement = &#123; "mcv" &#125;
TransportBoatReinforcement = &#123; "lst" &#125;

Rallypoints = &#123; Rallypoint &#125;
Barracks = &#123; Rax &#125;
Warfactory = &#123; Wafa &#125;

BuildVehicles = true
TrainInfantry = true
Attacking = true


--Tick = function&#40;&#41;
---	if ussr.HasNoRequiredUnits&#40;&#41; then
	--	allies.MarkCompletedObjective&#40;KillAll&#41;
	--end
--end

--keine Ahnung ob das was bewirkt

IdleHunt = function&#40;unit&#41; if not unit.IsDead then Trigger.OnIdle&#40;unit, unit.Hunt&#41; end end

--KI-SKRIPTE

ProduceInfantry = function&#40;&#41;

	local delay = Utils.RandomInteger&#40;DateTime.Seconds&#40;3&#41;, DateTime.Seconds&#40;9&#41;&#41;
	local toBuild = &#123; Utils.Random&#40;SovietInfantryTypes&#41; &#125;
	local Path = Utils.Random&#40;SovietAttackPathGround&#41;
	ussr.Build&#40;toBuild, function&#40;unit&#41;
		InfAttack&#91;#InfAttack + 1&#93; = unit&#91;1&#93;

		if #InfAttack >= 9 then
			SendUnits&#40;InfAttack, Path&#41;
			InfAttack = &#123; &#125;
			Trigger.AfterDelay&#40;DateTime.Minutes&#40;3&#41;, ProduceInfantry&#41;
		else
			Trigger.AfterDelay&#40;delay, ProduceInfantry&#41;
		end
	end&#41;
end

ProduceTanks = function&#40;&#41;

	local delay = Utils.RandomInteger&#40;DateTime.Seconds&#40;12&#41;, DateTime.Seconds&#40;15&#41;&#41;
	local toBuild = &#123; Utils.Random&#40;SovietArmorTypes&#41; &#125;
	local Path = Utils.Random&#40;SovietAttackPathGround&#41;
	ussr.Build&#40;toBuild, function&#40;unit&#41;
		TankAttack&#91;#TankAttack + 1&#93; = unit&#91;1&#93;

		if #TankAttack >= 3 then
			SendUnits&#40;TankAttack, Path&#41;
			TankAttack = &#123; &#125;
			Trigger.AfterDelay&#40;DateTime.Minutes&#40;3&#41;, ProduceTanks&#41;
		else
			Trigger.AfterDelay&#40;delay, ProduceTanks&#41;
		end
	end&#41;
end

ProducePlanes = function&#40;&#41;

	local delay = Utils.RandomInteger&#40;DateTime.Seconds&#40;12&#41;, DateTime.Seconds&#40;15&#41;&#41;
	local toBuild = &#123; Utils.Random&#40;SovietAircraftType&#41; &#125;
	local Path = Utils.Random&#40;SovietAttackAir&#41;
	ussr.Build&#40;toBuild, function&#40;unit&#41;
		AirAttack&#91;#AirAttack + 1&#93; = unit&#91;1&#93;

		if #AirAttack >= 1 then
			SendUnits&#40;AirAttack, Path&#41;
			AirAttack = &#123; &#125;
			Trigger.AfterDelay&#40;DateTime.Minutes&#40;3&#41;, ProducePlanes&#41;
		else
			Trigger.AfterDelay&#40;delay, ProducePlanes&#41;
		end
	end&#41;
end

ProduceHelis = function&#40;&#41;

	local delay = Utils.RandomInteger&#40;DateTime.Seconds&#40;12&#41;, DateTime.Seconds&#40;15&#41;&#41;
	local toBuild = &#123; Utils.Random&#40;SovietHeliType&#41; &#125;
	local Path = Utils.Random&#40;SovietAttackAir&#41;
	ussr.Build&#40;toBuild, function&#40;unit&#41;
		HeliAttack&#91;#HeliAttack + 1&#93; = unit&#91;1&#93;

		if #HeliAttack >= 1 then
			SendUnits&#40;HeliAttack, Path&#41;
			HeliAttack = &#123; &#125;
			Trigger.AfterDelay&#40;DateTime.Minutes&#40;3&#41;, ProduceHelis&#41;
		else
			Trigger.AfterDelay&#40;delay, ProduceHelis&#41;
		end
	end&#41;
end

SendUnits = function&#40;units, waypoints&#41;
	Utils.Do&#40;units, function&#40;unit&#41;
		if not unit.IsDead then
			Utils.Do&#40;waypoints, function&#40;waypoint&#41;
				unit.AttackMove&#40;waypoint.Location&#41;
			end&#41;
			unit.Hunt&#40;&#41;
		end
	end&#41;
end

InitProductionBuildings = function&#40;&#41;
	if not Wafa.IsDead then
		Wafa.IsPrimaryBuilding = true
		Trigger.OnKilled&#40;Wafa, function&#40;&#41; BuildVehicles = false end&#41;
	else
		BuildVehicles = false
	end

	if not Rax.IsDead then
		Rax.IsPrimaryBuilding = true
		Trigger.OnKilled&#40;Rax, function&#40;&#41; TrainInfantry = false end&#41;
	else
		TrainInfantry = false
	end
end

ActivateAI = function&#40;&#41;

	InitProductionBuildings&#40;&#41;

	Trigger.AfterDelay&#40;DateTime.Seconds&#40;10&#41;, function&#40;&#41;
		ProduceInfantry&#40;&#41;
		ProduceTanks&#40;&#41;
		ProducePlanes&#40;&#41;
		ProduceHelis&#40;&#41;
	end&#41;
end

--TRIGGER WÄHREND DER MISSION

SetupTriggers = function&#40;&#41;

	--Ziel 1&#58; Radaranlage zerstört
	Trigger.OnKilled&#40;RadarDome, function&#40;&#41;
		allies1.MarkCompletedObjective&#40;objDestroyRadar&#41;
		--allies2.MarkCompletedObjective&#40;objDestroyRadar2&#41;
		--Media.PlaySpeechNotification&#40;allies2, "AlliedReinforcementsArrived"&#41;
		Media.PlaySpeechNotification&#40;allies1, "AlliedReinforcementsArrived"&#41;
		Reinforcements.Reinforce&#40;allies1, TransportBoatReinforcement, &#123; TransportBoatSpawn.Location, TransportBoatMove.Location &#125;&#41;
		--Reinforcements.Reinforce&#40;allies2, TransportBoatReinforcement, &#123; TransportBoatSpawn.Location, TransportBoatMove.Location &#125;&#41;
		Reinforcements.Reinforce&#40;allies1, MCVReinforcement, &#123; MCVSpawn.Location, MCVMove.Location &#125;&#41;
		--Reinforcements.Reinforce&#40;allies2, MCVReinforcement, &#123; MCVSpawn.Location, MCVMove.Location &#125;&#41;

		Trigger.AfterDelay&#40;DateTime.Minutes&#40;10&#41;, ActivateAI&#41;
	end&#41;

	--Sekundärziel 1&#58; U-Boot-Werften
	Trigger.OnAllKilledOrCaptured&#40;SubPens, function&#40;&#41;
		allies1.MarkCompletedObjective&#40;objSubPens&#41;
		--allies2.MarkCompletedObjective&#40;objSubPens2&#41;
	end&#41;

	--Sekundärziel 2&#58; Luftwaffe
	Trigger.OnAllKilledOrCaptured&#40;AirFacilities, function&#40;&#41;
		allies1.MarkCompletedObjective&#40;objAirpower&#41;
		--allies2.MarkCompletedObjective&#40;objAirpower2&#41;
	end&#41;

	--Hauptziel&#58; Vorposten erobern
	Trigger.OnCapture&#40;ForwardCommand, function&#40;&#41;
		allies1.MarkCompletedObjective&#40;objCaptureFC&#41;
		--allies2.MarkCompletedObjective&#40;objCaptureFC2&#41;
	end&#41;


	--IDIOT
	Trigger.OnKilled&#40;ForwardCommand, function&#40;&#41;
		allies1.MarkFailedObjective&#40;objCaptureFC&#41;
		--allies2.MarkFailedObjective&#40;objCaptureFC2&#41;
	end&#41;
end


--MISSIONSZIELE PRÄSENTIEREN

InitObjectives = function&#40;&#41;

	ussrObj = ussr.AddPrimaryObjective&#40;"Deny the Allies."&#41;
	objCaptureFC = allies1.AddPrimaryObjective&#40;"Capture the Soviet Forward Command."&#41;
	--objCaptureFC2 = allies2.AddPrimaryObjective&#40;"Capture the Soviet Forward Command."&#41;
	objDestroyRadar = allies1.AddPrimaryObjective&#40;"Destroy the Soviet radar station."&#41;
	--objDestroyRadar2 = allies2.AddPrimaryObjective&#40;"Destroy the Soviet radar station."&#41;
	objAirpower = allies1.AddSecondaryObjective&#40;"Destroy all of the Soviets' air capabilities."&#41;
	--objAirpower2 = allies2.AddSecondaryObjective&#40;"Destroy all of the Soviets' air capabilities."&#41;
	objSubPens = allies1.AddSecondaryObjective&#40;"Destroy all of the Soviets' submarine production facilities."&#41;
	--objSubPens2 = allies2.AddSecondaryObjective&#40;"Destroy all of the Soviets' submarine production facilities."&#41;
end



WorldLoaded = function&#40;&#41;

	allies1 = Player.GetPlayer&#40;"Allies1"&#41;
	--allies2 = Player.GetPlayer&#40;"Allies2"&#41;
	ussr = Player.GetPlayer&#40;"USSR"&#41;
	
	Trigger.OnObjectiveAdded&#40;allies1, function&#40;p, id&#41;
		Media.DisplayMessage&#40;p.GetObjectiveDescription&#40;id&#41;, "New " .. string.lower&#40;p.GetObjectiveType&#40;id&#41;&#41; .. " objective"&#41;
	end&#41;

	Trigger.OnObjectiveCompleted&#40;allies1, function&#40;p, id&#41;
		Media.DisplayMessage&#40;p.GetObjectiveDescription&#40;id&#41;, "Objective completed"&#41;
	end&#41;
	Trigger.OnObjectiveFailed&#40;allies1, function&#40;p, id&#41;
		Media.DisplayMessage&#40;p.GetObjectiveDescription&#40;id&#41;, "Objective failed"&#41;
	end&#41;

	Trigger.OnPlayerLost&#40;allies1, function&#40;&#41;
		Media.PlaySpeechNotification&#40;player, "Lose"&#41;
	end&#41;
	Trigger.OnPlayerWon&#40;allies1, function&#40;&#41;
		Media.PlaySpeechNotification&#40;player, "Win"&#41;
	end&#41;
	SetupTriggers&#40;&#41;
	InitObjectives&#40;&#41;
end
seems to be some kind of silly parsing error (I mean, there is an "end", just not in line 245, but 246...

Any help would be greatly appreciated.

Posted: Mon Nov 20, 2017 11:16 am
by Headkillah
I have no knowledge about this, but the errormessage is:

" 'end' expected (to close 'function' at line 221) near '<eof>'"

For me it sounds, that you have an error with and "end"-Tag in "WorldLoaded = function()".

Maybe you´ve forgot an end-tag or you used the wrong end-tag ??

Posted: Mon Nov 20, 2017 10:38 pm
by SethXXX
I have done further research since posting this, and I'm inclined to consider this an error in the compiler. There is an "end"-tag in the last line, just not where the program seems to expect it.

Another example: another map below crashes if I don't put the "=" in the last line, even though this is obviously wrong. If I put them in, it loads without problems.

Code: Select all

WorldLoaded = function&#40;&#41;
	allies = Player.GetPlayer&#40;"Allies"&#41;
	ussr = Player.GetPlayer&#40;"USSR"&#41;
	greece = Player.GetPlayer&#40;"Greece"&#41;

	InitObjectives&#40;&#41;
	ActivateAI&#40;&#41;

	Trigger.AfterDelay&#40;DateTime.Seconds&#40;4&#41;, function&#40;&#41; MoveTruck&#40;TheTruck&#41; end&#41;
  Trigger.AfterDelay&#40;DateTime.Seconds&#40;7&#41;, function&#40;&#41; SendReinforcements&#40;&#41; end&#41;

end==

Posted: Tue Nov 21, 2017 12:37 am
by abcdefg30
Sorry for the very late response. I somehow forgot about this. :/

Found only a few errors and it works now for me.

- OnKilled and OnCapture only use a single actor as input. So you don't need to use "RadarDome = { RadarDome }" and "ForwardCommand = { SovietForwardCommand }" (and shouldn't use it here).
- You had "Media.PlaySpeechNotification(player, "Lose")". That player needs to be "allies1".

The full script I used:

Code: Select all

--VARIABLEN

SovietInfantryTypes = &#123; "e1", "e1", "e1", "e2", "e2", "e4", "e4", "shok" &#125;
SovietArmorTypes = &#123; "3tnk", "3tnk", "3tnk", "3tnk", "v2rl", "4tnk", "ttnk" &#125;
SovietAircraftType = &#123; "yak", "yak", "yak", "mig" &#125;
SovietHeliType = &#123; "hind" &#125;

SubPens = &#123; SubPen1, SubPen2, SubPen3, SubPen4 &#125;
AirFacilities = &#123; Airfield1, Airfield2, Airfield3, Helipad1, Helipad2, Helipad3 &#125;

IdlingUnits = &#123; &#125;
--AttackGroupSize = 3

SovietAttackPathGround = &#123; &#123; Rallypoint, AttackMoveSouth1, AlliedBaseEast, AlliedBaseWest &#125;, &#123; Rallypoint, AttackMoveNorth1, AlliedBaseWest, AlliedBaseEast &#125; &#125;
SovietAttackAir = &#123; &#123; AlliedBaseWest, AlliedBaseEast &#125;, &#123; AlliedBaseEast, AlliedBaseWest &#125; &#125;

InfAttack = &#123; &#125;
TankAttack = &#123; &#125;
AirAttack = &#123; &#125;
HeliAttack = &#123; &#125;

MCVReinforcement = &#123; "mcv" &#125;
TransportBoatReinforcement = &#123; "lst" &#125;

Rallypoints = &#123; Rallypoint &#125;
Barracks = &#123; Rax &#125;
Warfactory = &#123; Wafa &#125;

BuildVehicles = true
TrainInfantry = true
Attacking = true


--Tick = function&#40;&#41;
---	if ussr.HasNoRequiredUnits&#40;&#41; then
	--	allies.MarkCompletedObjective&#40;KillAll&#41;
	--end
--end

--keine Ahnung ob das was bewirkt

IdleHunt = function&#40;unit&#41; if not unit.IsDead then Trigger.OnIdle&#40;unit, unit.Hunt&#41; end end

--KI-SKRIPTE

ProduceInfantry = function&#40;&#41;

	local delay = Utils.RandomInteger&#40;DateTime.Seconds&#40;3&#41;, DateTime.Seconds&#40;9&#41;&#41;
	local toBuild = &#123; Utils.Random&#40;SovietInfantryTypes&#41; &#125;
	local Path = Utils.Random&#40;SovietAttackPathGround&#41;
	ussr.Build&#40;toBuild, function&#40;unit&#41;
		InfAttack&#91;#InfAttack + 1&#93; = unit&#91;1&#93;

		if #InfAttack >= 9 then
			SendUnits&#40;InfAttack, Path&#41;
			InfAttack = &#123; &#125;
			Trigger.AfterDelay&#40;DateTime.Minutes&#40;3&#41;, ProduceInfantry&#41;
		else
			Trigger.AfterDelay&#40;delay, ProduceInfantry&#41;
		end
	end&#41;
end

ProduceTanks = function&#40;&#41;

	local delay = Utils.RandomInteger&#40;DateTime.Seconds&#40;12&#41;, DateTime.Seconds&#40;15&#41;&#41;
	local toBuild = &#123; Utils.Random&#40;SovietArmorTypes&#41; &#125;
	local Path = Utils.Random&#40;SovietAttackPathGround&#41;
	ussr.Build&#40;toBuild, function&#40;unit&#41;
		TankAttack&#91;#TankAttack + 1&#93; = unit&#91;1&#93;

		if #TankAttack >= 3 then
			SendUnits&#40;TankAttack, Path&#41;
			TankAttack = &#123; &#125;
			Trigger.AfterDelay&#40;DateTime.Minutes&#40;3&#41;, ProduceTanks&#41;
		else
			Trigger.AfterDelay&#40;delay, ProduceTanks&#41;
		end
	end&#41;
end

ProducePlanes = function&#40;&#41;

	local delay = Utils.RandomInteger&#40;DateTime.Seconds&#40;12&#41;, DateTime.Seconds&#40;15&#41;&#41;
	local toBuild = &#123; Utils.Random&#40;SovietAircraftType&#41; &#125;
	local Path = Utils.Random&#40;SovietAttackAir&#41;
	ussr.Build&#40;toBuild, function&#40;unit&#41;
		AirAttack&#91;#AirAttack + 1&#93; = unit&#91;1&#93;

		if #AirAttack >= 1 then
			SendUnits&#40;AirAttack, Path&#41;
			AirAttack = &#123; &#125;
			Trigger.AfterDelay&#40;DateTime.Minutes&#40;3&#41;, ProducePlanes&#41;
		else
			Trigger.AfterDelay&#40;delay, ProducePlanes&#41;
		end
	end&#41;
end

ProduceHelis = function&#40;&#41;

	local delay = Utils.RandomInteger&#40;DateTime.Seconds&#40;12&#41;, DateTime.Seconds&#40;15&#41;&#41;
	local toBuild = &#123; Utils.Random&#40;SovietHeliType&#41; &#125;
	local Path = Utils.Random&#40;SovietAttackAir&#41;
	ussr.Build&#40;toBuild, function&#40;unit&#41;
		HeliAttack&#91;#HeliAttack + 1&#93; = unit&#91;1&#93;

		if #HeliAttack >= 1 then
			SendUnits&#40;HeliAttack, Path&#41;
			HeliAttack = &#123; &#125;
			Trigger.AfterDelay&#40;DateTime.Minutes&#40;3&#41;, ProduceHelis&#41;
		else
			Trigger.AfterDelay&#40;delay, ProduceHelis&#41;
		end
	end&#41;
end

SendUnits = function&#40;units, waypoints&#41;
	Utils.Do&#40;units, function&#40;unit&#41;
		if not unit.IsDead then
			Utils.Do&#40;waypoints, function&#40;waypoint&#41;
				unit.AttackMove&#40;waypoint.Location&#41;
			end&#41;
			unit.Hunt&#40;&#41;
		end
	end&#41;
end

InitProductionBuildings = function&#40;&#41;
	if not Wafa.IsDead then
		Wafa.IsPrimaryBuilding = true
		Trigger.OnKilled&#40;Wafa, function&#40;&#41; BuildVehicles = false end&#41;
	else
		BuildVehicles = false
	end

	if not Rax.IsDead then
		Rax.IsPrimaryBuilding = true
		Trigger.OnKilled&#40;Rax, function&#40;&#41; TrainInfantry = false end&#41;
	else
		TrainInfantry = false
	end
end

ActivateAI = function&#40;&#41;

	InitProductionBuildings&#40;&#41;

	Trigger.AfterDelay&#40;DateTime.Seconds&#40;10&#41;, function&#40;&#41;
		ProduceInfantry&#40;&#41;
		ProduceTanks&#40;&#41;
		ProducePlanes&#40;&#41;
		ProduceHelis&#40;&#41;
	end&#41;
end

--TRIGGER WÄHREND DER MISSION

SetupTriggers = function&#40;&#41;

	--Ziel 1&#58; Radaranlage zerstört
	Trigger.OnKilled&#40;RadarDome, function&#40;&#41;
		allies1.MarkCompletedObjective&#40;objDestroyRadar&#41;
		--allies2.MarkCompletedObjective&#40;objDestroyRadar2&#41;
		--Media.PlaySpeechNotification&#40;allies2, "AlliedReinforcementsArrived"&#41;
		Media.PlaySpeechNotification&#40;allies1, "AlliedReinforcementsArrived"&#41;
		Reinforcements.Reinforce&#40;allies1, TransportBoatReinforcement, &#123; TransportBoatSpawn.Location, TransportBoatMove.Location &#125;&#41;
		--Reinforcements.Reinforce&#40;allies2, TransportBoatReinforcement, &#123; TransportBoatSpawn.Location, TransportBoatMove.Location &#125;&#41;
		Reinforcements.Reinforce&#40;allies1, MCVReinforcement, &#123; MCVSpawn.Location, MCVMove.Location &#125;&#41;
		--Reinforcements.Reinforce&#40;allies2, MCVReinforcement, &#123; MCVSpawn.Location, MCVMove.Location &#125;&#41;

		Trigger.AfterDelay&#40;DateTime.Minutes&#40;10&#41;, ActivateAI&#41;
	end&#41;

	--Sekundärziel 1&#58; U-Boot-Werften
	Trigger.OnAllKilledOrCaptured&#40;SubPens, function&#40;&#41;
		allies1.MarkCompletedObjective&#40;objSubPens&#41;
		--allies2.MarkCompletedObjective&#40;objSubPens2&#41;
	end&#41;

	--Sekundärziel 2&#58; Luftwaffe
	Trigger.OnAllKilledOrCaptured&#40;AirFacilities, function&#40;&#41;
		allies1.MarkCompletedObjective&#40;objAirpower&#41;
		--allies2.MarkCompletedObjective&#40;objAirpower2&#41;
	end&#41;

	--Hauptziel&#58; Vorposten erobern
	Trigger.OnCapture&#40;SovietForwardCommand, function&#40;&#41;
		allies1.MarkCompletedObjective&#40;objCaptureFC&#41;
		--allies2.MarkCompletedObjective&#40;objCaptureFC2&#41;
	end&#41;


	--IDIOT
	Trigger.OnKilled&#40;SovietForwardCommand, function&#40;&#41;
		allies1.MarkFailedObjective&#40;objCaptureFC&#41;
		--allies2.MarkFailedObjective&#40;objCaptureFC2&#41;
	end&#41;
end


--MISSIONSZIELE PRÄSENTIEREN

InitObjectives = function&#40;&#41;

	ussrObj = ussr.AddPrimaryObjective&#40;"Deny the Allies."&#41;
	objCaptureFC = allies1.AddPrimaryObjective&#40;"Capture the Soviet Forward Command."&#41;
	--objCaptureFC2 = allies2.AddPrimaryObjective&#40;"Capture the Soviet Forward Command."&#41;
	objDestroyRadar = allies1.AddPrimaryObjective&#40;"Destroy the Soviet radar station."&#41;
	--objDestroyRadar2 = allies2.AddPrimaryObjective&#40;"Destroy the Soviet radar station."&#41;
	objAirpower = allies1.AddSecondaryObjective&#40;"Destroy all of the Soviets' air capabilities."&#41;
	--objAirpower2 = allies2.AddSecondaryObjective&#40;"Destroy all of the Soviets' air capabilities."&#41;
	objSubPens = allies1.AddSecondaryObjective&#40;"Destroy all of the Soviets' submarine production facilities."&#41;
	--objSubPens2 = allies2.AddSecondaryObjective&#40;"Destroy all of the Soviets' submarine production facilities."&#41;
end



WorldLoaded = function&#40;&#41;

	allies1 = Player.GetPlayer&#40;"Allies1"&#41;
	--allies2 = Player.GetPlayer&#40;"Allies2"&#41;
	ussr = Player.GetPlayer&#40;"USSR"&#41;

	Trigger.OnObjectiveAdded&#40;allies1, function&#40;p, id&#41;
		Media.DisplayMessage&#40;p.GetObjectiveDescription&#40;id&#41;, "New " .. string.lower&#40;p.GetObjectiveType&#40;id&#41;&#41; .. " objective"&#41;
	end&#41;

	Trigger.OnObjectiveCompleted&#40;allies1, function&#40;p, id&#41;
		Media.DisplayMessage&#40;p.GetObjectiveDescription&#40;id&#41;, "Objective completed"&#41;
	end&#41;
	Trigger.OnObjectiveFailed&#40;allies1, function&#40;p, id&#41;
		Media.DisplayMessage&#40;p.GetObjectiveDescription&#40;id&#41;, "Objective failed"&#41;
	end&#41;

	Trigger.OnPlayerLost&#40;allies1, function&#40;&#41;
		Media.PlaySpeechNotification&#40;allies1, "Lose"&#41;
	end&#41;
	Trigger.OnPlayerWon&#40;allies1, function&#40;&#41;
		Media.PlaySpeechNotification&#40;allies1, "Win"&#41;
	end&#41;
	SetupTriggers&#40;&#41;
	InitObjectives&#40;&#41;
end

Posted: Thu Nov 23, 2017 2:09 pm
by SethXXX
Thank you as well, I knew those experts would be lurking around here somewhere ;)

EDIT: Tested. Everything works, you are a genius ;)