Building templates(Functions properly. Needs GUI =>Smb help)

Building templates(Functions properly. Needs GUI =>Smb help)

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

Moderator: Moderators

Post Reply
User avatar
Pendrokar
Posts: 658
Joined: 30 May 2007, 10:45

Building templates(Functions properly. Needs GUI =>Smb help)

Post by Pendrokar »

Someone more experienced with GUI creation is needed to finish this widget!

Create "building-templates" folder in /LuaUI/Widgets/ before saving templates!

For testing purposes:
Use "U" key to save a template (widget counts units for their creation succession)
Use "O" key to select last template

Then left click to order the con/s to build the template(shift also works) or right click to remove template from selection

Image

How the GUI should look like? No idea. It could be placed as buildbar is or add a menu CMD that switches to Templates and replaces building icons with template icons if that's possible for a widget!

Link to widget code - http://pastebin.com/m222380a2
User avatar
Pendrokar
Posts: 658
Joined: 30 May 2007, 10:45

Re: Building templates(Functions properly. Needs GUI =>Smb help)

Post by Pendrokar »

A month passed and nobody picked it up. Bahh. It would have been a quick work for some of you.

Well ok then I will need to know a few things:

1) Can I add a custom Cmd to the command list and have a Lua script launched with a widget(with it follows box size and position)? I seen it done only in gadgets.

2) Can I add/remove/replace build icons? If yes then how?

That is all for now.
User avatar
Pendrokar
Posts: 658
Joined: 30 May 2007, 10:45

Re: Building templates(Functions properly. Needs GUI =>Smb help)

Post by Pendrokar »

Well I probably won't finish it here is the code if someone thinks about adding this feature...

Code: Select all

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
--  file:    unit_templates.lua
--  brief:   Saves and builds building templates.
--  original author:  Pendrokar
--
--  Copyright (C) 2007.
--  Licensed under the terms of the GNU GPL, v2 or later.
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

function widget:GetInfo()
return {
name      = "Templates",
desc      = "Saves and builds building templates.",
author    = "Pendrokar",
date      = "Jul 26, 2009",
license   = "GNU GPL, v2 or later",
layer     = 0,
enabled   = false -- loaded by default?
}
end

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

local game = Game.modShortName
local TFILE = LUAUI_DIRNAME .. "Widgets/" .. "building-templates/" .. game ..".lua"
local tselected = 999 --which template selected? 999 - for none, I doubt somebody will ever have that many templates
local myteamid = Spring.GetMyTeamID()
local yourunitids = {}
local countup, facing = 0
local templates = {} --loaded templates

function compTimeBuilt(a,b)
       if(yourunitids[a]) then a = yourunitids[a] end
   if(yourunitids[b]) then b = yourunitids[b] end
       return a < b
end

function widget:Initialize()
      if Spring.GetSpectatingState() then
              widgetHandler:RemoveWidget()
              return
      end
      LoadTemplates()
end
function widget:Shutdown()
      SaveTemplates()
end

---------------------Template saving and adding----------------------

