mirror of
https://github.com/cave-story-randomizer/cave-story-randomizer
synced 2024-11-12 18:02:52 +00:00
Merge pull request #164 from duncathan/completable
add completable logic
This commit is contained in:
commit
bbfa4e5661
8
.tscrc.json
Normal file
8
.tscrc.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"setup": {
|
||||
"looseChecking": {
|
||||
"events": true,
|
||||
"arguments": true
|
||||
}
|
||||
}
|
||||
}
|
0
pre-edited-cs/data/tsc_def.txt
Normal file
0
pre-edited-cs/data/tsc_def.txt
Normal file
|
@ -413,6 +413,29 @@ local function _itemData()
|
|||
obj100Percent = objective("100%", "<FL+6004<IT+0005")
|
||||
}
|
||||
|
||||
local function initializeHints(item)
|
||||
local hintArray = {
|
||||
--mandatory = {"a required item"},
|
||||
puppy = {"a puppy", "a living being"},
|
||||
--helpful = {"a helpful item"},
|
||||
--useless = {"a useless item"},
|
||||
weapon = {"a weapon"},
|
||||
--weaponSN = {"a weapon that breaks blocks"},
|
||||
--weaponStrong = {"a strong weapon"},
|
||||
flight = {"a method of flight", "flight"},
|
||||
missileLauncher = {"a Missile upgrade"}
|
||||
}
|
||||
|
||||
item.hints = item.hints or {} -- initialize item's hints array if not already
|
||||
|
||||
-- loop through item's attributes and add any matching hints from the hintArray table
|
||||
for k,v in ipairs(item.attributes) do
|
||||
for k2,v2 in ipairs(hintArray[v] or {}) do
|
||||
table.insert(item.hints, v2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local array = {}
|
||||
for k, t in pairs(data) do
|
||||
t.key = k
|
||||
|
@ -427,29 +450,6 @@ local function _itemData()
|
|||
return array
|
||||
end
|
||||
|
||||
local function initializeHints(item)
|
||||
local hintArray = {
|
||||
--mandatory = {"a required item"},
|
||||
puppy = {"a puppy", "a living being"},
|
||||
--helpful = {"a helpful item"},
|
||||
--useless = {"a useless item"},
|
||||
weapon = {"a weapon"},
|
||||
--weaponSN = {"a weapon that breaks blocks"},
|
||||
--weaponStrong = {"a strong weapon"},
|
||||
flight = {"a method of flight", "flight"},
|
||||
missileLauncher = {"a Missile upgrade"}
|
||||
}
|
||||
|
||||
item.hints = item.hints or {} -- initialize item's hints array if not already
|
||||
|
||||
-- loop through item's attributes and add any matching hints from the hintArray table
|
||||
for k,v in ipairs(t.attributes) do
|
||||
for k2,v2 in ipairs(hintArray[v] or {}) do
|
||||
table.insert(t.hints, v2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local C = Class:extend()
|
||||
|
||||
function C:new()
|
||||
|
|
|
@ -28,6 +28,7 @@ end
|
|||
|
||||
function C:setItem(item)
|
||||
item.placed = true
|
||||
item.location_name = self.name
|
||||
self.item = item
|
||||
end
|
||||
|
||||
|
|
|
@ -179,7 +179,9 @@ local cues = {
|
|||
|
||||
local music = Class:extend()
|
||||
function music:new()
|
||||
self.vanillaEnabled = true
|
||||
self.betaEnabled = false
|
||||
self.secretEnabled = false
|
||||
self.songs = songs
|
||||
self.cues = cues
|
||||
self.flavor = "Shuffle"
|
||||
|
|
|
@ -456,9 +456,7 @@ function endgame:new(worldGraph)
|
|||
self.locations.hellB1.getPrebuiltHint = prebuilt
|
||||
self.locations.hellB3.getPrebuiltHint = prebuilt
|
||||
|
||||
self.requirements = function(self, items)
|
||||
return _has(items, "eventSue") and _has(items, "ironBond") and self.world.regions.lastCave:canAccess(items)
|
||||
end
|
||||
self.requirements = function(self, items) return false end -- just pretend you never get here
|
||||
end
|
||||
|
||||
local hintRegion = Region:extend()
|
||||
|
@ -560,6 +558,40 @@ function worldGraph:getSpawnScript()
|
|||
if self:Camp() then return baseStartScript .. "<FL+6202<TRA0040:0094:0014:0009" end
|
||||
end
|
||||
|
||||
function worldGraph:canBeatGame(items, obj)
|
||||
if obj == "objBadEnd" then
|
||||
|
||||
end
|
||||
local function normalReqs(self, items) return _has(items, "eventRocket") and _has(items, "eventSue") and self.regions.plantation:canAccess(items) end
|
||||
if obj == "objNormalEnd" then return normalReqs(self, items) end
|
||||
|
||||
local function bestReqs(self, items) return normalReqs(self, items) and _has(items, "ironBond") and _count(items, "booster", 2) end
|
||||
if obj == "objBestEnd" then return bestReqs(self, items) end
|
||||
|
||||
local function bossReqs(self, items)
|
||||
if not (bestReqs(self, items) and _has(items, "weaponBoss")) then return false end
|
||||
-- Igor, Balrog 1, Balrog 3, Core, Sisters
|
||||
if not (_has(items, "eventSue") and _has(items, "eventToroko") and _has(items, "eventCore")) then return false end
|
||||
-- Balrog 2, Balfrog
|
||||
if not (_has(items, "rustyKey") and _has(items, "gumKey") and self.regions.grasstownEast:canAccess(items)) then return false end
|
||||
-- Curly, Omega
|
||||
if not (self.regions.upperSandZone:canAccess(items)) then return false end
|
||||
-- Toroko+
|
||||
if not self.regions.lowerSandZone.king:canAccess(items) then return false end
|
||||
-- Puu Black, Monster X
|
||||
if not (self.regions.labyrinthW:canAccess(items) and _has(items, "clinicKey")) then return false end
|
||||
-- Ironhead
|
||||
if not self.regions.waterway:canAccess(items) then return false end
|
||||
-- Ma Pignon
|
||||
if not self.regions.mimigaVillage.maPignon:canAccess(items) then return false end
|
||||
-- Remaining bosses are all covered by the normal requirements
|
||||
return true
|
||||
end
|
||||
if obj == "objAllBosses" then return bossReqs(self, items) end
|
||||
return false -- I don't actually think the check below works as intended, false is sufficient for now since 100% and completable logic should be mutually exclusive anyway
|
||||
--return #items > #self:getLocations() - #self:getHintLocations() - 2 -- removing ANY items (besides in hell) from 100% makes a seed uncompletable
|
||||
end
|
||||
|
||||
function worldGraph:getLocations()
|
||||
local locations = {}
|
||||
for key, region in pairs(self.regions) do
|
||||
|
@ -631,7 +663,7 @@ function worldGraph:getFilledLocations(realOnly)
|
|||
local locations = {}
|
||||
for key, region in pairs(self.regions) do
|
||||
for k, location in pairs(region:getFilledLocations()) do
|
||||
if not realOnly or not (_.find(location.item.attributes,"abstract") or _.find(location.item.attributes,"mrLittle")) then table.insert(locations, location) end
|
||||
if not realOnly or not _.find(location.item.attributes,"abstract") then table.insert(locations, location) end
|
||||
end
|
||||
end
|
||||
return locations
|
||||
|
@ -662,9 +694,11 @@ function worldGraph:writeItems(tscFiles)
|
|||
self.hintregion:writeItems(tscFiles)
|
||||
end
|
||||
|
||||
function worldGraph:collect(preCollectedItems)
|
||||
local collected = _.clone(preCollectedItems) or {}
|
||||
local availableLocations = self:getFilledLocations()
|
||||
function worldGraph:collect(preCollectedItems, locations, singleSphere)
|
||||
local collected = _.clone(preCollectedItems, singleSphere) or {}
|
||||
local availableLocations = locations or self:getFilledLocations()
|
||||
|
||||
local inventory = (singleSphere and preCollectedItems) or collected
|
||||
|
||||
local foundItems = 0
|
||||
repeat
|
||||
|
@ -674,7 +708,7 @@ function worldGraph:collect(preCollectedItems)
|
|||
local j, n = 1, #availableLocations
|
||||
for i = 1, n do
|
||||
local location = availableLocations[i]
|
||||
if location:canAccess(collected) then
|
||||
if location:canAccess(inventory) then
|
||||
table.insert(collected, location.item)
|
||||
foundItems = foundItems + 1
|
||||
availableLocations[i] = nil
|
||||
|
@ -691,7 +725,7 @@ function worldGraph:collect(preCollectedItems)
|
|||
--[[local s = "Collected items: "
|
||||
for k,v in ipairs(collected) do s = s .. v.name .. ", " end
|
||||
logDebug(s)]]
|
||||
return collected
|
||||
return collected, availableLocations
|
||||
end
|
||||
|
||||
function worldGraph.locationsArray(locations)
|
||||
|
|
10
src/log.lua
10
src/log.lua
|
@ -1,4 +1,4 @@
|
|||
local LOG_LEVEL, _logCounts, _logLines = 4, nil, nil
|
||||
local LOG_LEVEL, _logCounts, _logLines = 6, nil, nil
|
||||
local function _log(level, prefix, text, ...)
|
||||
if LOG_LEVEL >= level then
|
||||
local text = prefix .. text
|
||||
|
@ -13,8 +13,10 @@ function logError(...) _log(1, 'ERROR: ', ...) end
|
|||
function logWarning(...) _log(2, 'WARNING: ', ...) end
|
||||
function logNotice(...) _log(3, 'NOTICE: ', ...) end
|
||||
function logSpoiler(...) _log(4, 'SPOILER: ', ...) end
|
||||
function logInfo(...) _log(5, 'INFO: ', ...) end
|
||||
function logDebug(...) _log(6, 'DEBUG: ', ...) end
|
||||
function logSphere(...) _log(5, 'SPHERE: ', ...) end
|
||||
function logRoute(...) _log(6, 'ROUTE: ', ...) end
|
||||
function logInfo(...) _log(7, 'INFO: ', ...) end
|
||||
function logDebug(...) _log(8, 'DEBUG: ', ...) end
|
||||
function countLogWarningsAndErrors()
|
||||
return _logCounts[2], _logCounts[1]
|
||||
end
|
||||
|
@ -22,7 +24,7 @@ function getLogText()
|
|||
return table.concat(_logLines, "\r\n")
|
||||
end
|
||||
function resetLog()
|
||||
_logCounts = {0, 0, 0, 0, 0, 0}
|
||||
_logCounts = {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
_logLines = {}
|
||||
end
|
||||
resetLog()
|
|
@ -47,6 +47,8 @@ function C:new()
|
|||
self.sharecode = ""
|
||||
self.mychar = ""
|
||||
self.shuffleMusic = false
|
||||
self.completableLogic = true
|
||||
self.spheres = {}
|
||||
end
|
||||
|
||||
function C:setPath(path)
|
||||
|
@ -76,6 +78,9 @@ function C:randomize()
|
|||
self:_generateHash()
|
||||
if self.shuffleMusic then self.music:shuffleMusic(tscFiles) end
|
||||
|
||||
self:_logSpheres()
|
||||
self:_generateRoute()
|
||||
|
||||
self:_writeModifiedData(tscFiles)
|
||||
self:_writePlaintext(tscFiles)
|
||||
self:_writeLog()
|
||||
|
@ -194,7 +199,9 @@ function C:_shuffleItems(tscFiles)
|
|||
end
|
||||
|
||||
-- next fill hell chests, which cannot have mandatory items
|
||||
self:_fastFillItems(optional, _.shuffle(self.worldGraph:getHellSpots()))
|
||||
if not self.completableLogic then
|
||||
self:_fastFillItems(optional, _.shuffle(self.worldGraph:getHellSpots()))
|
||||
end
|
||||
|
||||
-- add map system AFTER filling hell chests so that it gets placed somewhere accessible in every objective
|
||||
optional = _.append(optional, self.itemDeck:getByKey("mapSystem"))
|
||||
|
@ -225,8 +232,15 @@ function C:_fillItems(items, locations)
|
|||
repeat
|
||||
local item = _.pop(itemsLeft)
|
||||
local assumed = self.worldGraph:collect(itemsLeft)
|
||||
|
||||
local filter = function(k,v) return not v:hasItem() and v:canAccess(assumed) end
|
||||
|
||||
if self.completableLogic and self.worldGraph:canBeatGame(assumed, self.obj) then
|
||||
filter = function(k,v) return not v:hasItem() end
|
||||
end
|
||||
|
||||
local fillable = _.filter(locations, filter)
|
||||
|
||||
local fillable = _.filter(locations, function(k,v) return not v:hasItem() and v:canAccess(assumed) end)
|
||||
if #fillable > 0 then
|
||||
logDebug(("Placing %s at %s"):format(item.name, fillable[1].name))
|
||||
fillable[1]:setItem(item)
|
||||
|
@ -246,6 +260,60 @@ function C:_fastFillItems(items, locations)
|
|||
end
|
||||
end
|
||||
|
||||
function C:_analyzeSpheres(forceUpdate)
|
||||
if not forceUpdate and #self.spheres > 0 then
|
||||
return self.spheres
|
||||
end
|
||||
self.spheres = {}
|
||||
|
||||
local items = {}
|
||||
local locations
|
||||
|
||||
repeat
|
||||
local collected
|
||||
collected, locations = self.worldGraph:collect(items, locations, true)
|
||||
local sphereItems = _.difference(collected, items)
|
||||
items = collected
|
||||
|
||||
local sphere = {}
|
||||
for k,v in pairs(sphereItems) do
|
||||
table.insert(sphere, v)
|
||||
end
|
||||
if #sphere == 0 then break end
|
||||
|
||||
table.insert(self.spheres, sphere)
|
||||
until false
|
||||
if self.obj ~= "objBadEnd" and self.obj ~= "objNormalEnd" then
|
||||
-- add the hell sphere at the very end, shh it works trust me
|
||||
local sphere = {}
|
||||
table.insert(sphere, self.worldGraph.regions.endgame.locations.hellB1.item)
|
||||
table.insert(sphere, self.worldGraph.regions.endgame.locations.hellB3.item)
|
||||
table.insert(self.spheres, sphere)
|
||||
end
|
||||
|
||||
return self.spheres
|
||||
end
|
||||
|
||||
function C:_logSpheres()
|
||||
local total = 0
|
||||
for i,sphere in ipairs(self:_analyzeSpheres()) do
|
||||
logSphere(("Sphere %i"):format(i))
|
||||
for i2,item in ipairs(sphere) do
|
||||
if not _.contains(item.attributes, "abstract") then
|
||||
total = total + 1
|
||||
end
|
||||
if not _.contains(item.attributes, "objective") then
|
||||
logSphere(("\t %s: %s"):format(item.location_name, item.name))
|
||||
end
|
||||
end
|
||||
end
|
||||
logSphere(("Maximum items to collect: %i"):format(total))
|
||||
end
|
||||
|
||||
function C:_generateRoute()
|
||||
return
|
||||
end
|
||||
|
||||
function C:_generateHints()
|
||||
local toHint = _.shuffle(self.worldGraph:getHintableLocations(self.obj))
|
||||
for k, hintLocation in ipairs(_.shuffle(self.worldGraph:getHintLocations())) do
|
||||
|
@ -356,17 +424,19 @@ function C:_updateSettings()
|
|||
Settings.settings.musicBeta = self.music.betaEnabled
|
||||
Settings.settings.musicFlavor = self.music.flavor
|
||||
Settings.settings.noFallingBlocks = self.worldGraph.noFallingBlocks
|
||||
Settings.settings.completableLogic = self.completableLogic
|
||||
Settings:update()
|
||||
end
|
||||
|
||||
function C:_updateSharecode(seed)
|
||||
local settings = 0 -- 0b00000000
|
||||
local settings = 0 -- 0b0000000000000000
|
||||
-- P: single bit used for puppysanity
|
||||
-- O: three bits used for objective
|
||||
-- S: three bits used for spawn location
|
||||
-- B: single bit used for sequence breaks
|
||||
-- F: single bit used for falling blocks in Hell
|
||||
-- 0bFBSSSOOOP
|
||||
-- C: single bit used for completeable logic
|
||||
-- 0b000000CFBSSSOOOP
|
||||
|
||||
-- bitshift intervals
|
||||
local obj = 1
|
||||
|
@ -374,6 +444,7 @@ function C:_updateSharecode(seed)
|
|||
local spn = 4
|
||||
local brk = 7
|
||||
local nfb = 8
|
||||
local cpl = 9
|
||||
|
||||
if self.obj == "objBadEnd" then
|
||||
settings = bit.bor(settings, bit.blshift(1, obj))
|
||||
|
@ -410,6 +481,9 @@ function C:_updateSharecode(seed)
|
|||
if self.worldGraph.noFallingBlocks then
|
||||
settings = bit.bor(settings, bit.blshift(1, nfb))
|
||||
end
|
||||
if self.completableLogic then
|
||||
settings = bit.bor(settings, bit.blshift(1, cpl))
|
||||
end
|
||||
|
||||
if #seed < 20 then
|
||||
seed = seed .. (" "):rep(20-#seed)
|
||||
|
|
|
@ -37,9 +37,12 @@ function C:getDefaults()
|
|||
rocket = true
|
||||
},
|
||||
musicShuffle = false,
|
||||
musicVanilla = true,
|
||||
musicBeta = false,
|
||||
musicSecret = false,
|
||||
musicFlavor = "Shuffle",
|
||||
noFallingBlocks = false,
|
||||
completableLogic = false,
|
||||
csversion = 0
|
||||
}
|
||||
end
|
||||
|
@ -68,9 +71,12 @@ function C:serialize()
|
|||
line = line .. tab .. ("seqbreaks = %s,\r\n"):format(self.settings.seqbreaks)
|
||||
line = line .. tab .. ("dboosts = %s,\r\n"):format(dboost)
|
||||
line = line .. tab .. ("musicShuffle = %s,\r\n"):format(self.settings.musicShuffle)
|
||||
line = line .. tab .. ("musicVanilla = %s,\r\n"):format(self.settings.musicVanilla)
|
||||
line = line .. tab .. ("musicBeta = %s,\r\n"):format(self.settings.musicBeta)
|
||||
line = line .. tab .. ("musicSecret = %s,\r\n"):format(self.settings.musicSecret)
|
||||
line = line .. tab .. ("musicFlavor = %q,\r\n"):format(self.settings.musicFlavor)
|
||||
line = line .. tab .. ("noFallingBlocks = %s,\r\n"):format(self.settings.noFallingBlocks)
|
||||
line = line .. tab .. ("completableLogic = %s,\r\n"):format(self.settings.completableLogic)
|
||||
line = line .. tab .. ("csversion = %s,\r\n"):format(self.settings.csversion)
|
||||
|
||||
return line .. "}"
|
||||
|
|
|
@ -28,8 +28,9 @@ function C:setup()
|
|||
self:loadMyChar(Settings.settings.mychar)
|
||||
self:loadSpawn(Settings.settings.spawn)
|
||||
self:loadSeqSettings(Settings.settings.seqbreaks, Settings.settings.dboosts)
|
||||
self:loadMusicSettings(Settings.settings.musicShuffle, Settings.settings.musicBeta, Settings.settings.musicFlavor)
|
||||
self:loadMusicSettings(Settings.settings.musicShuffle, Settings.settings.musicFlavor, Settings.settings.musicVanilla, Settings.settings.musicBeta, Settings.settings.musicSecret)
|
||||
self:loadNoFallingBlocks(Settings.settings.noFallingBlocks)
|
||||
self:loadCompleteableLogic(Settings.settings.completableLogic)
|
||||
|
||||
background = lg.newImage('assets/background.png')
|
||||
self:draw()
|
||||
|
@ -86,28 +87,29 @@ function C:loadSeed(seed)
|
|||
end
|
||||
|
||||
function C:loadMyChar(mychar)
|
||||
local mc = music.mychar
|
||||
if type(mychar) == "number" then
|
||||
settings.mychar.index = mychar
|
||||
mc.index = mychar
|
||||
elseif mychar == "assets/myChar/Quote.bmp" then
|
||||
settings.mychar.index = 1
|
||||
mc.index = 1
|
||||
elseif mychar == "assets/myChar/Curly.bmp" then
|
||||
settings.mychar.index = 2
|
||||
mc.index = 2
|
||||
elseif mychar == "assets/myChar/Sue.bmp" then
|
||||
settings.mychar.index = 3
|
||||
mc.index = 3
|
||||
elseif mychar == "assets/myChar/Toroko.bmp" then
|
||||
settings.mychar.index = 4
|
||||
mc.index = 4
|
||||
elseif mychar == "assets/myChar/King.bmp" then
|
||||
settings.mychar.index = 5
|
||||
mc.index = 5
|
||||
elseif mychar == "assets/myChar/Chaco.bmp" then
|
||||
settings.mychar.index = 6
|
||||
mc.index = 6
|
||||
elseif mychar == "assets/myChar/Kanpachi.bmp" then
|
||||
settings.mychar.index = 7
|
||||
mc.index = 7
|
||||
elseif mychar == "assets/myChar/Misery.bmp" then
|
||||
settings.mychar.index = 8
|
||||
mc.index = 8
|
||||
elseif mychar == "assets/myChar/Frog.bmp" then
|
||||
settings.mychar.index = 9
|
||||
mc.index = 9
|
||||
end
|
||||
settings.mychar.value = "override"
|
||||
mc.value = "override"
|
||||
end
|
||||
|
||||
function C:loadSpawn(spawn)
|
||||
|
@ -135,9 +137,11 @@ function C:loadSeqSettings(breaks, seq)
|
|||
end
|
||||
end
|
||||
|
||||
function C:loadMusicSettings(shuffle, beta, flavor)
|
||||
settings.music.value = shuffle
|
||||
function C:loadMusicSettings(shuffle, flavor, cs, beta, secret)
|
||||
music.music.value = shuffle
|
||||
music.cavestory.value = cs
|
||||
music.beta.value = beta
|
||||
--music.secret.value = secret
|
||||
if flavor == "Shuffle" or flavor == 1 then
|
||||
music.shuffle.value = true
|
||||
music.random.value = false
|
||||
|
@ -159,6 +163,10 @@ function C:loadNoFallingBlocks(noFallingBlocks)
|
|||
settings.noFallingBlocks.value = noFallingBlocks
|
||||
end
|
||||
|
||||
function C:loadCompleteableLogic(completableLogic)
|
||||
settings.completable.value = not completableLogic
|
||||
end
|
||||
|
||||
layout.version.text = 'Cave Story Randomizer v' .. VERSION
|
||||
layout.author.text = 'by duncathan'
|
||||
layout.twitter.text = '(@duncathan_salt)'
|
||||
|
@ -178,14 +186,6 @@ end)
|
|||
|
||||
layout.footershru.text = 'Original randomizer by @shruuu'
|
||||
|
||||
music.panel.text = [[Shuffle: remap every song to a new song. For example, all instances of Mischievous Robot become Pulse. Songs may remap to themselves.
|
||||
|
||||
Random: remap every cue to a new song. For example, entering the Egg Corridor by any means plays Meltdown 2.
|
||||
|
||||
Chaos: remap every <CMU to a new song. For example, teleporting to the Egg Corridor plays Charge, but entering Egg Corridor from Cthulhu's Abode plays Run!
|
||||
|
||||
Beta music: include Wind Fortress, Halloween 2, People of the Root, Pier Walk, and Snoopy Cake in the potential songs. Only compatible with the included Doukutsu.exe - no other platforms.]]
|
||||
|
||||
layout.go:onPress(function()
|
||||
Randomizer:new()
|
||||
|
||||
|
@ -196,7 +196,7 @@ layout.go:onPress(function()
|
|||
|
||||
Randomizer.obj = settings.objective.value
|
||||
Randomizer.puppy = settings.puppy.value
|
||||
Randomizer.mychar = settings.mychar.value
|
||||
Randomizer.mychar = music.mychar.value
|
||||
Randomizer.worldGraph.spawn = settings.spawn.value
|
||||
|
||||
Randomizer.worldGraph.seqbreak = settings.seqbreak.value
|
||||
|
@ -209,13 +209,16 @@ layout.go:onPress(function()
|
|||
Randomizer.worldGraph.dboosts.plantation.enabled = sequence.plantation.value
|
||||
Randomizer.worldGraph.dboosts.rocket.enabled = sequence.rocket.value
|
||||
|
||||
Randomizer.shuffleMusic = settings.music.value
|
||||
Randomizer.shuffleMusic = music.music.value
|
||||
Randomizer.music.vanillaEnabled = music.cavestory.value
|
||||
Randomizer.music.betaEnabled = music.beta.value
|
||||
-- Randomizer.music.secretEnabled = music.secret.value
|
||||
if music.shuffle.value then Randomizer.music.flavor = "Shuffle" end
|
||||
if music.random.value then Randomizer.music.flavor = "Random" end
|
||||
if music.chaos.value then Randomizer.music.flavor = "Chaos" end
|
||||
|
||||
Randomizer.worldGraph.noFallingBlocks = settings.noFallingBlocks.value
|
||||
Randomizer.completableLogic = not settings.completable.value
|
||||
|
||||
C:setStatus(Randomizer:randomize())
|
||||
|
||||
|
@ -303,6 +306,7 @@ settings.importshare:onPress(function()
|
|||
rocket = bit.band(seq, 128) ~= 0
|
||||
})
|
||||
Screen:loadNoFallingBlocks(bit.band(sharesettings, 256) ~= 0) -- (settings & 0b100000000)
|
||||
Screen:loadCompleteableLogic(bit.band(sharesettings, 512) ~= 0) -- (settings & 0b1000000000)
|
||||
else
|
||||
settings.importshare.text = "Invalid Sharecode!"
|
||||
end
|
||||
|
|
|
@ -1,25 +1,60 @@
|
|||
return { style = 'dialog',
|
||||
{ style = 'dialogHead', text = 'Music Settings' },
|
||||
{ style = 'dialogHead', text = 'Personal Settings' },
|
||||
{ style = 'dialogBody', padding = 24, flow = 'x',
|
||||
{
|
||||
{ type = 'check', value = false, id = 'music', text = "Randomize music", minheight = 32, width = 170},
|
||||
{ type = 'label', text = 'Type of randomization' },
|
||||
{ type = 'radio', group = 'music', text = 'Shuffle', id = 'shuffle', minheight = 27 },
|
||||
{ type = 'radio', group = 'music', text = 'Random', id = 'random', minheight = 27 },
|
||||
{ type = 'radio', group = 'music', text = 'Chaos', id = 'chaos', minheight = 27 },
|
||||
{ type = 'label', text = 'Other settings' },
|
||||
{ type = 'check', id = 'beta', value = false, text = 'Enable beta music', minheight = 27 },
|
||||
{ type = 'radio', group = 'flavor', text = 'Shuffle', id = 'shuffle', minheight = 27, status = "Remap every song to a new song. For example, all instances of Mischievous Robot become Pulse. Songs may remap to themselves." },
|
||||
{ type = 'radio', group = 'flavor', text = 'Random', id = 'random', minheight = 27, status = "Remap every cue to a new song. For example, entering the Egg Corridor by any means plays Meltdown 2." },
|
||||
{ type = 'radio', group = 'flavor', text = 'Chaos', id = 'chaos', minheight = 27, status = "Remap every <CMU to a new song. For example, teleporting to the Egg Corridor plays Charge, but entering Egg Corridor from Cthulhu's Abode plays Run!" },
|
||||
{ type = 'label', text = 'Enabled music' },
|
||||
--[[ individual toggles is a lot of work actually
|
||||
{ type = 'panel', id = 'musicToggles', scroll = true,
|
||||
{ type = 'check', id = 'mischievousRobot', value = true, text = 'Mischievous Robot', minheight = 27},
|
||||
{ type = 'check', id = 'safety', value = true, text = 'Safety', minheight = 27},
|
||||
{ type = 'check', id = 'gravity', value = true, text = 'Gravity', minheight = 27},
|
||||
{ type = 'check', id = 'onToGrasstown', value = true, text = 'On to Grasstown', minheight = 27},
|
||||
{ type = 'check', id = 'meltdown', value = true, text = 'Meltdown 2', minheight = 27},
|
||||
{ type = 'check', id = 'eyesOfFlame', value = true, text = 'Eyes of Flame', minheight = 27},
|
||||
{ type = 'check', id = 'gestation', value = true, text = 'Gestation', minheight = 27},
|
||||
{ type = 'check', id = 'mimigaTown', value = true, text = 'Mimiga Town', minheight = 27},
|
||||
{ type = 'check', id = 'balrogsTheme', value = true, text = "Balrog's Theme", minheight = 27},
|
||||
{ type = 'check', id = 'cemetary', value = true, text = 'Cemetary', minheight = 27},
|
||||
{ type = 'check', id = 'plant', value = true, text = 'Plant', minheight = 27},
|
||||
{ type = 'check', id = 'pulse', value = true, text = 'Pulse', minheight = 27},
|
||||
{ type = 'check', id = 'tyrant', value = true, text = 'Tyrant', minheight = 27},
|
||||
{ type = 'check', id = 'run', value = true, text = 'Run!', minheight = 27},
|
||||
{ type = 'check', id = 'jenka1', value = true, text = 'Jenka 1', minheight = 27},
|
||||
{ type = 'check', id = 'labyrinthFight', value = true, text = 'Labyrinth Fight', minheight = 27},
|
||||
{ type = 'check', id = 'access', value = true, text = 'Access', minheight = 27},
|
||||
{ type = 'check', id = 'oppression', value = true, text = 'Oppression', minheight = 27},
|
||||
{ type = 'check', id = 'geothermal', value = true, text = 'Geothermal', minheight = 27},
|
||||
{ type = 'check', id = 'caveStory', value = true, text = 'Cave Story', minheight = 27},
|
||||
{ type = 'check', id = 'moonsong', value = true, text = 'Moonsong', minheight = 27},
|
||||
}
|
||||
]]
|
||||
{ type = 'check', id = 'cavestory', value = true, text = 'Enable Cave Story music', minheight = 27 },
|
||||
{ type = 'check', id = 'beta', value = false, text = 'Enable beta music', minheight = 27, status = "Only compatible with the included Doukutsu.exe - no other platforms." },
|
||||
--{ type = 'check', id = 'secret', value = false, text = 'Enable [redacted] music', minheight = 27, status = "Only compatible with the included Doukutsu.exe - no other platforms." },
|
||||
},
|
||||
{ type = 'sash' },
|
||||
{
|
||||
{
|
||||
align = 'top center',
|
||||
wrap = true,
|
||||
id = 'panel',
|
||||
width = 275,
|
||||
scroll = true
|
||||
width = 275,
|
||||
{ type = 'label', text = 'Player Sprite', minheight = 32 },
|
||||
{ type = 'stepper', id = 'mychar', align = 'middle left', height = 48, width = 200,
|
||||
{ text = " Quote", value = "assets/myChar/Quote.bmp", icon = "assets/icon/Quote.png" },
|
||||
{ text = " Curly", value = "assets/myChar/Curly.bmp", icon = "assets/icon/Curly.png" },
|
||||
{ text = " Sue", value = "assets/myChar/Sue.bmp", icon = "assets/icon/Sue.png" },
|
||||
{ text = " Toroko", value = "assets/myChar/Toroko.bmp", icon = "assets/icon/Toroko.png" },
|
||||
{ text = " King", value = "assets/myChar/King.bmp", icon = "assets/icon/King.png" },
|
||||
{ text = " Chaco", value = "assets/myChar/Chaco.bmp", icon = "assets/icon/Chaco.png" },
|
||||
{ text = " Kanpachi", value = "assets/myChar/Kanpachi.bmp", icon = "assets/icon/Kanpachi.png" },
|
||||
{ text = " Misery", value = "assets/myChar/Misery.bmp", icon = "assets/icon/Misery.png" },
|
||||
{ text = " Frog", value = "assets/myChar/Frog.bmp", icon = "assets/icon/Frog.png" }
|
||||
},
|
||||
{ height = 10 },
|
||||
{ type = 'label', text = '[scroll for more]', align = 'center', width = 275, minheight = 27 }
|
||||
}
|
||||
{ type = 'sash' },
|
||||
{ type = 'status', wrap = true, height = false, },
|
||||
},
|
||||
},
|
||||
{ style = 'dialogFoot',
|
||||
{},
|
||||
|
|
|
@ -16,16 +16,12 @@ return { style = 'dialog',
|
|||
},
|
||||
{ type = 'label', text = 'Randomization Options', minheight = 32 },
|
||||
{ type = 'check', value = false, id = 'puppy', text = "Puppies outside Sand Zone", minheight = 27 },
|
||||
{ type = 'check', value = true, id = 'completable', text = "Guarantee access to all locations", minheight = 54},
|
||||
{ flow = 'x', height = 32,
|
||||
{ type = 'check', value = false, id = 'seqbreak', text = "Sequence breaks", minheight = 32, width = 170},
|
||||
{ type = 'button', style = 'dialogButton', text = "Modify", id = 'seqButton', width = 70, align = 'center' },
|
||||
{ width = false }
|
||||
},
|
||||
{ flow = 'x', height = 32,
|
||||
{ type = 'check', value = false, id = 'music', text = "Randomize music", minheight = 32, width = 170},
|
||||
{ type = 'button', style = 'dialogButton', text = "Modify", id = 'musicButton', width = 70, align = 'center' },
|
||||
{ width = false }
|
||||
},
|
||||
},
|
||||
{
|
||||
{ type = 'label', text = 'Objective', minheight = 32 },
|
||||
|
@ -36,25 +32,14 @@ return { style = 'dialog',
|
|||
{ text = "All bosses", value = "objAllBosses" },
|
||||
{ text = "100%", value = "obj100Percent" }
|
||||
},
|
||||
{ type = 'label', text = 'Player Sprite', minheight = 32 },
|
||||
{ type = 'stepper', id = 'mychar', align = 'middle left', height = 48, width = 200,
|
||||
{ text = " Quote", value = "assets/myChar/Quote.bmp", icon = "assets/icon/Quote.png" },
|
||||
{ text = " Curly", value = "assets/myChar/Curly.bmp", icon = "assets/icon/Curly.png" },
|
||||
{ text = " Sue", value = "assets/myChar/Sue.bmp", icon = "assets/icon/Sue.png" },
|
||||
{ text = " Toroko", value = "assets/myChar/Toroko.bmp", icon = "assets/icon/Toroko.png" },
|
||||
{ text = " King", value = "assets/myChar/King.bmp", icon = "assets/icon/King.png" },
|
||||
{ text = " Chaco", value = "assets/myChar/Chaco.bmp", icon = "assets/icon/Chaco.png" },
|
||||
{ text = " Kanpachi", value = "assets/myChar/Kanpachi.bmp", icon = "assets/icon/Kanpachi.png" },
|
||||
{ text = " Misery", value = "assets/myChar/Misery.bmp", icon = "assets/icon/Misery.png" },
|
||||
{ text = " Frog", value = "assets/myChar/Frog.bmp", icon = "assets/icon/Frog.png" }
|
||||
},
|
||||
{ type = 'label', text = 'Spawn Location', minheight = 32 },
|
||||
{ type = 'stepper', id = 'spawn', align = 'middle left', height = 48, width = 200,
|
||||
{ text = " Start\r\n Point", value = "Start Point", icon = "assets/icon/StartPoint2.png" },
|
||||
{ text = " Arthur's\r\n House", value = "Arthur's House", icon = "assets/icon/Arthur2.png" },
|
||||
{ text = " Camp", value = "Camp", icon = "assets/icon/Camp.png" }
|
||||
},
|
||||
{ type = 'check', value = false, id = 'noFallingBlocks', text = "No Falling Blocks in Hell", minheight = 27 }
|
||||
{ type = 'button', style = 'dialogButton', text = "Personal Settings", id = 'musicButton', width = 200, height = 48, align = 'center' },
|
||||
{ type = 'check', value = false, id = 'noFallingBlocks', text = "No Falling Blocks in Hell", minheight = 32 },
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue