Item Randomizer works! Need full database though!!

This commit is contained in:
shru 2018-12-14 16:57:56 -05:00
parent 768895badc
commit 510be9a9a1
6 changed files with 166 additions and 56 deletions

View File

@ -1,3 +1,7 @@
Cave Story Randomizer
=====================
Issues
------
- Bubbler (and other weapons?) can't break blocks in the First Cave.

41
src/conf.lua Normal file
View File

@ -0,0 +1,41 @@
if io then
io.stdout:setvbuf("no")
end
local seed = os.time()
math.randomseed(seed)
function love.conf(t)
t.window = {
title = "Cave Story Randomizer",
-- icon = 'icon.png',
width = 640,
height = 480,
resizable = false,
}
t.version = '11.1'
t.console = false
t.identity = 'CaveStoryRandomizer'
t.accelerometerjoystick = false
t.gammacorrect = false
-- t.releases = {
-- -- This is the name of the zip archive which contains your game.
-- title = 'Cave Story Randomizer',
-- -- This is the name of your game's executable.
-- package = 'Cave Story Randomizer',
-- loveVersion = '11.1',
-- version = nil,
-- author = 'shru',
-- email = nil,
-- description = nil,
-- homepage = 'https://shru.itch.io/cave-story-randomizer',
-- -- MacOS needs this.
-- identifier = 'CaveStoryRandomizer',
-- excludeFileList = {
-- -- '.+%.ase',
-- },
-- compile = false,
-- releaseDirectory = 'releases',
-- }
end

View File