function SaveTemplates()
       if(#templates ~= 0) then
               table.save(templates, TFILE)
       else
               table.save({}, TFILE)
       end
end


function LoadTemplates()
       if VFS.FileExists(TFILE, VFS.RAW) then
               Spring.Echo("Loaded Template File")
               templates = VFS.Include(TFILE, nil, VFS.RAW)
               if(not #templates) then
                       templates = {}
               end
       else
               Spring.Echo(TFILE .. "No Template File")
       end
end

function AddTemplate()
      local selected = Spring.GetSelectedUnits()
      local x, x1, x2, z, z1, z2, posx, posz, pic = 0, 0, 0, 0, 0, 0, 0, 0, 0
      local templatename = ""
      local unitfacing, unitdefid = 0, 0
      local template = {}
               template[2] = {}
      local unit = {}

      table.sort(selected, compTimeBuilt)

      --check min and max coordinates between units(find center)
      for k,i in ipairs(selected) do
                          if(not yourunitids[i]) then
                               Spring.Echo("Unit with unknown creation time detected. Template could not be added.")
                               return
                          end

                       unitdefid = Spring.GetUnitDefID(i)
                       if (UnitDefs[unitdefid]["isBuilding"] or UnitDefs[unitdefid]["isFactory"]) then
              x, _, z = Spring.GetUnitPosition(i)
              if (x<x1) or (x1==0) then
                      x1 = x
              end
              if (x>x2) then
                      x2 = x
              end
              if (z<z1) or (z1==0) then
                      z1 = z
              end
              if (z>z2) then
                      z2 = z
              end
                       end
      end
              x2 = (x2-x1)/2
              z2 = (z2-z1)/2
      --use the same function to add units to template
      for k,uid in ipairs(selected) do
                          unitdefid = Spring.GetUnitDefID(uid)
                          if (UnitDefs[unitdefid]["isBuilding"] or UnitDefs[unitdefid]["isFactory"]) then
                                          x, _, z = Spring.GetUnitPosition(uid)
                                          posx, posz = x-x1-x2, z-z1-z2
                                          unitdefid = Spring.GetUnitDefID(uid)
                                          if(k == 1) then templatename = UnitDefs[unitdefid].name end
                                          if(k == 1) then pic = k end
                                          unitfacing = Spring.GetUnitBuildFacing(uid)

                                          template[2][k] = {unitdefid = unitdefid, unitname = UnitDefs[unitdefid].name, unitfacing = unitfacing, posx = posx, posz = posz}
                          end
      end
      template[0] = templatename
      template[1] = pic
      table.insert(templates, template)
          Spring.Echo("Building template added.")
end

---------------------Template editing----------------------

function ChangeTemplateName(templatenum, newname)
       templates[templatenum][0] = newname
       Spring.Echo("Template name changed to "..newname)
end

function ChangeTemplatePic(templatenum, newpic)
       templates[templatenum][1] = newpic
       Spring.Echo("Template pic changed")
end

---------------------Template deployment----------------------

function CheckBuilds()
   local selected = Spring.GetSelectedUnits()
       local unitlist = {} --array of units that can be built by specific unit
       local checktemp = {} -- templates which can be built by all selected units
       local ntemplates = templates --remove template from template list if one con cannot build
       local unitdefid
       for _, unitid in ipairs(selected) do
               unitdefid = Spring.GetUnitDefID(unitid)
               local ud = UnitDefs[unitdefid]
               if(#ud.buildOptions ~= 0) then
                       for _, unitdefid in ipairs(ud.buildOptions) do
                               unitlist[unitdefid] = true
                       end
                       for templatenum, template in ipairs(ntemplates) do
                               for _, unit in ipairs(template[2]) do
                                       if(unitlist[ (unit["unitdefid"]) ]) then
                                               checktemp[templatenum] = true
                                       else
                                               checktemp[templatenum] = nil
                                               ntemplates[templatenum] = nil
                                               break
                                       end
                               end
                       end
               end
               unitlist = {}
       end
end

function BuildTemplate(builders, x, z, buildings, withshift)
       local orderarray = {}
       local newx, newz, newfacing
       local getfacing = Spring.GetBuildFacing()
          if(withshift == "") then tselected = 999 end
      for k,building in ipairs(buildings) do
			if(getfacing == 0) then -- switch didnt work for me
			   newx, newz = z+building["posz"], x+building["posx"]
			   newfacing = building["unitfacing"]
			elseif(getfacing == 1) then
			   newx, newz = z+building["posz"], (x+(building["posx"]*(-1)))
			   if(1+building["unitfacing"] == 4) then
					   newfacing = 0
			   end
			elseif(getfacing == 2) then
			   newx, newz = (x+(building["posx"]*(-1))), (z+(building["posz"]*(-1)))
			   if(1+building["unitfacing"] == 4) then
					   newfacing = 0
			   elseif(1+building["facing"] == 5) then
					   newfacing = 1
			   end
			elseif(getfacing == 3) then
			   newx, newz = (z+(building["posz"]*(-1))), x+building["posx"]
			   if(1+building["unitfacing"] == 4) then
					   newfacing = 0
			   elseif(1+building["unitfacing"] == 5) then
					   newfacing = 1
			   elseif(1+building["unitfacing"] == 6) then
					   newfacing = 2
			   end
			end
               newx, _, newz = Spring.Pos2BuildPos(building["unitdefid"], (x+building["posx"]), 0, (z+building["posz"]))
              if (Spring.TestBuildOrder(building["unitdefid"], newx, 0, newz, newfacing) ~= 0) then
                      orderarray[k] = {-building["unitdefid"], newx, 0, newz, newfacing, {withshift}}
                                          withshift = "shift"
              end
      end
      Spring.GiveOrderArrayToUnitArray(builders, orderarray)
end

function widget:KeyPress(key)
       if (key == 111) then -- "O" for selecting last template from templates
               tselected = #templates
               return false
       end
       if (key == 117) then -- "U" for adding selected units to a template
               AddTemplate()
               return false
       end
end

function widget:UnitFinished(unitid, unitdefid, teamid)
       if(myteamid == teamid) and (UnitDefs[unitdefid]["isBuilding"] or UnitDefs[unitdefid]["isFactory"]) and not UnitDefs[unitdefid]["isFeature"] then
               yourunitids[unitid] = countup
               countup = countup + 1
       end
end

function widget:UnitTaken(unitid, unitdefid, teamid)
       if(myteamid == teamid) and (UnitDefs[unitdefid]["isBuilding"] or UnitDefs[unitdefid]["isFactory"]) then
               yourunitids[unitid] = countup
               countup = countup + 1
       end
end

function widget:UnitDestroyed(unitid, unitdefid, teamid)
       if(myteamid == teamid) and (UnitDefs[unitdefid]["isBuilding"] or UnitDefs[unitdefid]["isFactory"]) then
               yourunitids[unitid] = nil
       end
end

function widget:UnitGiven(unitid, unitdefid, teamid)
       if(myteamid == teamid) and (UnitDefs[unitdefid]["isBuilding"] or UnitDefs[unitdefid]["isFactory"]) then
               yourunitids[unitid] = nil
       end
end

function widget:DrawWorld()
      if(tselected ~= 999) then
              DrawTemplate()
      end
end


function DrawTemplate()
 gl.Color(1.0, 1.0, 1.0, 0.35 )
 gl.DepthTest(true)
 local x, z =  Spring.GetMouseState() --z as World z even though it's y for mouse
 local getfacing = Spring.GetBuildFacing()
 local height, newx, newz, newfacing
 local cord = {}
 local dimensions = {}
 if(not Spring.IsAboveMiniMap(x,z)) then
  x, z = math.floor(x), math.floor(z)
  _, cord = Spring.TraceScreenRay(x, z, true)
  if(cord ~= nil) then
       x = cord[1]
               z = cord[3]
      for k,unit in ipairs(templates[tselected][2]) do
					if(getfacing == 0) then -- switch didnt work for me
					   newx, newz = x+unit["posx"], z+unit["posz"]
					   newfacing = unit["unitfacing"]
					elseif(getfacing == 1) then
					   newx, newz = z+unit["posz"], (x+(unit["posx"]*(-1)))
					   if(1+unit["unitfacing"] == 2) then
							   newfacing = 0
					   end
					elseif(getfacing == 2) then
					   newx, newz = (x+(unit["posx"]*(-1))), (z+(unit["posz"]*(-1)))
					   if(1+unit["unitfacing"] == 3) then
							   newfacing = 0
					   elseif(1+unit["unitfacing"] == 5) then
							   newfacing = 1
					   end
					elseif(getfacing == 3) then
					   newx, newz = (z+(unit["posz"]*(-1))), x+unit["posx"]
					   if(1+unit["unitfacing"] == 4) then
							   newfacing = 0
					   elseif(1+unit["unitfacing"] == 5) then
							   newfacing = 1
					   elseif(1+unit["unitfacing"] == 6) then
							   newfacing = 2
					   end
					end
                       newx, _, newz = Spring.Pos2BuildPos(unit["unitdefid"], newx, 0, newz)
              if (Spring.TestBuildOrder(unit["unitdefid"], newx, 0, newz, newfacing) ~= 0) then
                      gl.Color(0.1, 1.0, 0.1, 0.40 ) --Can be built -> Green
              else
                      gl.Color(1.0, 0.1, 0.1, 0.40 ) --Cannot be built -> Red
              end
              gl.PushMatrix()

              height = Spring.GetGroundHeight( newx, newz )

              gl.Translate( (newx+10), (height+10), (z+newz) )

                          dimensions = Spring.GetUnitDefDimensions(unit["unitdefid"])
                          gl.Rotate(90, x, 0, 0)
                          gl.Rect(dimensions["minx"], dimensions["minx"], dimensions["maxx"], dimensions["maxx"])
                          gl.Rotate(-90, x, 0, 0)

              gl.Translate( 0, (-10), 0)

              gl.Rotate((newfacing*90), 0, height, 0)
              gl.UnitShape( unit["unitdefid"], myteamid )


              gl.PopMatrix()
      end
  else --Out of map bounds/etc
  end
 end
      gl.DepthTest(false)
      gl.Color(1, 1, 1, 1)
end

function widget:MousePress(x, y, button)
      if (tselected ~= 999) and (button == 1) then
                       local x, y, z
                       local cord = {}
                       local builders = Spring.GetSelectedUnits()
                       x, y = Spring.GetMouseState()
                       x, y = math.floor(x), math.floor(y)
                       _, cord = Spring.TraceScreenRay(x, y, true)
                       x, z = cord[1], cord[3]
                       local _, _, _, shiftpressed = Spring.GetModKeyState()
                       if(shiftpressed) then shiftpressed = "shift"
                       else shiftpressed = ""
                       end
                       BuildTemplate(builders, x, z, templates[tselected][2], shiftpressed)
                       return true
      elseif (tselected ~= 999) and (button == 3) then
           tselected = 999
           return true
      end
      return false
end

function widget:MouseMove(x, y, dx, dy, button)
      if (button == 1) then
		Spring.Echo(x.." - "..y.." - "..dx.." - "..dy)

	  end
	return true
end

User avatar
Tribulex
A.N.T.S. Developer
Posts: 1894
Joined: 26 Sep 2009, 21:26

Re: Building templates(Functions properly. Needs GUI =>Smb help)

Post by Tribulex »

I picked this up a long time ago. Lock the thread, go away, and in a few month look in XTA.
Post Reply

Return to “Lua Scripts”