Red Alert: Tiberium Origins MOD

Information and discussion for custom maps and mods.
Post Reply
kaneCVR
Posts: 93
Joined: Tue Dec 10, 2013 9:20 pm

Post 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)
Last edited by kaneCVR on Sun Jan 26, 2014 10:37 pm, edited 1 time in total.
User avatar
Sleipnir
Posts: 878
Joined: Wed Apr 10, 2002 11:52 pm
Contact:

Post 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.
kaneCVR
Posts: 93
Joined: Tue Dec 10, 2013 9:20 pm

Post 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....
User avatar
Sleipnir
Posts: 878
Joined: Wed Apr 10, 2002 11:52 pm
Contact:

Post by Sleipnir »

Take a look near the bottom of sequences/misc.yaml. You'll probably want to duplicate the -temperat definitions.
kaneCVR
Posts: 93
Joined: Tue Dec 10, 2013 9:20 pm

Post by kaneCVR »

Yuuuuuup - that did it. Thanks again!
kaneCVR
Posts: 93
Joined: Tue Dec 10, 2013 9:20 pm

Post 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)
Matt
Posts: 1164
Joined: Tue May 01, 2012 12:21 pm
Location: Germany

Post 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.
User avatar
Sleipnir
Posts: 878
Joined: Wed Apr 10, 2002 11:52 pm
Contact:

Post 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.
kaneCVR
Posts: 93
Joined: Tue Dec 10, 2013 9:20 pm

Post 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
User avatar
Sleipnir
Posts: 878
Joined: Wed Apr 10, 2002 11:52 pm
Contact:

Post by Sleipnir »

You have a typo in your script: "SendFiftAttackWave". I have filed #4512 about having OpenRA catch this error in the future.
kaneCVR
Posts: 93
Joined: Tue Dec 10, 2013 9:20 pm

Post 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...
kaneCVR
Posts: 93
Joined: Tue Dec 10, 2013 9:20 pm

Post 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
Scott_NZ
Posts: 94
Joined: Thu Sep 13, 2012 9:09 am

Post 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.
kaneCVR
Posts: 93
Joined: Tue Dec 10, 2013 9:20 pm

Post by kaneCVR »

Yeah, it's supposed to be "FirstNavaAttackWave[FirstNavalAttackWaveCount]"
User avatar
Sleipnir
Posts: 878
Joined: Wed Apr 10, 2002 11:52 pm
Contact:

Post 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.
Post Reply