|
 |
| Author |
Message |
|
BulletMagnet
|
Posted: 14 Aug, 2010
|
|
Joined: 05 Oct, 2007 Posts: 16425 Location: camping near the biggest power-up
|
Mithy wrote: [...] Mex Auto-build would be to key deposit_markers with position hashes, and then poke that table for the few hashes that might be in range of the location clicked. e.g. if the click is at 130.05340730578 x 103.39991213 or whatever, you would check your table for the 9 possible hashes +/- 1 from that location (129x102 to 131x104).
Or, for that matter, you could pre-load all of these potential adjacent hashes into deposit_markers, even doing 6x6 or 9x9 for hydrocarbons. Then you'd only have to check for the hash at the current click position. That's an option, probably a better one since I was contemplating making a less-accurate hash. I kept it as it is currently because of the common situation in custom maps where mexes are close together, but that is probably a non-issue when mapping extra hash positions. Mithy wrote: Also, once you've determined it's a deposit click, you might want to check for a structure at that location already, and perform a normal automode command instead of a mex build. This would solve everyone's complaints about not being able to assist mexes without pressing I. I've already accounted for that; the code branches away from the deposit_marker loop if it detects that it's over a structure. BAH. You ninja'ed me. Let me see what you have.
_________________
Nephylim wrote: But, an FA army in an FA environment just looks... right. Does anyone know how to use air transports? I cant get them to pick up troops.
|
|
| Top |
|
 |
|
Mithy
|
Posted: 14 Aug, 2010
|
|
Joined: 19 Jul, 2009 Posts: 2972
|
That was just to give it a nudge. I don't know what the exact results of that code would be, but I suspect it will create a square of hashes slightly offset from any deposits at fractional (.5) positions, which is why I went with a min size of 2, which should cover at least the entire square, and then some on the 'off' side. On further thought, it might be a good idea to add a second check after deposit_markers[mouseHash] that checks the current unit selection for some categories (ENGINEER or something, I don't know). On that note, can you use the vector category manipulation in UI? That would probably be a lot faster than table loops and string checks. Edit: I see ParseEntityCategory in User.Global, but I don't see a function that would compare a category vector against another category vector, which is what you'd need to make e.g. ParseEntityCategory('MASSEXTRACTION') compare against buildableCategories as populated by GetUnitCommands. Welp. Edit 2: With respect to checking for engineering units in selection before performing a deposit check, something like: Code: local engineers = EntityCategoryFilterDown(categories.ENGINEER, selectedUnits) if engineers then --do deposit checks end ...would be more than adequate.
|
|
| Top |
|
 |
|
Mithy
|
Posted: 14 Aug, 2010
|
|
Joined: 19 Jul, 2009 Posts: 2972
|
Oh-ho, maybe you can compare category vectors directly. EntityCategoryEmpty. Code: if not EntityCategoryEmpty(buildableCategories - (buildableCategories - categories.MASSEXTRACTION) ) then --do stuff end Subtract MASSEXTRACTION from buildableCategories, then subtract that from buildableCategories, to see if anything remains. If it returns false, then we know that buildableCategories contained the category that we subtracted. I have no idea if this actually works, or if you can even add/subtract category vector variables, but it's worth a shot.
|
|
| Top |
|
 |
