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

[General] Save/Load System Bug

Status
Not open for further replies.
Level 7
Joined
Jul 18, 2012
Messages
136
When Players on my ORPG type -save and then the save code saves for all players in the w3 folder not just for the player that type the code. and the code after he saves shows to all players how to fix that please help?
Im using Save/Load-system by Neostorm.
[tr]
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Wait, did you forget that Neostorm's save/load does not create text-files, but that it's been added by me?
Anyway, I completely forgot about that :D (couldn't test with multiple people back then).

So, I think this works (tested it and didn't desync, can only test this with multiple Warcraft clients running on 1 PC though).
JASS:
function CreateTextFile takes nothing returns nothing
    local integer p = GetPlayerId(GetTriggerPlayer())+1
    local string heroName = GetUnitName(udg_Hero)
    local integer heroLevel = GetHeroLevel(udg_Hero)
    
	if GetLocalPlayer() == GetTriggerPlayer() then
		call PreloadGenClear()
		call PreloadGenStart()
		call Preload("\r\n\t\t\t\tHero: " + heroName + "\r\n\t\t\t\t" + "Level: " + I2S(heroLevel) + "\t\t\r\n\t\t\t\t" + "Code: -load " + udg_NPS_Password + "\r\n\n\t\t    ")
		call PreloadGenEnd("Legion of Heroes\\" + heroName + " - " + I2S(heroLevel) + ".txt")
	endif
endfunction
Replace it with the previous one, obviously.

Also, if the map desyncs after adding this: please report this immediately.
 
Level 7
Joined
Jul 18, 2012
Messages
136
Do you mean like this?
JASS:
//TESH.scrollpos=0
//TESH.alwaysfold=0
function CreateTextFile takes nothing returns nothing
    local integer p = GetPlayerId(GetTriggerPlayer())+1
    local string heroName = GetUnitName(udg_Hero)
    local integer heroLevel = GetHeroLevel(udg_Hero)
    
    if GetLocalPlayer() == GetTriggerPlayer() then
    call PreloadGenClear()
    call PreloadGenStart()
    call Preload("\r\n\t\t\t\tHero: " + heroName + "\r\n\t\t\t\t" + "Level: " + I2S(heroLevel) + "\t\t\r\n\t\t\t\t" + "Code: -load " + udg_NPS_Password + "\r\n\n\t\t    ")
    
    // The line below creates the file at the specified location
    // Right now, this is:
    //      "Warcraft III\MapName\(hero name) - (hero level)"
    call PreloadGenEnd("Legion of Heroes\\" + heroName + " - " + I2S(heroLevel) + ".txt")
    endif
endfunction

// The regular "Rect Contains Unit" doesn't work properly
function RectContainsUnitExt takes rect r, unit u returns boolean
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    return GetRectMinX(r)-32. <= x and x <= GetRectMaxX(r)+32. and GetRectMinY(r)-32. <= y and y <= GetRectMaxY(r)+32.
endfunction
Is there anyway to put item protection to the save/load system? people multiply their items they drop and load again till strongest items.
 
Last edited:
Level 28
Joined
Jan 26, 2007
Messages
4,789
@DSG: good solution, but this way you can still multiply items for yourself.

Personally, I would store items created with a save/load inside a hashtable (Saved value: item, Parent: player number, Child: item count).
Whenever a player loads, remove all items stored in the hashtable.

This way, you keep the ability to trade, yet prevent duplication through the save/load-system.

In the trigger "NPS L Write Data To Unit":
  • -------- Item Data --------
  • -------- For each Integer A ------ FIX ------ For some reason any use of For each Integer A loops can malfunction (If there is another trigger which uses Hero aquires item Event) I have changed this to B in hopes that if you wont use it in this case. --------
  • For each (Integer LoopInt2) from 1 to 6, do (Actions)
    • Loop - Actions
      • Set TempInt1 = (TempInt1 + 1)
      • Item - Create Item_List_Array[NPS_Data_Int[TempInt1]] at (Center of (Playable map area))
      • Hero - Give (Last created item) to (Last created unit)
      • Item - Remove (Load LoopInt2 of (Player number of (Triggering player)) in Hashtable)
      • Hashtable - Save Handle Of(Last created item) as LoopInt2 of (Player number of (Triggering player)) in Hashtable
The last 2 actions have been added.
Do not forget to initialize the hashtable.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
This way, you keep the ability to trade, yet prevent duplication through the save/load-system.
Except this does not stop save rollback. Especially if the save is a physical file, you can just revert that file to a previous version via any means of backup.

Player 1 backs up save
Player 1 loads
Player 1 trades items to player 2
Player 1 leaves (saving automatically)
Player 2 leaves with items (saving automatically)
Player 1 restores save from backup

The cycle can repeat indefinitely and duplicate wealth.
 
Level 7
Joined
Jul 18, 2012
Messages
136
hmm i didint get it can you make a map with those trigers or screenshot. and what happend to : " -save and then the save code saves for all players in the w3 folder not just for the player that type the code. " ? Can someone explain i didint get it where should i add that what ap0calypse told me to do?
 
Last edited:
Level 28
Joined
Jan 26, 2007
Messages
4,789
Ah, of course. Then it would indeed make sense to make loaded items not able to be traded.
So loaded items will be destroyed once another code is reloaded (preventing personal wealth through dropping --> reloading),
and loaded items cannot be traded (preventing shared wealth, through the means mentioned by Nes and DSG).
That would make it completely safe, unless I'm missing something?

Can someone explain i didint get it where should i add that what ap0calypse told me to do?
The script you pasted in your previous post is correct.
If it is about the GUI-trigger, I already told you where you should put that.

In the trigger ""NPS L Write Data To Unit", find these actions:
  • -------- Item Data --------
  • -------- For each Integer A ------ FIX ------ For some reason any use of For each Integer A loops can malfunction (If there is another trigger which uses Hero aquires item Event) I have changed this to B in hopes that if you wont use it in this case. --------
  • For each (Integer LoopInt2) from 1 to 6, do (Actions)
    • Loop - Actions
      • Set TempInt1 = (TempInt1 + 1)
      • Item - Create Item_List_Array[NPS_Data_Int[TempInt1]] at (Center of (Playable map area))
      • Hero - Give (Last created item) to (Last created unit)
And add these 2 actions to the end of the loop:
  • Item - Remove (Load LoopInt2 of (Player number of (Triggering player)) in Hashtable)
  • Hashtable - Save Handle Of(Last created item) as LoopInt2 of (Player number of (Triggering player)) in Hashtable
That said, you still need to disable trading loaded items.
I'm going off now for a little while. I'm thinking of saving those items in the hashtable (now that we've already got it anyway), with the item id as the parent and the player number as the child value.
This would give us an O(1) lookup I believe.
 
Status
Not open for further replies.
Top