• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Autogenerate IDs for object IDs for smaller savecodes

Status
Not open for further replies.
Level 26
Joined
Feb 2, 2006
Messages
1,697
Hi,
for my save/load system I want to be able to store certain unit, building, item and research types but not ALL of them and I do not want to use the 4 digit raw codes which will become quite big numbers.
Currently, I am registering all types manually with something like this:
  • Actions
    • -------- Humans --------
    • Set VariableSet TmpUnitType = Footman
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Knight
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Rifleman
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Mortar Team
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Flying Machine
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Gryphon Rider
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Priest
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Sorceress
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Siege Engine
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Spellbreaker
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Dragonhawk Rider
    • Custom script: call AddSaveObjectUnitType()
    • -------- Orcs --------
    • Set VariableSet TmpUnitType = Grunt
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Raider
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Tauren
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Headhunter
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Demolisher
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Kodo Beast
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Wind Rider
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Batrider
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Witch Doctor
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Shaman
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Spirit Walker
    • Custom script: call AddSaveObjectUnitType()
    • -------- Night Elf --------
    • Set VariableSet TmpUnitType = Archer
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Huntress
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Dryad
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Glaive Thrower
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Hippogryph
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Hippogryph Rider
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Chimaera
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Druid of the Talon (Night Elf Form)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Druid of the Claw (Night Elf Form)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Mountain Giant
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Faerie Dragon
    • Custom script: call AddSaveObjectUnitType()
    • -------- Undead --------
    • Set VariableSet TmpUnitType = Shade
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Ghoul
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Abomination
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Meat Wagon
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Crypt Fiend
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Gargoyle
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Banshee
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Necromancer
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Obsidian Statue
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Frost Wyrm
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Dalaran Mutant
    • Custom script: call AddSaveObjectUnitType()
    • -------- Naga --------
    • Set VariableSet TmpUnitType = Couatl
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Mur'gul Reaver
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Naga Siren
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Snap Dragon
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Naga Myrmidon
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Naga Royal Guard
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Dragon Turtle
    • Custom script: call AddSaveObjectUnitType()
    • -------- Demon --------
    • Set VariableSet TmpUnitType = Overlord (Demons)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Fel Stalker (Demons)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Infernal Machine (Demons)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Greater Voidwalker (Demons)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Infernal (Demons)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Doom Guard (Demons)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Succubus (Demons)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Eredar Sorcerer (Demons)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Nether Drake (Demons)
    • Custom script: call AddSaveObjectUnitType()
    • -------- Draenei --------
    • Set VariableSet TmpUnitType = Draenei Harbinger (Draenei)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Draenei Seer (Draenei)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Tamed Nether Drake (Draenei)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Salamander (Draenei)
    • Custom script: call AddSaveObjectUnitType()
    • -------- Furbolg --------
    • Set VariableSet TmpUnitType = Furbolg (Furbolg)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Furbolg Shaman (Furbolg)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Furbolg Tracker (Furbolg)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Furbolg Champion (Furbolg)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Furbolg Elder Shaman (Furbolg)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Furbolg Ursa Warrior (Furbolg)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Timber Wolf (Furbolg)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Giant Wolf (Furbolg)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Dire Wolf (Furbolg)
    • Custom script: call AddSaveObjectUnitType()
    • -------- Goblin --------
    • Set VariableSet TmpUnitType = Goblin Flamethrower
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Goblin Sapper (Goblins)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Ogre Goblin Squad (Walking)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Ogre Goblin Squad (Ready)
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Assault Tank (Goblin)
    • Custom script: call AddSaveObjectUnitType()
    • -------- TODO Add them all here --------
    • -------- CREEPS --------
    • -------- Dragons --------
    • Set VariableSet TmpUnitType = Green Dragon Whelp
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Green Drake
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Green Dragon
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Bronze Dragon Whelp
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Bronze Drake
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Bronze Dragon
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Nether Dragon Hatchling
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Nether Drake
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Nether Dragon
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Black Dragon Whelp
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Black Drake
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Black Dragon
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Red Dragon Whelp
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Red Drake
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Red Dragon
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Blue Dragon Whelp
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Blue Drake
    • Custom script: call AddSaveObjectUnitType()
    • Set VariableSet TmpUnitType = Blue Dragon
    • Custom script: call AddSaveObjectUnitType()
for which I use the following code:

JASS:
globals
    constant integer SAVE_OBJECT_CLASSIFICATION_VALUE = 0
    constant integer SAVE_OBJECT_CLASSIFICATION_UNIT = 1
    constant integer SAVE_OBJECT_CLASSIFICATION_ITEM = 2
    constant integer SAVE_OBJECT_CLASSIFICATION_RESEARCH = 3

    string array SaveObjectName
    integer array SaveObjectId
    integer array SaveCodeObjectClassification
    integer SaveObjectTypeCounter = 0
