make links between ships and their database entry explicit
This changes the database entry to look up via the multiplayer id.
This in turn makes the locale issue with database solvable.
It allows ships to have different database entries per type, which could be used to give histories of named ships. I don't have a use for this currently, but I think that's a lack of imagination on my part.
It also allows multiple ships to point to the same database entry which seems more useful. As an example a new faction could all link to a page about the faction rather than the ship type, while not major I think it could be useful.
It does change the current behavior, as such the database button will stop working for custom ship types with new database entries. This behavior could be easily restored, but then we hit the same locale issues.
due to the newness of that feature I suspect the only scripts that rely on it are @Xansta (who I can help verify and update his scripts) and maybe @czenker (who I think originally wrote the remote science database feature)
Could we have an example of how the new database lookup would work compared to the old? For example, if I have this Lua code today:
local ships_db = queryScienceDatabase("Ships")
local fighter_db = queryScienceDatabase("Ships","Starfighter")
fighter_db:setLongDescription("Starfighters are single to 3 person small ships")
local stock_db = ships_db:addEntry("Mainstream")
stock_db = queryScienceDatabase("Ships","Mainstream")
stock_db:setLongDescription("Mainstream ships are those ship types that are commonly available")
local fighter_stock_db = stock_db:addEntry("Starfighter")
fighter_stock_db:setLongDescription("Starfighters are single to 3 person small ships.")
fighter_stock_db:addEntry("MP52 Hornet")
local mp52_hornet_db = queryScienceDatabase("Ships","Mainstream","Starfighter","MP52 Hornet")
mp52_hornet_db:setLongDescription("The MP52 Hornet is a significantly upgraded version of MU52 Hornet")
mp52_hornet_db:setKeyValue("Class","Starfighter")
mp52_hornet_db:setKeyValue("Sub-class","Interceptor")
mp52_hornet_db:setKeyValue("Size","30")
mp52_hornet_db:setKeyValue("Shield","60")
mp52_hornet_db:setKeyValue("Hull","70")
mp52_hornet_db:setKeyValue("Repair Crew",1)
mp52_hornet_db:setKeyValue("Warp Speed","60 U/min") --1000 (added for scenario)
mp52_hornet_db:setKeyValue("Battery Capacity",400)
mp52_hornet_db:setKeyValue("Sensor Ranges","Long: 18 U / Short: 4 U")
mp52_hornet_db:setKeyValue("Move speed","7.5 U/min") --125 (value * 60 / 1000 = units per minute)
mp52_hornet_db:setKeyValue("Turn speed","32 deg/sec")
mp52_hornet_db:setKeyValue("Beam weapon 355:30","Rng:.9 Dmg:2.5 Cyc:4")
mp52_hornet_db:setKeyValue("Beam weapon 5:30","Rng:.9 Dmg:2.5 Cyc:4")
mp52_hornet_db:setImage("radar_fighter.png")
How might that code look different after the change? In particular what changes in addEntry() and/or queryScienceDatabase()? I learn best by example
that would all be unedited, likewise anything in the template files would be unedited.
The only thing which would change is where you create new types of ships outside of the template files
as an example if you added a "MP52 mk2 hornet"
-- code to get new_fighter_db:
mp52_mk2_db = new_fighter_db:addEntry("MP52 Hornet")
-- code to configure mp52_mk2_db
function mp52_mk2_hornet()
local ship=playerShip:applyTemplate("MP52 Hornet")
-- multiple calls to ship:add each change to make a "M52 Hornet" a "MP52 Hornet"
return ship
end
it would change to
-- code to get new_fighter_db:
mp52_mk2_db = new_fighter_db:addEntry("MP52 Hornet")
-- code to configure mp52_mk2_db
function mp52_mk2_hornet()
local ship=playerShip:applyTemplate("MP52 Hornet")
-- multiple calls to ship:add each change to make a "M52 Hornet" a "MP52 Hornet"
ship:setScienceDatabaseEntry(mp52_mk2_db) -- new line - the link between the sci database and the ship
return ship
end
ships that are defined in template files are unaffected (other than fixing ships where a localeName is set like the cpu cruiser)
The only thing which would change is where you create new types of ships outside of the template files
An example of that:
local ship = CpuShip():setFaction("Kraylor"):setTemplate("Adder MK4"):orderRoaming()
local db = ScienceDatabase():setName(_("Mysterious Ship")):setLongDescription(_("A very mysterious ship, maybe you will find out more later"))
ship:setScienceDatabaseEntry(db)
// To return the new entry's long description, these should be equivalent:
ship:getScienceDatabaseEntry():getLongDescription()
queryScienceDatabase("Mysterious Ship"):getLongDescription()
Implementing via API, I got:
$ curl --data 'ship = CpuShip():setFaction("Kraylor"):setTemplate("Adder MK4"):orderRoaming(); db = ScienceDatabase():setName(_("Mysterious Ship")):setLongDescription(_("A very mysterious ship, maybe you will find out more later")); ship:setScienceDatabaseEntry(db); return ship:getScienceDatabaseEntry():getLongDescription()' http://localhost:8080/exec.lua
"A very mysterious ship, maybe you will find out more later"%
$ curl --data 'ship = CpuShip():setFaction("Kraylor"):setTemplate("Adder MK4"):orderRoaming(); db = ScienceDatabase():setName(_("Weird Ship")):setLongDescription(_("A very weird ship, maybe you will find out more later")); ship:setScienceDatabaseEntry(db); return queryScienceDatabase("Weird Ship"):getLongDescription()' http://localhost:8080/exec.lua
"A very weird ship, maybe you will find out more later"%
Also, the DB button for that specific ship on Science gets linked to this specific entry, rather than the ship type.
I need a better example. The one I initially chose was just what I happened to be working on at the moment. It seems that that use case does not fit the change very well. Perhaps this might be better:
function jade5(enemyFaction)
local ship = CpuShip():setFaction(enemyFaction):setTemplate("Adder MK5"):orderRoaming()
ship:setTypeName("Jade 5")
ship:setJumpDrive(true)
ship:setJumpDriveRange(5000,35000)
local jade_5_db = queryScienceDatabase("Ships","Starfighter","Jade 5")
if jade_5_db == nil then
local starfighter_db = queryScienceDatabase("Ships","Starfighter")
starfighter_db:addEntry("Jade 5")
jade_5_db = queryScienceDatabase("Ships","Starfighter","Jade 5")
jade_5_db:setLongDescription("Conversions R Us purchased a number of Adder MK 5 ships at auction and added jump drives to them to produce the Jade 5")
jade_5_db:setKeyValue("Class","Starfighter")
jade_5_db:setKeyValue("Sub-class","Gunship")
jade_5_db:setKeyValue("Size","80")
jade_5_db:setKeyValue("Shield","30")
jade_5_db:setKeyValue("Hull","50")
jade_5_db:setKeyValue("Move speed","4.8 U/min")
jade_5_db:setKeyValue("Turn speed","28.0 deg/sec")
jade_5_db:setKeyValue("Jump Range","5 - 35 U")
jade_5_db:setKeyValue("Beam weapon 0:35","2.0 Dmg / 5.0 sec")
jade_5_db:setKeyValue("Beam weapon 30:70","2.0 Dmg / 5.0 sec")
jade_5_db:setKeyValue("Beam weapon -30:70","2.0 Dmg / 5.0 sec")
jade_5_db:setImage("radar_fighter.png")
end
return ship
end
In this example, I query the database to see if it already contains an entry for the Jade 5. If not, I make one for it. This means that there's one Jade 5 entry for any number of Jade 5 type ships created. If I'm reading properly between the lines of the change, there would be one database entry for every Jade 5 created.
in Xansta's the above example - this version would behave identically
function jade5(enemyFaction)
local ship = CpuShip():setFaction(enemyFaction):setTemplate("Adder MK5"):orderRoaming()
ship:setTypeName("Jade 5")
ship:setJumpDrive(true)
ship:setJumpDriveRange(5000,35000)
local jade_5_db = queryScienceDatabase("Ships","Starfighter","Jade 5")
if jade_5_db == nil then
local starfighter_db = queryScienceDatabase("Ships","Starfighter")
starfighter_db:addEntry("Jade 5")
jade_5_db = queryScienceDatabase("Ships","Starfighter","Jade 5")
jade_5_db:setLongDescription("Conversions R Us purchased a number of Adder MK 5 ships at auction and added jump drives to them to produce the Jade 5")
jade_5_db:setKeyValue("Class","Starfighter")
jade_5_db:setKeyValue("Sub-class","Gunship")
jade_5_db:setKeyValue("Size","80")
jade_5_db:setKeyValue("Shield","30")
jade_5_db:setKeyValue("Hull","50")
jade_5_db:setKeyValue("Move speed","4.8 U/min")
jade_5_db:setKeyValue("Turn speed","28.0 deg/sec")
jade_5_db:setKeyValue("Jump Range","5 - 35 U")
jade_5_db:setKeyValue("Beam weapon 0:35","2.0 Dmg / 5.0 sec")
jade_5_db:setKeyValue("Beam weapon 30:70","2.0 Dmg / 5.0 sec")
jade_5_db:setKeyValue("Beam weapon -30:70","2.0 Dmg / 5.0 sec")
jade_5_db:setImage("radar_fighter.png")
end
ship:setScienceDatabaseEntry(jade_5_db) -- new line here
return ship
end
personally I would hoist the jade_5_db out of the pseudo template function and always create it and link them later, though this is true regardless of this pull request
I put the check in not just for the current run, but in case the Jade 5 ever made it into the base game, I would not accidentally create another science database entry for it. I've already abstracted out a database creation routine for ships, I just did not show it here because that would make the code less clear as an example.