Guest User

Untitled

a guest
Jul 11th, 2016
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.12 KB | None | 0 0
  1. local version = "0.2" -- String declaration. We can do this before the GetInfo callin (event).
  2. function widget:GetInfo()
  3. return {
  4. name = "Graphic Unit selector " .. version, -- .. means to combine two strings. The second string, 'version' (see above) is added to the end of this string.
  5. desc = "Selects units when a user presses a certain key.",
  6. author = "Shaman, mod by Helwor, NCG",
  7. date = "June 13, 2016",
  8. license = "None",
  9. layer = 15,
  10. enabled = true,
  11. }
  12. end -- All widgets/gadgets need this to run. You can declare variables before it though. This tells the engine this is a widget.
  13.  
  14. --config--
  15. local debug = false
  16. local color = {raider = {0.25,0.41,1},
  17. assault = {0.86,0.08,0.24},
  18. skirm = {0.25,0.55,0.13},
  19. arty = {0.8,0.68,0},
  20. riot = {0,0.81,0.82},
  21. special1 = {0.25,0.41,1},
  22. special2 = {0.86,0.08,0.24},
  23. aaunit = {0.25,0.41,1},
  24. conunit = {5,2,1},
  25. none = {1,1,1},
  26. growth = {0.19,0.5,0.08},
  27. shrink = {1,0.08,0.58},} -- OpenGL uses floating points instead of 255 (float = decimal num)
  28. local keypresses = {raider = 49, -- 1 Number keys, starting form 1=49, 2=50 etc.
  29. assault = 50; -- 2
  30. riot = 51, -- 3
  31. skirm = 52, -- 4
  32. arty = 56, -- 5
  33. aaunit = 57, -- 6
  34. special1 = 45, -- 7
  35. special2 = 61, -- 8
  36. conunit = 48, -- 0
  37. plus = 265, -- increase radius button (Keys are currently numpad 9 and 6)
  38. minus = 262, -- decrease radius button. Change these as desired.
  39. } -- Table. Format is Key = Value. 110.44.59.58.308
  40.  
  41. local triggerkeys = {}
  42. triggerkeys[keypresses.raider] = 1
  43. triggerkeys[keypresses.skirm] = 1
  44. triggerkeys[keypresses.riot] = 1
  45. triggerkeys[keypresses.assault] = 1
  46. triggerkeys[keypresses.arty] = 1
  47. triggerkeys[keypresses.special1] = 1
  48. triggerkeys[keypresses.special2] = 1
  49. triggerkeys[keypresses.aaunit] = 1
  50. triggerkeys[keypresses.conunit] = 1
  51.  
  52. local rad = 1250
  53. local on = false
  54. local ontype = "none" -- we'll use ontype and on to talk to gameframe and drawworld.
  55. local unittypes = {raider = {
  56. armpw = 1,
  57. corak = 1,
  58. corgator = 1,
  59. amphraider3 = 1,
  60. corpyro = 1,
  61. corsh = 1,
  62. subraider = 1,
  63. logkoda = 1,
  64. armkam = 1,
  65. puppy = 1,
  66. panther = 1,
  67. },
  68. skirm = {
  69. armrock = 1,
  70. armsptk = 1,
  71. slowmort = 1,
  72. corstorm = 1,
  73. shipskirm = 1,
  74. amphfloater = 1,
  75. cormist = 1,
  76. hoverassault = 1,
  77. gunshipsupport = 1,
  78. },
  79. riot = {
  80. armwar = 1,
  81. cormak = 1,
  82. spiderriot = 1,
  83. arm_venom = 1,
  84. jumpblackhole = 1,
  85. corlevlr = 1,
  86. tawf114 = 1,
  87. amphriot = 1,
  88. shiptorp = 1,
  89. hoverriot = 1,
  90. blackdawn = 1,
  91. },
  92. assault = {
  93. armzeus = 1,
  94. armorco = 1,
  95. spiderassault = 1,
  96. corgol = 1,
  97. correap = 1,
  98. shipraider = 1,
  99. amphassault = 1,
  100. corraid = 1,
  101. corthud = 1,
  102. corcan = 1,
  103. nsaclash = 1,
  104. armbrawl = 1,
  105. },
  106. arty = {
  107. armham = 1,
  108. armraven = 1,
  109. shieldarty = 1,
  110. firewalker = 1,
  111. corgarp = 1,
  112. cormart = 1,
  113. armcrabe = 1,
  114. shiparty = 1,
  115. corbats = 1,
  116. reef = 1,
  117. armmanni = 1,
  118. },
  119. special1 = {
  120. corclog = 1,
  121. spherepole = 1,
  122. capturecar = 1,
  123. blastwing = 1,
  124. hoverdepthcharge = 1,
  125. amphraider2 = 1,
  126. armspy = 1,
  127. shipscout = 1,
  128. spherecloaker = 1,
  129. },
  130. special2 = {
  131. corroach = 1,
  132. armtick = 1,
  133. armmerl = 1,
  134. bladew = 1,
  135. corsktl = 1,
  136. subarty = 1,
  137. },
  138. aaunit = {
  139. corcrash = 1,
  140. armjeth = 1,
  141. vehaa = 1,
  142. hoveraa = 1,
  143. amphaa = 1,
  144. spideraa = 1,
  145. armaak = 1,
  146. corsent = 1,
  147. shipaa = 1,
  148. },
  149. conunit = {
  150. amphcon = 1,
  151. armca = 1,
  152. armrectr = 1,
  153. arm_spider = 1,
  154. coracv = 1,
  155. corch = 1,
  156. cornecro = 1,
  157. corned = 1,
  158. gunshipcon = 1,
  159. shipcon = 1,
  160. }
  161. }
  162.  
  163. local selection = {}
  164. local selected = {}
  165. local checked = {}
  166. local radchanged = false
  167. local originalrad = rad
  168. local radchangeddrawtime = 0
  169. local lastrelease = -1
  170.  
  171. function widget:KeyPress(key, mods, isRepeat) -- This callin is triggered whenever the user presses a key.
  172. if key == keypresses.plus then
  173. if radchanged == false then
  174. originalrad = rad
  175. radchangeddrawtime = 4
  176. end
  177. rad = rad+20
  178. radchanged = true
  179.  
  180. end
  181.  
  182. if key == keypresses.minus and rad > 101 then
  183. if radchanged == false then
  184. originalrad = rad
  185. radchangeddrawtime = 4
  186. end
  187. rad = rad-20
  188. radchanged = true
  189. end
  190.  
  191. if key == keypresses.minus and rad < 101 then
  192. if radchanged == false then
  193. originalrad = rad
  194. radchangeddrawtime = 8
  195. end
  196. radchanged = true
  197. end
  198.  
  199. if isRepeat == false and debug then
  200. Spring.Echo("game_message: key: " .. key)
  201. end
  202. if key == keypresses.raider and ontype == "none" then --Here keypresses.raider is the same as keypresses["raider"]. This is how you look up values in a table.
  203. on = true -- we're using this variable to talk to KeyRelease and DrawWorld. This way then they know we're working on getting a selection going.
  204. ontype = "raider"
  205. end
  206. if key == keypresses.skirm and ontype == "none" then
  207. on = true
  208. ontype = "skirm"
  209. end
  210. if key == keypresses.riot and ontype == "none" then
  211. on = true
  212. ontype = "riot"
  213. end
  214. if key == keypresses.assault and ontype == "none" then
  215. on = true
  216. ontype = "assault"
  217. end
  218. if key == keypresses.arty and ontype == "none" then
  219. on = true
  220. ontype = "arty"
  221. end
  222. if key == keypresses.special1 and ontype == "none" then
  223. on = true
  224. ontype = "special1"
  225. end
  226. if key == keypresses.special2 and ontype == "none" then
  227. on = true
  228. ontype = "special2"
  229. end
  230. if key == keypresses.aaunit and ontype == "none" then
  231. on = true
  232. ontype = "aaunit"
  233. end
  234. if key == keypresses.conunit and ontype == "none" then
  235. on = true
  236. ontype = "conunit"
  237. end
  238.  
  239. end
  240.  
  241. function widget:GameFrame(f) -- called once every frame. This is so we don't keep looking for units every keypress.
  242.  
  243. if radchanged then
  244. radchangeddrawtime = radchangeddrawtime - 1
  245. if radchangeddrawtime == 0 then
  246. radchanged = false
  247. end
  248. end
  249.  
  250.  
  251. if f%2 == 0 then -- % - remainers left after divided by the second number. here it's framenum divided by 2. So this happens every 2nd frame.
  252. -- this has performance impact, test in use
  253. if on and ontype ~= "none" then
  254. local x,y = Spring.GetMouseState()
  255. local _,pos = Spring.TraceScreenRay(x,y,true)
  256. if type(pos) == "table" then -- prevent crashing from attempting to index a number value. The above seems to give random numbers sometimes.
  257. x = pos[1];y = pos[3];pos = nil -- ; is effectively a new line in LUA. This just makes your code look nicer.
  258. else
  259. if Spring.ValidUnitID(pos) then
  260. x,_,y = Spring.GetUnitPosition(pos)
  261. -- elseif Spring.ValidFeatureID(pos) then This crashes, if unit selection button is pressed outside map area and is not really needed anyway
  262. -- x,_,y = Spring.GetFeaturePosition(pos)
  263. end
  264. end
  265. if x ~= nil and y ~= nil then
  266. for _,id in pairs(Spring.GetUnitsInCylinder(x,y,rad,Spring.GetMyTeamID())) do -- Here we're skipping the creation of the table altogether in favor of just plugging in the results of 'getunitsincylinder'
  267. if checked[id] == nil and unittypes[ontype][UnitDefs[Spring.GetUnitDefID(id)].name] and not selected[id] then -- Here we're using LUA's if true or exists logic. This says 'if this unit's unitdefid exists as a value in this table AND it's not a key in selected, then do this. This means units must match on the table and be a unique unit
  268. if debug then Spring.Echo("game_message: Selected " .. id) end
  269. selection[#selection+1] = id
  270. selected[id] = id
  271. end
  272. checked[id] = 1
  273. end
  274. end
  275. end
  276. end
  277. end
  278.  
  279. function widget:KeyRelease(key) -- Called whenever user stops pressing a key.
  280. if triggerkeys[key] and on then
  281. on = false
  282. ontype = "none"
  283. Spring.SelectUnitArray(selection,false)
  284. selection = {} -- clear the table.
  285. selected = {}
  286. checked = {}
  287. end
  288. end
  289.  
  290. function widget:DrawWorld() -- this is used for openGL stuff.
  291. if on or radchanged then
  292. local x,y = Spring.GetMouseState()
  293. local _,pos = Spring.TraceScreenRay(x,y,true)
  294. x,y = nil
  295. if type(pos) == "number" then -- prevent crashing from attempting to index a number value. The above seems to give random numbers sometimes.
  296. if Spring.ValidUnitID(pos) then
  297. local id = pos
  298. pos = {}
  299. pos[1],pos[2],pos[3] = Spring.GetUnitPosition(id)
  300. id = nil
  301. elseif Spring.ValidFeatureID(pos) then -- This is also not needed...
  302. local id = pos --
  303. pos = {} --
  304. pos[1],pos[2],pos[3] = Spring.GetFeaturePosition(id) --
  305. end --
  306. end
  307. if on then
  308. if type(pos) == "table" and pos[1] ~= nil and pos[2] ~= nil then
  309. gl.PushMatrix() --This is the start of an openGL function.
  310. gl.LineStipple(true)
  311. gl.LineWidth(2.0)
  312. gl.Color(color[ontype][1],color[ontype][2],color[ontype][3],1)
  313. gl.DrawGroundCircle(pos[1], pos[2], pos[3], rad, 40) -- draws a simple circle.
  314. gl.Translate(pos[1],pos[2],pos[3])
  315. gl.Billboard()
  316. gl.Text("Selecting " .. ontype,-0,-25,12,"v") -- Displays text. First value is the string, second is a modifier for x (in this case it's x-25), third is a modifier for y, fourth is the size, then last is a modifier for the text itself. "v" means vertical align.
  317. gl.Color(1,1,1,1) -- we have to reset what we did here.
  318. gl.LineWidth(1.0)
  319. gl.LineStipple(false)
  320. gl.PopMatrix() -- end of function. Have to use this with after a push!
  321. end
  322. end
  323. if radchanged and not on and type(pos) == "table" and originalrad then
  324. gl.PushMatrix()
  325. gl.LineWidth(1.0)
  326. gl.Color(1,1,1,1)
  327. gl.DrawGroundCircle(pos[1],pos[2],pos[3],originalrad,40)
  328. gl.Translate(pos[1],pos[2],pos[3])
  329. gl.Billboard()
  330. gl.Text("Unit selection circle size: " .. rad,-105,10,15,"v")
  331. gl.LineWidth(1.0)
  332. gl.Color(1,1,1,1)
  333. gl.PopMatrix()
  334. end
  335. pos = nil
  336.  
  337. end
  338. if #selection > 0 then -- Draw circles around selected units. #tablename is the length of the ordered table (or last consecutive value)
  339. local pos = {}
  340. for i=1,#selection do -- do this for every entry in the ordered table. i is the incremental value. i=1 means that the first value is 1. i increases by 1 (or a third value if provided eg 1,5,0.25 would do 1 + 0.25 every execution) with every execution and will continue until i == #selection. i=1,#table is very useful for doing things to every entry in an ordered table.
  341. if Spring.ValidUnitID(selection[i]) then
  342. pos[1],pos[2],pos[3] = Spring.GetUnitPosition(selection[i])
  343. gl.PushMatrix()
  344. gl.LineWidth(3.0)
  345. gl.Color(color[ontype][1],color[ontype][2],color[ontype][3],1)
  346. gl.DrawGroundCircle(pos[1],pos[2],pos[3],40,40)
  347. gl.Color(1,1,1,1)
  348. gl.PopMatrix()
  349. end
  350. end
  351. end
  352. end
Add Comment
Please, Sign In to add comment