endglobals

function AddSaveObjectType takes string name, integer id, integer classification returns integer
    local integer index = SaveObjectTypeCounter
    set SaveObjectName[index] = name
    set SaveObjectId[index] = id
    set SaveCodeObjectClassification[index] = classification
    set SaveObjectTypeCounter = SaveObjectTypeCounter + 1
    return index
endfunction

function AddSaveObjectUnitType takes nothing returns integer
    return AddSaveObjectType(GetObjectName(udg_TmpUnitType), udg_TmpUnitType, SAVE_OBJECT_CLASSIFICATION_UNIT)
endfunction

As you can see I simply increase the counter and give each type a new unique ID. I could use a separate array for each classification like unit, item, research and even building etc. to keep the numbers lower since in my savecodes I know what to expect.

It works but it is a lot of work to add all unit types, item types etc. manually. Is there some way to iterate through all raw code IDs and check certain properties of the object type (maybe by creating a dummy) and then decide whether to add it or not?
Besides, when adding new items or units I will either have to append them or the IDs will change with the next map release and you will load different stuff.

How do save/load systems usually solve this issue?
 

Uncle

Warcraft Moderator
Level 65
Joined
Aug 10, 2018
Messages
6,679
So TriggerHappy's Codeless Save/Load System for example can only save Integers. You use these Integers to represent different types of data by creating Arrays.

Basically the same idea you have:
  • // initialize these
  • Set Variable UnitType[0] = Footman
  • Set Variable UnitType[1] = Rifleman
  • Set Variable UnitType[2] = Knight

Now let's say the Player can only choose one of these 3 Unit-types and you want to save/load this between games.

For saving you would first Loop over the UnitType array, comparing the player's chosen Unit-type to UnitType[X].

Once you found their chosen UnitType, you save the Integer of the Loop (X), which in this case would be 0, 1, or 2.

For loading, you simply plug this loaded value into the [index] of UnitType:
  • Unit - Create 1 UnitType[LoadedInteger] for Player...
  • Set Variable ChosenUnitType[Player number] = Last created unit

Not sure if that answered your question or not. Maybe this will help, here's some edited C# code I was using in a sandbox map I made. It has Arrays containing all of the Ability/Unit-Type rawcodes in the game which could come in handy. I'm using the Unit-Type codes for my Unit spawning system where the player can bring up a custom UI menu which contains every single Unit-Type in the game and can spawn them with the click of a button.

The Ability codes are used in the Save System to increase how much data I can store in a single save file:
WCSharp.SaveLoad v2 · Orden4/WCSharp Wiki

I think spawning in the Units/Items would be a good idea. You could have a loading process at the start of the game which loops over these Arrays and spawns all of the different objects. Then you can get whatever information you need from them -> GetUnitName(), GetUnitLevel(), GetItemLevel(), etc...

Note: I commented out some of the Ability rawcodes that didn't work properly with the Save System for some reason, probably Tooltip related.
 

Attachments

  • unit and ability rawcodes.txt
    34.3 KB · Views: 17
Last edited:
Level 26
Joined
Feb 2, 2006
Messages
1,697
This sounds like you still have to initialize the UnitType array manually with the types your save/load system has to support. Since every map with custom object data has different IDs there seems no way around that except for the standard raw codes of Warcraft.

I am not sure if I want to use a C# tool but I guess an external tool would be the only way to go through all rawcodes of the map automatically.
 

Uncle

Warcraft Moderator
Level 65
Joined
Aug 10, 2018
Messages
6,679
I wrote it in C# but it's no different than how you'd do it in Jass/Lua. There's just slightly different syntax. The converting of the Array to a List is entirely optional (and unavailable in Jass), you can always enumerate over an Array with a For Loop.

I got the rawcodes from here: How do I get the lists of type ids (units, items, abilities, ...) ?

You can copy and paste those rawcodes into something like Visual Studio Code and edit them to have a format that's Jass friendly like:

vJASS:
globals
    UnitArray[0] = "AAAA"
    UnitArray[1] = "BBBB"
    UnitArray[2] = "CCCC"
    // etc
endglobals

I'm sure you could even find a way to autofill the [Indexes].
 
Last edited:
Level 26
Joined
Feb 2, 2006
Messages
1,697
hm I am pretty unsure right now since there are some items like legendary artifacts or quest items which I do not want to be saved at all but my exclusion list would probably be smaller than the inclusion list of IDs. The vJass libraries seem pretty interesting! I wanted to add a debugging cheat which at least lists all IDs which cannot be found in my manually filled lists, so I can decide to add them or not. Thx for the replies.

Is there any way to get if the max possible ID with GetNextObjectId or should I simply stop if I do not find anything with GetObjectName or can there be gaps in between?
 
Status
Not open for further replies.
Top