Open GL Api

Open GL Api

Discuss Lua based Spring scripts (LuaUI widgets, mission scripts, gaia scripts, mod-rules scripts, scripted keybindings, etc...)

Moderator: Moderators

Post Reply
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Open GL Api

Post by PicassoCT »

Gentleman, the game i was hunting for was a shy one, the ability to scale a unit via openGL from a tiny spec, to a thunderous giant, something every hunter dreams to archieve.

This was the function:

Code: Select all

        function gadget:DrawWorld()
               if GG.scaleUpTable ~=nil and table.getn(GG.scaleUpTable) ~=0 then
					  for i=1,table.getn(GG.scaleUpTable),1 do
					  gl.BeginEnd(gl.Unit(GG.scaleUpTable[i][1]),function ()
						   gl.PushMatrix()
						   gl.UnitRaw(unitID,true);
						   gl.Scale(GG.scaleUpTable[i][2],GG.scaleUpTable[i][2],GG.scaleUpTable[i][2]);
						   gl.DepthTest(true,GL.LESS);
						   gl.DepthMask(true,GL.GREATER);
						   gl.PopMatrix()  
					       end  )
					
					  end
               end
       
       
       
     
       
         end
It existed in lua unsynced, and every piece of logic in me tells me that it is wrong. Because a unit-modell is not one solid object, rather a datastructure, so in order to traverse it, i expected at least one for in it.

I searched the other mods i got, but it seems such a thing is rarely needed. (there are gl.scales on mapboxes and sfx)

I would be glad-even for just a example snippet. The stage is yours..
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7049
Joined: 16 Nov 2004, 13:08

Re: Open GL Api

Post by zwzsg »

I'm pretty sure I told you already :

Code: Select all

function gadget:DrawWorld()
	local u=YourUnitID
	local f=YourScaleFactor
	local x,y,z=Spring.GetUnitPosition(u)
	gl.PushMatrix()
	gl.Translate(-f*x,-f*y,-f*z)
	gl.Scale(f,f,f)
	gl.Translate(x/f,y/f,z/f)
	gl.Blending(GL.ONE_MINUS_SRC_COLOR,GL.ONE)
	gl.Unit(u)
	gl.Blending(GL.SRC_ALPHA,GL.ONE_MINUS_SRC_ALPHA)
	gl.PopMatrix()
end
And yes, there is no for.
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Re: Open GL Api

Post by PicassoCT »

Thoose noobs they all look alike

No indention and questionmarks everywhere..

Thanks zwzsg..
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Open GL Api

Post by jK »

Code: Select all

	gl.Translate(-f*x,-f*y,-f*z)
	gl.Scale(f,f,f)
	gl.Translate(x/f,y/f,z/f)
==

Code: Select all

	gl.Translate(x, y, z)
	gl.Scale(f,f,f)
	gl.Translate(-x,-y,-z)
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Re: Open GL Api

Post by PicassoCT »

so its basically.. reset to origin, scale, move back.. okay... but the unit is treated like one huge matrice?
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Re: Open GL Api

Post by PicassoCT »

Well, to everyones suprise.. it doesent work:

Code: Select all

--    Copyright (C) 2010,2011.
--    Licensed under the terms of the GNU GPL, v2 or later.
    
                                           
                                           
     
      function gadget:GetInfo()
      return {
      name = "glScaleUp ",
      desc = "test123",
      author = "PicassoCT",
      date = "7 b.Creation",
      license = "GNU GPL, v2 its goes in all fields",
      layer = 0,
      enabled = true  -- loaded by default?
      }
      end
     
                                           
                                           
     
