Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ResourceModule = require(game.ReplicatedStorage.ResourceModule)
- CatalogModule = require(game.ReplicatedStorage.CatalogModule)
- --[[ INFO DATA SAVING FORMAT
- [KEY] = INFO_{USER_ID}
- [1] = Username (Updates every save)
- [2] = Table of all usernames saved to the barn (Constant accross all regions)
- [3] = Table of all resources saved in the barn (Constant accross all regions)
- [4] = Table of all saved regions (FULL NAME eg. Region_{USER_ID}_1 )
- ]]
- --[[ OBJECT DATA SAVING FORMAT
- [1] = Object Name (Integer pulled from a dictionary table)
- [2] = X value of position
- Terrain is flat so we don't need the Y value of position
- [3] = Z value of position
- [4] = Rotation (Objects only rotate on 1 axis in increments of 90 degrees)
- [5] = Age (Can be nil)
- [6] = Table of any additional data (Can be nil)
- ]]
- --Fun code for later!
- function splitString(str, delim, maxNb)
- -- Eliminate bad cases...
- if string.find(str, delim) == nil then
- return { str }
- end
- if maxNb == nil or maxNb < 1 then
- maxNb = 0 -- No limit
- end
- local result = {}
- local pat = "(.-)" .. delim .. "()"
- local nb = 0
- local lastPos
- for part, pos in string.gmatch(str, pat) do
- nb = nb + 1
- result[nb] = part
- lastPos = pos
- if nb == maxNb then break end
- end
- -- Handle the last field
- if nb ~= maxNb then
- result[nb + 1] = string.sub(str, lastPos)
- end
- return result
- end
- local NameForIntegerIndex = { --This is going to get really messy with more plants and objects :(
- Grass = 0,
- YoungSapling = 1,
- OldSapling = 2,
- Wheat = 3,
- Corn = 4,
- Lettuce = 5,
- YoungTree = 6,
- SmallTree = 7,
- MediumTree = 8,
- LargeTree = 9,
- OldTree = 10,
- SmallRock = 11,
- MediumRock = 12,
- LargeRock = 13,
- WoodHut = 14,
- WoodFence = 15,
- PlankFence = 16,
- StoneFence = 17,
- StonePath = 18,
- Torch = 19,
- Sprinkler = 20,
- HugeRock = 21,
- SmallPond = 22,
- FirePit = 23,
- Potato = 24,
- TomatoBush = 25,
- CowSet = 26,
- SheepSet = 27,
- GoldPile = 28,
- StonePile = 29,
- PotatoStand = 30,
- TomatoStand = 31,
- LettuceStand = 32,
- PigSet = 33,
- Generator = 34,
- AnimalReactor = 35,
- FlourMill = 36,
- Carrot = 37,
- Outhouse = 38,
- WoodenGate = 39,
- }
- local IntegerForNameIndex = {}
- for k, v in pairs(NameForIntegerIndex) do
- IntegerForNameIndex[v] = k
- end
- local GW = game.Workspace --Makes below easier; don't use other places so code stays readable
- local IntegerForLocationIndex = {}
- IntegerForLocationIndex[0] = GW.GrassStorage --lol never used
- IntegerForLocationIndex[1] = GW.SaplingStorage
- IntegerForLocationIndex[2] = GW.SaplingStorage
- IntegerForLocationIndex[3] = GW.CropStorage
- IntegerForLocationIndex[4] = GW.CropStorage
- IntegerForLocationIndex[5] = GW.CropStorage
- IntegerForLocationIndex[6] = GW.TreeStorage
- IntegerForLocationIndex[7] = GW.TreeStorage
- IntegerForLocationIndex[8] = GW.TreeStorage
- IntegerForLocationIndex[9] = GW.TreeStorage
- IntegerForLocationIndex[10] = GW.TreeStorage
- IntegerForLocationIndex[11] = GW.RockStorage
- IntegerForLocationIndex[12] = GW.RockStorage
- IntegerForLocationIndex[13] = GW.RockStorage
- IntegerForLocationIndex[14] = GW.StaticStorage
- IntegerForLocationIndex[15] = GW.StaticStorage
- IntegerForLocationIndex[16] = GW.StaticStorage
- IntegerForLocationIndex[17] = GW.StaticStorage
- IntegerForLocationIndex[18] = GW.StaticStorage
- IntegerForLocationIndex[19] = GW.StaticStorage
- IntegerForLocationIndex[20] = GW.StaticStorage
- IntegerForLocationIndex[21] = GW.StaticStorage
- IntegerForLocationIndex[22] = GW.StaticStorage
- IntegerForLocationIndex[23] = GW.StaticStorage
- IntegerForLocationIndex[24] = GW.CropStorage
- IntegerForLocationIndex[25] = GW.CropStorage
- IntegerForLocationIndex[26] = GW.StaticStorage
- IntegerForLocationIndex[27] = GW.StaticStorage
- IntegerForLocationIndex[28] = GW.StaticStorage
- IntegerForLocationIndex[29] = GW.StaticStorage
- IntegerForLocationIndex[30] = GW.StaticStorage
- IntegerForLocationIndex[31] = GW.StaticStorage
- IntegerForLocationIndex[32] = GW.StaticStorage
- IntegerForLocationIndex[33] = GW.StaticStorage
- IntegerForLocationIndex[34] = GW.DynamicStorage
- IntegerForLocationIndex[35] = GW.StaticStorage
- IntegerForLocationIndex[36] = GW.DynamicStorage
- IntegerForLocationIndex[37] = GW.CropStorage
- IntegerForLocationIndex[38] = GW.StaticStorage
- IntegerForLocationIndex[39] = GW.StaticStorage
- local RegionDataStore = game:GetService("DataStoreService"):GetDataStore("RegionStorage") --WE ARE LIVE :D :D :D :D
- local CurrentPlayerData = { } --So we don't have to constantly call the player info files
- function loadPlayerData( Player ) --Actual player passed
- if( Player )then
- local PlayerData = nil
- local good = pcall( function()
- playerData = RegionDataStore:GetAsync( "INFO_" .. Player.userId )
- end)
- if( playerData )then
- return playerData
- elseif( good )then --Time to make new template data
- playerData = {}
- playerData[1] = Player.Name
- playerData[2] = {}
- playerData[3] = {}
- playerData[4] = {}
- return playerData
- end
- end
- if( Player )then
- Player:kick("Critical Data Error")
- end
- return nil --This means something went very wrong
- end
- function updatePlayerData( Player, Barn )
- if( Player and Barn )then --I sure hope they exist
- local PlayerData = CurrentPlayerData[ Player.userId ]
- PlayerData[2] = { }
- for _, v in pairs(Barn.Control.Players:getChildren())do
- table.insert(PlayerData[2], v.Value)
- end
- for _, v in pairs(Barn.Control.Resources:getChildren())do
- PlayerData[3][v.Name] = v.Value
- end
- local good = pcall( function()
- RegionDataStore:SetAsync( "INFO_" .. Player.userId, PlayerData )
- end )
- if( not good )then
- print("BAD BAD BAD BAD @updatePlayerData")
- end
- end
- end
- --Not used for some reason
- function savePlayerData( Player )
- if( Player and CurrentPlayerData[ Player.userId ] )then
- local good = pcall( function()
- RegionDataStore:SetAsync( "INFO_" .. Player.userId, CurrentPlayerData[ Player.userId ] )
- end )
- if( not good )then
- print("BAD BAD BAD BAD @savePlayerData")
- end
- end
- end
- --Region Control stuff
- local DefaultRegions = {}
- local searchLocations = { game.Workspace.StaticStorage, game.Workspace.DynamicStorage, game.Workspace.CropStorage,
- game.Workspace.RockStorage, game.Workspace.GrassStorage, --Optimizations should make this possible!
- game.Workspace.TreeStorage, game.Workspace.SaplingStorage }
- function regionToString( region )
- local finalString = ""
- for o, v in pairs( region )do
- for i, u in pairs( v )do
- finalString = finalString .. math.floor(tonumber(u) + .5) .. ','
- end
- finalString = finalString .. ";"
- end
- return finalString
- end
- function stringToRegion( regionString )
- --print( regionString )
- if( string.sub(regionString, 1, 1) == '[' )then --We have old data
- return game:GetService("HttpService"):JSONDecode( regionString )
- else
- local finalRegion = { }
- for i, v in pairs(splitString(regionString, ',;'))do
- finalRegion[i] = {}
- for o, u in pairs(splitString(v, ','))do
- --print( i .. ":" .. o .. ":" .. u )
- finalRegion[i][o] = tonumber(u)
- end
- end
- if( finalRegion[#finalRegion][1] == "" )then --So loading doesn't act funky
- table.remove(finalRegion, #finalRegion)
- end
- return finalRegion
- end
- end
- function getRegionContents( BarnBase ) --Let's do some recursion and complex data stuff >:D JK Use my own functions :l
- local lilX, lilZ = BarnBase.Position.X - 100, BarnBase.Position.Z - 75
- local bigX, bigZ = BarnBase.Position.X + 100, BarnBase.Position.Z + 75
- local foundObjects = { }
- for _, l in pairs( searchLocations ) do
- for __, t in pairs(l:getChildren())do
- local part = t:findFirstChild("Base")
- if( part and ( lilX < part.Position.X and part.Position.X < bigX )
- and ( lilZ < part.Position.Z and part.Position.Z < bigZ ) )then
- table.insert(foundObjects, t)
- end
- end
- end
- return foundObjects
- end
- local maxSize = 64998
- function SaveRegion( Player, regionContents )
- local savePieces = { regionContents }
- --print( string.len(savePieces[#savePieces]))
- while( string.len(savePieces[#savePieces]) > (maxSize - 10) )do
- local piece = savePieces[#savePieces]
- savePieces[#savePieces] = string.sub(piece, 1, (maxSize - 10))
- savePieces[#savePieces + 1] = string.sub(piece, (maxSize - 9))
- end
- CurrentPlayerData[Player.userId][4] = {}
- local success, why = pcall(function()
- for i, v in pairs( savePieces )do
- --print( i )
- RegionDataStore:SetAsync("REGION_" .. Player.userId .. "_" .. i, v)
- CurrentPlayerData[Player.userId][4][i] = "REGION_" .. Player.userId .. "_" .. i
- end
- end)
- print( ( success and "Barn Data Saved!" ) or why )
- end
- function LoadRegion( Player )
- local segments = CurrentPlayerData[Player.userId][4]
- local region = ""
- local good = pcall( function()
- for i, v in pairs(segments)do
- region = region .. RegionDataStore:GetAsync( v )
- end
- end )
- if( not good)then
- print("BAD BAD BAD @LoadRegion")
- end
- return region
- end
- --JSON Functions
- function ConvertRegionToJSON( regionContents, Barn )
- if( Barn )then --We need the barn so we can correctly calculate the offset position of the objects
- local BarnBPX = Barn.Base.Position.X
- local BarnBPZ = Barn.Base.Position.Z
- local finalTable = { }
- if( tonumber( string.sub(Barn.Name, 5) ) < 4 )then--First three barns don't require rotation around the barn
- for _, v in pairs(regionContents)do
- local o = { }
- o[1] = NameForIntegerIndex[v.Name]
- o[2] = v.Base.Position.X - BarnBPX
- o[3] = v.Base.Position.Z - BarnBPZ
- o[4] = ( math.abs(v.Base.Rotation.X) > 90 and 2 ) or math.floor(v.Base.Rotation.Y/90 + .5)
- if( v:findFirstChild("Age") )then
- o[5] = v.Age.Value
- end
- --o[6] = { } --No objects currently use this
- table.insert(finalTable, o)
- end
- else--Last three barns need roation applied to their positions
- for _, v in pairs(regionContents)do
- local o = { }
- o[1] = NameForIntegerIndex[v.Name]
- o[2] = -1*( v.Base.Position.X - BarnBPX ) --Negate to rotate around barn
- o[3] = -1*( v.Base.Position.Z - BarnBPZ ) --Negate to rotate around barn
- o[4] = ( math.abs(v.Base.Rotation.X) > 90 and 2 + 2 ) or math.floor(v.Base.Rotation.Y/90 + .5) + 2 --Add two to rotate 180 degrees
- if( v:findFirstChild("Age") )then
- o[5] = v.Age.Value
- end
- --o[6] = { } --No objects currently use this
- table.insert(finalTable, o)
- end
- end
- --return game:GetService("HttpService"):JSONEncode(finalTable) --old
- return regionToString( finalTable ) --new
- end
- end
- function addTag(where, who)
- local tag = Instance.new("StringValue")
- tag.Name = "Tag"
- tag.Parent = where
- tag.Value = ( who ~= nil and who ) or ""
- end
- function DeployRegionFromJSON( JSONData, Barn, playerName )
- --print( JSONData )
- if( Barn )then --We need the barn so we can correctly calculate the offset position of the objects
- --local regionTable = game:GetService("HttpService"):JSONDecode( JSONData ) --old
- local regionTable = stringToRegion( JSONData ) --new
- --print( #regionTable )
- local BarnBPX = Barn.Base.Position.X
- local BarnBPZ = Barn.Base.Position.Z
- if( tonumber( string.sub(Barn.Name, 5) ) < 4 )then--First three barns don't require rotation around the barn
- for i, v in pairs( regionTable )do
- --print( v[1] )
- --print( IntegerForLocationIndex[ v[1] ] )
- if( i % 20 == 0 )then wait() end
- if( IntegerForLocationIndex[ v[1] ] )then --because I'm stupid
- if( IntegerForLocationIndex[ v[1] ] == game.Workspace.CropStorage )then --We have to do crops differantly
- local newName = IntegerForNameIndex[ v[1] ] --Makes the age proccess a bit easier
- local newObject = game.ServerStorage[ newName ]:clone()
- newObject.Parent = IntegerForLocationIndex[ v[1] ] or game.Workspace.StaticStorage
- newObject.Age.Value = v[5]
- --Complicated because crops move as they age
- local maxAge = CatalogModule.CropConfig[newName].Age
- if( v[5] < maxAge )then
- newObject.Base.CFrame = CFrame.new( v[2] + BarnBPX,
- (v[5]/maxAge - .5)*newObject.Base.Size.Y + 1.2,
- v[3] + BarnBPZ ) * CFrame.Angles(0, (math.pi/2)*v[4], 0)
- elseif( v[5] == maxAge )then
- newObject.Base.CFrame = CFrame.new( v[2] + BarnBPX,
- .5*newObject.Base.Size.Y + 1.2,
- v[3] + BarnBPZ ) * CFrame.Angles(0, (math.pi/2)*v[4], 0)
- AdjustColor( newObject, BrickColor.new(CatalogModule.CropConfig[newName].Color) )
- if( CatalogModule.CropConfig[newName].Mature )then
- AdjustMatureVis(newObject, true)
- end
- else --We know it is a dead crop x(
- newObject.Base.CFrame = CFrame.new( v[2] + BarnBPX,
- ((maxAge-1)/maxAge - .5)*newObject.Base.Size.Y + 1.2,
- v[3] + BarnBPZ ) * CFrame.Angles(0, (math.pi/2)*v[4], 0)
- AdjustColor( newObject, BrickColor.new(CatalogModule.CropConfig[newName].Death) )
- if( CatalogModule.CropConfig[newName].Mature )then
- AdjustMatureVis(newObject, false)
- end
- end
- AdjustPosition( newObject, game.ServerStorage[ IntegerForNameIndex[ v[1] ] ] )
- local newPlot = game.ServerStorage.CropPlot:clone() --We have to make the crop base
- newPlot.Base.CFrame = CFrame.new(v[2] + BarnBPX, 1.3, v[3] + BarnBPZ)
- newPlot.Parent = newObject
- addTag(newObject, playerName)
- else
- local newObject = game.ServerStorage[ IntegerForNameIndex[ v[1] ] ]:clone()
- newObject.Parent = IntegerForLocationIndex[ v[1] ] or game.Workspace.StaticStorage
- newObject.Base.CFrame = CFrame.new( v[2] + BarnBPX, newObject.Base.Size.Y/2 + 1.2,
- v[3] + BarnBPZ ) * CFrame.Angles(0, (math.pi/2)*v[4], 0)
- AdjustPosition( newObject, game.ServerStorage[ IntegerForNameIndex[ v[1] ] ] )
- if( v[5] )then
- newObject.Age.Value = v[5]
- elseif( IntegerForLocationIndex[ v[1] ] == GW.StaticStorage or
- IntegerForLocationIndex[ v[1] ] == GW.DynamicStorage )then
- addTag(newObject, playerName)
- end
- end
- end
- end
- else--Last three barns need roation applied to their positions
- for i, v in pairs( regionTable )do
- if( i % 20 == 0 )then wait() end
- if( IntegerForLocationIndex[ v[1] ] )then --because I'm stupid
- if( IntegerForLocationIndex[ v[1] ] == game.Workspace.CropStorage )then --We have to do crops differantly
- local newName = IntegerForNameIndex[ v[1] ] --Makes the age proccess a bit easier
- local newObject = game.ServerStorage[ newName ]:clone()
- newObject.Parent = IntegerForLocationIndex[ v[1] ] or game.Workspace.StaticStorage
- newObject.Age.Value = v[5]
- --Complicated because crops move as they age
- local maxAge = CatalogModule.CropConfig[newName].Age
- if( v[5] < maxAge )then
- newObject.Base.CFrame = CFrame.new( -1*v[2] + BarnBPX,
- (v[5]/maxAge - .5)*newObject.Base.Size.Y + 1.2,
- -1*v[3] + BarnBPZ ) * CFrame.Angles(0, (math.pi/2)*( v[4] - 2 ), 0)
- elseif( v[5] == maxAge )then
- newObject.Base.CFrame = CFrame.new( -1*v[2] + BarnBPX,
- .5*newObject.Base.Size.Y + 1.2,
- -1*v[3] + BarnBPZ ) * CFrame.Angles(0, (math.pi/2)*( v[4] - 2 ), 0)
- AdjustColor( newObject, BrickColor.new(CatalogModule.CropConfig[newName].Color) )
- if( CatalogModule.CropConfig[newName].Mature )then
- AdjustMatureVis(newObject, true)
- end
- else --We know it is a dead crop x(
- newObject.Base.CFrame = CFrame.new( -1*v[2] + BarnBPX,
- ((maxAge-1)/maxAge - .5)*newObject.Base.Size.Y + 1.2,
- -1*v[3] + BarnBPZ ) * CFrame.Angles(0, (math.pi/2)*( v[4] - 2 ), 0)
- AdjustColor( newObject, BrickColor.new(CatalogModule.CropConfig[newName].Death) )
- if( CatalogModule.CropConfig[newName].Mature )then
- AdjustMatureVis(newObject, false)
- end
- end
- AdjustPosition( newObject, game.ServerStorage[ IntegerForNameIndex[ v[1] ] ] )
- local newPlot = game.ServerStorage.CropPlot:clone() --We have to make the crop base
- newPlot.Base.CFrame = CFrame.new(-1*v[2] + BarnBPX, 1.3, -1*v[3] + BarnBPZ)
- newPlot.Parent = newObject
- addTag(newObject, playerName)
- else
- local newObject = game.ServerStorage[ IntegerForNameIndex[ v[1] ] ]:clone()
- newObject.Parent = IntegerForLocationIndex[ v[1] ] or game.Workspace.StaticStorage
- newObject.Base.CFrame = CFrame.new( -1*v[2] + BarnBPX, newObject.Base.Size.Y/2 + 1.2,
- -1*v[3] + BarnBPZ ) * CFrame.Angles(0, (math.pi/2)*( v[4] - 2 ), 0)
- AdjustPosition( newObject, game.ServerStorage[ IntegerForNameIndex[ v[1] ] ] )
- if( v[5] )then
- newObject.Age.Value = v[5]
- elseif( IntegerForLocationIndex[ v[1] ] == GW.StaticStorage or
- IntegerForLocationIndex[ v[1] ] == GW.DynamicStorage )then
- addTag(newObject, playerName)
- end
- end
- end
- end
- end
- end
- end
- --Model Manipulation
- function AdjustModelPos( Model, Template, InternalName )
- for i, v in pairs(Model[InternalName]:GetChildren()) do
- if( v:IsA("BasePart") )then
- v.CFrame = Model.Base.CFrame:toWorldSpace(Template.Base.CFrame:toObjectSpace(Template[InternalName][v.Name].CFrame))
- end
- end
- end
- function AdjustPosition(Model, Template, InternalName) --Root Part Called Base
- for i, v in pairs(Model:GetChildren()) do
- if( v.Name ~= "Base" and ( v:IsA("BasePart") or v:IsA("UnionOperation") ) )then
- v.CFrame = Model.Base.CFrame:toWorldSpace(Template.Base.CFrame:toObjectSpace(Template[v.Name].CFrame))
- elseif( v:IsA("Model") )then
- AdjustModelPos( Model, Template, v.Name )
- end
- end
- end
- --Plant Stuff
- function AdjustColor(Model, Color)
- for i, v in pairs(Model:getChildren()) do
- if( v:IsA("Part") or v:IsA("UnionOperation") )then
- v.BrickColor = Color
- --elseif( v:IsA("Model") and v.Name ~= "CropPlot" )then --Mature does it itself
- -- AdjustColor(v, Color)
- end
- end
- end
- function AdjustMatureVis(Model, Visible)
- local Trans = ( Visible and 0 ) or 1
- for _, v in pairs(Model.Mature:getChildren())do
- if( v:IsA("Part") )then
- v.Transparency = Trans
- end
- end
- end
- --Actual code for when does happen stuff
- local safe = true --Set to false after loading is complete!
- BarnSetupFunction = Instance.new("RemoteFunction")
- BarnSetupFunction.Name = "SetupBarn" --We messed up the naming :'(
- BarnSetupFunction.OnServerInvoke = function( Player )
- while( safe )do wait(1) end
- safe = true
- local Barn = nil
- for i, v in pairs(game.Workspace.BarnStorage:GetChildren())do
- if( not v:findFirstChild("Owner") )then
- Barn = v
- break
- end
- end
- if( not Barn or Player.Barn.Value ~= nil and Player.Parent ~= nil )then safe = false; return false; end --One last check
- Player.Barn.Value = Barn
- local Owner = Instance.new("StringValue") --Do this first to avoid other people stealing your barn
- Owner.Name = "Owner"
- Owner.Parent = Barn
- local good = pcall( function()
- local playerData = CurrentPlayerData[ Player.userId ]
- if( playerData[4][1] == nil )then --Client doesn't have anything to load
- local region = ConvertRegionToJSON( getRegionContents( Barn.Base ), Barn )
- SaveRegion( Player, region )
- --RegionDataStore:SetAsync( "REGION_" .. Player.userId .. "_1", ConvertRegionToJSON( region, Barn ) )
- --1playerData[4][1] = "REGION_" .. Player.userId .. "_1"
- else --They are loading a past region
- local region = getRegionContents( Barn.Base )
- for _, v in pairs(region)do
- v:Destroy()
- end
- --print( playerData[4][1] )
- --print( RegionDataStore:GetAsync( playerData[4][1] ) )
- --DeployRegionFromJSON( RegionDataStore:GetAsync( playerData[4][1] ), Barn, Player.Name )
- DeployRegionFromJSON( LoadRegion( Player ), Barn, Player.Name )
- end
- for _, v in pairs(playerData[2])do --Load the people able to use the barn
- local newPlayer = Instance.new("StringValue", Barn.Control.Players)
- newPlayer.Name = string.lower(v) --Makes the names not case sensitive. See the barn control script
- newPlayer.Value = v
- end
- if( not Barn.Control.Players:findFirstChild( string.lower(Player.Name) ) )then--We want the owner to be able to use the barn!
- local newPlayer = Instance.new("StringValue", Barn.Control.Players)
- newPlayer.Name = string.lower(Player.Name) --Makes the names not case sensitive. See the barn control script
- newPlayer.Value = Player.Name
- end
- for k, v in pairs(playerData[3])do --Load the resources saved in the barn
- if( Barn.Control.Resources:findFirstChild(k) )then --Resources come and go; we don't wanna break anything
- Barn.Control.Resources[k].Value = v
- end
- end
- Owner.Value = Player.Name --Do this last to avoid autosave unleashing evil
- end)
- if( not good )then
- print("ERROR SETTING UP BARN")
- Player.Barn.Value = nil
- Owner:destroy()
- safe = false
- return false
- else
- safe = false
- return true
- end
- --safe = false
- --return true --Everything Worked!
- end
- BarnSetupFunction.Parent = game.ReplicatedStorage
- game.Players.PlayerAdded:connect( function( newPlayer )
- local good = pcall( function() --We have to load the player data so we can do stuff with it later
- local currentData = loadPlayerData( newPlayer )
- currentData[1] = newPlayer.Name
- CurrentPlayerData[ newPlayer.userId ] = currentData
- end)
- if( not good ) then newPlayer:Kick("Data Loading Issue, Please Try Again") end
- end)
- game.Players.PlayerRemoving:connect( function( oldPlayer ) pcall( function() --We have to save everything and stuff
- if( oldPlayer:findFirstChild("Barn") and oldPlayer.Barn.Value ~= nil )then
- local Barn = oldPlayer.Barn.Value
- Barn:WaitForChild("Owner")
- while( Barn:findFirstChild("Owner") and Barn.Owner.Value == "" )do wait() end
- while( safe )do wait(1) end
- safe = true
- if( Barn:findFirstChild("Owner") and Barn.Owner.Value == oldPlayer.Name )then --Make sure a player owns the barn
- pcall( function()
- local PlayerData = CurrentPlayerData[ oldPlayer.userId ]
- if( PlayerData )then --We found where to save the region!
- Barn.Owner.Value = "" --Prevent evil autosave stuff
- local region = getRegionContents( Barn.Base )
- SaveRegion( oldPlayer, ConvertRegionToJSON(region, Barn) )
- updatePlayerData( oldPlayer, Barn )
- --Refresh Barn
- for _, v in pairs( Barn.Control.Players:getChildren() )do
- v:Destroy()
- end
- for _, v in pairs( Barn.Control.Resources:getChildren() )do
- v.Value = 0
- end
- Barn.Owner:Destroy()
- --Now restore the region
- for _,v in pairs(region)do
- v:Destroy()
- end
- DeployRegionFromJSON( DefaultRegions[tonumber( string.sub(Barn.Name, 5) )], Barn )
- end
- end)
- end
- safe = false
- end
- end) end)
- game.OnClose = function() --We got to save the stuffs
- for _, Barn in pairs(game.Workspace.BarnStorage:GetChildren())do
- if( Barn:findFirstChild("Owner") and game.Players:FindFirstChild(Barn.Owner.Value) )then --Make sure a player owns the barn
- local Player = game.Players:FindFirstChild(Barn.Owner.Value)
- local playerData = CurrentPlayerData[ Player.userId ]
- if( playerData and playerData[4][1] )then --We found where to save the region!
- local region = getRegionContents( Barn.Base )
- SaveRegion( Player, ConvertRegionToJSON(region, Barn) )
- --pcall( function()
- -- RegionDataStore:SetAsync( playerData[4][1], ConvertRegionToJSON( region, Barn ) )
- --end )
- updatePlayerData( Player, Barn )
- end
- end
- end
- end
- game.ReplicatedStorage:WaitForChild("ResetFarmCommand").OnServerEvent:connect(function(Player, confirm, p)
- if( confirm and Player and Player == p and Player:findFirstChild("Barn") and Player.Barn.Value )then --safety first
- local Barn = Player.Barn.Value
- if( Barn:findFirstChild("Owner") and Barn.Owner.Value == Player.Name )then --Make sure a player owns the barn
- local region = getRegionContents( Barn.Base )
- for _,v in pairs(region)do
- v:Destroy()
- end
- DeployRegionFromJSON( DefaultRegions[tonumber( string.sub(Barn.Name, 5) )], Barn )
- end
- end
- end)
- script.Parent.DecorDeployed.Event:connect( function() --Everything that runs after the game is ready
- --wait(1)
- for _, v in pairs(game.Workspace.BarnStorage:GetChildren())do
- local region = getRegionContents( v.Base )
- --print( #region )
- --print( tonumber( string.sub(v.Name, 5) ) )
- DefaultRegions[ tonumber( string.sub(v.Name, 5) ) ] = ConvertRegionToJSON( region, v ) --old, but okay because we lie about JSON
- --for _, o in pairs(region)do --For Testing
- -- o:Destroy()
- --end
- end
- --wait(1)
- --for _, v in pairs(game.Workspace.BarnStorage:GetChildren())do --Second half of the testing
- --print( DefaultRegions[tonumber( string.sub(v.Name, 5) )] )
- --DeployRegionFromJSON( DefaultRegions[ tonumber( string.sub(v.Name, 5) ) ], v )
- --end
- safe = false --I know opposite of what it means
- while wait(1) do --Using other wait
- print("AUTOSAVE")
- for _, Barn in pairs(game.Workspace.BarnStorage:GetChildren())do
- while( safe )do wait(1) end
- safe = true
- if( Barn:findFirstChild("Owner") )then --Make sure a player owns the barn
- if( game.Players:FindFirstChild(Barn.Owner.Value) )then
- local Player = game.Players:FindFirstChild(Barn.Owner.Value)
- local playerData = CurrentPlayerData[ Player.userId ]
- if( playerData and playerData[4][1] )then --We found where to save the region!
- local region = ConvertRegionToJSON( getRegionContents( Barn.Base ), Barn )
- SaveRegion( Player, region )
- --RegionDataStore:SetAsync( playerData[4][1], ConvertRegionToJSON( region, Barn ) )
- updatePlayerData( Player, Barn )
- end
- else
- --wait(5)
- local good = pcall( function()
- if( Barn:findFirstChild("Owner") and Barn.Owner.Value ~= "" and not game.Players:FindFirstChild(Barn.Owner.Value) )then
- print("Broken Barn Found")
- local region = getRegionContents( Barn.Base )
- for _, o in pairs(region)do --For Testing
- o:Destroy()
- end
- DeployRegionFromJSON( DefaultRegions[tonumber( string.sub(Barn.Name, 5) )], Barn )
- for _, v in pairs( Barn.Control.Players:getChildren() )do
- v:Destroy()
- end
- for _, v in pairs( Barn.Control.Resources:getChildren() )do
- v.Value = 0
- end
- Barn.Owner:Destroy()
- end
- end )
- if( not good )then
- print("ERROR REMOVING BROKEN BARN")
- end
- end
- end
- safe = false
- wait(30) --Slows down saving
- end
- end
- end )
Add Comment
Please, Sign In to add comment