Merge pull request #164 from duncathan/completable

add completable logic
This commit is contained in:
duncathan salt 2021-07-26 20:38:11 -06:00 committed by GitHub
commit bbfa4e5661
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 248 additions and 97 deletions

8
.tscrc.json Normal file
View file

@ -0,0 +1,8 @@
{
"setup": {
"looseChecking": {
"events": true,
"arguments": true
}
}
}

View file

View 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()

View file

@ -28,6 +28,7 @@ end
function C:setItem(item)
item.placed = true
item.location_name = self.name
self.item = item
end

View file

@ -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"

View file

@ -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)

View file

@ -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()

View file

@ -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)

View file

@ -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 .. "}"

View file

@ -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

View file

@ -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',
{},

View file

@ -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 },
},
},
{