--    synced only
      if (gadgetHandler:IsSyncedCode()) then
      local startScale=0.1
      GG.scaleUpTable={}
   -- registrates the units created
        function gadget:UnitCreated(unitID, unitDefID, unitTeam)
                  if unitDefID== UnitDefNames["jswiftspear"].id then
				   
				   Spring.Echo("jw_scaleUpGadget::To us a swiftspear is born")
				   GG.scaleUpTable[#GG.scaleUpTable+1]={}
				   GG.scaleUpTable[#GG.scaleUpTable][1]={}
				   GG.scaleUpTable[#GG.scaleUpTable][1]=unitID
				   GG.scaleUpTable[#GG.scaleUpTable][2]={}
				   GG.scaleUpTable[#GG.scaleUpTable][2]=startScale
                  end
             
         end
     
     
      local UPDATE_FREQUNECY=100
     
           function gadget:GameFrame(f)
                  if f%UPDATE_FREQUNECY== 0 and GG.scaleUpTable~=nil then
                     for i=1,#GG.scaleUpTable,1 do
					     if GG.scaleUpTable[i]~=nil then
						 tempDead=Spring.GetUnitIsDead(GG.scaleUpTable[i][1])
						    if tempDead == false and GG.scaleUpTable[i][2] < 1 then
						    GG.scaleUpTable[i][2]=(GG.scaleUpTable[i][2]+0.01)
						  	elseif  tempDead == false and GG.scaleUpTable[i][2] >= 1 then
							--Donno
								else
									GG.scaleUpTable[i]=nil
								end
						  end	 
                   
                     end
               
          --   call a unsyced function  
                  end
               
            end
     
     
       
     
     
     
     

              

       

	   else
	   
	   
	   
	   
         function gadget:DrawWorld()
               if GG.scaleUpTable ~=nil and table.getn(GG.scaleUpTable) ~=0 then
					  for i=1,table.getn(GG.scaleUpTable),1 do
							  if GG.scaleUpTable[i]~= nil then
								   local u=GG.scaleUpTable[1]
								   local f=GG.scaleUpTable[2]
								   local x,y,z=Spring.GetUnitPosition(u)
								   gl.PushMatrix()
								   gl.Translate(-f*x,-f*y,-f*z)
								   gl.Scale(f,f,f)
								   gl.Translate(x/f,y/f,z/f)
								   gl.Blending(GL.ONE_MINUS_SRC_COLOR,GL.ONE)
								   gl.Unit(u)
								   gl.Blending(GL.SRC_ALPHA,GL.ONE_MINUS_SRC_ALPHA)
								   gl.PopMatrix()
								end   
					  end
               end
       
       
       
     
       
         end
     
     
     
     
       
      end
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Open GL Api

Post by jK »

User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Re: Open GL Api

Post by PicassoCT »

Code: Select all

--    Copyright (C) 2010,2011.
--    Licensed under the terms of the GNU GPL, v2 or later.
    
                                           
                                           
     
      function gadget:GetInfo()
      return {
      name = "glScaleUp ",
      desc = "test123",
      author = "PicassoCT",
      date = "7 b.Creation",
      license = "GNU GPL, v2 its goes in all fields",
      layer = 0,
      enabled = true  -- loaded by default?
      }
      end
     
                                           
                                           
     
--    synced only
      if (gadgetHandler:IsSyncedCode()) then
      local startScale=0.1
     local  scaleUpTable={}
   -- registrates the units created
        function gadget:UnitCreated(unitID, unitDefID, unitTeam)
                  if unitDefID== UnitDefNames["jswiftspear"].id then
				   
				   Spring.Echo("jw_scaleUpGadget::To us a swiftspear is born")
				    scaleUpTable[#scaleUpTable+1]={}
				    scaleUpTable[#scaleUpTable][1]={}
				    scaleUpTable[#scaleUpTable][1]=unitID
				    scaleUpTable[#scaleUpTable][2]={}
				    scaleUpTable[#scaleUpTable][2]=startScale
                  end
             
			 _G.scaleUpTable=scaleUpTable
         end
     
     
      local UPDATE_FREQUNECY=100
     
           function gadget:GameFrame(f)
                  if f%UPDATE_FREQUNECY== 0 and _G.scaleUpTable~=nil then
                     for i=1,#_G.scaleUpTable,1 do
					     if _G.scaleUpTable[i]~=nil then
						 tempDead=Spring.GetUnitIsDead(_G.scaleUpTable[i][1])
						    if tempDead == false and _G.scaleUpTable[i][2] < 1 then
						    _G.scaleUpTable[i][2]=(_G.scaleUpTable[i][2]+0.01)
						  	elseif  tempDead == false and _G.scaleUpTable[i][2] >= 1 then
							--Donno
								else
									_G.scaleUpTable[i]=nil
								end
						  end	 
                   
                     end
               
          --   call a unsyced function  
                  end
               
            end
     
     
       
     
     
     
     

              

       

	   else
	   
	   
	   
	   
         function gadget:DrawWorld()
               if SYNCED.scaleUpTable ~=nil and table.getn(SYNCED.scaleUpTable) ~=0 then
					  for i=1,table.getn(SYNCED.scaleUpTable),1 do
							  if SYNCED.scaleUpTable[i]~= nil then
								   local u=SYNCED.scaleUpTable[1]
								   local f=SYNCED.scaleUpTable[2]
								   local x,y,z=Spring.GetUnitPosition(u)
								   gl.PushMatrix()
								   gl.Translate(-f*x,-f*y,-f*z)
								   gl.Scale(f,f,f)
								   gl.Translate(x/f,y/f,z/f)
								   gl.Blending(GL.ONE_MINUS_SRC_COLOR,GL.ONE)
								   gl.Unit(u)
								   gl.Blending(GL.SRC_ALPHA,GL.ONE_MINUS_SRC_ALPHA)
								   gl.PopMatrix()
								end   
					  end
               end
       
       
       
     
       
         end
     
     
     
     
       
      end
better? or anit-better?
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Open GL Api

Post by jK »

better but you cannot use table.getn
everything in SYNCED nees to be iterated with spairs & sipairs
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Re: Open GL Api

Post by PicassoCT »

better²

Code: Select all

--    Copyright (C) 2010,2011.
--    Licensed under the terms of the GNU GPL, v2 or later.
    
                                           
                                           
     
      function gadget:GetInfo()
      return {
      name = "glScaleUp ",
      desc = "test123",
      author = "PicassoCT",
      date = "7 b.Creation",
      license = "GNU GPL, v2 its goes in all fields",
      layer = 0,
      enabled = true  -- loaded by default?
      }
      end
     
                                           
                                           
     
--    synced only
      if (gadgetHandler:IsSyncedCode()) then
      local startScale=0.1
     local  scaleUpTable={}
   -- registrates the units created
        function gadget:UnitCreated(unitID, unitDefID, unitTeam)
                  if unitDefID== UnitDefNames["jswiftspear"].id then
				   
				   Spring.Echo("jw_scaleUpGadget::To us a swiftspear is born")
				    scaleUpTable[#scaleUpTable+1]={}
				    scaleUpTable[#scaleUpTable][1]={}
				    scaleUpTable[#scaleUpTable][1]=unitID
				    scaleUpTable[#scaleUpTable][2]={}
				    scaleUpTable[#scaleUpTable][2]=startScale
                  end
             
			 _G.scaleUpTable=scaleUpTable
         end
     
     
      local UPDATE_FREQUNECY=100
     
           function gadget:GameFrame(f)
                  if f%UPDATE_FREQUNECY== 0 and _G.scaleUpTable~=nil then
                     for i=1,#_G.scaleUpTable,1 do
					     if _G.scaleUpTable[i]~=nil then
						 tempDead=Spring.GetUnitIsDead(_G.scaleUpTable[i][1])
						    if tempDead == false and _G.scaleUpTable[i][2] < 1 then
						    _G.scaleUpTable[i][2]=(_G.scaleUpTable[i][2]+0.01)
						  	elseif  tempDead == false and _G.scaleUpTable[i][2] >= 1 then
							--Donno
								else
									_G.scaleUpTable[i]=nil
								end
						  end	 
                   
                     end
               
          --   call a unsyced function  
                  end
               
            end
     
     
       
     
     
     
     

              

       

	   else
	   
	   
	   
	   
         function gadget:DrawWorld()
               if SYNCED.scaleUpTable ~=nil  then
					  for i,v in ipairs(SYNCED.scaleUpTable) do
							  if SYNCED.scaleUpTable[v]~= nil then
								   local u=SYNCED.scaleUpTable[1]
								   local f=SYNCED.scaleUpTable[2]
								   local x,y,z=Spring.GetUnitPosition(u)
								   gl.PushMatrix()
								   gl.Translate(-f*x,-f*y,-f*z)
								   gl.Scale(f,f,f)
								   gl.Translate(x/f,y/f,z/f)
								   gl.Blending(GL.ONE_MINUS_SRC_COLOR,GL.ONE)
								   gl.Unit(u)
								   gl.Blending(GL.SRC_ALPHA,GL.ONE_MINUS_SRC_ALPHA)
								   gl.PopMatrix()
								end   
					  end
               end
       
       
       
     
       
         end
     
     
     
     
       
      end
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Open GL Api

Post by jK »

jK wrote:better but you cannot use table.getn
everything in SYNCED needs to be iterated with spairs & sipairs
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Re: Open GL Api

Post by PicassoCT »

Code: Select all

--    Copyright (C) 2010,2011.
--    Licensed under the terms of the GNU GPL, v2 or later.
    
                                           
                                           
     
      function gadget:GetInfo()
      return {
      name = "glScaleUp ",
      desc = "test123",
      author = "PicassoCT",
      date = "7 b.Creation",
      license = "GNU GPL, v2 its goes in all fields",
      layer = 0,
      enabled = true  -- loaded by default?
      }
      end
     
                                           
                                           
     
--    synced only
      if (gadgetHandler:IsSyncedCode()) then
      local startScale=0.1
     local  scaleUpTable={}
   -- registrates the units created
        function gadget:UnitCreated(unitID, unitDefID, unitTeam)
                  if unitDefID== UnitDefNames["jswiftspear"].id then
				   
				   Spring.Echo("jw_scaleUpGadget::To us a swiftspear is born")
				    scaleUpTable[#scaleUpTable+1]={}
				    scaleUpTable[#scaleUpTable][1]={}
				    scaleUpTable[#scaleUpTable][1]=unitID
				    scaleUpTable[#scaleUpTable][2]={}
				    scaleUpTable[#scaleUpTable][2]=startScale
                  end
             
			 _G.scaleUpTable=scaleUpTable
         end
     
     
      local UPDATE_FREQUNECY=100
     
           function gadget:GameFrame(f)
                  if f%UPDATE_FREQUNECY== 0 and _G.scaleUpTable~=nil then
				  
				   for i,v in sipairs(_G.scaleUpTable) do
							 	     if _G.scaleUpTable[i]~=nil then
										 tempDead=Spring.GetUnitIsDead(_G.scaleUpTable[i][1])
											if tempDead == false and _G.scaleUpTable[i][2] < 1.9 then
											_G.scaleUpTable[i][2]=(_G.scaleUpTable[i][2]+0.02)
											elseif  tempDead == false and _G.scaleUpTable[i][2] >= 1 then
											--Donno
												else
													_G.scaleUpTable[i]=nil
												end
										  end	 
                   
					  end
				  
                    
               
          --   call a unsyced function  
                  end
               
            end
     
     
       
     
     
     
     

              

       

	   else
	   

	   
	   
         function gadget:DrawWorld()
               if SYNCED.scaleUpTable ~=nil  then
			   	 
					  for i,v in sipairs(SYNCED.scaleUpTable) do
							  if SYNCED.scaleUpTable[i]~= nil then
								   local u=SYNCED.scaleUpTable[i][1]
								   local l=SYNCED.scaleUpTable[i][2]
								   local x,y,z=Spring.GetUnitPosition(u)
								   gl.PushMatrix()
								   gl.Translate(-l*x,-l*y,-l*z)
								   Spring.Echo("IM UNSYNCED AND YOU Are to blame!",l)
								   gl.Scale(l,l,l)
								   gl.Translate(x/l,y/l,z/l)
								   gl.Blending(GL.ONE_MINUS_SRC_COLOR,GL.ONE)
								   gl.Unit(u)
								   gl.Blending(GL.SRC_ALPHA,GL.ONE_MINUS_SRC_ALPHA)
								   gl.PopMatrix()
								end   
					  end
               end
       
       
       
     
       
         end
     
     
     
     
       
      end

Well it now does enter the unsynced parts- AND it changes something graphicwise. Sooo close! Also, good news everyone, i will attend a graphics programming course this semesters.. this should fill some knowledge gaps..

Image
Attachments
screen00570.jpg
(1019.42 KiB) Downloaded 1 time
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7049
Joined: 16 Nov 2004, 13:08

Re: Open GL Api

Post by zwzsg »

Picasso, try this :

Code: Select all

function gadget:GetInfo()
	return {
		name = "Pulsate",
		desc = "Make units grow and shrink",
		author = "zwzsg",
		date = "21st of March 2013",
		license = "Free",
		layer = 0,
		enabled = true
	}
end

function gadget:DrawWorld()
	gl.PushAttrib()
	gl.DepthTest(true)
	gl.DepthMask(true)
	local scale=1.5+math.sin(Spring.GetGameFrame()/99)
	for _,unitID in ipairs(Spring.GetAllUnits()) do
		local x,y,z=Spring.GetUnitPosition(unitID)
		Spring.SetUnitNoDraw(unitID,true)
		gl.PushMatrix()
		gl.Translate(x,y,z)
		gl.Scale(scale,scale,scale)
		gl.Translate(-x,-y,-z)
		gl.Unit(unitID)
		gl.PopMatrix()
	end
	gl.PopAttrib()
end
It's not the cleanest or most optimised, but the code is super short and works as is.


















Ok, now that you see that the bare OpenGL part is working, let's move on to something closer to your goal.

To transmit data from synced to unsynced, yes, you can write in _G. then read in SYNCED. however that is the bad, old method. The new and advised method is to use messages instead. I was told it's pretty important to switch to it for multithreading or something.

Also, I use different callin and callouts to do the actual drawing, mostly to show there's more than one way to do it.

Code: Select all

function gadget:GetInfo()
	return {
		name = "Pulsate",
		desc = "Make mobile units grow and shrink",
		author = "zwzsg",
		date = "21st of March 2013",
		license = "Free",
		layer = 0,
		enabled = true
	}
end


if (gadgetHandler:IsSyncedCode()) then

	local SyncedDataTable={}-- Table that contains some data about some units


	function gadget:UnitFinished(unitID, unitDefID)
		local ud=UnitDefs[unitDefID]

		-- Here the chosen units will be all moving unit. Put your own filter obviously!
		if ud.canMove and ud.speed > 1 then 

			-- The key is the unitID
			-- The value must be something else than false and nil
			SyncedDataTable[unitID]={ birth=Spring.GetGameFrame() }
			-- Here I put as value a table with the time of birth, but could be anything

		end
	end


	function gadget:UnitDestroyed(unitID, unitDefID)
		-- Never forget to delete data about dead units!
		-- Or else your tables will slowly grow during game with huge amount of useless data!
		if SyncedDataTable[unitID] then
			SyncedDataTable[unitID]=nil
			SendToUnsynced("UnsetScale",unitID)
		end
	end


	function gadget:GameFrame(frame)
		for unitID,data in pairs(SyncedDataTable) do
			-- Here my scale is a sinusoid of time. So they grow and shrink smoothly and periodically
			-- Use your own formula obviously
			local scale = 1+0.5*math.sin((frame - data.birth)/50)

			-- You should not call it every frame, but only when you wish to change scale
			SendToUnsynced("SetScale", unitID, scale)
			-- Well, I change it constantly, so call it every frame, but that's for a more visual example
		end
	end


else -- unsynced


	local UnsyncedScaleTable={}-- Table that contains the scale of units to be scaled

	local function SetScale(callname,unitID,scale)
		UnsyncedScaleTable[unitID]=scale
		Spring.UnitRendering.SetUnitLuaDraw(unitID,true)
	end

	local function UnsetScale(callname,unitID)
		UnsyncedScaleTable[unitID]=nil
		Spring.UnitRendering.SetUnitLuaDraw(unitID,false)
	end

	function gadget:Initialize()
		-- This associate the messages with the functions
		-- So that when the synced sends a message "f" it calls the function f in unsynced
		gadgetHandler:AddSyncAction("SetScale",SetScale)
		gadgetHandler:AddSyncAction("UnsetScale",UnsetScale)
	end

	function gadget:DrawUnit(unitID)
		if UnsyncedScaleTable[unitID] then
			local scale=UnsyncedScaleTable[unitID]
			gl.Scale(scale,scale,scale)
			gl.UnitRaw(unitID)
		end
	end

end
First, use it as it is, and notice that indeeds moving units pulsate.
Then edit the synced part. The thing to remember is :
- Use SendToUnsynced("SetScale", unitID, scale) to rescale a unit.
- Use SendToUnsynced("UnsetScale",unitID) when you no longer want to rescale a unit. Don't forget to do it on dead units to free memory!

In the synced part, I also show an example of keeping in a table some data about the units you want to handle with the gadget. Maybe you won't need it. But it's a handy method, if not for this gadget, then for another. In my example, I put in this table all the moving unit. Then every frame I change the scale of all of them. Your needs will likely be different, remember you don't have to call "SetScale" that often!
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Re: Open GL Api

Post by PicassoCT »

Hurray it works
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Re: Open GL Api

Post by PicassoCT »

Horray it does not work anylonger :(

Code: Select all

function gadget:GetInfo()
	return {
		name = "JW_ScaleUpGadget::",
		desc = "Make mobile units grow and shrink",
		author = "zwzsg",
		date = "21st of March 2013",
		license = "Free, wishing for a benevolent dicatorship, cause instinctarded. To value luarulesdom, you got to be able to use it.",--Janus License- under Software Patent Nr. 23432-756F-11-2014 held by the FSF for commercial purposes, under GPL for non-commercial usage
		layer = 0,
		enabled = true
	}
end


if (gadgetHandler:IsSyncedCode()) then
	
	JBUILDANIM="NOTYPE"
	
	--all units that are buildings
	jBuilding={
		[UnitDefNames["jswiftspear"].id]=true,
		[UnitDefNames["jmovingfac1"].id]=true,	
		[UnitDefNames["jdrilltree"].id]=true,
		[UnitDefNames["jmeggstack"].id]=true,
		[UnitDefNames["jtree"].id]=true,
		[UnitDefNames["jtree2"].id]=true,
		[UnitDefNames["jtree3"].id]=true,
		[UnitDefNames["jgeohive"].id]=true,
		[UnitDefNames["jwatergate"].id]=true,
		[UnitDefNames["jfireflower"].id]=true,
		[UnitDefNames["jbeehive"].id]=true,
		[UnitDefNames["jfungiforrest"].id]=true,
		[UnitDefNames["jnativevil"].id]=true,
		[UnitDefNames["jtreel"].id]=true,
		[UnitDefNames["jabyss"].id]=true	
	}
	
	
	
	DefTypeTable={
		[UnitDefNames["jswiftspear"].id]=true,
		[UnitDefNames["jbeherith"].id]=true,
		[UnitDefNames["jsungodcattle"].id]=true,
		[UnitDefNames["cawilduniverseappears"].id]=true,
		[UnitDefNames["ghohymen"].id]=true,
		[UnitDefNames["jvaryfoo"].id]=true,
		[UnitDefNames["jspacebornembryo"].id]=true,
		[UnitDefNames["gseastar"].id]=true
	}
	
	jBuildAnimDefID=UnitDefNames["jbuildanim"].id
	SyncedDataTable={}-- Table that contains some data about some units
	scaleTable={}
	LastSetBuildAnim={}
	jWorkInProgress={}
	buildList={}
	
	local spValidUnitID= Spring.ValidUnitID
	
	
	function gadget:UnitCreated(unitID, unitDefID, unitTeam)
		if DefTypeTable[unitDefID] then --unitDefID== UnitDefNames["tiglil"].id or unitDefID== UnitDefNames["skinfantry"].id or 
			boolPulse=false
			StartScale=0.06
			--	if unitDefID== UnitDefNames["tiglil"].id or unitDefID== UnitDefNames["skinfantry"].id then StartScale=0.52 end
			
			ScaleFactorProFrame=0.001
			
			ScaleUpLimit=1
			if unitDefID== UnitDefNames["gseastar"].id then ScaleFactorProFrame= 0.003 		end --or unitDefID== UnitDefNames["tiglil"].id or unitDefID== UnitDefNames["skinfantry"].id 	
			if unitDefID== UnitDefNames["jswiftspear"].id then ScaleFactorProFrame=0.001 		end --or unitDefID== UnitDefNames["tiglil"].id or unitDefID== UnitDefNames["skinfantry"].id 	
			if unitDefID== UnitDefNames["jbeherith"].id 	then ScaleFactorProFrame=0.0005 	end
			if unitDefID== UnitDefNames["jsungodcattle"].id then ScaleFactorProFrame=0.0006 	end
			if unitDefID== UnitDefNames["jspacebornembryo"].id then 
				ScaleFactorProFrame=0
				ScaleUpLimit=1
				boolPulse=true	
			end
			
			if unitDefID== UnitDefNames["cawilduniverseappears"].id then 
				ScaleFactorProFrame=0.05 
				ScaleUpLimit=3.14159
			end
			
			if unitDefID== UnitDefNames["ghohymen"].id then 	
				StartScale=0.12			
				ScaleFactorProFrame=0.0005
				ScaleUpLimit=2.14159
			end
			
			if unitDefID== UnitDefNames["jvaryfoo"].id then 		
				ScaleFactorProFrame=0.0005
				ScaleUpLimit=3.14159
			end
			
			scaleTable[unitID]={ scale=StartScale ,factor=ScaleFactorProFrame,utype=unitDefID,uid=unitID, scaleLimit=ScaleUpLimit, pulse=boolPulse}
			
			
			-- Here the chosen units will be all moving unit. Put your own filter obviously!
			-- The key is the unitID
			-- The value must be something else than false and nil
			SyncedDataTable[unitID]={}
			SyncedDataTable[unitID]={ birth=unitID+ Spring.GetGameFrame() }
			-- Here I put as value a table with the time of birth, but could be anything
			
		end
		--if journeybuild animation
		if jBuilding[unitDefID] then
			--Spring.Echo("JourneyBuilding Inserted")
			
			x,y,z=Spring.GetUnitPosition(unitID)
			GG.UnitsToSpawn:PushCreateUnit("jbuildanim",x,y,z+4,0,unitTeam)
			
			
			LastSetBuildAnim[#LastSetBuildAnim+1]={unitID=unitID, unitDefID=unitDefID, unitTeam=unitTeam,birth=Spring.GetGameFrame()}		
		end	
		
		if unitDefID == jBuildAnimDefID then		 
			buildList[unitID]=LastSetBuildAnim[#LastSetBuildAnim]
			table.remove(LastSetBuildAnim,#LastSetBuildAnim)
		end
		
	end
	
	function gadget:UnitDestroyed(unitID, unitDefID)
		-- Never forget to delete data about dead units!
		-- Or else your tables will slowly grow during game with huge amount of useless data!
		if SyncedDataTable[unitID] then
			--Spring.Echo("jw_ScaleUPGadget::", SyncedDataTable[unitID])
			SyncedDataTable[unitID]=nil
			SendToUnsynced("UnsetScale",unitID)
		end
	end
	
	--All units that do a constant scaling up
	local UnitsScaling={	
		[UnitDefNames["jswiftspear"].id] 			=true,
		[UnitDefNames["jbeherith"].id] 				=true,
		[UnitDefNames["jsungodcattle"].id] 			=true,
		[UnitDefNames["cawilduniverseappears"].id]	=true,
		[UnitDefNames["ghohymen"].id]				=true,
		[UnitDefNames["jspacebornembryo"].id]		=true
	}
	
	local VARYFOODEFID= UnitDefNames["jvaryfoo"].id
	local SUNGODCATTLEDEFID= UnitDefNames["jsungodcattle"].id
	local EMBRYODEFID= UnitDefNames["jspacebornembryo"].id
	local spGetUnitHealth=Spring.GetUnitHealth
	
	local function handleNewEntrys()
		if table.getn(buildList) > 0 then 
			for id,v in pairs(buildList) do
				x,y,z=Spring.GetUnitPosition(buildList[id].unitID)
				
				if id then
					guid=buildList[id].unitID
					scale = 1+0.5*math.sin((frame - v.birth)/50)
					SendToUnsynced("SetScale", unitID, scale)
					scaleTable[id]={scale=scale, utype=JBUILDANIM, uid=id, scaleLimit=1+math.random(10,30)/100, pulse=true}
					Spring.SetUnitAlwaysVisible(guid,false)
					Spring.SetUnitNoSelect(id,true)
					jWorkInProgress[guid] = id
					
					
					SyncedDataTable[guid] = {}
					SyncedDataTable[guid] = { birth=buildList[id].unitID + frame }	
				end
			end
			buildList={}
		end
		
	end
	
	local function handleBuildAnims()
		
		------------	--BuildAnims	--------------------------------------------------------------------	
		if #jWorkInProgress > 0 then
			for k,v in pairs(jWorkInProgress) do
				if v then
					health, maxHealth, paralyzeDamage, captureProgress, buildProgress=spGetUnitHealth(k)
					if buildProgress then
						if buildProgress < 1 then
							Spring.SetUnitAlwaysVisible(k,false)
							Spring.SetUnitAlwaysVisible(v,true)
							scaleTable[v]={scale=buildProgress+math.sin((frame+9000)/100), utype=JBUILDANIM, uid=v, scaleLimit=1+math.random(0.1,0.3)}
							
						elseif buildProgress == 1 then
							Spring.SetUnitAlwaysVisible(k,true)
							Spring.DestroyUnit(v,true,true)
							scaleTable[v]=nil
						end
					end
				end	
			end	
			
			for k,v in pairs(jWorkInProgress) do
				if v and Spring.GetUnitIsDead(v)==true then
					jWorkInProgress[k]=nil
				end
			end 
			
		end
		----------------------------------------------------------------------------------------------------
		
		
	end
	
	local function setScaleTable()
		local FeedingVaryFooCopy=GG.VaryFooFeeding
		--PrepCycle 
		for unitID,_ in pairs(scaleTable) do
			-- Here my scale is a sinusoid of time. So they grow and shrink smoothly and periodically
			-- Use your own formula obviously
			
			if UnitsScaling[scaleTable[unitID].utype] then
				temp=scaleTable[unitID].scale + scaleTable[unitID].factor
				scaleTable[unitID].scale = temp
			end
			--if it is a sungodcattle
			if scaleTable[unitID].utype == SUNGODCATTLEDEFID and scaleTable[unitID].scale >= math.random(87,100)/100 then scaleTable[unitID] = nil end 
			
			--if it is a varyfoo it grows by how much it has eaten
			if scaleTable and scaleTable[unitID] and scaleTable[unitID].utype==VARYFOODEFID and FeedingVaryFooCopy and FeedingVaryFooCopy[unitID] then
				scaleTable[unitID].scale= math.min(scaleTable[unitID].scale+scaleTable[unitID].factor, FeedingVaryFooCopy[unitID])							
			end
			
			if scaleTable[unitID] and scaleTable[unitID].utype==EMBRYODEFID then
				hp=spGetUnitHealth(unitID)	
				if hp then
					scaleTable[unitID].scale=math.max(0.01,hp/100)
				else
					scaleTable[unitID].scale=0.01
				end
			end
			--ending clause
			if scaleTable[unitID] and scaleTable[unitID].scale >= scaleTable[unitID].scaleLimit then 
				scaleTable[unitID] = nil
			end
			--end
		end
		
		
		for unitID,_ in pairs(scaleTable) do
			-- Here my scale is a sinusoid of time. So they grow and shrink smoothly and periodically
			-- Use your own formula obviously
			-- You should not call it every frame, but only when you wish to change scale
			SendToUnsynced("SetScale",scaleTable[unitID].scale, scaleTable[unitID].uid )
			-- Well, I change it constantly, so call it every frame, but that's for a more visual example
		end
		
		
	end
	
	
	
	function gadget:GameFrame(frame)
		
		
		if frame > 0 and frame%7 == 0 then
			
			handleNewEntrys()
			
			handleBuildAnims()
			
			setScaleTable()
			
		end			
		
		
	end
	
	
	
else -- unsynced
	
	
	local UnsyncedScaleTable={}-- Table that contains the scale of units to be scaled
	
	local function SetScale(callname,scale,unitID)
		--		Spring.Echo("jw_ScaleUPGadget::GameFrame::SetScale")
		--Spring.Echoqq("JW_ScaleUpGadget_"..unitID.." |"..scale)
		UnsyncedScaleTable[unitID]=scale
		Spring.UnitRendering.SetUnitLuaDraw(unitID,true)
	end
	
	local function UnsetScale(callname,unitID)
		
		--	 Spring.Echo("jw_ScaleUPGadget::GameFrame::UnSetScale")
		UnsyncedScaleTable[unitID]=nil
		Spring.UnitRendering.SetUnitLuaDraw(unitID,false)
	end
	
	function gadget:Initialize()
		

		-- This associate the messages with the functions
		-- So that when the synced sends a message "f" it calls the function f in unsynced
		gadgetHandler:AddSyncAction("SetScale",SetScale)
		gadgetHandler:AddSyncAction("UnsetScale",UnsetScale)
	end
	
	function gadget:DrawUnit(unitID)
		if UnsyncedScaleTable[unitID] then
			local scale=UnsyncedScaleTable[unitID]

			gl.Scale(scale,scale,scale)
			gl.UnitRaw(unitID)

		end
	end
	
end
I broke it along the way- but too many units depend upon for correct display. Anyone any advice?
Post Reply

Return to “Lua Scripts”