|
BulletMagnet
|
Posted: 14 Aug, 2010
|
|
Joined: 05 Oct, 2007 Posts: 16425 Location: camping near the biggest power-up
|
Mithy, I suggest you look at; Code: local availableOrders, availableToggles, buildableCategories = GetUnitCommandData(selectedUnits) local buildableUnits = EntityCategoryGetUnitList(buildableCategories) I can only guess that you're trying to do what I've got in the above. Anyway, I implemented the changes on the previous page. Buildings are positioned every half o-grid, I have to have a five-by-five lump of hashes for each mass deposit (I haven't even considered hydros. yet) instead of a three-by-three or the system won't work well on some deposits. Trying it on a small (10x10km) eight player map, I've discovered another concern about this; too many damn elements in the table. The map I played has 80 deposits on it, gives me a 2000 element deposit_marker table. I'm worried that any performance gains from keying mass positions will be lost by Lua searching for a matching key.
_________________
Nephylim wrote: But, an FA army in an FA environment just looks... right. Does anyone know how to use air transports? I cant get them to pick up troops.
|
|
| Top |
|
 |
|
Mithy
|
Posted: 14 Aug, 2010
|
|
Joined: 19 Jul, 2009 Posts: 2972
|
BulletMagnet wrote: I can only guess that you're trying to do what I've got in the above. Nope, I saw that. The last bit of code I posted was intended to replace the double loop that goes through buildableUnits and each unit's blueprint's categories, but I didn't really finish the thought - that would only tell you whether or not your selected units can build a mass extraction unit, and wouldn't actually give you the blueprintid of one. BulletMagnet wrote: Anyway, I implemented the changes on the previous page. Buildings are positioned every half o-grid, I have to have a five-by-five lump of hashes for each mass deposit (I haven't even considered hydros. yet) instead of a three-by-three or the system won't work well on some deposits.
Trying it on a small (10x10km) eight player map, I've discovered another concern about this; too many damn elements in the table. The map I played has 80 deposits on it, gives me a 2000 element deposit_marker table. I'm worried that any performance gains from keying mass positions will be lost by Lua searching for a matching key. Lua's table accessing is bound to be faster than an iterative loop 1/25th as large doing vector math functions. You could try breaking it up a bit by doing nested x and z tables, e.g. deposit_markers[x][z] = markerTable.type and if deposit_markers[x] and deposit_markers[x][z] then ..which would cut down the number of entries in the base table by at least 1/5th, assuming 5x5 squares (more if there are same-x-coord extractor locations). This method could also use straight up numbered indexes, instead of string indexes. You don't have to use any of this of course, I'm just throwing suggestions out. I can't really tell what's specifically hurting performance on my machine, since it always runs slowly, but that's why I'm always looking for ways to optimize this kind of thing.
|
|
| Top |
|
 |
|
BulletMagnet
|
Posted: 14 Aug, 2010
|
|
Joined: 05 Oct, 2007 Posts: 16425 Location: camping near the biggest power-up
|
|
I'm all for optimising for the sake of optimisation!
_________________
Nephylim wrote: But, an FA army in an FA environment just looks... right. Does anyone know how to use air transports? I cant get them to pick up troops.
|
|
| Top |
|
 |
|
Mithy
|
Posted: 14 Aug, 2010
|
|
Joined: 19 Jul, 2009 Posts: 2972
|
Oh hey, I did have the right idea. Here's a really quick way (in theory) to pull a T1 mex bpid from your selected units' buildable categories: Code: --Get a cat vector for our resource structure type local depositCategory = ParseEntityCategory(depositType) * categories.TECH1
--Make sure selected units can build at least one of these local buildableUnits = EntityCategoryGetUnitList(buildableCategories * depositCategory) if buildableUnits then --Grab the first one that matches BuildBP = buildableUnits[1] end Stick this after where you've successfully located a deposit position/type. EntityCategoryEmpty can still be used earlier on in the block, as I first posted it, to check whether or not your selected units can build any kind of mex or hydro, before you even bother looking for a deposit marker. You'd just have to use a cat intersection like: Code: if not EntityCategoryEmpty(buildableCategories * ((categories.MASSEXTRACTION + categories.HYDROCARBON) * categories.TECH1) ) then which should pass if your selected units can build any T1 extractor or hydrocarbon, with near-zero performance hit.
|
|
| Top |
|
 |
|
BulletMagnet
|
Posted: 14 Aug, 2010
|
|
Joined: 05 Oct, 2007 Posts: 16425 Location: camping near the biggest power-up
|
|
I've just put in the category changes; works a treat!
However, I'm likely going to revert back to walking the deposit_markers table each time. I noticed that the snap-to thing that mexes and hydros. have to deposits is zoom dependent. I think I have to match that because placing a mex while zoomed out is easy when manually building things, but sucks royally with OCW.
If I'm going to vary the distance that OCW activates, I'll have to do distance checks.
I suppose I could divide the map into quarters, and then just walking a table of some of the deposits.
_________________
Nephylim wrote: But, an FA army in an FA environment just looks... right. Does anyone know how to use air transports? I cant get them to pick up troops.
|
|
| Top |
|
 |
|
Mithy
|
Posted: 14 Aug, 2010
|
|
Joined: 19 Jul, 2009 Posts: 2972
|
|
Yeah, I hadn't considered zoom at all. Dividing into quarters would help.
New thought: what about next(table, index)? What I'm thinking is that you numerically key the table by x coord, but otherwise maintain the same structure. Then iterate with next using an until or while loop, starting at mousex - tolerance. If next needs an actual valid index, then iterate with a numerical for loop from that starting point until you get one. Then distance check each, until the indexes have exceeded mousex + tolerance.
This radically reduces the number of iterations necessary, down to maybe 1-5 depending on how many mexes share similar x coords.
Edit: Scratch that. next doesn't iterate in any particular order, even in a numerically-keyed table. How the hell is that useful at all? I don't know!
This idea could still work with a numerical for loop, though. A few dozen nil table accesses should still be a lot faster than a few dozen VDist2 checks.
|
|
| Top |
|
 |
|
Ghaleon
|
Posted: 15 Aug, 2010
|
|
Joined: 13 Jun, 2008 Posts: 729
|
|
It's a joy reading your ongoing efforts, great work!
Oh and a request relayed from a friend of mine, he wants to preview nuke damage for all units below the cursor when you target stuff.
_________________ TVg V5 Alpha Testers Wanted!
 Bulletstorm released other mods
|
|
| Top |
|
 |
|
Veqryn
|
Posted: 19 Aug, 2010
|
|
Joined: 07 Dec, 2007 Posts: 122
|
|
About the one-click-Wonder ui mod,
I love it, clicking to build mexes and hydrocarbons is great
however, i can't seem to get the re-built destroyed structure thing to work. no matter how many times i grab some engineers, click and/or alt-click in the middle of a burned out building, nothing happens
and the alt repair seems to work only half the time... sometimes when i hold down alt, i don't get the repair key, and sometime i do.
|
|
| Top |
|
 |
|
conKORD
|
Posted: 19 Aug, 2010
|
|
Joined: 26 Jul, 2007 Posts: 139
|
Well done  But one click rebuilder doesn't work. Cursor changes to "repair" icon (when holding alt) only if no units currently selected. It could be indicator of problem. No any external mods (UI and sim).
|
|
| Top |
|
 |
|
Mithy
|
Posted: 19 Aug, 2010
|
|
Joined: 19 Jul, 2009 Posts: 2972
|
|
Yeah, about that: I noticed that the rebuilder is trying to look up dead units from a coordinate hash table, except that I couldn't find anywhere where units were actually being added to the living units table, which is where the dead units table gets its data. I don't know if he finished implementing this yet.
|
|
| Top |
|
 |
|
BulletMagnet
|
Posted: 19 Aug, 2010
|
|
Joined: 05 Oct, 2007 Posts: 16425 Location: camping near the biggest power-up
|
|
I do that in UserSync, but the changes you suggested earlier have killed my rebuild code.
_________________
Nephylim wrote: But, an FA army in an FA environment just looks... right. Does anyone know how to use air transports? I cant get them to pick up troops.
|
|
| Top |
|
 |
|
conKORD
|
Posted: 19 Aug, 2010
|
|
Joined: 26 Jul, 2007 Posts: 139
|
I've looked into worldview.lua and yes, mod switching commandmode to repair only when no units selected. if rollOver or not selectedUnits then Looks like it should be if rollOver and selectedUnits then But it is only about one click repair UI. Rebuilder's UI looks ok. I'll try to trace where is problem. And one question. I understand correctly that through hooked usersync.lua every tick passes unitlist of active player? Is possible to get that unitlist? BulletmagnetSo where we can download previous working version? 
|
|
| Top |
|
 |
|
Mithy
|
Posted: 19 Aug, 2010
|
|
Joined: 19 Jul, 2009 Posts: 2972
|
BulletMagnet wrote: I do that in UserSync, but the changes you suggested earlier have killed my rebuild code. Oh sure, blame me. But seriously, I don't see where you're populating the structs.alive table in commandmode.lua. I see where you're harvesting releaseids in usersync, but those are supposedly coming from the structs.alive table, which uh, isn't having anything added to it, anywhere in the mod. conKORD wrote: And one question. I understand correctly that through hooked usersync.lua every tick passes unitlist of active player? Is possible to get that unitlist? It's just a table of every entityid belonging to that player (UnitData), with data optionally synced from the sim. There isn't any data naturally accessible there other than things like enhancements, although you can use the entityids to harvest blueprint info etc.
|
|
| Top |
|
 |
|
BulletMagnet
|
Posted: 19 Aug, 2010
|
|
Joined: 05 Oct, 2007 Posts: 16425 Location: camping near the biggest power-up
|
|
Oh, I must have left that code in the Backport branch.
...whoops.
I'll get that fixed soon.
_________________
Nephylim wrote: But, an FA army in an FA environment just looks... right. Does anyone know how to use air transports? I cant get them to pick up troops.
|
|
| Top |
|
 |
|
conKORD
|
Posted: 19 Aug, 2010
|
|
Joined: 26 Jul, 2007 Posts: 139
|
Mithy wrote: It's just a table of every entityid belonging to that player (UnitData), with data optionally synced from the sim. There isn't any data naturally accessible there other than things like enhancements, although you can use the entityids to harvest blueprint info etc. I just need method to get list of all units and structures belonging to player. I saw two ways to do it - -to track every units and fill unitlist with units that currently under construction. Save selection, select all units, add selection to unitlist, restore selection. If is possible to get unitlist from usersync - it could be more accurate and useful. Edit: I've uncommented SPEW('Sync = ' .. repr(Sync)) in usersinc.lua, but in log in "sync" array fields UnitData and ReleaseIds is empty. Code: if Sync.ReleaseIds[1] or Sync.UnitData[1] then SPEW('Sync = ' .. repr(Sync)) end returns nothing in log. So nothing fills CM.structs.dead and CM.structs.alive . And, of course, mod have no enough data to rebuild something. I'm very disappointed that I have not working version to look how it should to be.
|
|
| Top |
|
 |
|
BulletMagnet
|
Posted: 19 Aug, 2010
|
|
Joined: 05 Oct, 2007 Posts: 16425 Location: camping near the biggest power-up
|
conKORD wrote: Mithy wrote: It's just a table of every entityid belonging to that player (UnitData), with data optionally synced from the sim. There isn't any data naturally accessible there other than things like enhancements, although you can use the entityids to harvest blueprint info etc. I just need method to get list of all units and structures belonging to player. I saw two ways to do it - -to track every units and fill unitlist with units that currently under construction. Save selection, select all units, add selection to unitlist, restore selection. Tried that, incredibly slow for what I wanted it for. Messes with buildmode too. I just table every structure that I select or give an order to, and try to to the same for any selected units building structures. Quote: If is possible to get unitlist from usersync - it could be more accurate and useful. Edit: I've uncommented SPEW('Sync = ' .. repr(Sync)) in usersinc.lua, but in log in "sync" array fields UnitData and ReleaseIds is empty. Code: if Sync.ReleaseIds[1] or Sync.UnitData[1] then SPEW('Sync = ' .. repr(Sync)) end returns nothing in log. So nothing fills CM.structs.dead and CM.structs.alive . And, of course, mod have no enough data to rebuild something. I'm very disappointed that I have not working version to look how it should to be. They're only added to ReleaseIds the tick they die, and only for the tick they die. If you miss them then, they're lost to the aether forever. If memory serves correctly, the userunit objects seem to vanish rather quickly as well.
_________________
Nephylim wrote: But, an FA army in an FA environment just looks... right. Does anyone know how to use air transports? I cant get them to pick up troops.
|
|
| Top |
|
 |
|
conKORD
|
Posted: 19 Aug, 2010
|
|
Joined: 26 Jul, 2007 Posts: 139
|
BulletMagnet wrote: Tried that, incredibly slow for what I wanted it for. Messes with buildmode too.
Not so slow. I've made ingame turnoffable supreme economy for personal usage and while simspeed is about 0 turning it on or off gives max +/- 1 simspeed. But anyway it is not best method.
|
|
| Top |
|
 |
|
Mithy
|
Posted: 19 Aug, 2010
|
|
Joined: 19 Jul, 2009 Posts: 2972
|
|
The Sync table in usersync is incoming data on a per-sync basis, i.e. changed data for the current sync beat. Not persistent data.
UnitData (NOT Sync.UnitData) is the persistent user-side Sync data, into which Sync.UnitData is merged. Sync.ReleaseIds is dead/destroyed unit entityids whose references are removed from the persistent UnitData table.
BM: Does Sync.UnitData contain tables for all units, or just changed unit data? I realize it is only meant to hold changed data, but what I'm not sure about is whether or not there are empty tables for entityids whose data has not been changed. If not, then it would be possible to use this to gather data on only new / changed units, and check those for categories.STRUCTURE.
Edit-- conKORD, the reason Sync.UnitData[1] and Sync.ReleaseIds[1] don't ever exist is because they're indexed by entityid, not numerically. If you iterate those tables, or repr() the base table, you'll get what you're looking for.
|
|
| Top |
|
 |
|
conKORD
|
Posted: 19 Aug, 2010
|
|
Joined: 26 Jul, 2007 Posts: 139
|
Mithy wrote: conKORD, the reason Sync.UnitData[1] and Sync.ReleaseIds[1] don't ever exist is because they're indexed by entityid, not numerically. If you iterate those tables, or repr() the base table, you'll get what you're looking for. You are right. I used Code: for id, unit in Sync.UnitData do CM.unitlist[id] = {id,unit,GetEntityById(id)}
SPEW('unitlist = ' .. repr(CM.unitlist)) end to fill my new unitlist. And I've got table of unit IDs debug: unitlist = { debug: 2={ "2", false }, debug: 3={ "3", false }, debug: 4={ "4", false }, debug: 5={ "5", false }, debug: 6={ "6", false } debug: } But by some reasons I can't get references to units from those ids 
|
|
| Top |
|
 |
|
Domino
|
Posted: 19 Aug, 2010
|
|
Joined: 26 Feb, 2009 Posts: 2996
|
|
hey,
does this also rebuild destroyed units that are not structures? if it doesnt how come your not doing that also?
_________________ Domino. ______________
|
|
| Top |
|
 |
|
Mithy
|
Posted: 19 Aug, 2010
|
|
Joined: 19 Jul, 2009 Posts: 2972
|
|
um, because only structures get the rebuild bonus from being built on top of an identical wreck? It would be trivial to expand the check to experimental-type units with NEEDMOBILEBUILD, but it would also be totally pointless as the engineers being commanded would have to reclaim the wreck first. In other words, there would be no point to actually building the new unit there, just reclaim the wreck and build it in a more logical place.
conKORD, again, remember that Sync.UnitData is a temp table, and won't have a list of all current units, just changed units. Have you tried just a repr(UnitData) for one sync beat after say, 10 seconds of sim time? Just use a check against GetGameTick() in an OnSync hook, and then set a local var so it doesn't do it again.
If what you want is incoming data, then just repr(Sync.UnitData) every sync beat.
|
|
| Top |
|
 |
|
conKORD
|
Posted: 19 Aug, 2010
|
|
Joined: 26 Jul, 2007 Posts: 139
|
Mithy wrote: Code: for id, unit in Sync.UnitData do CM.unitlist[id] = {id,unit,GetEntityById(id)}
SPEW('unitlist = ' .. repr(CM.unitlist)) end It passes through every element of Sync.UnitData every tick and adds IDs of every new unit to unitlist. Yes, it do it, If not - then would not be those strings in log. Code: debug: unitlist = { debug: 2={ "2", false }, debug: 3={ "3", false }, debug: 4={ "4", false }, debug: 5={ "5", false }, debug: 6={ "6", false } debug: } SPEW(repr(UnitData)) always returns empty array
|
|
| Top |
|
 |
 |
 |
|