News:

SMF - Just Installed!

Main Menu

[Mod] Toolbox

Started by ImpassIve, September 11, 2012, 05:27:41 PM

Previous topic - Next topic

ImpassIve

Toolbox v4.2.1



Last update:
July 4, 2014


This is a beta version of the mod.
It doesn't add any new sprites, sound, monsters etc., also it doesn't change gameplay.

This mod was made to simplify process of merging different mods together and it is provided to gamemoders.
"Toolbox" have several functions (only 11 atm, divided into 3 groups) for other mods. Here they are:

Functions

Mods communication group
RegisterMod ( name, version )
RegisterMod ( name, version, folder )
IsModRegistered ( name ) --returns true or false
GetRegisteredMod ( name ) --returns result of require(name) or nil
GetModVersion ( name ) --returns version or nil
IsModEnabled ( name ) -- return true / false / (nil if the mod was not found)


RegisterMod ( name, version ) - declares the fact what your mod is installed on this server + provides version of your mod. It is expected, what name of folder name matches mod's name. It is recommended to call this function at the end of your "init.lua" file (after main initialization of your mod).
RegisterMod ( name, version, folder ) - same thing, but for mods with different "name" and folder name inside of knights_data/server/. Otherwise, recommended use: T.RegisterNamedMod("mod_name", mod_version, ...) - "..." will be automatically replaced with foldername of your mod.
IsModRegistered - checks whether the mod is installed on this server.
GetRegisteredMod - returns same value as require() function if the mod was registered, nil otherwise
GetModVersion - returns version of the mod if it was registered, nil otherwise
IsModEnabled - will return true if the mod is enabled/not supports enabling system; nil if the mod wasn't found; false if the mod is disabled.

Implement toolbox_enable (S) and toolbox_disable (S) functions in your mod to add it into "Enable/Disable mod" list.

Hooks
RegisterHook( hook, id, function ) -- returns true (success) or false (fail)
DeleteHook( hook, id )


Correct types for hook variable are: 
"WEAPON_DOWNSWING", "WEAPON_PARRY", "KNIGHT_DAMAGE", "CREATURE_SQUELCH", "SHOOT", "MISSILE_MISS"

Using this you can install hook at any time (even ingame) and remove it without problems.
Example:
local T = require("toolbox")

function ouch()
   print("Ouch!")
   T.DeleteHook("KNIGHT_DAMAGE", "mymod_ouch")
end

T.RegisterHook("KNIGHT_DAMAGE", "mymod_ouch", ouch)


This code will write "Ouch!" when the knight was hit in a first time.
Pretty easy, imho.

Action Listeners

Action Listeners is an unofficial analog of hooks system.
AL_AddListener ( action_id, function_id, function )
AL_DeleteListener ( action_id, function_id )
AL_SendAction ( id, argument )


AL_AddListener - declares what you want to listen "action_id" action using "function" with "function_id" identificator (a string to identify your listener).
AL_DeleteListener - removes previously installed listener using its identificator.
AL_SendAction - sends the argument to all listeners of this action. Returns last non-nil value given by listeners.

Default Actions (events):

"GAME_START" - called when the match starts (same effect as editing kts.MENU.start_game_func by yourself)
"GAME_PREPARE" - called before dungeon generation (kts.MENU.prepare_game_func)
"RESPAWN" - called when knight is preparing to spawn. Gives a player as parameter of the function. You can return a position to spawn this knight in.
"MOD_REGISTERED" - called every time some mod was registered. Gives a name of the mod as an argument.

Also, using this you can make your own "hooks" and events.
Example:

--FIRST MOD
local T = require("toolbox")

function spawned_1 (location)
   print("Oh no, spiders are coming!")
   T.AL_DeleteListener (  "spiders_spider_spawned", "f1" )
end

function spawned_2 (location)
   print("A spider spawned at "..location.x.." "..location.y)
end

T.AL_AddListener ( "spiders_spider_spawned", "f1", spawned_1 )
T.AL_AddListener ( "spiders_spider_spawned", "f2", spawned_2 )


--ANOTHER MOD
local T = require("toolbox")

--...some functions are here
function spawn_a_spider()
   T.AL_SendAction ( "spiders_spider_spawned", {x=15, y=20} )
   --...
end


This code will print "Oh no, spiders are coming!" at first appear of this event and print given coordinates (as example, you can use any type of parameter) every time.

A configuration file

You can edit "config.lua" file to change some behavior of the mod.

DEFAULT_MOD_STATE = "on" -- if you will set this to "off" value - all switchable mods will be disabled by default.

Recent changes (also take a look at changelog.txt)

Version 4.2
26.06.2014

Duel to the Death black screen problem fixed

Installation
1) Download "toolbox.zip" from attachments
2) Unzip it into "<path to your knights>\knights_data\server"
3) Put 'require ("toolbox")' line into "knights_data\server\main.lua"
Warning! Put it right after 'require ("classic")', as here:

require ("classic")
require ("toolbox")

require ("spiders_v2")
require ("multiwand")
require ("heroes")

Because it should be loaded before any other mods.
____________________________________________
Any questions, comments and suggestions are welcome.
Feel free to study and use any part of the source code.




K9

I can think of lots funny things to do with these functions.
Hopefully I have some time soon for these things after seeing the other mods in action.

Very cool, thank you!

Worst

Nice work,
I'm supporting this in my mods.  :)

ImpassIve

#3
Toolbox version 2 is out!

I have added some new features (they are listed in the changelog).

Main features are:

1) Added Action Listeners (look at the description).
2) Added RegisterNamedMod ( name, version, folder ) function:
Special to Worst:
You should replace T.RegisterMod("spiders", 3) with T.RegisterNamedMod("spiders", 3, "spiders_v3").
I hope, that will fix an error while using T.GetRegisteredMod("spiders") function (that was my bad, I forgot what mod's name can differs from installed folder's name).

Download link can be found in attachments of the first post.


Thanks, guys, for your comments.
This mod is not perfect, but I will try to develop it.
If you found any bug, please tell me about that =)




Worst

Quote from: ImpassIve_rus on September 13, 2012, 03:14:44 PM
Special to Worst:
You should replace T.RegisterMod("spiders", 3) with T.RegisterNamedMod("spiders", 3, "spiders_v3").
I hope, that will fix an error while using T.GetRegisteredMod("spiders") function (that was my bad, I forgot what mod's name can differs from installed folder's name).
Ah.. I did take a look at the toolbox code, but I also missed that there would be a problem like this.

Thanks for the update, I've now updated all my mods to use T.RegisterNamedMod.

Stephen

Note that, within init.lua, you can use "..." to refer to the current module's folder name.

So you can write T.RegisterNamedMod("spiders", 3, ...) instead of T.RegisterNamedMod("spiders", 3, "spiders_v3").

Worst

Quote from: Stephen on September 14, 2012, 02:45:14 PM
Note that, within init.lua, you can use "..." to refer to the current module's folder name.

So you can write T.RegisterNamedMod("spiders", 3, ...) instead of T.RegisterNamedMod("spiders", 3, "spiders_v3").
Ah neat, i'll use that from now on.

I wonder if that would work if it was built-in inside the T.RegisterMod function instead? (I guess easy enough for me to test and find out..)

Stephen

Quote from: Worst on September 17, 2012, 11:56:31 PM
I wonder if that would work if it was built-in inside the T.RegisterMod function instead? (I guess easy enough for me to test and find out..)

I don't think so, because it would be the name of the toolbox mod, not the name of your mod...

ImpassIve

#8
That was a really tiny update (that is why I called it "version 2b", but not "version 3").

There is only one noticeable feature.
Using Stephen's advice, I have added 2 standart actions to the already implemented Action Listeners system: "GAME_PREPARE" and "GAME_START".
Toolbox sends this action every time kts.MENU.prepare_game_func (kts.MENU.start_game_func) is called.

Some information about those functions can be found here (at the bottom part of the page). In short, those functions are called before dungeon preparation and beginning of the game respectively.

UPD:
The 2b version of the mod was a bit failed. I had implemented the "GAME_START" and "GAME_PREPARE" actions... but because of my mistake Game_Start action was called before the dungeon has been created despite of it's desctiption.
I have made a 2c version to fix this (can be downloaded from attachments of the first post)




ImpassIve

#9
Toolbox version 3 is out!

I have made several changes to code (they are listed in the changelog).

From now, Action Listener can return some value to the initiator of the action. If there are more than 1 Listener to this action - last non-nil value will be returned.

