Magitex
(Magitex)
#8
Well, you’re right Mikali; I can’t write from it. It seems you can only READ files from it… odd limitation. My system works the other way around (I re-write the gametype every mission) and then spawn the level through that so I haven’t run into this yet.
Magitex
(Magitex)
#9
Here you go Mikali, I wasted an hour and sorted this out:
local r = openfile("HwRM.log", "r")
if r then
local read_string = nil
local read_strings = {}
local r_num = 0
local record_next = 0
local last_level_string = ""
repeat
read_string = read(r, "*w")
if record_next == 1 then
r_num = r_num + 1
read_strings[r_num] = tostring(read_string)
record_next = 0
elseif read_string ~= nil then
local str = strfind(read_string, "Level:")
if str then
record_next = 1
end
end
until(read_string == nil)
closefile(r)
if r_num > 0 then
last_level_string = read_strings[r_num]
else
last_level_string = "none"
end
print("loaded level:" .. tostring(last_level_string))
else
print("log file not found.")
end
Tested with gamerule functions, and should theoretically work anywhere that can access read functions (which is everything pretty much). It does not require luatrace.
Keep in mind it’s not well tested, and it doesn’t help that the HWRM log is full of binary trash. It’s not 100% guaranteed to produce a result every read so make sure you check if r is invalid and try again. Also don’t run this function more than you have to, it would probably cause homeworld to stall for a microsecond if you call it during gameplay situations.
It still wouldn’t hurt for some proper functionality to be put in.
Mikali
#10
This script doesn’t work in level files either.
The example of my method:
level:
[code]function StoreVar(varName, varValue)
i=0
createSOBGroup(varName)
while (i<varValue) do
addSquadron(varName…i, “HWAT_NUT_NavBouy”, {0, 0, 0}, 0, {0, 0, 0}, 0, 0)
addToSOBGroup(varName…i, varName)
i=i+1
end
end
function DetermChunk()
StoreVar(“segments”,8)
…
end
[/code]
Gamerule:
function GetVar(varName)
temp=SobGroup_Count(varName)
SobGroup_Despawn(varName)
return temp
end
function OnInit()
...
numSegments=GetVar("segments")
...
end
Magitex
(Magitex)
#12
You don’t need to use it in the level script, you use it in your gametype script to tell what level is loaded.
Burly
(Burly)
#13
Sorry I didn’t ask this before, but do you want the human readable level name or the filename?
Also, where all would you be trying to call the command to get the levelname? In the level script, UI, gametype script, etc…?
Burly
(Burly)
#14
Ok, I added a new function that will get the currently loaded level name. Works in deathmatch.lua, UI screens, level script. I hope this fits the bill for you.
I’ll reply here with the function name with the next patch. (Cleaning up some things and the name might change.)
Any other level info you want?
2 Likes
Ideally I’d like to be able to store values, perhaps in a special table, in a level file, then have a gamerule retrieve those values or the table. Perhaps another way to this end would be to have a levelname.lua optional file that gets executed in the gamerule scope? That’d allow even more customized behavior per-map, but might be blurring the lines too much. Level filename should be enough information to get the job done, but not in the most convenient way.
Mikali
#16
The filename.
I agree. Passing less arbitrary information than just the level name would be even better.
Burly
(Burly)
#17
I imagine it could be possible to add a section to the levels like function DetermChunk() or add a new lua command that can be executed there called “addLevelVar(varname, int val1, int val2, string val3)” and then add a “getLevelVar” command.
What is an example of something you’d want to store in there? There might be something that already exists if I know the exact use you are looking for.
1 Like
Mikali
#18
I created a test mod for creating level thumbnails that prints the level name, number of players and (predetermined) player races on the screen using ATI text. The workaround I used only worked because I knew beforehand what levels would be loaded and in what order. But it would have made things a lot easier if the gametype could obtain this information directly from the level files.
In addition, my “Mission Grid” mod could benefit from this:
http://forums.relicnews.com/showthread.php?256699
My example code above comes from the Homeworld:@ mod, botman’s looked at our private workshop build a few times, and I use it for two things.
- We have a survival mode, and different maps can have different numbers of spawn points for hostile ships to attack from.
- We have a strange work-around to make something like the Bridge of Sighs spinning inhibitor. It depends on some game rule commands, but since I wanted to experiment with different numbers of segments the gamerule has some flexibility and the level saves the segment count.
Burly
(Burly)
#20
@Mikali Cool concept. That is way different than what I was thinking you would use that for. The thing I just added gives you the info just for the level you are playing. It doesn’t get you info on all of the levels that are currently pre-loaded in the frontend. To get that information through lua, it looks like it would require a decent amount engine code. If I was you, I’d just hardcode the mission grid into a frontend UI element. It would be rather trivial to do since you know what maps you are trying to load and it would probably be more extensible over time.
@EatThePath The function I wrote to get the level name should be able to get you the ability to at least check which mission is loaded during your gametype update loop so you can run some custom code per level.
Mikali
#21
Was this implemented in a patch? What is the name of the function? Thanks.
1 Like
b8factor
(B8factor)
#23
This is probably old news now, but I did find and test this new function.
local lvlname = getCurrentLevelName()
print(lvlname)
returns in log:

Now if I could find a way to get the resource locations and player locations from level that would rock!
4 Likes
It also appears that _LuaConfigName also contains the entire path for the file name.
for finding player and resource locations, you could try loading the level script in the gamerule…
for example
asteroidPos = { }
function LoadLevelScript(path)
asteroidPos = { } --Make sure variables are empty
dofilepath(path) --Load the level script
DetermChunk() --Run level script functions
NonDetermChunk() --
-- asteroidPos will now contain asteroid types and positions
end
-- --- DUMMY FUNCTIONS --- --
rawset(globals(), "addAsteroid", function (...)
--When level script calls 'addAsteroid', it''s type and position are stored in asteroidPos
asteroidPos[getn(asteroidPos)+ 1]= { arg[1], arg[2] }
end)
--This is to quickly create dummy functions that the level script uses, but who''s information is not required
local levelScriptDummyFunctions = { "addSquadron", "addSquadronToSOBGroup", "setDefaultMusic" }
for key,var in levelScriptDummyFunctions do
rawset(globals(), var, function (...) return 0 end)
end
Notes:
To use the above, just call LoadLevelScript with the complete path to the level script (Make sure it starts with “Data:”)
I’m not at my computer, so I don’t know all the level script functions, but they should be able to be quickly added to the above.
3 Likes
b8factor
(B8factor)
#25
that is cool i shall try though at first glance it is far > than my current lua experience. But I really do want to be able to pull that level info… it is essential to get an AI to perform better.
1 Like
Mikali
#26
Do you know the names of all the levels that might get played? Are they maps that you created yourself?
You could create a table with level-specific data:
level_data =
{
3p_dantes_requiem =
{
asteroids =
{
{position, rotation, RUs},
{position, rotation, RUs},
{position, rotation, RUs},
{position, rotation, RUs},
{position, rotation, RUs},
}
players =
{
{position, rotation, ID},
{position, rotation, ID},
{position, rotation, ID},
{position, rotation, ID},
}
}
}
b8factor
(B8factor)
#27
Well, the MOD is new AI for HW. So i would like to be able to read map info in so I can play all my favorite maps, like @mikal s lol… with the new AI.
But if i don’t succeed in reading the info in, i will just doctor the original game maps so I can script better AI for those.