Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
yea bro i can help ya just use the save/load system and dis the "advanced" equipment system unless you have knowledge in vjass... vjass is incompatible with normal we code you gotta convert it. if you wanna learn some of the vjass tutorials (in case you dont know it) go to this page http://www.thehelper.net/forums/showthread.php/80241-GUI-vJASS
First of all, you might wanna try your hand at Nestharus' save-load system instead of those old systems...
Anyway, no matter which SL system u use, you just need to obtain the itemindex or itemid of the equipped items [the equipment system has codes for that, or you can use its own SL system if you want the item save to be separate from the others] then feed it to the save trigger, then when you load you just use the force equip by something function of the equipment system
First of all, you might wanna try your hand at Nestharus' save-load system instead of those old systems...
Anyway, no matter which SL system u use, you just need to obtain the itemindex or itemid of the equipped items then feed it to the save trigger, then when you load you just use the force equip by something function of the equipment system
That system is way too complicated for me, and its overcomplicating what i want to do. All i want is gold, hero type, hero stats maybe, item slots 1-6, and 9 item rawcodes... maybe something like that in CoT FoC
Anyway, no matter which SL system u use, you just need to obtain the itemindex or itemid of the equipped items [the equipment system has codes for that, or you can use its own SL system if you want the item save to be separate from the others] then feed it to the save trigger, then when you load you just use the force equip by something function of the equipment system
btw, complicated? that's what I thought too, but when I tried it, its not really complicated as you use it almost the same way as how you use these old systems (trust me, I used to use AceHart's system a lot before)... you know why I stopped using those old systems? cause the break when saving lots of stuff or when saving a huge number...
First of all, you might wanna try your hand at Nestharus' save-load system instead of those old systems...
Anyway, no matter which SL system u use, you just need to obtain the itemindex or itemid of the equipped items [the equipment system has codes for that, or you can use its own SL system if you want the item save to be separate from the others] then feed it to the save trigger, then when you load you just use the force equip by something function of the equipment system
btw, complicated? that's what I thought too, but when I tried it, its not really complicated as you use it almost the same way as how you use these old systems (trust me, I used to use AceHart's system a lot before)... you know why I stopped using those old systems? cause the break when saving lots of stuff or when saving a huge number...
// **** Save / Load Codes ****
function SaveEquipment takes player p returns string
local integer i = 0
local string s = ""
loop
set i = i + 1
[B] if Equipment.Item[i].id != 0 then
set s = s + I2S(Equipment.Item[i].id - 'I000')[/B]
endif
set s = s + "-"
exitwhen i >= classes
endloop
return s
endfunction
function LoadEquipment takes player p, string LoadCode returns nothing
local integer i = 0
local integer i2 = 0
local integer i3 = 1
local string s
local string c = LoadCode
loop
set i = i + 1
set i2 = 1
loop
set s = SubString(c, 6, i2)
exitwhen SubString(s, StringLength(s) - 1, StringLength(s)) == "-"
set i2 = i2 + 1
endloop
set c = SubString(c, i2, 99999)
set s = SubString(s, 0, StringLength(s) - 1)
if s != "" then
[B] call Equipment.equip(CreateItem('I000' + S2I(s), 0, 0))[/B]
endif
exitwhen i >= classes or c == ""
endloop
endfunction
Ill look into nestharus's, but honestly i have a very very small clue about Jass. the bold stuff, im assuming, is the call triggers i would use?
library SaveHeroStats /*
*************************************************************************************
*
* Saves hero strength, agility, and intelligence
*
*************************************************************************************
*
* */uses/*
*
* */ NumberStack /* hiveworkshop.com/forums/1993458-post521.html
*
************************************************************************************
*
*
* SETTINGS
*/
globals
/*************************************************************************************
*
* ALL_STATS_SPENT
*
* Every stat point is spent at every level
*
* If every stat point is spent at every level, the strength can be calculated from
* the remaining stat points. If the stat points are not spent, the strength has
* to be stored in the code.
*
* Stat points spent at every level means a smaller code.
*
*************************************************************************************/
private constant boolean ALL_STATS_SPENT = true
/*************************************************************************************
*
* SPLIT_BONUSES
*
* Makes bonus specific to each stat rather than shared among all stats.
*
* If SPLIT_BONUSES is true and 1024 is passed in as a max bonus, 1024 will be the cap
* for each individual stat.
*
* If SPLIT_BONUSES is false and 1024 is passed in as a max bonus, 1024 will be the cap
* for all three stats put together. If intelligence is 500, then 524 bonus stats
* will be left.
*
*************************************************************************************/
private constant boolean SPLIT_BONUSES = false
endglobals
/*
************************************************************************************
* function SaveHeroStats takes NumberStack stack, unit whichUnit, integer maxBonusForLevel returns nothing
* function LoadHeroStats takes NumberStack stack, unit whichUnit, integer maxBonusForLevel returns nothing
*
************************************************************************************/
function SaveHeroStats takes NumberStack stack, unit whichUnit, integer maxBonusForLevel returns nothing
local unit u
static if SPLIT_BONUSES then
local integer bonusStr
elseif not ALL_STATS_SPENT then
local integer bonusStr
endif
local integer bonusAgi
local integer bonusInt
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = false
endif
set u = CreateUnit(Player(15), GetUnitTypeId(whichUnit), GetRectMaxX(bj_mapInitialPlayableArea), GetRectMaxY(bj_mapInitialPlayableArea), 0)
call SetHeroLevel(u, GetHeroLevel(whichUnit), false)
static if SPLIT_BONUSES then
set bonusStr = GetHeroStr(whichUnit, false)-GetHeroStr(u, false)
elseif not ALL_STATS_SPENT then
set bonusStr = GetHeroStr(whichUnit, false)-GetHeroStr(u, false)
endif
set bonusAgi = GetHeroAgi(whichUnit, false)-GetHeroAgi(u, false)
set bonusInt = GetHeroInt(whichUnit, false)-GetHeroInt(u, false)
static if SPLIT_BONUSES then
call stack.push(bonusStr, maxBonusForLevel)
call stack.push(bonusAgi, maxBonusForLevel)
call stack.push(bonusInt, maxBonusForLevel)
else
static if not ALL_STATS_SPENT then
call stack.push(bonusStr, maxBonusForLevel-bonusAgi-bonusInt)
endif
//else
//bonus strength is the remaining bonus points
call stack.push(bonusAgi, maxBonusForLevel-bonusInt)
call stack.push(bonusInt, maxBonusForLevel)
endif
call RemoveUnit(u)
set u = null
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = true
endif
endfunction
function LoadHeroStats takes NumberStack stack, unit whichUnit, integer maxBonusForLevel returns nothing
local unit u
local integer bonusStr
local integer bonusAgi
local integer bonusInt
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = false
endif
set u = CreateUnit(Player(15), GetUnitTypeId(whichUnit), GetRectMaxX(bj_mapInitialPlayableArea), GetRectMaxY(bj_mapInitialPlayableArea), 0)
call SetHeroLevel(u, GetHeroLevel(whichUnit), false)
static if SPLIT_BONUSES then
set bonusInt = stack.pop(maxBonusForLevel)
set bonusAgi = stack.pop(maxBonusForLevel)
set bonusStr = stack.pop(maxBonusForLevel)
else
set bonusInt = stack.pop(maxBonusForLevel)
set bonusAgi = stack.pop(maxBonusForLevel-bonusInt)
static if ALL_STATS_SPENT then
set bonusStr = maxBonusForLevel-bonusAgi-bonusInt
else
set bonusStr = stack.pop(maxBonusForLevel-bonusAgi-bonusInt)
endif
endif
call SetHeroInt(whichUnit, bonusInt+GetHeroInt(u, false), true)
call SetHeroAgi(whichUnit, bonusAgi+GetHeroAgi(u, false), true)
call SetHeroStr(whichUnit, bonusStr+GetHeroStr(u, false), true)
call RemoveUnit(u)
set u = null
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = true
endif
endfunction
endlibrary
function SaveHeroStats takes NumberStack stack, unit whichUnit, integer maxBonusForLevel returns nothing
where max bonus is like how much +str they can have from upgrades or w/e =). For example, a map that allows a player to add +1 to any stat at every level saving a level 10 hero would have a max +str of 10. SPLIT_BONUSES split them, like if you put in 10, you can have +10 str, +10 agi, +10 int instead of a combination of all 3 adding to 10.
Item Slots 1-6 of the custom inventory?
loop through the inventory -> Equipment.Item[i].id
Collect all non null items, then save them. If the inventory wasn't completely saved, save a 0 as a null item first. For item charges, only save the item charge if the item has an item charge. This means an if statement. If item max charge > 1, save item charge. If not, don't save item charge ;p. Pretty simple no?
From there, you can convert raw codes into catalog ids and back. It's for converting a massive number into a small one ;p
Also keep in mind that you should only save items that aren't null : O. Partial sets of data just plain rock.
For version control, the standard method is to now add the version to the checksum and use the version as a CRC.
JASS:
library KnuthChecksum uses BigInt
function GetKnuthChecksum takes BigInt k, integer m returns integer
local BigInt c = k.copy()
local BigInt c2 = k.copy()
call c.add(3,0)
call c2.multiplyBig(c)
call c.destroy()
set c = c2.mod(m)
call c2.destroy()
return c
endfunction
endlibrary
And at the very start, before you do anything else call BigInt(stack).add(versionNumber, 0)
You can then also encrypt the number using Scrambler.
Now this may seem like mumbo jumbo and super complicated stuff to you, but that is only because there is so much stuff being used here >.<. If you know the bajillion snippets, using and modifying them is actually really easy ;o.
Sadly, xp can only be safely saved with HeroReward. However, if you do have smaller levels that don't have a chance of overflowing, then you can save xp another way ^)^.
Here's how you save xp
Create a dummy hero. Set that hero level to the same level as the hero you are saving (only if that hero being saved is >1). From there, saving hero xp - dummy hero xp. Next, add 1 level to the dummy hero. From there, dummy hero xp new - dummy hero xp old. Now, compress the first value you retrieved (hero xp) and the second value you retrieved (max possible xp for that level). Now save that + the level ^)^.
Another method is to save the xp as a % into the level by doing hero xp / dummy hero xp of hero level + 1 * 100. This will then cap the value to a max of 99, a bit less accurate but still works.
Finally, you can also just save the xp as a compressed value, something I wouldn't recommend. Just compress the hero xp and store it in a max of all of the possible xp. Saving the xp in a compressed form with the level will give you a smaller value than just the plain xp. Saving the xp as a percent may or may not give you a smaller value, it depends ; ).
The good thing about HeroReward is that there is only percent hero xp. All levels are out of 10,000, which is essentially 100.00, which is a percent with 2 decimal places. That makes saving hero xp using HeroReward super easy. You can easily change your map settings to use % xp by looking at the custom values used in Hero Reward and changing your xp settings to those. However, you will need to change your xp algorithm to work with %s rather than raw values. Working with %s also makes it safe to go up to a level like 10,000 without overflowing.
My final recommendation is to, at a bare minimum, use BigInt. BigInt is not a save/load system but rather a system to handle really big numbers. Save/Load codes, if done correctly, are really big numbers. If you know how to do the math, you can just use BigInt and forgo all of the save/load system nonsense ;D.
The stuff isn't complicated, there are just many ways to save things and different things need to be saved in different ways. For example, gold is saved differently from an inventory ;p. The naive approach is to save everything the same way, which is what older systems do. If you know a value is part of a set of a value has a relation with another value, you can take advantage of that. For example, will a level 1 hero ever have 1,000,000 gold? Probably not. Will a max level hero have that? Possibly. Take advantage of all of these things to minimize your save/load code ;p.
And you should always use Scrambler for protection. It adds absolutely nothing to the code and produces almost randomized output. Just adding 1 to a single value will change the entire code ;o. It also makes codes player unique. You can use Scrambler to scramble up the encryption keys too ; ).
Click the Non Lua Version in the Unit Indexer thread and copy and paste the ability in there. Also cnp the script from in there as it has the constant. Change the value of the constant to the id you assign to the ability.
On the other hand, you could always use the Lua Framework, but that would be more work ^)^
Click the Non Lua Version in the Unit Indexer thread and copy and paste the ability in there. Also cnp the script from in there as it has the constant. Change the value of the constant to the id you assign to the ability.
On the other hand, you could always use the Lua Framework, but that would be more work ^)^
The save/load with snippets map in spells section already has all of the snippets assembled for use and includes a framework for versioned save/load, which is something I highly recommend using. However, NumberEncryptor should probably be modified to remove the variance of checksums. I don't think that player unique checksums are a good idea ; P.
The save/load with snippets map in spells section already has all of the snippets assembled for use and includes a framework for versioned save/load, which is something I highly recommend using. However, NumberEncryptor should probably be modified to remove the variance of checksums. I don't think that player unique checksums are a good idea ; P.
i just merged the snippets that are required by the save-load snippets in one and the save-load snippets in another :O
also, 4? i counted 3...
e/ there might be 4 xD
Undeclared Function : CompressInt
2e/ now
JASS:
struct Demo extends array
private static Base encryptionKey
private static method save takes nothing returns boolean
//notice that encryption key is passed in
local NumberStack stack = NumberStack.create(encryptionKey) //create a number stack
local string encrypted
//push numbers on to stack (save two values)
//value max
call stack.push(CompressInt(GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_GOLD)), CompressInt(1000000))
call SaveHeroXP(stack, udg_PlayerUnit[GetConvertedPlayerId(GetTriggerPlayer())], 2)//10 in stack in that order
//display numbers in stack
call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,0,60,"Saving: 10,20")
how do i put the call stack.push and call saveheroxp in the load side..?
Yeah, sorry, i was an idiot and tried to call it in GUI :s
anyway, after i stopped being an idiot and realized how to set the xp, it come out some wicked numbers, always randomized... (800ish, 2000ish, 6000, back to 4000, 6000, 2000, etc.)
call LoadHeroXP(stack, udg_PlayerUnit[GetConvertedPlayerId(GetTriggerPlayer())], 2) after Loaded : +I2S(....
/sigh... looks like I'm doing the save/load for you >.<
do you want to wait for BigInt 2? It'll be a lot faster. Encryption has a crap ton of overhead. This overhead causes a slight freeze on BigInt 1.
I'm actually in the process of coding BigInt 2 right now, so hopefully it'll be done by the end of the week, but who knows... we'll see what I end up feeling like doing (if I get tired of it before I finish it or not, lol).
/sigh... looks like I'm doing the save/load for you >.<
do you want to wait for BigInt 2? It'll be a lot faster. Encryption has a crap ton of overhead. This overhead causes a slight freeze on BigInt 1.
I'm actually in the process of coding BigInt 2 right now, so hopefully it'll be done by the end of the week, but who knows... we'll see what I end up feeling like doing (if I get tired of it before I finish it or not, lol).
than be my guest with BigInt2... map def. wont be in a playable state (getting f***ked over by sports) for a while.
Also, if you dont want to do it / help me its fine, i was gonna go down to a much weaker save-load system but since you responded offering help on your system, id figure id take it
e/ also, is there ANY way to stop using HeroReward..? it really messes up alot of my quests (soon to come) and its functions provided do not suit my usage...
I'm going to update HeroReward to be a lot more dynamic by splitting up the Bounty and XP into two libs that sort of merge together (so that you can just take what you need). I'm also going to add a little display area for text tags or w/e you want to do (merge the two into one tag if you want).
However, I don't quite understand how it messes up your quests. There is a very useful snippet ^)^.
JASS:
library GetBonusXP
//xpRate: desired xp rate, like 350
//awardLevel: the level of the award, like a level 5 quest
//awardedLevel: the level of the awarded thing, like a level 10 unit
//xpRecieveRate: the rate at which xp recieved increases relative to level (bigger means more xp)
//xpReqRate: the rate at which xp requirement increases relative to level (bigger means more xp required)
//maxes:
// xpBountyRate: 1.8
// xpReqRate: 2.1
function GetBonusXP takes integer awardLevel, integer awardedLevel, real xpRate, real xpRecieveRate, real xpReqRate returns integer
local real xp = Pow(awardLevel+1,xpRecieveRate)
local real xpReq = Pow(awardedLevel,xpReqRate)
//calculate awarded xp
return R2I(xp/xpReq*xpRate+.5)
endfunction
endlibrary
I'm going to update HeroReward to be a lot more dynamic by splitting up the Bounty and XP into two libs that sort of merge together (so that you can just take what you need). I'm also going to add a little display area for text tags or w/e you want to do (merge the two into one tag if you want).
However, I don't quite understand how it messes up your quests. There is a very useful snippet ^)^.
JASS:
library GetBonusXP
//xpRate: desired xp rate, like 350
//awardLevel: the level of the award, like a level 5 quest
//awardedLevel: the level of the awarded thing, like a level 10 unit
//xpRecieveRate: the rate at which xp recieved increases relative to level (bigger means more xp)
//xpReqRate: the rate at which xp requirement increases relative to level (bigger means more xp required)
//maxes:
// xpBountyRate: 1.8
// xpReqRate: 2.1
function GetBonusXP takes integer awardLevel, integer awardedLevel, real xpRate, real xpRecieveRate, real xpReqRate returns integer
local real xp = Pow(awardLevel+1,xpRecieveRate)
local real xpReq = Pow(awardedLevel,xpReqRate)
//calculate awarded xp
return R2I(xp/xpReq*xpRate+.5)
endfunction
endlibrary
How would i use that return..? (as i said i suck at jass)
e/ the last things i need before you touch up those snippits (i guess...?) is "how would i use that return" and why the loading xp prints out some random level
2e/ damn i suck at this. What line would be for loading gold after its compressed? So far i have call SetPlayerStateBJ( GetTriggerPlayer(), PLAYER_STATE_RESOURCE_GOLD, ?????? )
Play with this stuff so you get a feel of how to retrieve values from the stack and push values into the stack. save/load codes are numbers, and numbers act like stacks when storing data.
From there, try compressing a value using CompressInt and then decompress a value with DecompressInt. Then you can try saving gold.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.