• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Integrating Tools Into JNGP

Integrating Tools Into JNGP

Introduction:

This quick guide will show you how to integrate a tool of your choice into JNGP, so that it may be executed from the toolbar. This tutorial covers:
  • Adding a menu.
  • Adding a menu entry.
  • Executing the tool.

Many tools, such as GMSI, use this process for the convenience of the map maker.

Note: The latest compilation of JNGP has a new feature, "Custom Menu Settings", that will automate much of this process. The below information is still useful, but you may want to consider checking that feature out. Here is the main thread:
JassNewGen Pack

Requirements:
  • JassNewGen Pack
  • NotePad, or any text editing document that can save as .lua.
  • A tool of your choice. I will be using BLP Lab as my example.

*Note: Some of the screenshots will be from my Mac.

Table of Contents:

Initial Preparations:

First, you must install the tool. Go to your JNGP folder.
JNGP.png
Place whatever tool you are using into your JNGP folder.
BLP Lab.png
Go to your JNGP folder. Open wehack.lua with a text editor. I recommend that you close JNGP Editor while you are modifying wehack.lua.
wehacklua.png

Adding a Menu:

wehack.lua is executed on startup, adding the toolbars to WE and executing the appropriate applications/dlls. This is where we will add the toolbar menus. A toolbar menu refers to an individual "button" in the toolbar, such as "File", "Edit", "View", etc.

The syntax to add a menu is relatively simple:
Lua:
varName = wehack.addmenu("Menu Name")
You will assign the menu to the variable represented by varName. We assign it to a variable because we will need to refer to it later when we add menu entries. The "Menu Name" is the name that will show up in the toolbar.

In my case, I will add a toolbar menu titled "External Programs". You can write essentially anywhere in the file, but the order in which you write it will determine where it is on the toolbar. If you place the code all the way at the top, then it will be placed before "Extensions", "UMSWE", "Grimoire", etc.

For that reason, I will place it at the end right before "isstartup = false":
wehackmenu.png

I named the variable "extPrograms", and the title shown will be "External Programs". This is how it will look in the editor:
ExtPrograms.jpeg

Adding a Menu Entry:

If you open JNGP with your current wehack.lua, you'll notice that nothing happens when you click it (aside from highlighting the text). This is because it doesn't have any menu entries! This is the general format of adding a menu entry:
Lua:
varName = MenuEntry:New( menu, "Menu Entry Title", callbackFunction )

The menu entry will be assigned to the variable represented by "varName". The "menu" is the menu you want to place it under. Mine will be extPrograms, since that is what I named my variable. The "Menu Entry Title" will be whatever you want to name your menu entry. I will name mine, "BLP Lab".

The final field is the callbackFunction. The function specified will be called when the menu entry is clicked. As such, we'll make a function to serve as the callback, right above the menu entry and such. This is how it will look like in the end:
Lua:
function blpLabStartup()

end

extPrograms = wehack.addmenu("External Programs")
blpLab = MenuEntry:New( extPrograms, "BLP Lab", blpLabStartup)

Again, this is written in Lua. If you are not familiar with the syntax, please refer to:
http://www.hiveworkshop.com/forums/jass-ai-scripts-tutorials-280/lua-object-generation-191740/#V

After that code, this is what it will look like in the editor:
BLPLab.png

As an extra bonus, you can add what is known as a menu separator. This is just a line that separates one set of menu entries from the rest. Here is the syntax:
Lua:
wehack.addmenuseparator(menu)
So if I add the following code after the menu entry code:
Lua:
wehack.addmenuseparator(extPrograms)
This is what it will look like:
BLPLabMenu.png

Starting The Program:

Now we just need to make the program run. The line is:
Lua:
wehack.execprocess("path.exe")
There are two other functions for this, wehack.runprocess and wehack.runprocess2. The first waits for exit code and reports error, the second just waits for exit code and doesn't report errors. execprocess doesn't wait for exit code. We only need to use wehack.execprocess.

Now, all we need to do is place the line above into the function "callback" that we specified. The path is simply the path to the program. The paths are relative to the jassnewgenpack folder unless otherwise specified. This is why I placed the tool into the JNGP folder itself. In my case, the path will be:
Lua:
wehack.execprocess("BLP Laboratory/blplab.exe")
Note that you include spaces, and that you use a single forward slash "/" to navigate inside a directory (folder).

If your program has no folder, then the path will be simply the name of the executable file. This is what our code will look like in the end:
Lua:
function blpLabStartup()
	wehack.execprocess("BLP Laboratory/blplab.exe")
end

extPrograms = wehack.addmenu("External Programs")
blpLab = MenuEntry:New( extPrograms, "BLP Lab", blpLabStartup)

Now to test it. It should open the program:
Works.png

Lua

You can also run Lua files through a menu entry. Instead of execprocess, just use:
Lua:
dofile("path.lua")

This will allow you to execute Lua through JNGP without copying and pasting the code. This will be very convenient if you have several maps that use the same Lua code.

Why?

  • It is convenient.
  • It is cool.
  • More importantly, this tutorial will help those programs that are designed to be integrated into WE. If you have a tool that you think would be sensible to include in the JNGP package (the new ones by moyack), then just PM me.

F.A.Q.

  • Q:
    Why doesn't it work?

    Lua is case sensitive. Make sure you have all your capitalizations in order. Also make sure you don't have any typos in the syntax. The code may run into an error, but it won't throw an error.
  • Q:
    Why doesn't it apply right away?

    wehack.lua is ran on JNGP WE's startup. In order for it to apply, you have to close and reopen WE. I suppose you could add a menu entry to run a lua file with such changes, but I haven't tested it.
  • Q:
    How do I make entries that can be checkmarked (toggled on or off)?

    The function format is:
    Lua:
    varName = TogMenuEntry:New( menu, "Title", callback, default )
    -- default should be either true or false
    There are various functions to deal with them. For more information on the functions available, see the grimoire source:
    https://w3grimoire.svn.sourceforge.net/svnroot/w3grimoire/
    (old)


Samples

I'll continually post sample addons that may prove useful for modding.
  • View Output War3map.j - This will view the output war3map.j of the last saved map. When a vJASS script is saved, jasshelper will convert the code to vanilla JASS and place the contents under logs\outputwar3map.j. This option will allow you to start it up from the editor. Note that this only applies to the last map you saved (not necessarily the one you opened), and you may be prompted to associate the .j file with a certain program (choose notepad or some other text editor):
    Lua:
    extPrograms = wehack.addmenu("External Programs")
    -- only add this if you do not have it already (it is the same menu from the tutorial)
    
    function viewOutputCode()
        -- updated for 1.5e
        if jh_isvexorian.checked then
            os.execute("logs\\outputwar3map.j")
        elseif jh_iscohadar.checked then
            os.execute("logs\\output_war3map.j")
        end
    
        -- os.execute("logs\\outputwar3map.j")
        -- ^ use this  function for pre-1.5e and comment out the rest
    end
    
    outputj = MenuEntry:New( extPrograms, "View war3map.j", viewOutputCode )
 
Last edited:
Sweet tutorial. I haven't tried it yet but this will surely be useful as I hate to put a lot of apps on my desktop.

Thanks for sharing this info.

EDIT:

This does work on any tool right?

Yep, pretty much.

It is almost like adding a shortcut inside JNGP's menu. As long as you spell the name/fields correctly it should work.

Thanks for the comments. :)
 
Level 14
Joined
Dec 29, 2009
Messages
931
You sir, make an excellent tutorial!
I'm going to try adding Button Manager. :p

Very informative, but lacking in...

AWESOME BBCODES

EDIT: tried it out and it works. I'm gonna add a bunch of tools that I use to this thing.
Are there any limitations to the tools? Ex. Quantity?
 
Last edited:
Thanks for the feedback everyone. :) I'll approve it since no one has reported any issues with it yet and the overall comments are positive.

EDIT: tried it out and it works. I'm gonna add a bunch of tools that I use to this thing.
Are there any limitations to the tools? Ex. Quantity?

There aren't any practical limits. There may be a limit length-wise, but it isn't anything you'll hit very easily.
 
Question.
Do MS-DOS work in this integration?

No. MS DOS programs require special commands to run (they can't be executed natively afaik). You might be able to make a tool to execute it but it can't be ran through wehack.execprocess().

Remember that this is essentially the same as right-clicking the program and selecting "Open"/"Run", but it adds a shortcut in the WE menu.
 
You can.

JASS:
os.execute("path")

For example:
JASS:
os.execute("war3.lua")

Paths are still relative to the jassnewgenpack folder. There may be another way, but that is the function I would use. Note that it leaves the command prompt in the background, but it will disappear when you exit the program so it is a minor issue. There is probably a method to get rid of it, I am just too lazy to look it up.
 
May i ask, Is the tool name execution case-sensitive? you know,will it run a simple name like "SomeTool.exe" even without the folder name?

It is not case sensitive. So if you have:
Lua:
dofile("Addons\\OutputWar3Map.lua")
Versus:
Lua:
dofile("Addons\\outputwar3map.lua")
Both will work as long as the file exists (same for wehack.execprocess).
*correction: on Windows

However, you cannot choose it without the folder name. dofile will look for the file in the directory, but it won't search for it.

I do have a sort of "Load Addon" thing that I've made (it works 100% but I haven't released it yet since I need to sort out a few details). Basically, instead of writing in the wehack.lua you can load a custom lua file and it will automatically load it every time JNGP opens. There is also a "Remove Addon" feature that will remove it from being loaded. That way, you won't make mistakes when you are adding a file because it will automate the process. This is all for lua files though. I think I may add one for exe files later on.

But anyway, to solve your problem, you can just prompt them with a browser to search for the file:
Lua:
function loadExeFunction()
    source = wehack.openfiledialog("Exe files (*.exe)|*.exe", "Select an exe to load ... ", true)
    -- prompt them with a dialog to choose a file
    -- limit it to exe files 

    name = wehack.inputbox("Specify the exe name ... ", "Load Exe", "")
    -- prompt them to input the exe name for the menu

    if source ~= "" and name ~= "" then
        -- check to make sure the strings are not nil
        local callback = function() wehack.execprocess(source) end
        -- anonymous function for the callback
        MenuEntry:New(utils, name, callback)
        -- add the menu under "Extensions"
    else
        wehack.messagebox("Error: nil string", "Load Exe", true)
    end
end

loadExe = MenuEntry:New(utils, "Load exe", loadExeFunction)
-- add the menu to load exes

I didn't test it, it is just pseudo code so there might be errors. That is something along the lines of what you would do. However, the problem is that you must load it every time. That's why I made the "load addon" thing to write all the info to a lua file. I still have a few things to sort out though... such as if someone wants to reference a different lua file (requirements) or something like that.
 
Last edited:
Updated with lua tags because they are bootiful.

Windows paths are not case sensitive, every other OS is case sensitive.

Prefer "/" to "\\", because the latter is Windows being stupid, while the former is used in every OS (including Windows).

Updated, thanks. Not that JNGP works on any OS other than Windows, but it is good to know that forward slashes work.

Hmmm, with JNGP 2.0.4, this tutorial should have an update, at least showing the tool to do it without coding.

I added some info about it. I might update it a little later with a little guide on how to use the feature. :)
 
Top