Added default "RESPAWN" action (to be used instead of kts.setRespawnFunction(function_name)).

Added default "MOD_REGISTERED" action. Called every time some mod was registered.
Because you can have some dependency from another mod, but for some reason (most usual - the user have put your mod to load before the required one) at the time of your initialization it is not registered yet.

RegisterNamedMod was removed (in fact it is still here for backward compatibility, but you shouldn't use it anymore).
Added RegisterMod ( name, version, folder ) instead.



Updated download link can be found in attachments of the first post.

P.S. A question for those who uses Toolbox in their mods.
Is everything clear with using it? Should I make some extended documentation for it, with much more examples?




K9

Thank you for this update.

I'm excited to learn lua Knights modding  and use your Toolbox as soon as I can, maybe during some holiday time soon. 

Nice that you've been thorough so far, I'll let you know if I get stuck on anything.

ImpassIve

#11
Toolbox version 4 is out!

GetRegisteredMod won't fail anymore if the requested mod had typed wrong information about it's folder. It will return nil instead.

Main feature:
Now certain mods can be "disabled" using Toolbox!

To use this feature in your mod - just implement
  toolbox_enable (S)
  toolbox_disable (S)
functions. (Toolbox will auto-detect their existance during registeration of your mod)

Example (from heroes mod):
function toolbox_enable (S)
end

function toolbox_disable (S)
S.IsNot("quest", "Heroes")
S.IsNot("mission", "heroes")
if (DEV) then
S.IsNot("mission", "heroespp")
end
end


Thanks to doublejack for the idea!

Added IsModEnabled ( name )

Added "config.lua" file
if you would set DEFAULT_MOD_STATE to "off" value - all switchable mods will be disabled by default.

Download link for Heroes mod was also updated.




doublejack

it's really good, that you added this function to toolbox. now players can switch on/off all installed mods in a single click. thanks for it

and maybe it will be a good idea to show the mod author and version somewhere under the STATE button.   so function RegisterMod ( name,version,folder ) needs an extra AUTHOR parameter.

RegisterMod ( name, version, folder, author )

ImpassIve

#13
Quote from: doublejack on November 09, 2012, 05:18:22 PM
it's really good, that you added this function to toolbox. now players can switch on/off all installed mods in a single click. thanks for it

Well, implementation of this feature is not perfect.
In fact, a modder has to implement 'disabling' of the mod by himself.

Also, in current knights menu system you can't remove already placed elements.
That means what it will still occupy space on the screen.

In my case, 'Heroes' mod just has added additional case to already existed element, so I can hid it after deleting all installed hooks (this was made automatically because of the inner structure of Heroes mod). But you can't hide the whole element (as in other existing mods - count of specific monsters to place. The only thing modder can do is to freeze selection of this element on zero amount)
That's not good.

Quote from: doublejack on November 09, 2012, 05:18:22 PM
and maybe it will be a good idea to show the mod author and version somewhere under the STATE button.   so function RegisterMod ( name,version,folder ) needs an extra AUTHOR parameter.

RegisterMod ( name, version, folder, author )
RegisterMod function registers only those parameters of the mod, what are used by other mods.

name is used to identify your mod.
version is used to check its version (some features could be not implemented in early versions, right?)
folder is used to get real link to the mod (because some modders have a tendency to change foldername with every release, as you can see)

But if your mod is adressing some other specific mod - it is sure what it (you, in fact) will know its author...

I can implement requesting such information in the same way as  toolbox_enable and  toolbox_disable (auto-detect of some variable or e.g. function 'RetrieveInformation'), but here lays another problem:

I have installed 7 mods on my notebook (Toolbox, Heroes, Multiwand, Telewand, Rat Riders, Spiders and Living Armors) and my current menu hardly fits on the screen...
If I would add one more menu element into Toolbox, I will have to scroll the window every time I want to press 'Ready' button, even in fullscreen.
That is an interesting idea to tell some additional information about the mod to the user, but I don't know, how to properly implement it.




ImpassIve

#14
Toolbox version 4.2 is out.

Duel to the Death black screen problem fixed

Note the new "AUTO_ELIMINATE" config field.
Do not disable it without implementing a real respawn function (or the 'black screen' problem will appear once again)