Commit 1542c253 authored by duncathan salt's avatar duncathan salt

slowly moving towards functionality. replaces items but doesn't logic

parent 86e0ae0e
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
......@@ -85,8 +85,7 @@ ERROR<NOD<END
<PRI<MSGIt's tangled up.
You can't get it loose...<NOD<END
#0243
<PRI<MSG<TUR<GIT1030<IT+0030
Got the =Tow Rope=.<WAI0025<NOD<END
<EVE0080
#0250
#0251
......
......@@ -186,9 +186,11 @@ up with something around here...<NOD<CLRMan, I'm hungry...<NOD<END
<PRI<FL+1022
<MSGPeered into the bucket.<NOD
Looking closely, you can see
something down at the bottom.<NOD<CLR<EVE0075
something down at the bottom.<NOD<CLR<EVE0268
#0267
<PRI<MSGNothing in here anymore...<NOD<END
#0268
<EVE0075
#0299
<PRI<MSG.....<NOD<END
......@@ -250,8 +252,7 @@ Jammed it into Curly's mouth.<NOD<CLR<CLO<WAI0050<EQ-0064<WAI0050
<PRI<EQ+0064<EVE0324
#0324
<PRI<MSG<TUR<GIT1039
<IT+0039Got the =Iron Bond=!<WAI0025<NOD<END
<EVE0089
#0325
......@@ -307,8 +308,7 @@ at a frightening rate.<NOD<END
#0416
<PRI<DNP0415<FL-1028<EVE0417
#0417
<MSG<TUR<GIT1028<IT+0028
Got the =Broken Sprinkler=.<WAI0025<NOD<END
<EVE0078
#0450
......
......@@ -163,8 +163,7 @@ the other robots...<NOD<CLO
to meet that gunsmith...<NOD<END
#0518
<MSG<TUR<AM+0004:0100<GIT0004
Got the =Machine Gun=!<WAI0025<NOD<END
<EVE0008
#0520
<KEY<MSG<FAC0019Really?<NOD<CLRWell, if you ever change
......
......@@ -60,6 +60,5 @@ You're not dead, are you?<NOD<CLR.....<NOD<CLO
#0300
<PRI<FLJ2700:0001<FL+2700<SOU0022<CNP0300:0021:0000<CMP0024:0016:0066<EVE0301
#0301
<PRI<MSG<TUR<GIT1026<IT+0026
Got =Sue's Letter=!<WAI0025<NOD<END
<EVE0076
......@@ -23,7 +23,7 @@
#0200
<PRI<FLJ1564:0101<FLJ2400:0001<FL+2400<SOU0022<CNP0200:0021:0000<EVE0202
#0202
<MSG<TUR<GIT1033<IT+0033Got the =Mushroom Badge=!<WAI0025<NOD<END
<EVE0083
#0400
<KEY<MYB0002<WAI0020
......@@ -79,5 +79,5 @@ it, right?<YNJ0410<EVE0409
<MSGYou win......<NOD<CLR<FL-1564<DNP0500<EVE0501
#0501
<MSG<GIT1034<IT+0034<CMU0015Got the =Ma Pignon=!<WAI0140<NOD<RMU<END
<EVE0084
......@@ -114,7 +114,7 @@ let you have what's inside.<NOD<END
#0501
<KEY<FLJ2500:0001<FL+2500<SOU0022<CNP0500:0021:0000<EVE0502
#0502
<KEY<MSG<TUR<GIT1020<IT+0020<EQ+0008Got the =Turbocharge=!<WAI0025<NOD<END
<EVE0070
#0510
<KEY<AMJ0003:0511<MYB0002<SOU0052<MSG<TURHEY!!!<WAI0100<NOD
......@@ -124,7 +124,7 @@ you have what's inside.<NOD<END
#0511
<KEY<FLJ2501:0001<FL+2501<SOU0022<CNP0510:0021:0000<EVE0512
#0512
<KEY<MSG<TUR<GIT0001<AM+0001:0000Got the =Snake=!<WAI0025<NOD<END
<EVE0005
#0520
<KEY<AMJ0013:0521<MYB0002<SOU0052<MSG<TURHEY!!!<WAI0100<NOD
......@@ -134,4 +134,4 @@ have what's inside.<NOD<END
#0521
<KEY<FLJ2502:0001<FL+2502<SOU0022<CNP0520:0021:0000<EVE0522
#0522
<KEY<MSG<TUR<GIT1038<IT+0038<EQ+0128Got the =Whimsical Star=!<WAI0025<NOD<END
\ No newline at end of file
<EVE0088
\ No newline at end of file
......@@ -31,7 +31,8 @@ end
local function event(n)
return {
name = "Event: " .. n,
attributes = {"event"}
attributes = {"event"},
placed = true
}
end
......@@ -73,7 +74,7 @@ local function _itemData()
bubbler = {
name = "Bubbler",
script = "<EVE0007",
attributes = {"weaponBoss", "weaponSN", "nonProgressive"} -- have fun grinding to lv3 to get out of the first cave :)
attributes = {"weaponBoss", "weaponSN", "nonProgressive"}
},
machineGun = {
name = "Machine Gun",
......@@ -265,12 +266,18 @@ local function _itemData()
mrLittle = {
name = "Little Man",
script = "<EVE0082",
attributes = {"event"}
attributes = {"event"},
placed = true
},
ironBond = {
name = "Iron Bond",
script = "<EVE0089"
},
clayMedal = {
name = "Clay Figure Medal",
script = "<EVE0081",
attributes = {"nonProgressive"}
},
-------------------
-- LIFE CAPSULES --
......@@ -314,13 +321,16 @@ local function _itemData()
eventRocket = event("Built Rocket")
}
local array = {}
for k, t in pairs(data) do
t.key = k
t.placed = t.placed or false
t.attributes = t.attributes or {}
table.insert(t.attributes, k)
table.insert(array, t)
end
return data
return array
end
local C = Class:extend()
......@@ -330,17 +340,19 @@ function C:new()
end
function C:getByKey(key)
for k, v in ipairs(self.itemData) do
if k == key then return v end
end
return _.filter(self.itemData, function(k,v) return v.key == key end)[1]
end
function C:_getItems(filterFn)
return _.filter(self.itemData, filterFn)
end
function C:getItems()
return self:_getItems(function(k,v) return true end)
end
function C:getItemsByAttribute(attribute)
local items = {}
for item in ipairs(self.itemData) do
if _.contains(item.attributes, attribute) then table.insert(items, item) end
end
return items
return self:_getItems(function(k,v) return _.contains(v.attributes, attribute) end)
end
function C:getEvents()
......@@ -352,7 +364,23 @@ function C:getOptionalItems()
end
function C:getMandatoryItems()
return _.difference(self.items, _.union(self:getOptionalItems(), self:getEvents()))
return self:_getItems(function(k,v)
return not (_.contains(v.attributes, "event") or _.contains(v.attributes, "nonProgressive") or _.contains(v.attributes, "puppy"))
end)
end
function C:getMandatory()
return self:_getItems(function(k,v) return not _.contains(v.attributes, "nonProgressive") end)
end
function C:getUnplacedItems()
return self:_getItems(function(k,v) return not v.placed end)
end
function C:unplacedString()
local s = "\r\nUnplaced items:"
for k,v in pairs(self:getUnplacedItems()) do s = s .. "\r\n" .. v.name end
return s
end
return C
......@@ -17,7 +17,7 @@ end
function C:canAccess(items)
if not self.region:canAccess(items) then return false end
return self.requirements == nil or self:requirements(items)
return self.requirements == nil or self.requirements(self, items)
end
function C:hasItem()
......@@ -25,13 +25,15 @@ function C:hasItem()
end
function C:setItem(item)
item.placed = true
self.item = item
end
function C:writeItem(tscFiles, item)
item = item or self.item
assert(self.item ~= nil, self.name)
if self.map == nil or self.event == nil or item.script == nil then return end
tscFiles[self.map .. '.tsc']:placeItemAtLocation(item.script, self.event)
tscFiles[self.map]:placeItemAtLocation(item, self)
end
return C
\ No newline at end of file
......@@ -7,27 +7,28 @@ function C:new(worldGraph, name)
end
function C:canAccess(items)
return self.requirements == nil or self.requirements(items)
return self.requirements == nil or self.requirements(self, items)
end
function C:getLocation(key)
return self.locations[key]
end
function C:getLocations()
return self.locations
function C:getLocations(filterFn)
filterFn = filterFn or function(k,v) return true end
return _.filter(self.locations, filterFn)
end
function C:getEmptyLocations()
return _.filter(self.locations, function(k,v) return not v:hasItem() end)
return self:getLocations(function(k,v) return v.item == nil end)
end
function C:getFilledLocations()
return _.filter(self.locations, function(k,v) return v:hasItem() end)
return self:getLocations(function(k,v) return v.item ~= nil end)
end
function C:writeItems(tscFiles)
for location in ipairs(self.locations) do location:writeItem(tscFiles) end
for key, location in pairs(self.locations) do location:writeItem(tscFiles) end
end
return C
\ No newline at end of file
This diff is collapsed.
......@@ -6,10 +6,12 @@ local C = Class:extend()
local TSC_FILES = {}
do
for location in ipairs(WorldGraph(Items()):getLocations()) do
local filename = location.map .. '.tsc'
if not _.contains(TSC_FILES, filename) then
table.insert(TSC_FILES, filename)
for key, location in ipairs(WorldGraph(Items()):getLocations()) do
if location.map ~= nil and location.event ~= nil then
local filename = location.map
if not _.contains(TSC_FILES, filename) then
table.insert(TSC_FILES, filename)
end
end
end
end
......@@ -17,7 +19,7 @@ end
function C:new()
self._isCaveStoryPlus = false
self.itemDeck = Items()
self.worldGraph = WorldGraph(itemDeck)
self.worldGraph = WorldGraph(self.itemDeck)
end
function C:randomize(path)
......@@ -31,7 +33,7 @@ function C:randomize(path)
local tscFiles = self:_createTscFiles(dirStage)
-- self:_writePlaintext(tscFiles)
self:_shuffleItems(tscFiles)
-- self:_writeModifiedData(tscFiles)
self:_writeModifiedData(tscFiles)
self:_writePlaintext(tscFiles)
self:_writeLog()
self:_unmountDirectory(path)
......@@ -77,8 +79,9 @@ end
function C:_createTscFiles(dirStage)
local tscFiles = {}
for _, filename in ipairs(TSC_FILES) do
local path = dirStage .. '/' .. filename
local path = dirStage .. '/' .. filename .. '.tsc'
tscFiles[filename] = TscFile(path)
tscFiles[filename].mapName = filename
end
return tscFiles
end
......@@ -92,58 +95,65 @@ function C:_writePlaintext(tscFiles)
-- Write modified files.
for filename, tscFile in pairs(tscFiles) do
local path = sourcePath .. '/data/Plaintext/' .. filename
local path = sourcePath .. '/data/Plaintext/' .. filename .. '.txt'
tscFile:writePlaintextTo(path)
end
end
function C:_shuffleItems(tscFiles)
local l, i = #self.worldGraph:getLocations(), #self.itemDeck:getItems()
assert(l == i, ("Locations: %d\r\nItems: %d"):format(l, i))
-- first fill puppies
local puppies = self.itemDeck:getItemsByAttribute("puppy")
local sandZone = _.shuffle(self.worldGraph:getLocationsByRegion("upperSandZone", "lowerSandZone"))
self:_fastFillItems(puppies, sandZone)
self:_fastFillItems(self.itemDeck:getItemsByAttribute("puppy"), _.shuffle(self.worldGraph:getPuppySpots()))
local mandatory = _.shuffle(self.itemDeck:getMandatoryItems())
local optional = _.shuffle(self.itemDeck:getOptionalItems())
local mandatory = _.compact(_.shuffle(self.itemDeck:getMandatoryItems()))
local optional = _.compact(_.shuffle(self.itemDeck:getOptionalItems()))
-- next fill hell chests, which cannot have mandatory items
self:_fastFillItems(optional, self.worldGraph:getLocationsByRegion("endgame"))
self:_fastFillItems(optional, _.shuffle(self.worldGraph:getHellSpots()))
self:_fillItems(mandatory, _.shuffle(self.worldGraph:getEmptyLocations()))
self:_fillItems(mandatory, _.shuffle(_.reverse(self.worldGraph:getEmptyLocations())))
self:_fastFillItems(optional, _.shuffle(self.worldGraph:getEmptyLocations()))
worldGraph:writeItems()
assert(#self.worldGraph:getEmptyLocations() == 0, self.worldGraph:emptyString() .. "\r\n" .. self.itemDeck:unplacedString())
self.worldGraph:writeItems(tscFiles)
end
function C:_fillItems(items, locations)
local itemsLeft = _.clone(items)
assert(#items <= #locations, 'Trying to fill more items than there are locations!')
function C:_fillItems(items, locations, baseItems)
local itemsLeft
if baseItems ~= nil then
itemsLeft = _.union(items, baseItems)
else
itemsLeft = _.clone(items)
end
assert(#items <= #locations, string.format("Trying to fill more items than there are locations! Items: %d Locations: %d", #items, #locations))
for item in ipairs(items) do
for key, item in ipairs(items) do
local assumed = self.worldGraph:collect(_.remove(itemsLeft, item))
local fillable = {}
for location in ipairs(locations) do
if not location:hasItem() and location:canAccess(assumed) then table.insert(fillable, location) end
end
assert(#fillable > 0, 'No available locations!')
local fillable = _.filter(locations, function(k,v) return not v:hasItem() and v:canAccess(assumed) end)
local empty = _.filter(locations, function(k,v) return not v:hasItem() end)
assert(#fillable > 0, "No available locations!")
assert(item ~= nil, "No item found!")
fillable[1]:setItem(item)
end
end
function C:_fastFillItems(items, locations)
for location in ipairs(locations) do
if not location:hasItem() then
local item = _.pop(items)
if item == nil then break end -- no items left to place, but there are still locations open
location:setItem(item)
end
--assert(#items > 0, ("Items: %d Locations: %d"):format(#items, #locations))
for key, location in ipairs(locations) do
local item = items[#items]
table.remove(items)
--assert(item ~= nil, ("Items: %d Locations: %d"):format(#items, key))
if item == nil then break end -- no items left to place, but there are still locations open
location:setItem(item)
end
end
function C:_writeModifiedData(tscFiles)
local basePath = self:_getWritePathStage()
for filename, tscFile in pairs(tscFiles) do
local path = basePath .. '/' .. filename
local path = basePath .. '/' .. filename .. '.tsc'
tscFile:writeTo(path)
end
end
......
......@@ -21,6 +21,7 @@ function C:new(path)
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
......@@ -31,15 +32,23 @@ function C:new(path)
table.insert(self._unreplaced, item)
until true end
self._unreplaced = _.shuffle(self._unreplaced)
]]
end
function C:hasUnreplacedItems()
return #self._unreplaced >= 1
end
function C:placeItemAtLocation(script, event)
local labelStart = self:_getLabelPositionRange(event)
self:_stringReplace(self._text, "<EVE$%d%d%d%d", script, event)
function C:placeItemAtLocation(item, location)
local template = '[%s] "%s" -> "%s"'
logNotice(template:format(location.map, location.name, item.name))
local wasChanged
self._text, wasChanged = self:_stringReplace(self._text, "<EVE....", item.script, location.event)
if not wasChanged then
local template = 'Unable to place [%s] "%s" at "%s".'
logError(template:format(location.map, item.name, location.name))
end
end
function C:replaceItem(replacement)
......@@ -130,13 +139,13 @@ end
function C:_stringReplace(text, needle, replacement, label)
local pStart, pEnd = self:_getLabelPositionRange(label)
local i = text:find(needle, pStart, true)
local i = text:find(needle, pStart)
if i == nil then
-- logWarning(('Unable to replace "%s" with "%s"'):format(needle, replacement))
logNotice(('Unable to replace "%s" with "%s"'):format(needle, replacement))
return text, false
elseif i > pEnd then
-- This is totally normal and can be ignored.
-- logDebug(('Found "%s", but was outside of label.'):format(needle, replacement))
logNotice(('Found "%s", but was outside of label.'):format(needle, replacement))
return text, false
end
local len = needle:len()
......@@ -188,7 +197,7 @@ function C:_getLabelPositionRange(label)
end
if labelStart == nil then
logError("Could not find label: " .. label)
logError(("%s: Could not find label: %s"):format(self.mapName, label))
labelStart = 1
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment