• 🏆 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!

What options exist for programmatically manipulating Object Editor data, anno domini 2023?

Status
Not open for further replies.
Level 2
Joined
Jul 2, 2012
Messages
5
Using World Editor 1.34

The dream here is to perform a batch update of multiple data fields of multiple units rather than manually modify them in the Object Editor. In my ideal world, I'd be able to do this:

1. Export Object Editor data into a plain text format such as JSON, CSV, etc.
2. Use some Linux CLI tools to change the values of several data fields of several different units in said text files
3. Create new custom units by simply duplicating text data of an existing unit and modifying some data fields
4. Convert/import these text files back into the World Editor

This is my particular use-case: I have several custom units with several data fields that are modified in a formulaic manner - i.e. several fields are simply scaled based on some percentage. I'd like to avoid the tedium of manually applying these formulaic modifications to hundreds of different custom units.

I see that "Lua Object Generation" was a relevant option at one point, however this uses deprecated tools and versions of the World Editor. What modern options exist to accomplish this for World Editor v1.34?
 
Last edited:
Level 18
Joined
Oct 17, 2012
Messages
821
You got many options for manipulating object data via code: Wurstscript, CSharp, Ceres, w3ts, etc.

Wurst:
@compiletime function generateDummyUnit()
       new UnitDefinition(DUMMY_UNIT_ID, UnitIds.wisp)
       ..setName("Effect Dummy Unit")
       ..setUpgradesUsed("")
       ..setStructuresBuilt("")
       ..setManaRegeneration(0.1)
       ..setManaInitialAmount(1000)
       ..setManaMaximum(1000)
       ..setCollisionSize(0.0)
       ..setRace(Race.Commoner)
       ..setFoodCost(0)
       ..setArmorType(ArmorType.Divine)
       ..setIconGameInterface(Icons.bTNTemp)
       ..setSpeedBase(522)
       ..setModelFile("dummy.mdl")
Lua:
public void TestFallbackWithCampaignAndStandard()
{
     const int PaladinDefaultHp = 100;
     const int PaladinDefaultMp = 0;
     const int PaladinDefaultStr = 22;
     const int PaladinDefaultAgi = 13;
     const int PaladinDefaultInt = 17;

     var campaignDb = new ObjectDatabase();
     var mapDb = new ObjectDatabase(campaignDb);

     var unitCampaign1 = new Unit(UnitType.Paladin, campaignDb);
     var unitCampaign2 = new Unit(UnitType.Paladin, "H002", campaignDb);

     var unitMap1 = new Unit(UnitType.Paladin, mapDb);
     var unitMap2 = new Unit(UnitType.Paladin, "H002", mapDb);
     var unitMap3 = new Unit(UnitType.Paladin, "H003", mapDb);

     unitCampaign1.StatsHitPointsMaximumBase = 1000;
     unitCampaign1.StatsManaMaximum = 2000;

     unitCampaign2.StatsStartingStrength = 200;
     unitCampaign2.StatsStartingAgility = 250;

     unitMap1.StatsManaMaximum = 3000;

     unitMap2.StatsStartingAgility = 200;

     unitMap3.StatsStartingIntelligence = 300;
}
Lua:
-- example creating a new object
compiletime(function()
    local customFootman = currentMap.objects.unit['hfoo']:clone()
    customFootman.Name = "A Custom Footman"
    currentMap.objects.unit['x000'] = customFootman
end)

-- example exposing data from the compile stage to the script
local metadata = compiletime(function()
    local metadata = {}
    for id, object in pairs(currentMap.objects.unit.all) do
        metadata[id] = object.umdl
    end

    return metadata
end)
 
Last edited:
Level 18
Joined
Jan 1, 2018
Messages
728
If you know a bit of C# you can use my library: War3Api.Object 1.31.1-rc.11
I only made it for 1.31, but there's a generator so you can make it for 1.34 as well: War3Api/src/War3Api.Generator.Object at master · Drake53/War3Api
Wouldn't recommend this if you don't know C# though since I haven't documented it at all.

You could also use War3Net.Build.Core, which is used by War3Api.Object: War3Net.Build.Core 5.6.1
I recently added JSON support to this library, so you could use it for step 1 and 4: War3Net/src/War3Net.Build.Core/Serialization/Json at master · Drake53/War3Net
Note that the main use case I had in mind for JSON is to allow diffing binary files by giving them a text representation. Since the JSON structure is based on its binary format it may not be easy to work with.
 
Status
Not open for further replies.
Top