@ -1,5 +1,21 @@
return {
-- Weapons
-- wXXX = {
-- name = "",
-- map = "",
-- getText = "",
-- command = "",
-- displayCmd = "",
-- kind = "weapon",
-- },
wBubbler = {
name = "Bubbler",
map = "Comu",
getText = "Got the =Bubbler=!",
command = "<AM+0007:0100",
displayCmd = "<GIT0007",
kind = "weapon",
},
wPolar = {
name = "Polar Star",
map = "Pole",
@ -12,10 +28,21 @@ return {
iPanties = {
name = "Curly's Panties",
map = "CurlyS",
-- getText = "Found =Curly's Underwear=.",
getText = "Found =Curly's Panties=.",
getText = "Found =Curly's Underwear=.",
-- getText = "Found =Curly's Panties=.", -- Grrr
command = "<IT+0035",
displayCmd = "<GIT1035",
kind = "item",
},
}
-- #0200
-- <KEY<FLJ1640:0201<FL+1640<SOU0022<CNP0200:0021:0000
-- <MSGOpened the chest.<NOD<GIT0002<AM+0002:0000<CLR
-- <CMU0010Got the =Polar Star=!<WAI0160<NOD<GIT0000<CLO<RMU
-- <MSG
-- From somewhere, a transmission...<FAO0004<NOD<TRA0018:0501:0002:0000
-- #0420
-- <KEY<DNP0420<MSG<GIT1035<IT+0035
-- Found Curly's Panties.<NOD<END

View File

@ -4,11 +4,9 @@ local ITEM_DATA = require 'database.items'
function C:new()
self._left = {}
self._indexMap = {}
for k, v in pairs(ITEM_DATA) do
local item = _.clone(v)
table.insert(self._left, item)
self._indexMap[item] = #self._left
end
end
@ -26,18 +24,19 @@ end
function C:_getItem(filterFn)
-- Filter down to only applicable items.
local applicable = {}
for _, item in ipairs(self._left) do
local indexMap = {}
for index, item in ipairs(self._left) do
if filterFn(item) then
table.insert(applicable, item)
indexMap[item] = index
end
end
assert(#applicable >= 1, 'No applicable items!')
-- Select an item.
local selected = _.sample(applicable)
local index = self._indexMap[selected]
local index = indexMap[selected]
table.remove(self._left, index)
self._indexMap[selected] = nil
return selected
end

View File

@ -1,5 +1,3 @@
io.stdout:setvbuf("no")
require 'lib.strict'
Class = require 'lib.classic'
@ -8,7 +6,7 @@ Serpent = require 'lib.serpent'
lf = love.filesystem
local LOG_LEVEL = 5
local LOG_LEVEL = 4
local function _log(level, prefix, text, ...)
if LOG_LEVEL >= level then
print(prefix .. text, ...)
@ -20,9 +18,16 @@ function logNotice(...) _log(3, 'NOTICE: ', ...) end
function logInfo(...) _log(4, 'INFO: ', ...) end
function logDebug(...) _log(5, 'DEBUG: ', ...) end
local TSC_FILES = {
'Pole.tsc',
}
local TSC_FILES = {}
do
local ITEM_DATA = require 'database.items'
for k, v in pairs(ITEM_DATA) do
local filename = v.map .. '.tsc'
if _.contains(TSC_FILES, filename) == false then
table.insert(TSC_FILES, filename)
end
end
end
-- function love.load()
-- -- readPXM('Pole.pxm')
@ -32,32 +37,42 @@ local TSC_FILES = {
-- end
function love.directorydropped(path)
-- Mount
assert(lf.mount(path, 'data'))
local items = lf.getDirectoryItems('/data')
-- Mount.
local mountPath = 'mounted-data'
assert(lf.mount(path, mountPath))
local items = lf.getDirectoryItems('/' .. mountPath)
local containsStage = _.contains(items, 'Stage')
assert(containsStage)
local dirStage = '/data/Stage'
local dirStage = '/' .. mountPath .. '/Stage'
local tscFiles = {}
for _, filename in ipairs(TSC_FILES) do
local path = dirStage .. '/' .. filename
local TscFile = require 'tsc_file'
tscFiles[filename] = TscFile(path)
-- decoded = stringReplace(decoded, ITEM_DATA.wPolar.command, ITEM_DATA.iPanties.command)
-- decoded = stringReplace(decoded, ITEM_DATA.wPolar.getText, ITEM_DATA.iPanties.getText)
-- decoded = stringReplace(decoded, ITEM_DATA.wPolar.displayCmd, ITEM_DATA.iPanties.displayCmd)
end
-- Create ItemDeck.
local ItemDeck = require 'item_deck'
local itemDeck = ItemDeck()
print(Serpent.line(itemDeck:getWeapon()))
print(Serpent.line(itemDeck:getAny()))
tscFiles['Pole.tsc']:writeTo('Testing.tsc')
-- Place random weapon in Hermit Gunsmith.
tscFiles['Pole.tsc']:replaceItem(itemDeck:getWeapon())
-- Unmount
-- Replace all items.
for _, tscFile in pairs(tscFiles) do
while tscFile:hasUnreplacedItems() do
tscFile:replaceItem(itemDeck:getAny())
end
end
-- Write modified files.
for filename, tscFile in pairs(tscFiles) do
local path = '/data/Stage/' .. filename
tscFile:writeTo(path)
end
-- Unmount.
assert(lf.unmount(path))
end
@ -66,14 +81,3 @@ function love.keypressed(key)
love.event.push('quit')
end
end
-- #0200
-- <KEY<FLJ1640:0201<FL+1640<SOU0022<CNP0200:0021:0000
-- <MSGOpened the chest.<NOD<GIT0002<AM+0002:0000<CLR
-- <CMU0010Got the =Polar Star=!<WAI0160<NOD<GIT0000<CLO<RMU
-- <MSG
-- From somewhere, a transmission...<FAO0004<NOD<TRA0018:0501:0002:0000
-- #0420
-- <KEY<DNP0420<MSG<GIT1035<IT+0035
-- Found Curly's Panties.<NOD<END

View File

@ -1,7 +1,11 @@
local C = Class:extend()
-- local MODE_READ_BINARY = 'rb'
local MODE_WRITE_BINARY = 'wb'
-- https://www.lua.org/manual/5.1/manual.html#5.7
-- w+: Update mode, all previous data is erased;
-- b: Binary mode, forces Windows to save with Unix endings.
MODE_WRITE_ERASE_EXISTING = 'w+b'
local ITEM_DATA = require 'database.items'
function C:new(path)
logInfo('reading TSC: ' .. path)
@ -14,16 +18,61 @@ function C:new(path)
assert(file:close())
assert(file:release())
-- Determine set of items which can be replaced later.
self._unreplaced = {}
self._mapName = path:match("^.+/(.+)$")
for k, v in pairs(ITEM_DATA) do repeat
if (v.map .. '.tsc') ~= self._mapName then
break -- continue
end
local item = _.clone(v)
table.insert(self._unreplaced, item)
until true end
self._unreplaced = _.shuffle(self._unreplaced)
end
function C:hasUnreplacedItems()
return #self._unreplaced >= 1
end
local function _stringReplace(text, needle, replacement)
local i = text:find(needle, 1, true)
if i == nil then
logWarning(('Unable to replace "%s" with "%s"'):format(needle, replacement))
return text
end
local len = needle:len()
local j = i + len - 1
assert((i % 1 == 0) and (i > 0) and (i <= j), tostring(i))
assert((j % 1 == 0), tostring(j))
local a = text:sub(1, i - 1)
local b = text:sub(j + 1)
return a .. replacement .. b
end
function C:replaceItem(replacement)
assert(self:hasUnreplacedItems())
local original = table.remove(self._unreplaced)
self._text = _stringReplace(self._text, original.command, replacement.command)
self._text = _stringReplace(self._text, original.getText, replacement.getText)
self._text = _stringReplace(self._text, original.displayCmd, replacement.displayCmd)
local template = "[%s] %s -> %s"
logNotice(template:format(self._mapName, original.name, replacement.name))
end
function C:writeTo(path)
local encoded = self:_codec(self._text, 'encode')
local tmpFile, err = io.open(path, MODE_WRITE_BINARY)
local filepath = lf.getSourceBaseDirectory() .. path
logInfo('writing TSC to: ' .. filepath)
local file, err = io.open(filepath, MODE_WRITE_ERASE_EXISTING)
assert(err == nil, err)
tmpFile:write(encoded)
tmpFile:flush()
tmpFile:close()
file:write(encoded)
file:flush()
file:close()
end
function C:_codec(text, mode)
@ -66,18 +115,4 @@ function C:_codec(text, mode)
return decoded
end
local function stringReplace(text, needle, replacement)
local i = text:find(needle, 1, true)
if i == nil then
return text
end
local len = needle:len()
local j = i + len - 1
assert((i % 1 == 0) and (i > 0) and (i <= j), tostring(i))
assert((j % 1 == 0), tostring(j))
local a = text:sub(1, i - 1)
local b = text:sub(j + 1)
return a .. replacement .. b
end
return C