Open DDLegionTN opened 9 years ago
Sorry, accidentally posted without completing the post, 1st issue i facing is when my hero lv is 1, when loaded it became lv 2. For 2nd, the function SelectHeroSkill() doesn't works for me, and also my heroes don't have skill points, all the abilities are added/leveled through trigger. So i couldn't save abilities for my heroes, any ideas? Below is my save/load code :
Saver :
private function OnSave takes nothing returns nothing
call SaveHeroAbilities(stack, udg_Hero[playerId], AbilityCatalog[GetUnitTypeId(udg_Hero[playerId])])
call stack.push(GetPlayerState(triggerPlayer, PLAYER_STATE_RESOURCE_GOLD)/100, 10000)
call stack.push(GetPlayerState(triggerPlayer, PLAYER_STATE_RESOURCE_LUMBER)/100, 10000)
call stack.push(udg_Hero_XP[playerId+1], 10000) //Max 10000 (Current XP)
call stack.push(udg_Hero_XP2[playerId+1], 10000) //Max 10000 (Lv up required XP)
call stack.push(GetHeroLevel(udg_Hero[playerId]), 50) //Max lv 50 <-----Problem here
call stack.push(S2I(udg_Player_DungeonString[playerId]), 2000) //Max Dungeon Integer 2000
call SaveUnitMana(stack, udg_Hero[playerId])
call SaveUnitLife(stack, udg_Hero[playerId])
call SaveInventory(stack, udg_Hero[playerId], ItemCatalog.catalog)
call SaveInventory(stack, udg_Player_Bag[playerId+1], ItemCatalog.catalog)
call stack.push(Heroes[GetUnitTypeId(udg_Hero[playerId])].id, Heroes.count)
endfunction
Loader :
globals
private constant integer VERSION_COUNT = 1
private unit loadedUnit
endglobals
private function OnLoadBuffer1 takes nothing returns nothing
set udg_Player_Bag[playerId+1] = CreateUnit(triggerPlayer, 'h006', GetRectCenterX(gg_rct_Starting_Point), GetRectCenterY(gg_rct_Starting_Point), 0)
call Buffer.reset()
set loadedUnit = CreateUnit(triggerPlayer, Heroes[stack.pop(Heroes.count)].raw, GetRectCenterX(gg_rct_Starting_Point), GetRectCenterY(gg_rct_Starting_Point), 0)
call LoadInventory(stack, udg_Player_Bag[playerId+1], ItemCatalog.catalog)
call LoadInventory(stack, loadedUnit, ItemCatalog.catalog)
call LoadUnitLife(stack, loadedUnit)
call LoadUnitMana(stack, loadedUnit)
call Buffer.write(stack.pop(2000))
call SetHeroLevel(loadedUnit, stack.pop(50), false) //Max lv 50 <---- Loaded here with lv2
call Buffer.write(stack.pop(10000)) //Max XP 10000
call Buffer.write(stack.pop(10000)) //Max XP 10000
call Buffer.write(stack.pop(10000)*100) //lumber
call Buffer.write(stack.pop(10000)*100) //gold
call LoadHeroAbilities(stack, loadedUnit, AbilityCatalog[GetUnitTypeId(loadedUnit)])
endfunction
private function OnLoad1 takes nothing returns nothing
local multiboarditem mb
set udg_Hero[playerId] = loadedUnit
set udg_Player_DungeonString[playerId] = I2S(Buffer.read())
set udg_Hero_XP2[playerId+1] = Buffer.read()
if udg_Hero_XP2[playerId+1] == 45 and GetHeroLevel(udg_Hero[playerId]) == 2 then
call SetHeroLevel(loadedUnit, 1, false)
endif
set udg_Hero_XP[playerId+1] = Buffer.read()
call PanCameraToTimed(GetRectCenterX(gg_rct_Starting_Point), GetRectCenterY(gg_rct_Starting_Point), 0)
set mb = MultiboardGetItem(udg_Multiboard, playerId+1, 2)
call MultiboardSetItemValue(mb, I2S(GetHeroLevel(loadedUnit)))
set mb = MultiboardGetItem(udg_Multiboard, playerId+1, 1)
call MultiboardSetItemStyle(mb, true, true)
call MultiboardSetItemValue(mb, GetUnitName(loadedUnit))
if GetUnitTypeId(loadedUnit) == 'E008' then
call MultiboardSetItemIcon(mb, "ReplaceableTextures\\CommandButtons\\BTNArcher.blp")
elseif GetUnitTypeId(loadedUnit) == 'H002' then
call MultiboardSetItemIcon(mb, "ReplaceableTextures\\CommandButtons\\BTNFootman.blp")
elseif GetUnitTypeId(loadedUnit) == 'H000' then
call MultiboardSetItemIcon(mb, "ReplaceableTextures\\CommandButtons\\BTNPriest.blp")
elseif GetUnitTypeId(loadedUnit) == 'E000' then
call MultiboardSetItemIcon(mb, "ReplaceableTextures\\CommandButtons\\BTNNightElfRunner.blp")
endif
call SetPlayerState(triggerPlayer, PLAYER_STATE_RESOURCE_LUMBER, Buffer.read())
call SetPlayerState(triggerPlayer, PLAYER_STATE_RESOURCE_GOLD, Buffer.read())
call ShowUnit(udg_Player_Bag[playerId+1], false)
set mb = null
endfunction
private function OnUnload1 takes nothing returns nothing //Fail load
call UnloadInventory(loadedUnit)
call UnloadInventory(udg_Player_Bag[playerId+1])
call RemoveUnit(loadedUnit)
call RemoveUnit(udg_Player_Bag[playerId+1])
set loadedUnit = null
endfunction
SetHeroLevel() on a level 1 to level 1 will make it level 2 because blizzard is lulzy. you hve to check if level != 1 or save exp instead
for abilities, just save them catalog style... you could push a # of abilities with a maximum as 16 (for non-spellbook) or 256 (for spellbook)
also if you're interested im looking for testers for my codeless save load system http://www.hiveworkshop.com/forums/lab-715/order-based-string-synchronization-260813/#post2631401 currently not totally tested but... you know... it needs testing...
thanks for your reply, but currently i don't want to waste my time again for another save/load system, so i will still continue using Nestharus's save/load system. From your answered, i learnt 1 thing again about the SetHeroLevel() from the lazy blizzard. For my 2nd question, after few times of testing, i realized that SelectHeroSkill() only will works only if hero has the ability is learn-able inside the OE, since my heroes don't have those, so its not working, guess i would need to take some time for working around.
The only reason I suggested it is because the system is fundamentally based on nestharus's system, except that instead of using -save as the event a dialog is used instead. The "Simple Save/Load" in my map should be familiar.
What do you mean? If you are adding learnable abilities via triggers to a unit than SetUnitAbilityLevel should work fine. On Friday, January 16, 2015, DDLegionTN notifications@github.com wrote:
thanks for your reply, but currently i don't want to waste my time again for another save/load system, so i will still continue using Nestharus's save/load system. From your answered, i learnt 1 thing again about the SetHeroLevel() from the lazy blizzard. For my 2nd question, after few times of testing, i realized that SelectHeroSkill() only will works only if hero has the ability is learn-able inside the OE, since my heroes don't have those, so its not working, guess i would need to take some time for working around.
— Reply to this email directly or view it on GitHub https://github.com/nestharus/JASS/issues/25#issuecomment-70251199.
SaveHeroAbilities depends on a hero having the abilities in object editor. It uses a few optimization tricks based on the maximum number of ability points the hero can have at a given level and the max level an ability can be at a given level. This saves space. The same can be done with abilities that are managed completely by code, you just have to modify the algorithm.
Most code I write follows the default Warcraft 3 stuff. If you are doing a custom solution, the default code isn't going to work for you.
I have something for saving an inventory too, but if you use a custom inventory system, you can't use my function.
I'm not sure how to save the custom abilities that aren't added via OE. I've already tried few times, fail completely. Using AddUnitAbility() and SetUnitAbilityLevel() as well, its seem like AddUnitAbility sometimes could fails to function (fail to add ability to unit), i got a headache with is bug (or not sure if it my mistake?)
For inventory, i'm using default war3 inventory, so i have no problem with it.
You need to keep a list of all abilities the unit knows. You also need to figure out the max ability level that each ability can be for the unit considering the unit's level. You also need to factor in how high an ability can be considering the level of the other abilities on the unit.
If the unit is level 3 and there is ability A, B, and C, then
A can be level 3 B can be level 3 C can be level 1
Overall, the unit has, by this example, 3 ability points.
The unit has learned A and C.
A is hit first. There are 3 ability points remaining and A's max level is 3. A is level 2. A is saved (the ability) as well as its level (2) with a max value of 3. The next ability that is hit is C. C is level 1 with a max level of 1 with 1 ability point remaining. C is saved as the ability, but the level is not saved because it can only ever be one. There are no ability points remaining, so B is skipped. You want to save this stuff in reverse order, and you want to be sure to load the hero and the hero level first.
On load, A is retrieved as well as its level. 2 ability points are used up to keep A. 1 ability point remains, this means that the next thing to be loaded will not have an ability level on it. C is loaded and is set to 1. There are no ability points left, so loading is done.
What happens if there are ability points left, but the hero doesn't use them all? 0 must be added to the end of the list. When 0 is retrieved, there are no abilities remaining.
Will B ever be hit? No, because the hero hasn't learned it, so it's not part of the list. What is B important for? The ability catalog. If a hero can only learn A, B, and C, then the catalog will have A, B, and C in it. What happens once you go over A? The catalog should only then have B and C in it. I haven't designed filters for this yet : |. I'm going to eventually make a filter that does this.
This is of course the most optimal way to save your data and it might merit a general function.
Uhh, i know how your Save Abilities works, just i want to know how could i save abilities that aren't in the list of hero spell. Although i may know how to make it, but i always facing weird bug while i finished it :/
First of all, thanks for reading my post. I had 2 issues currently regarding to your save/load system.