- Joined
- Mar 27, 2012
- Messages
- 3,232
Perhaps by this point everyone knows about ObjectMerger and how to use lua to make it easier. Well, it doesn't fully solve the problem in some cases. Having a scripted way to generate objects is better than typing monstrous lines of objectmerger commands, but it still sucks to have to rewrite it for every map. It would also suck to have to keep a folder per map like Nestharus does, because that's quite a lot of stuff to keep track of. It's fine to have one folder per map, but it shouldn't be mandatory.
This is why I created ObjectDefinition. Essentially what ObjectDefinition does is that it creates objects based on specifically written files. You can make them in notepad if you want. That alone wouldn't be all that impressive, but what really makes ObjectDefinition shine is the shortcuts you can take.
Without further ado, the features.
In your map you put a few lines of lua script that doesn't have to change after this. Example:
Note that this example has a lot of map-specific stuff. A more clean example would be:
The system assumes that you're passing it a folder in the JNGP folder(this whole thing requires JNGP, if you haven't realized by now). It will take every file of a specific kind from this folder and implements the objects from those files. You can also give it specific files instead of folders with ProcessFile.
The files
ObjectDefinition ignores every file that doesn't have the right extension. By default this extension is .obj, but you can change it in the configuration if needed.
Within every file with that extension it expects a basic format:
field=value
There are 2 fields that must exist for any objects to be created at all: baseid and raw4. By excluding those you can make objects that are not implemented, which can be used as templates.
baseid is the rawcode of the ability that you want to base the new object on.
raw4 is the rawcode of the new ability that you're creating. If you want multiple abilities, you can just add them with a comma. For example:
raw4=A000,A001,AGHK
For fields with levels you just add the level after the field. Example: Acdn1=5
If you insert 0 as the level it will apply for every level, based on how many levels you specified in the object. The amount of levels must be defined in the object files.
You can add stuff to the previous line by starting a line with a plus. E.g, +field=value
You can add stuff to a different object by adding the objectid and a colon to the beginning of the line. E.g, object:field=value. If the object doesn't exist, it will be created, so you can create dummy objects/templates like this.
It's also possible to copy all field-value pairs from another object by using inherit. It's a special field that never makes it to the game.
inherit=rawcode
inherit=rawcode,rawcode,rawcode...
There's also the possibility to set a field dynamically. That is, without having to write the specific value. You can do this by adding -f to the end of the line. The way it works is that any value ending with -f is treated as lua code to be executed. -f is shorthand for "function".
Example: aubx=return 1+3-f
This alone wouldn't be very useful, but it lets you use various variables, such as the current level being defined(when you've set the level of the field to 0). It also lets you use various functions:
getField(object,field) - returns the value of the specified field on specified object. If you don't specify an object and instead write getField(field), then it assumes that the object is the same as the field in which this function is called.
Finishing notes
I originally started writing ObjectDefinition as a map-specific script to externalize object creation. I didn't really think of it as a general-purpose tool, but over time I made it more and more into one, as that was what I needed. However, despite the numerous rewrites it's still not built from the ground up to be a general purpose tool. Code is organized badly, functions that I consider core features are spread around, etc. As such, I will not release it publicly right now, but instead rewrite it first in a more structured manner. Once I finish rewriting the whole thing I'll make numerous examples on how to use the various features.
Current intended structure would be that I have these files:
ObjectDefinition - The main script that you should run everything else through.
ODFunctions - Gives access to some extra convenience functions. Loaded by default, so you don't have to do anything special. I'm keeping this separate because although useful, those functions can be added and removed without breaking the system. They are not the core of the system, external object definition is.
ODConfig - Text file for configuring various things, such as the markers used for specific features.
I will start rewriting ObjectDefinition on saturday, 3/09/2016. It might take a couple days. Meanwhile I would appreciate feedback on anything mentioned here, especially features that would make things easier.
This is why I created ObjectDefinition. Essentially what ObjectDefinition does is that it creates objects based on specifically written files. You can make them in notepad if you want. That alone wouldn't be all that impressive, but what really makes ObjectDefinition shine is the shortcuts you can take.
Without further ado, the features.
In your map you put a few lines of lua script that doesn't have to change after this. Example:
JASS:
//! externalblock extension=Lua ObjectMerger $FILENAME$
//! i require "lua\\ObjectDefinition"
//! i require "lua\\Heroic Functions"
//! i local t = ProcessFolder("Heroic")
//! i t = addEngineers(t)
//! i ImplementTable(t)
//! endexternalblock
JASS:
//! externalblock extension=Lua ObjectMerger $FILENAME$
//! i require "lua\\ObjectDefinition"
//! i local t = ProcessFolder("Heroic")
//! i ImplementTable(t)
//! endexternalblock
The files
ObjectDefinition ignores every file that doesn't have the right extension. By default this extension is .obj, but you can change it in the configuration if needed.
Within every file with that extension it expects a basic format:
field=value
There are 2 fields that must exist for any objects to be created at all: baseid and raw4. By excluding those you can make objects that are not implemented, which can be used as templates.
baseid is the rawcode of the ability that you want to base the new object on.
raw4 is the rawcode of the new ability that you're creating. If you want multiple abilities, you can just add them with a comma. For example:
raw4=A000,A001,AGHK
For fields with levels you just add the level after the field. Example: Acdn1=5
If you insert 0 as the level it will apply for every level, based on how many levels you specified in the object. The amount of levels must be defined in the object files.
You can add stuff to the previous line by starting a line with a plus. E.g, +field=value
You can add stuff to a different object by adding the objectid and a colon to the beginning of the line. E.g, object:field=value. If the object doesn't exist, it will be created, so you can create dummy objects/templates like this.
It's also possible to copy all field-value pairs from another object by using inherit. It's a special field that never makes it to the game.
inherit=rawcode
inherit=rawcode,rawcode,rawcode...
There's also the possibility to set a field dynamically. That is, without having to write the specific value. You can do this by adding -f to the end of the line. The way it works is that any value ending with -f is treated as lua code to be executed. -f is shorthand for "function".
Example: aubx=return 1+3-f
This alone wouldn't be very useful, but it lets you use various variables, such as the current level being defined(when you've set the level of the field to 0). It also lets you use various functions:
getField(object,field) - returns the value of the specified field on specified object. If you don't specify an object and instead write getField(field), then it assumes that the object is the same as the field in which this function is called.
Finishing notes
I originally started writing ObjectDefinition as a map-specific script to externalize object creation. I didn't really think of it as a general-purpose tool, but over time I made it more and more into one, as that was what I needed. However, despite the numerous rewrites it's still not built from the ground up to be a general purpose tool. Code is organized badly, functions that I consider core features are spread around, etc. As such, I will not release it publicly right now, but instead rewrite it first in a more structured manner. Once I finish rewriting the whole thing I'll make numerous examples on how to use the various features.
Current intended structure would be that I have these files:
ObjectDefinition - The main script that you should run everything else through.
ODFunctions - Gives access to some extra convenience functions. Loaded by default, so you don't have to do anything special. I'm keeping this separate because although useful, those functions can be added and removed without breaking the system. They are not the core of the system, external object definition is.
ODConfig - Text file for configuring various things, such as the markers used for specific features.
I will start rewriting ObjectDefinition on saturday, 3/09/2016. It might take a couple days. Meanwhile I would appreciate feedback on anything mentioned here, especially features that would make things easier.
Last edited: