Page 5 of 13

Posted: Sun Jan 26, 2014 8:59 pm
by kaneCVR
Ok - I have officially put the mod into a BETA stage :D YAY!

Now I need help with some gruntwork - if anyone is available, and wats to contribute to this mod, I need to have all .SHP and .TEM files in C&C's WINTER.MIX converted from the winter.pal to Red Alert's TEMPERAT.PAL or SNOW.PAL (whichever works best)...

- either this or an ideea for a clever workaround that forces the openRA engine to render all ACTORS in RA Temperat.pal and the tileset in C&C's winter.pal...

I want to introduce this tileset into my mod - but It needs load a separate (winter.pal) palette that corrupts the unit graphics :(

- you will be mentioned in the mod's credits of course :D -

I can do it myself like I did with most other units, but I don't have the time right now, as I am busy scripting sigleplayer missions - got the first 3 nod missions down, and three more in the pipeline (want to have 15 in total for each faction)

Posted: Sun Jan 26, 2014 9:58 pm
by Sleipnir
OpenRA already uses different palettes for terrain and actors. No workarounds are needed :)

Take a look at the RA desert tileset (which is a direct copy from C&C, like you want to do) for an example on how to set this up.

Posted: Sun Jan 26, 2014 10:47 pm
by kaneCVR
...that fixed the graphics corruption bug, but now I get:

Code: Select all

