Insertion?

Thalassicus

Bytes and Nibblers
Joined
Nov 9, 2005
Messages
11,057
Location
Texas
I'm trying to figure out how to insert a value into the game's database at a specific location. I'm assuming their <Row> xml statements get parsed to an INSERT INTO sql statement... so I looked up information on the latter but couldn't find how to specify a specific row. How can I do this?

In particular, I've got a unique unit I'd like to insert right after its normal variety, so it shows up on the same spot as the original in production lists ingame.
 
To my knowledge, there's no way to insert mid-table in terms of 'natural order' in SQL. However, if you can identify which variable is being sorted on, you may be able to specify a value for that or transform all value to create a gap if it's sequential integers. I doubt there's an easy way, though.
 
I think units are referenced by their DB ID, which can't easily be changed without changing the vanilla files. You could in theory introduce an ordering group field that takes a higher priority than ID if present and orders all units in a group together, but that would require adding it in all the UI scripts where it would be relevant, of course.
 
You could delete everything and re-add in custom order. Maybe give your custom unit an id of -1? That way everything else would keep the same id. Tho I'm unsure what unintended consequences an id of -1 might have.
 
You could delete everything and re-add in custom order. Maybe give your custom unit an id of -1? That way everything else would keep the same id. Tho I'm unsure what unintended consequences an id of -1 might have.

-1 is probably a bad idea because the game uses it to mean "no unit" in some Lua scripts iirc

Great idea to re-add everything, though. I don't think re-ordering like this should cause any trouble for units because no PostDefines use any.You should make sure to mark your changes well, though, and keeping a copy of the vanilla file to run diffs - otherwise copying over new changes in a patch becomes a PITA.
 
-1 is probably a bad idea because the game uses it to mean "no unit" in some Lua scripts iirc

Great idea to re-add everything, though. I don't think re-ordering like this should cause any trouble for units because no PostDefines use any.You should make sure to mark your changes well, though, and keeping a copy of the vanilla file to run diffs - otherwise copying over new changes in a patch becomes a PITA.
Possibly less heavy than removing and re-adding everything would be to write a local script to generate SQL to create a gap. It would need information from the existing system, but it wouldn't be too hard to write one that took the current max, a list of places you wanted gaps (which numbers it would be shoving up, but all based on their vanilla numbers) and output SQL that moved the top one up however many necessary, and then worked its way down. If I had time I'd run it off in perl right now; or I could, when I have time, write it in php and put it online somewhere for everyone to use. An improvement would be for it to have a list of all IDs available to it, and then users would be able to select which unit they want to add before/after... the algorithm is quite straightforward.
 
The easier way to insert a unit into the established build option list would be to modify the Lua that creates the build list itself, instead of trying to hack the XML. Right now, it does all units (by ID), all non-wonder buildings (by ID), all national wonders (by ID) and all wonders (by ID). Within each category, it does a simple FOR loop over entries (which means by IDs) and adds each eligible unit as it comes up.

So what you'd want to do is change the units to sort by, say, the ID of the tech prerequisite of each unit; you'd create a temporary array, loop once through the units, place their IDs in the appropriate spot in that array, and then do a second loop where you display based on that new array. If you did this by tech ID then your new UU would be placed right where the original unit would have been, since they'd both require the same tech and it'd be unlikely any other units would be at that tech.

The only real downside to this is that the way the IDs are done in the vanilla game sorts units by "type", with all the naval units together, all air units together, all non-combat units together, and so on. I suppose you could add that logic to the sorting array, by looping over units with a given Domain first and putting anything with Strength=0 in its own category. It's a little more work, though.

This isn't idle speculation, really; I've been thinking about something like this for my own mod. My new future-era units are currently all sorted by tech, with lower-tech units listed first (because that's how I added them to the XML), but I'm trying to change that.
 
Good idea! My original post was before I knew anything about UI modding, that solution makes a lot of sense now. :)

It seems something like this should do it, with a loop to fill out w-z for each row of the table:

PHP:
unitList = {unitID=w, priority=x, techCost=y, txtKey=z}

table.sort(unitList, function (a,b)
  if a.priority ~= b.priority then
    return a.priority > b.priority 
  elseif a.techCost ~= b.techCost
    return a.techCost < b.techCost
  else
    return a.txtKey < b.txtKey
  end
end)

I've added a "TooltipPriority" field to the Units table, so users can specify the top-level priority instead of hardcoding it to specific domain types. It defaults to -1, which automatically classifies the unit by combat/civilian status then domain.

I've attached ProductionPopup.lua to diff with the original.
 
Back
Top Bottom