[Mod] Highlight Structures on Map
I recently had an idea for a commander quality-of-life feature, which I suggested in another thread:
Instead of waiting for someone to add this, I decided to learn NS2 modding and create this as a mod And here's the first version: http://steamcommunity.com/sharedfiles/filedetails/?id=308092512
So far, it's working as intended (with the exception below). Please take a look and let me know what you think! If enough people consider this useful, maybe this could even be included into the standard UI?
There is one technical issue with it - mod compatibility. I'm using the .event file approach, as I understand that this is the current/preferred way to bootstrap a mod. However, when I combine it with NS2+, for example, the mod simply stops working. There are no errors on the console, but no Print output either - the mod simply isn't loaded. The only standard class that I overwrite (as there is no matching hook) is GUIMinimap, and as far as I can see, NS2+ does not overwrite that file. Does anyone have an idea why this is happening, or how to debug this? (May I even invoke @Mendasp ? )
This is the directory layout of the mod, as downloaded and installed from the workshop:
HighlightStructuresOnMap.entry:
HighlightStructuresOnMap_Client.lua
And this is the inclusion from the modified GUIMinimap.lua:
Also, is there a way to replace a standard file (like GUIMinimap.lua) with a subclass or wrapper, and invoke methods of the replaced class from it? (For example, overriding a method, and then calling super.theMethod() somewhere inside it?) This would be more robust than just overwriting the file.
An even better feature might be to highlight all structures of a certain type on the map. Of course, not all the time, but only one structure type at a time. To avoid adding new buttons for this, it could automatically activate whenever a structure is selected for building: For example, you select "Crag" from the commander menu, but instead of left-clicking to place it, you hold the map key, and all existing Crags on the map are highlighted. This should fit well with the UI flow as you could jump immediately to the location that does *not* have a Crag by clicking the map.
Instead of waiting for someone to add this, I decided to learn NS2 modding and create this as a mod And here's the first version: http://steamcommunity.com/sharedfiles/filedetails/?id=308092512
So far, it's working as intended (with the exception below). Please take a look and let me know what you think! If enough people consider this useful, maybe this could even be included into the standard UI?
There is one technical issue with it - mod compatibility. I'm using the .event file approach, as I understand that this is the current/preferred way to bootstrap a mod. However, when I combine it with NS2+, for example, the mod simply stops working. There are no errors on the console, but no Print output either - the mod simply isn't loaded. The only standard class that I overwrite (as there is no matching hook) is GUIMinimap, and as far as I can see, NS2+ does not overwrite that file. Does anyone have an idea why this is happening, or how to debug this? (May I even invoke @Mendasp ? )
This is the directory layout of the mod, as downloaded and installed from the workshop:
.modinfo lua lua\entry lua\entry\HighlightStructuresOnMap.entry lua\GUIMinimap.lua lua\HighlightStructures.lua lua\HighlightStructuresOnMap_Client.lua
HighlightStructuresOnMap.entry:
modEntry = [[ Client: lua/HighlightStructuresOnMap_Client.lua, Priority: 5 ]]
HighlightStructuresOnMap_Client.lua
Script.Load("lua/Client.lua") Print("HighlightStructuresOnMap v0.5 loaded")
And this is the inclusion from the modified GUIMinimap.lua:
... Script.Load("lua/GUIMinimapConnection.lua") // mod start Script.Load("lua/HighlightStructures.lua") // mod end ...There are two other places where the code from HighlightStructures.lua is actually invoked, but they should not be relevant to the question why the mod isn't being loaded at all (I think). Any pointers how to debug this?
Also, is there a way to replace a standard file (like GUIMinimap.lua) with a subclass or wrapper, and invoke methods of the replaced class from it? (For example, overriding a method, and then calling super.theMethod() somewhere inside it?) This would be more robust than just overwriting the file.
Comments
On the other hand, you don't really need the entry system if you're going to end up replacing a file to do the mod, might as well load your file from the overwritten one and use your code directly.
The funny thing is I'm overriding the function to do something similar (coloring player blips).
I'll have a quick look at resolving this.
Edit: I've published an update and your mod should work now.
Ah, ok... that's a good pointer. I assumed that a script could only be overridden by a file in the exact same location. Now I've looked at how NS2+ handles GUIMinimap, and I think I understand the approach. Unless I'm missing something, I should be able to rewrite my mod so it does not need to modify GUIMinimap.lua at all. Basically like this (untested):
The only thing I don't know yet is if I'll need any local variables of GUIMinimap (which I may not have access to). Or can you access them by injecting a new function via Class_AddMethod(...)?
I did it this way because I was hoping I could avoid overwriting files at all. And as long as I had to overwrite, I wanted to keep the changes as small as possible, also to make upgrading to a new version of NS2 easier. But the ReplaceMethod approach is far better anyway, if I can get it working.
Maybe this would be a good place for a predefined hook, then? (PostUpdateStaticBlips or something?) I have no clue how much this affects performance, though.
Ah , that's great
I'll still try to adapt my mod so it's safe against other mods that do the same thing - and to do it the right way. Thanks for the help!
The thing is that is a local function, so you can't override it like that (and no, you can't get locals like that). The options you have in that case is either fully replacing it (what I was doing before) or just sort of run it again with your changes...
What I was doing is using the Elixer functions to replace the local function with my own version which was basically copy & pasted the original with a few modifications. The change that I've done now so your mod runs is to stop replacing the local function and only run the bits of code I need after the original runs (in GUIMinimap:Update) and changing the color of certain blips if it's needed.
Take a look at the Elixer library to deal with local variables and functions. https://github.com/sclark39/NS2Elixer
There's also plenty of usage of it in NS2Plus.
edit: Here you go: http://forums.unknownworlds.com/discussion/134944/elixer-cross-mod-compatible-utility-library-for-modders