Exception of type `System.InvalidOperationException`: Unit `overlay` does not have a sequence `build-valid-winter`
when I try to place a building... :(

I could not find a reference to any unit named "overlay" in any .yaml file....

Posted: Mon Jan 27, 2014 1:18 am
by Sleipnir
Take a look near the bottom of sequences/misc.yaml. You'll probably want to duplicate the -temperat definitions.

Posted: Mon Jan 27, 2014 9:33 am
by kaneCVR
Yuuuuuup - that did it. Thanks again!

Posted: Wed Jan 29, 2014 6:07 pm
by kaneCVR
Now I seem to be having an issue with the walls... all wall types get corrupted on the WINTER tileset...

How can I fix this? If I remove Palette: terrain from Defaults.yaml, I get corruption on the DESERT and TEMPERAT tilesets....

Can I use Palette: player for all walls?

Also, been getting this random crash recently;

Code: Select all

Red Alert: Tiberian Origins Mod at Version Beta 0.1
Operating System: Windows (Microsoft Windows NT 6.1.7600.0)
Runtime Version: .NET CLR 2.0.50727.4984
Exception of type `System.NullReferenceException`: Object reference not set to an instance of an object.
   at OpenRA.Effects.DelayedAction.<Tick>m__17F(World w)
   at OpenRA.World.Tick()
   at OpenRA.Game.TickInner(OrderManager orderManager)
   at OpenRA.Game.Tick(OrderManager orderManager)
   at OpenRA.Game.Run()
   at OpenRA.Program.Run(String[] args)
   at OpenRA.Program.Main(String[] args)

Posted: Wed Jan 29, 2014 8:43 pm
by Matt
Have a look at https://github.com/OpenRA/OpenRA/blob/b ... esert.yaml where I have both Palette vs. PlayerPalette defined to solve the problem that TD walls/terrain and RA player actors have incompatible color ranges.

Posted: Wed Jan 29, 2014 10:23 pm
by Sleipnir
DelayedAction is used in a few places, and unfortunately that exception doesn't tell us which one. Would you be able to narrow that crash down to one of the following cases?
  • Use C4 on an actor.
  • Demolish or repair bridges.
  • Kill a building with the DeadBuildingState trait.
  • Fire a weapon with a warhead that defines a delay.
  • Construct a building that grants new construction options.
  • Use a lua script that calls RunAfterDelay.
  • Launch a GPS satellite.

Posted: Wed Jan 29, 2014 11:29 pm
by kaneCVR
Sleipnir wrote: DelayedAction is used in a few places, and unfortunately that exception doesn't tell us which one. Would you be able to narrow that crash down to one of the following cases?
  • Use C4 on an actor.
  • Demolish or repair bridges.
  • Kill a building with the DeadBuildingState trait.
  • Fire a weapon with a warhead that defines a delay.
  • Construct a building that grants new construction options.
  • Use a lua script that calls RunAfterDelay.
  • Launch a GPS satellite.
I'm pretty sure it's - Use a lua script that calls RunAfterDelay. Here is my mission code:

Code: Select all

-- Setup reinforcement wave unit tipes --

FirstAttackWave = { "2tnk", "2tnk", "1tnk", "1tnk", "arty", "jeep", "jeep" }
SecondThirdAttackWave = { "2tnk", "2tnk", "2tnk", "arty", "arty", "1tnk", "1tnk" }
FourthFifthAttackWave = { "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "arty", "arty" }

MissionAccomplished = function()
	Mission.MissionOver({ player }, nil, false)
	--Media.PlayMovieFullscreen("snowbomb.vqa")
end

MissionFailed = function()
	Mission.MissionOver(nil, { player }, false)
	--Media.PlayMovieFullscreen("bmap.vqa")
end

-- Configuring attack wave functions

SendFirstAttackWave = function()
        for FirstAttackWaveCount = 1, 7 do
                local waveunit = Actor.Create(FirstAttackWave[FirstAttackWaveCount], { Owner = enemy, Location = LandSpawn.Location })
                Actor.AttackMove(waveunit, PlayerBase.Location)
        end
end

SendSecondAttackWave = function()
        for SecondAttackWaveCount = 1, 7 do
                local waveunit = Actor.Create(SecondThirdAttackWave[SecondAttackWaveCount], { Owner = enemy, Location = LandSpawn.Location })
                Actor.AttackMove(waveunit, PlayerBase.Location)
        end
end

SendThirdAttackWave = function()
        for ThirdAttackWaveCount = 1, 7 do
                local waveunit = Actor.Create(SecondThirdAttackWave[ThirdAttackWaveCount], { Owner = enemy, Location = LandSpawn.Location })
                Actor.AttackMove(waveunit, PlayerBase.Location)
        end
end

SendFourthAttackWave = function()
        for FourthAttackWaveCount = 1, 7 do
                local waveunit = Actor.Create(FourthFifthAttackWave[FourthAttackWaveCount], { Owner = enemy, Location = LandSpawn.Location })
                Actor.AttackMove(waveunit, PlayerBase.Location)
        end
end

SendFiftAttackWave = function()
        for FifthAttackWaveCount = 1, 7 do
                local waveunit = Actor.Create(FourthFifthAttackWave[FifthAttackWaveCount], { Owner = enemy, Location = LandSpawn.Location })
                Actor.AttackMove(waveunit, PlayerBase.Location)
        end
end

-- Creates a patrol function with two waypoints and one unit.

LoopPatrol = function(actor, waypoints) 
   Utils.Do(waypoints, function(waypoint) 
      Actor.AttackMove(actor, waypoint.Location) 
   end) 
   Actor.CallFunc(actor, function() LoopPatrol(actor, waypoints) end) 
end

tick = 0 -- Used for Briefing display code.

WorldLoaded = function() -- used to call previously created functions
	player = OpenRA.GetPlayer("Nod")
	enemy = OpenRA.GetPlayer("Allies")
	LoopPatrol(PatrolN1, { PatrolN1A, PatrolN1B })
	LoopPatrol(PatrolN2, { PatrolN1B, PatrolN1A })
	LoopPatrol(PatrolL1, { PatrolL1B, PatrolL1A })
	LoopPatrol(PatrolN5, { PatrolN2B, PatrolN2A })
	LoopPatrol(PatrolN4, { PatrolN2B, PatrolN2A })
	LoopPatrol(PatrolN3, { PatrolN2A, PatrolN2B })
	LoopPatrol(PatrolL2, { PatrolL2B, PatrolL2A })
	LoopPatrol(PatrolL4, { PatrolL2B, PatrolL2A })
	LoopPatrol(PatrolL3, { PatrolL2A, PatrolL2B })
	LoopPatrol(PatrolL5, { PatrolL2A, PatrolL2B })
	LoopPatrol(PatrolL6, { PatrolL3A, PatrolL3B })
	LoopPatrol(Truck1, { TibRouteA, TibRouteB })
	LoopPatrol(Truck2, { TibRouteA, TibRouteB })
	OpenRA.RunAfterDelay(25 * 240, SendFirstAttackWave) 
    OpenRA.RunAfterDelay(25 * 480, SendSecondAttackWave)
    OpenRA.RunAfterDelay(25 * 600, SendThirdAttackWave)
    OpenRA.RunAfterDelay(25 * 780, SendFourthAttackWave)
    OpenRA.RunAfterDelay(25 * 820, SendFifthAttackWave)
	print(" Briefing: The Tiber River Meteor sample you acquired contains an element foreign to our solar system. Our scientists speculate that has multiple uses - a power source, a perfect semiconductor, it can reinforce alloys... ")
	print(" Capture the Allied base near your LZ then secure the meteor crash site for the Brotherhood and push the allies out of the region. ")
end

-- Briefing and win/lose check Code

Tick = function()
        if Mission.RequiredUnitsAreDestroyed(player) then
                MissionFailed()
        end
		tick = tick + 1
    if tick % 3000 == 0 then
	print(" Secure the meteor crash site. Eliminate all Allied units and structures. ")
    	end
end

Posted: Thu Jan 30, 2014 8:04 am
by Sleipnir
You have a typo in your script: "SendFiftAttackWave". I have filed #4512 about having OpenRA catch this error in the future.

Posted: Thu Jan 30, 2014 11:49 am
by kaneCVR
Cmd. Matt wrote: Have a look at https://github.com/OpenRA/OpenRA/blob/b ... esert.yaml where I have both Palette vs. PlayerPalette defined to solve the problem that TD walls/terrain and RA player actors have incompatible color ranges.
That's what I did, but the walls still use Winter.pal. Here is part of my winter.yaml file:

Code: Select all

General:
	Name: Winter
	Id: WINTER
	Extensions: .win, .shp, .tem
	Palette: winter.pal
	PlayerPalette: temperat.pal
	WaterPaletteRotationBase: 32
	EditorTemplateOrder: Terrain, Debris, Road, Cliffs, Water Cliffs, Beach, River, Bridge
Maybe if I use Palette: PlayerPalette for ~Walls in the Defaults.yaml file?
Sleipnir wrote: You have a typo in your script: "SendFiftAttackWave". I have filed #4512 about having OpenRA catch this error in the future.
Thanks man, I missed that typo :z Will give it another test run...

Posted: Thu Jan 30, 2014 2:30 pm
by kaneCVR
Ok - found something new - this is either a bug, or my coding SUCKS... It looks to me as if the game engine does not recognize naval units...

When I try to call for naval reinforcements, the game crashes with the following error:

Code: Select all

Red Alert: Tiberian Origins Mod at Version Beta 0.1
Operating System: Windows (Microsoft Windows NT 6.1.7600.0)
Runtime Version: .NET CLR 2.0.50727.4984
Exception of type `NLua.Exceptions.LuaScriptException`: [string "mission.lua"]:83: No actor name specified
   at NLua.Lua.ThrowExceptionFromError(Int32 oldTop)
   at NLua.Lua.CallFunction(Object function, Object[] args, Type[] returnTypes)
   at NLua.LuaFunction.Call(Object[] args, Type[] returnTypes)
   at NLua.Method.LuaDelegate.CallFunction(Object[] args, Object[] inArgs, Int32[] outArgs)
   at LuaGeneratedClass1.CallFunction()
   at OpenRA.Effects.DelayedAction.<Tick>m__17F(World w)
   at OpenRA.World.Tick()
   at OpenRA.Game.TickInner(OrderManager orderManager)
   at OpenRA.Game.Tick(OrderManager orderManager)
   at OpenRA.Game.Run()
   at OpenRA.Program.Run(String[] args)
   at OpenRA.Program.Main(String[] args)
Here is my mission.lua file - maybe I misspelled something again...

Code: Select all

-- Setup reinforcement wave unit tipes --

FirstAttackWave = { "2tnk", "2tnk", "1tnk", "1tnk", "arty", "jeep", "jeep" }
SecondThirdAttackWave = { "2tnk", "2tnk", "2tnk", "1tnk", "1tnk", "arty", "arty" }
FourthFifthAttackWave = { "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "arty", "arty" }
SixthAttackWave = { "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "mlrs", "mlrs" }
SeventhAttackWave = { "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "mlrs", "mlrs", "mlrs" }
EigthAttackWave = { "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "mlrs", "mlrs", "mlrs" }
FirstNavalAttackWave = { "pt", "pt", "dd", "dd" }
SecondNavalAttackWave = { "pt", "pt", "dd", "ca" }
ThirdNavalAttackWave = { "pt", "dd", "dd", "ca" }

MissionAccomplished = function()
	Mission.MissionOver({ player }, nil, false)
	--Media.PlayMovieFullscreen("snowbomb.vqa")
end

MissionFailed = function()
	Mission.MissionOver(nil, { player }, false)
	--Media.PlayMovieFullscreen("bmap.vqa")
end

-- Configuring attack wave functions

SendFirstAttackWave = function()
        for FirstAttackWaveCount = 1, 7 do
                local waveunit = Actor.Create(FirstAttackWave[FirstAttackWaveCount], { Owner = enemy, Location = LandSpawn.Location })
                Actor.AttackMove(waveunit, PlayerBase.Location)
        end
end

SendSecondAttackWave = function()
        for SecondAttackWaveCount = 1, 7 do
                local waveunit = Actor.Create(SecondThirdAttackWave[SecondAttackWaveCount], { Owner = enemy, Location = LandSpawn.Location })
                Actor.AttackMove(waveunit, PlayerBase.Location)
        end
end

SendThirdAttackWave = function()
        for ThirdAttackWaveCount = 1, 7 do
                local waveunit = Actor.Create(SecondThirdAttackWave[ThirdAttackWaveCount], { Owner = enemy, Location = LandSpawn.Location })
                Actor.AttackMove(waveunit, PlayerBase.Location)
        end
end

SendFourthAttackWave = function()
        for FourthAttackWaveCount = 1, 7 do
                local waveunit = Actor.Create(FourthFifthAttackWave[FourthAttackWaveCount], { Owner = enemy, Location = LandSpawn.Location })
                Actor.AttackMove(waveunit, PlayerBase.Location)
        end
end

SendFifthAttackWave = function()
        for FifthAttackWaveCount = 1, 7 do
                local waveunit = Actor.Create(FourthFifthAttackWave[FifthAttackWaveCount], { Owner = enemy, Location = LandSpawn.Location })
                Actor.AttackMove(waveunit, PlayerBase.Location)
        end
end

SendSixthAttackWave = function()
        for SixthAttackWaveCount = 1, 7 do
                local waveunit = Actor.Create(SixthAttackWave[SixthAttackWaveCount], { Owner = enemy, Location = LandSpawn.Location })
                Actor.AttackMove(waveunit, PlayerBase.Location)
        end
end

SendSeventhAttackWave = function()
        for SeventhAttackWaveCount = 1, 9 do
                local waveunit = Actor.Create(SeventhAttackWave[SeventhAttackWaveCount], { Owner = enemy, Location = LandSpawn.Location })
                Actor.AttackMove(waveunit, PlayerBase.Location)
        end
end

SendEigthAttackWave = function()
        for EigthAttackWaveCount = 1, 9 do
                local waveunit = Actor.Create(EigthAttackWave[EigthAttackWaveCount], { Owner = enemy, Location = LandSpawn.Location })
                Actor.AttackMove(waveunit, PlayerBase.Location)
        end
end

SendFirstNavalAttackWave = function()
        for FirstNavalAttackWaveCount = 1, 4 do
                local waveunit = Actor.Create(FirstNavalAttackWave[FirstNavalAttackWave], { Owner = enemy, Location = NavalSpawn.Location })
                Actor.AttackMove(waveunit, PlayerShore.Location)
        end
end

SendSecondNavalAttackWave = function()
        for SecondNavalAttackWaveCount = 1, 4 do
                local waveunit = Actor.Create(SecondNavalAttackWave[SecondNavalAttackWave], { Owner = enemy, Location = NavalSpawn.Location })
                Actor.AttackMove(waveunit, PlayerShore.Location)
        end
end

SendThirdNavalAttackWave = function()
        for ThirdNavalAttackWaveCount = 1, 4 do
                local waveunit = Actor.Create(ThirdNavalAttackWave[ThirdNavalAttackWave], { Owner = enemy, Location = NavalSpawn.Location })
                Actor.AttackMove(waveunit, PlayerShore.Location)
        end
end

-- Creates a patrol function with two waypoints and one unit.

LoopPatrol = function(actor, waypoints) 
   Utils.Do(waypoints, function(waypoint) 
      Actor.AttackMove(actor, waypoint.Location) 
   end) 
   Actor.CallFunc(actor, function() LoopPatrol(actor, waypoints) end) 
end

tick = 0 -- Used for Briefing display code.

WorldLoaded = function() -- used to call previously created functions
	player = OpenRA.GetPlayer("Nod")
	enemy = OpenRA.GetPlayer("Allies")
	LoopPatrol(PatrolN1, { PatrolN1A, PatrolN1B })
	LoopPatrol(PatrolN2, { PatrolN1B, PatrolN1A })
	LoopPatrol(PatrolL1, { PatrolL1B, PatrolL1A })
	LoopPatrol(PatrolN5, { PatrolN2B, PatrolN2A })
	LoopPatrol(PatrolN4, { PatrolN2B, PatrolN2A })
	LoopPatrol(PatrolN3, { PatrolN2A, PatrolN2B })
	LoopPatrol(PatrolL2, { PatrolL2B, PatrolL2A })
	LoopPatrol(PatrolL4, { PatrolL2B, PatrolL2A })
	LoopPatrol(PatrolL3, { PatrolL2A, PatrolL2B })
	LoopPatrol(PatrolL5, { PatrolL2A, PatrolL2B })
	LoopPatrol(PatrolL6, { PatrolL3A, PatrolL3B })
	LoopPatrol(Truck1, { TibRouteA, TibRouteB })
	LoopPatrol(Truck2, { TibRouteA, TibRouteB })
	OpenRA.RunAfterDelay(25 * 240, SendFirstAttackWave)
	OpenRA.RunAfterDelay(25 * 5, SendFirstNavalAttackWave) --360	
    OpenRA.RunAfterDelay(25 * 480, SendSecondAttackWave)
    OpenRA.RunAfterDelay(25 * 600, SendThirdAttackWave)
	OpenRA.RunAfterDelay(25 * 660, SendSecondNavalAttackWave)
    OpenRA.RunAfterDelay(25 * 780, SendFourthAttackWave)
    OpenRA.RunAfterDelay(25 * 840, SendFifthAttackWave)
	OpenRA.RunAfterDelay(25 * 960, SendSixthAttackWave)
	OpenRA.RunAfterDelay(25 * 1080, SendSeventhAttackWave)
	OpenRA.RunAfterDelay(25 * 1200, SendEigthAttackWave)
	OpenRA.RunAfterDelay(25 * 1320, SendThirdNavalAttackWave)
	print(" Briefing: The Tiber river meteor sample you acquired contains an element foreign to our solar system. Our scientists speculate that has multiple uses - a power source, a perfect semiconductor, it can reinforce alloys... ")
	print(" Capture the Allied base near your LZ then secure the meteor crash site for the Brotherhood and push the allies out of the region. ")
end

-- Briefing and win/lose check Code

Tick = function()
        if Mission.RequiredUnitsAreDestroyed(player) then
                MissionFailed()
        end
		tick = tick + 1
    if tick % 3000 == 0 then
	print(" Secure the meteor crash site. Eliminate all Allied units and structures. ")
    	end
end

Posted: Fri Jan 31, 2014 2:21 am
by Scott_NZ
Line 83, as noted by the error message:

Code: Select all

local waveunit = Actor.Create(FirstNavalAttackWave[FirstNavalAttackWave], { Owner = enemy, Location = NavalSpawn.Location })
FirstNavalAttackWave[FirstNavalAttackWave] doesn't make any sense, and is consistent with the error message because it will evaluate to nil.

Posted: Fri Jan 31, 2014 9:43 am
by kaneCVR
Yeah, it's supposed to be "FirstNavaAttackWave[FirstNavalAttackWaveCount]"

Posted: Fri Jan 31, 2014 11:23 am
by Sleipnir
You should consider writing a function that you pass your array of actors and waypoints to. This would remove most of your duplication, and the copy-paste errors that came with that. The function would look similar to LoopPatrol.