mirror of
https://github.com/cave-story-randomizer/cave-story-randomizer
synced 2024-11-22 14:53:00 +00:00
fixed issue with 100% and Best Ending producing the same results with the same seed.
also made it more efficient.
This commit is contained in:
parent
0a12d846c5
commit
67bf6706fc
|
@ -67,7 +67,7 @@ function C:randomize()
|
||||||
|
|
||||||
self:_logSettings()
|
self:_logSettings()
|
||||||
|
|
||||||
local seed = self:_seedRngesus()
|
local seed = self:_seedRngesus(self.obj) -- append obj string in order to shuffle differently depending on the objective
|
||||||
self:_updateSharecode(seed)
|
self:_updateSharecode(seed)
|
||||||
|
|
||||||
local tscFiles = self:_createTscFiles(dirStage)
|
local tscFiles = self:_createTscFiles(dirStage)
|
||||||
|
@ -117,9 +117,9 @@ function C:_mountDirectory(path)
|
||||||
return true, dirStage
|
return true, dirStage
|
||||||
end
|
end
|
||||||
|
|
||||||
function C:_seedRngesus()
|
function C:_seedRngesus(suffix)
|
||||||
local seedstring = self.customseed or tostring(os.time())
|
local seedstring = self.customseed or tostring(os.time())
|
||||||
local seed = ld.encode('string', 'hex', ld.hash('sha256', seedstring))
|
local seed = ld.encode('string', 'hex', ld.hash('sha256', seedstring .. suffix))
|
||||||
local s1 = tonumber(seed:sub(-8, -1), 16) -- first 32 bits (from right)
|
local s1 = tonumber(seed:sub(-8, -1), 16) -- first 32 bits (from right)
|
||||||
local s2 = tonumber(seed:sub(-16, -9), 16) -- next 32 bits
|
local s2 = tonumber(seed:sub(-16, -9), 16) -- next 32 bits
|
||||||
|
|
||||||
|
@ -157,14 +157,6 @@ function C:getObjective()
|
||||||
end
|
end
|
||||||
|
|
||||||
function C:_shuffleItems(tscFiles)
|
function C:_shuffleItems(tscFiles)
|
||||||
-- ensure unique randomization between settings with the same seed
|
|
||||||
local function shuffle(t)
|
|
||||||
if self.obj == "objBadEnd" then return _.shuffle(_.shuffle(t)) end
|
|
||||||
if self.obj == "objNormalEnd" then return _.shuffle(_.shuffle(_.shuffle(t))) end
|
|
||||||
if self.obj == "objAllBosses" then return _.shuffle(_.shuffle(_.shuffle(_.shuffle(t)))) end
|
|
||||||
return _.shuffle(t)
|
|
||||||
end
|
|
||||||
|
|
||||||
local obj = self:getObjective()[1]
|
local obj = self:getObjective()[1]
|
||||||
obj.name = obj.name .. (", %s"):format(self.worldGraph.spawn)
|
obj.name = obj.name .. (", %s"):format(self.worldGraph.spawn)
|
||||||
obj.script = obj.script .. self.worldGraph:getSpawnScript()
|
obj.script = obj.script .. self.worldGraph:getSpawnScript()
|
||||||
|
@ -175,10 +167,10 @@ function C:_shuffleItems(tscFiles)
|
||||||
|
|
||||||
if self.worldGraph:StartPoint() then
|
if self.worldGraph:StartPoint() then
|
||||||
-- first, fill one of the first cave spots with a weapon that can break blocks
|
-- first, fill one of the first cave spots with a weapon that can break blocks
|
||||||
_.shuffle(self.worldGraph:getFirstCaveSpots())[1]:setItem(shuffle(self.itemDeck:getItemsByAttribute("weaponSN"))[1])
|
_.shuffle(self.worldGraph:getFirstCaveSpots())[1]:setItem(_.shuffle(self.itemDeck:getItemsByAttribute("weaponSN"))[1])
|
||||||
elseif self.worldGraph:Camp() then
|
elseif self.worldGraph:Camp() then
|
||||||
-- give Dr. Gero a strong weapon... you'll need it
|
-- give Dr. Gero a strong weapon... you'll need it
|
||||||
self.worldGraph:getCamp()[1]:setItem(shuffle(self.itemDeck:getItemsByAttribute("weaponStrong"))[1])
|
self.worldGraph:getCamp()[1]:setItem(_.shuffle(self.itemDeck:getItemsByAttribute("weaponStrong"))[1])
|
||||||
-- and some HP once you fight your way past the first few enemies
|
-- and some HP once you fight your way past the first few enemies
|
||||||
self.worldGraph:getCamp()[2]:setItem(self.itemDeck:getByKey("capsule5G"))
|
self.worldGraph:getCamp()[2]:setItem(self.itemDeck:getByKey("capsule5G"))
|
||||||
end
|
end
|
||||||
|
@ -188,27 +180,27 @@ function C:_shuffleItems(tscFiles)
|
||||||
self.worldGraph:getMALCO()[1]:setItem(self.itemDeck:getByKey("bomb"))
|
self.worldGraph:getMALCO()[1]:setItem(self.itemDeck:getByKey("bomb"))
|
||||||
end
|
end
|
||||||
|
|
||||||
local mandatory = _.compact(shuffle(self.itemDeck:getMandatoryItems(true)))
|
local mandatory = _.compact(_.shuffle(self.itemDeck:getMandatoryItems(true)))
|
||||||
local optional = _.compact(shuffle(self.itemDeck:getOptionalItems(true)))
|
local optional = _.compact(_.shuffle(self.itemDeck:getOptionalItems(true)))
|
||||||
local puppies = _.compact(shuffle(self.itemDeck:getItemsByAttribute("puppy")))
|
local puppies = _.compact(_.shuffle(self.itemDeck:getItemsByAttribute("puppy")))
|
||||||
|
|
||||||
if not self.puppy then
|
if not self.puppy then
|
||||||
-- then fill puppies, for normal gameplay
|
-- then fill puppies, for normal gameplay
|
||||||
self:_fastFillItems(puppies, shuffle(self.worldGraph:getPuppySpots()))
|
self:_fastFillItems(puppies, _.shuffle(self.worldGraph:getPuppySpots()))
|
||||||
else
|
else
|
||||||
-- for puppysanity, shuffle puppies in with the mandatory items
|
-- for puppysanity, shuffle puppies in with the mandatory items
|
||||||
mandatory = shuffle(_.append(mandatory, puppies))
|
mandatory = _.shuffle(_.append(mandatory, puppies))
|
||||||
puppies = {}
|
puppies = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- next fill hell chests, which cannot have mandatory items
|
-- next fill hell chests, which cannot have mandatory items
|
||||||
self:_fastFillItems(optional, shuffle(self.worldGraph:getHellSpots()))
|
self:_fastFillItems(optional, _.shuffle(self.worldGraph:getHellSpots()))
|
||||||
|
|
||||||
-- add map system AFTER filling hell chests so that it gets placed somewhere accessible in every objective
|
-- add map system AFTER filling hell chests so that it gets placed somewhere accessible in every objective
|
||||||
optional = _.append(optional, self.itemDeck:getByKey("mapSystem"))
|
optional = _.append(optional, self.itemDeck:getByKey("mapSystem"))
|
||||||
|
|
||||||
-- place mandatory items with assume fill
|
-- place mandatory items with assume fill
|
||||||
self:_fillItems(mandatory, shuffle(_.reverse(self.worldGraph:getEmptyLocations())))
|
self:_fillItems(mandatory, _.shuffle(_.reverse(self.worldGraph:getEmptyLocations())))
|
||||||
|
|
||||||
-- place optional items with a simple random fill
|
-- place optional items with a simple random fill
|
||||||
local opt = #optional
|
local opt = #optional
|
||||||
|
@ -216,7 +208,7 @@ function C:_shuffleItems(tscFiles)
|
||||||
if opt > loc then
|
if opt > loc then
|
||||||
logWarning(("Trying to fill more optional items than there are locations! Items: %d Locations: %d"):format(opt, loc))
|
logWarning(("Trying to fill more optional items than there are locations! Items: %d Locations: %d"):format(opt, loc))
|
||||||
end
|
end
|
||||||
self:_fastFillItems(optional, shuffle(self.worldGraph:getEmptyLocations()))
|
self:_fastFillItems(optional, _.shuffle(self.worldGraph:getEmptyLocations()))
|
||||||
self:_generateHints()
|
self:_generateHints()
|
||||||
|
|
||||||
if tscFiles ~= nil then
|
if tscFiles ~= nil then
|
||||||
|
|
Loading…
Reference in a new issue