mirror of
https://github.com/cave-story-randomizer/cave-story-randomizer
synced 2025-07-15 16:06:50 +00:00
sets up the actual filling algorithm - how badly is this gonna fail?
This commit is contained in:
parent
b10433be2a
commit
56b057d027
|
@ -1 +1 @@
|
||||||
IF_llulIFx<EFBFBD>}x<78>llmnx<6E><78>lllx<6C><78>IF_llumIFx<46>}x<78>llmnx<6E><78>llmx<6D><78>IF_llunIFx<46>}x<78>llmnx<6E><78>llnx<6E><78>IF_lluoIFx<46>}x<78>llmnx<6E><78>llox<6F><78>IF_llupIFx<46>}x<78>llmnx<6E><78>llpx<70><78>IF_lmllIFx<46><78><EFBFBD>嚯lllx<6C>}llmmvllulvllqrvllooIF_lmmlIFx<46>𡣘<EFBFBD>𡡣lmmx}<7D>lmmlvllllvlllnIFx<46>嚯llpx<70>}lltovllupvlllsvllmlIF_lnllIFx<46><78>Fx<46><78>osmvlnlmIFx<46><78><EFBFBD>廾\㨩<><E3A8A9><EFBFBD>\<5C>狐{x<><78>x<EFBFBD><78>IF_lnlmIFx<46><78><EFBFBD><EFBFBD>垮\<5C>琵延\野╮c珮走咩左cIF◤娉屆{<<3C><>x<78>IF衮𤪓h\筍帷恣\恭ㄓ退x<E98080><78>IF<49>䔉泌豹鱝〞\井屆\左\𩄼酗巨】x<E38091><78>IF}悅奴什h\陞屆\鬥\ㄚjx<6A><78>x<EFBFBD>都lonx<6E><78>lnllx<78>𧞄帷恣\ㄚ牧𩄼<E789A7>均\屆\陘&︺IF哈\駚戛砥{x<><78>x<EFBFBD><78>ltnIF_lollIFx<78>lollvllllvllllx<6C><78>oulvlolnx<6E>gloulx<6C><78>olmIF_lolmIFx<46><78>lqmIF_lolnIFx<46><78><EFBFBD><EFBFBD>扇仃宮珮ㄝ𨮙】x<E38091><78>IF𨫡&︷珮陵弘左α囿\陘!F鬥<46>秣囿」x<E3808D><78>x<78>x<EFBFBD><78><EFBFBD><EFBFBD>&﹏祠﹛炫\陘﹏物𠸊﹏}扇仃屑IF乾情\丑悍\鬥\陘﹏竉岩<E7AB89>疽x<E796BD><78>x<78>x<EFBFBD><78>
|
0==F=IZ[NIPZb==>?ISNV====IR[Q0==F>IZ[NIPZb==>?ISNV===>IR[Q0==F?IZ[NIPZb==>?ISNV===?IR[Q0==F@IZ[NIPZb==>?ISNV===@IR[Q0==FAIZ[NIPZb==>?ISNV===AIR[Q0=>==I]_VISN\====Ia_N==>>G==F=G==BCG==@@0=>>=IXRfI`\b==>>IN[]=>>=G====G===?ISN\===AIa_N==E@G==FAG===DG==>=0=?==I]_VISYW>@D>G=?=>IZ`TfrnuL-dunqqn†n-„n{<7B>LI[\QIR[Q0=?=>I]_VIZ`Tf|‚-€n†-z†-„vsr4€-y||xv{4s|-zrLI[\QIPY_
frnu9-†|‚4r-vtu<74>9I[\QV-nv{4<>-orr{-u|zr-v{-n-„uvyr;I[\QNvtu<74>9-<2D>vzr-<2D>|-t|;I[\QITVa>=@?IQ[]=?==IPY_f|‚4r-t|{{n-<2D>nxr-zr-<2D>urr9|s-p|‚€rLI[\QIRcR=?=?0=?=?IRcR==E?0=@==IP[]=@==G====G====ISYW=@F=G=@=?ISY8=@F=IRcR=@=>0=@=>IRcR==B>0=@=?I]_VIZ`TN<4E>u‚4€-tn<7F>r;I[\Qaurr4€-„v<7F>v{t-|{-<2D>ur<17>|zo€<6F>|{rGI[\QIPY_IZ`TIab_Urr-€yrr}€-<2D>ur-{|oyr-N<4E>u‚9<17>‚r-ur|-<2D>|-<2D>ur-Zvzvtn€;I[\QIPY_IR[Q
|
|
@ -28,7 +28,9 @@ for me?<NOD<CLR
|
||||||
Yeah, you're right,<NOD
|
Yeah, you're right,<NOD
|
||||||
I ain't been home in a while.<NOD
|
I ain't been home in a while.<NOD
|
||||||
Arright, time to go.<NOD<GIT1032<DNP0200<CLRYou're gonna take me there,
|
Arright, time to go.<NOD<GIT1032<DNP0200<CLRYou're gonna take me there,
|
||||||
of course?<NOD<EVE0082
|
of course?<NOD<EVE0202
|
||||||
|
#0202
|
||||||
|
<EVE0082
|
||||||
|
|
||||||
#0300
|
#0300
|
||||||
<CNP0300:0000:0000<FLJ0390:0302<FL+0390<EVE0301
|
<CNP0300:0000:0000<FLJ0390:0302<FL+0390<EVE0301
|
||||||
|
|
|
@ -1,99 +1,103 @@
|
||||||
function item(t)
|
local function lifeCapsule3()
|
||||||
return t
|
return {
|
||||||
end
|
|
||||||
|
|
||||||
function weapon(t)
|
|
||||||
return item(t)
|
|
||||||
end
|
|
||||||
|
|
||||||
function inventory(t)
|
|
||||||
return item(t)
|
|
||||||
end
|
|
||||||
|
|
||||||
function lifeCapsule3()
|
|
||||||
return item({
|
|
||||||
name = "Life Capsule",
|
name = "Life Capsule",
|
||||||
script = "<EVE0012"
|
script = "<EVE0012",
|
||||||
})
|
attributes = {"nonProgressive"}
|
||||||
|
}
|
||||||
end
|
end
|
||||||
function lifeCapsule4()
|
local function lifeCapsule4()
|
||||||
return item({
|
return {
|
||||||
name = "Life Capsule",
|
name = "Life Capsule",
|
||||||
script = "<EVE0013"
|
script = "<EVE0013",
|
||||||
})
|
attributes = {"nonProgressive"}
|
||||||
|
}
|
||||||
end
|
end
|
||||||
function lifeCapsule5()
|
local function lifeCapsule5()
|
||||||
return item({
|
return {
|
||||||
name = "Life Capsule",
|
name = "Life Capsule",
|
||||||
script = "<EVE0014"
|
script = "<EVE0014",
|
||||||
})
|
attributes = {"nonProgressive"}
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
function missiles()
|
local function missiles()
|
||||||
return weapon({
|
return {
|
||||||
name = "Missile Expansion",
|
name = "Missile Expansion",
|
||||||
script = "<EVE0030",
|
script = "<EVE0030",
|
||||||
attributes = {"weaponSN", "missileLauncher"}
|
attributes = {"missileLauncher", "nonProgressive"}
|
||||||
})
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function event(n)
|
||||||
|
return {
|
||||||
|
name = "Event: " .. n,
|
||||||
|
attributes = {"event"}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _itemData()
|
||||||
local data = {
|
local data = {
|
||||||
-------------
|
-------------
|
||||||
-- WEAPONS --
|
-- WEAPONS --
|
||||||
-------------
|
-------------
|
||||||
polarStar = weapon({
|
polarStar1 = {
|
||||||
name = "Polar Star",
|
name = "Polar Star",
|
||||||
script = "<EVE0002",
|
script = "<EVE0002",
|
||||||
attributes = {"weaponBoss", "weaponSN"}
|
attributes = {"weaponBoss", "weaponSN", "polarStar"}
|
||||||
}),
|
},
|
||||||
spur = weapon({
|
polarStar2 = {
|
||||||
name = "Spur",
|
name = "Polar Star",
|
||||||
script = "<EVE0002",
|
script = "<EVE0002",
|
||||||
attributes = {"weaponBoss", "weaponSN", "polarStar"}
|
attributes = {"weaponBoss", "weaponSN", "polarStar"}
|
||||||
}),
|
},
|
||||||
missileLauncher = missiles(),
|
missileLauncher = {
|
||||||
superMissileLauncher = weapon({
|
name = "Missile Launcher",
|
||||||
|
script = "<EVE0030",
|
||||||
|
attributes = {"weaponSN", "nonProgressive"}
|
||||||
|
},
|
||||||
|
superMissileLauncher = {
|
||||||
name = "Super Missile Launcher",
|
name = "Super Missile Launcher",
|
||||||
script = "<EVE0033",
|
script = "<EVE0033",
|
||||||
attributes = {"weaponSN", "missileLauncher"}
|
attributes = {"weaponSN", "missileLauncher", "nonProgressive"}
|
||||||
}),
|
},
|
||||||
fireball = weapon({
|
fireball = {
|
||||||
name = "Fireball",
|
name = "Fireball",
|
||||||
script = "<EVE0004",
|
script = "<EVE0004",
|
||||||
attributes = {"weaponBoss"}
|
attributes = {"weaponBoss"}
|
||||||
}),
|
},
|
||||||
snake = weapon({
|
snake = {
|
||||||
name = "Snake",
|
name = "Snake",
|
||||||
script = "<EVE0005",
|
script = "<EVE0005",
|
||||||
attributes = {"weaponBoss"}
|
attributes = {"weaponBoss", "nonProgressive"}
|
||||||
}),
|
},
|
||||||
bubbler = weapon({
|
bubbler = {
|
||||||
name = "Bubbler",
|
name = "Bubbler",
|
||||||
script = "<EVE0007",
|
script = "<EVE0007",
|
||||||
attributes = {"weaponBoss", "weaponSN"} -- have fun grinding to lv3 to get out of the first cave :)
|
attributes = {"weaponBoss", "weaponSN", "nonProgressive"} -- have fun grinding to lv3 to get out of the first cave :)
|
||||||
}),
|
},
|
||||||
machineGun = weapon({
|
machineGun = {
|
||||||
name = "Machine Gun",
|
name = "Machine Gun",
|
||||||
script = "<EVE0008",
|
script = "<EVE0008",
|
||||||
attributes = {"weaponBoss", "flight"}
|
attributes = {"weaponBoss", "flight"}
|
||||||
}),
|
},
|
||||||
blade = weapon({
|
blade = {
|
||||||
name = "Blade",
|
name = "Blade",
|
||||||
script = "<EVE0009",
|
script = "<EVE0009",
|
||||||
attributes = {"weaponBoss", "weaponSN"}
|
attributes = {"weaponBoss", "weaponSN"}
|
||||||
}),
|
},
|
||||||
nemesis = weapon({
|
nemesis = {
|
||||||
name = "Nemesis",
|
name = "Nemesis",
|
||||||
script = "<EVE0010",
|
script = "<EVE0010",
|
||||||
attributes = {"weaponBoss", "weaponSN"}
|
attributes = {"weaponBoss", "weaponSN", "nonProgressive"}
|
||||||
}),
|
},
|
||||||
|
|
||||||
---------------
|
---------------
|
||||||
-- INVENTORY --
|
-- INVENTORY --
|
||||||
---------------
|
---------------
|
||||||
mapSystem = {
|
mapSystem = {
|
||||||
name = "Map System",
|
name = "Map System",
|
||||||
script = "<EVE0052"
|
script = "<EVE0052",
|
||||||
|
attributes = {"nonProgressive"}
|
||||||
},
|
},
|
||||||
locket = {
|
locket = {
|
||||||
name = "Silver Locket",
|
name = "Silver Locket",
|
||||||
|
@ -113,7 +117,8 @@ local data = {
|
||||||
},
|
},
|
||||||
lipstick = {
|
lipstick = {
|
||||||
name = "Chaco's Lipstick",
|
name = "Chaco's Lipstick",
|
||||||
script = "<EVE0087"
|
script = "<EVE0087",
|
||||||
|
attributes = {"nonProgressive"}
|
||||||
},
|
},
|
||||||
juice = {
|
juice = {
|
||||||
name = "Jellyfish Juice",
|
name = "Jellyfish Juice",
|
||||||
|
@ -141,7 +146,8 @@ local data = {
|
||||||
},
|
},
|
||||||
panties = {
|
panties = {
|
||||||
name = "Curly's Panties",
|
name = "Curly's Panties",
|
||||||
script = "<EVE0085"
|
script = "<EVE0085",
|
||||||
|
attributes = {"nonProgressive"}
|
||||||
},
|
},
|
||||||
puppy1 = {
|
puppy1 = {
|
||||||
name = "Hajime",
|
name = "Hajime",
|
||||||
|
@ -170,11 +176,13 @@ local data = {
|
||||||
},
|
},
|
||||||
lifepot = {
|
lifepot = {
|
||||||
name = "Life Pot",
|
name = "Life Pot",
|
||||||
script = "<EVE0065"
|
script = "<EVE0065",
|
||||||
|
attributes = {"nonProgressive"}
|
||||||
},
|
},
|
||||||
turbocharge = {
|
turbocharge = {
|
||||||
name = "Turbocharge",
|
name = "Turbocharge",
|
||||||
script = "<EVE0070"
|
script = "<EVE0070",
|
||||||
|
attributes = {"nonProgressive"}
|
||||||
},
|
},
|
||||||
clinicKey = {
|
clinicKey = {
|
||||||
name = "Clinic Key",
|
name = "Clinic Key",
|
||||||
|
@ -182,21 +190,22 @@ local data = {
|
||||||
},
|
},
|
||||||
armsBarrier = {
|
armsBarrier = {
|
||||||
name = "Arms Barrier",
|
name = "Arms Barrier",
|
||||||
script = "<EVE0069"
|
script = "<EVE0069",
|
||||||
|
attributes = {"nonProgressive"}
|
||||||
},
|
},
|
||||||
cureAll = {
|
cureAll = {
|
||||||
name = "Cure-All",
|
name = "Cure-All",
|
||||||
script = "<EVE0066"
|
script = "<EVE0066"
|
||||||
},
|
},
|
||||||
booster1 = {
|
booster1 = {
|
||||||
name = "Booster 0.8",
|
name = "Booster",
|
||||||
script = "<EVE0068",
|
script = "<EVE0068",
|
||||||
attributes = {"flight"}
|
attributes = {"flight", "booster"}
|
||||||
},
|
},
|
||||||
booster2 = {
|
booster2 = {
|
||||||
name = "Booster 2.0",
|
name = "Booster",
|
||||||
script = "<EVE0073",
|
script = "<EVE0068",
|
||||||
attributes = {"flight", "booster1"}
|
attributes = {"flight", "booster"}
|
||||||
},
|
},
|
||||||
towRope = {
|
towRope = {
|
||||||
name = "Tow Rope",
|
name = "Tow Rope",
|
||||||
|
@ -208,15 +217,18 @@ local data = {
|
||||||
},
|
},
|
||||||
alienMedal = {
|
alienMedal = {
|
||||||
name = "Alien Medal",
|
name = "Alien Medal",
|
||||||
script = "<EVE0086"
|
script = "<EVE0086",
|
||||||
|
attributes = {"nonProgressive"}
|
||||||
},
|
},
|
||||||
whimsicalStar = {
|
whimsicalStar = {
|
||||||
name = "Whimsical Star",
|
name = "Whimsical Star",
|
||||||
script = "<EVE0088"
|
script = "<EVE0088",
|
||||||
|
attributes = {"nonProgressive"}
|
||||||
},
|
},
|
||||||
nikumaru = {
|
nikumaru = {
|
||||||
name = "Nikumaru Counter",
|
name = "Nikumaru Counter",
|
||||||
script = "<EVE0072"
|
script = "<EVE0072",
|
||||||
|
attributes = {"nonProgressive"}
|
||||||
},
|
},
|
||||||
teleportKey = {
|
teleportKey = {
|
||||||
name = "Teleporter Room Key",
|
name = "Teleporter Room Key",
|
||||||
|
@ -250,9 +262,10 @@ local data = {
|
||||||
name = "Ma Pignon",
|
name = "Ma Pignon",
|
||||||
script = "<EVE0084"
|
script = "<EVE0084"
|
||||||
},
|
},
|
||||||
little = {
|
mrLittle = {
|
||||||
name = "Little Man",
|
name = "Little Man",
|
||||||
script = "<EVE0082"
|
script = "<EVE0082",
|
||||||
|
attributes = {"event"}
|
||||||
},
|
},
|
||||||
ironBond = {
|
ironBond = {
|
||||||
name = "Iron Bond",
|
name = "Iron Bond",
|
||||||
|
@ -282,15 +295,61 @@ local data = {
|
||||||
missileB = missiles(), -- Grasstown Hut
|
missileB = missiles(), -- Grasstown Hut
|
||||||
missileC = missiles(), -- Egg Corridor?
|
missileC = missiles(), -- Egg Corridor?
|
||||||
missileD = missiles(), -- Egg Observation Room?
|
missileD = missiles(), -- Egg Observation Room?
|
||||||
missileHell = weapon({
|
missileHell = {
|
||||||
name = "Missile Expansion",
|
name = "Missile Expansion",
|
||||||
script = "<EVE0035",
|
script = "<EVE0035",
|
||||||
attributes = {"weaponSN", "missileLauncher"}
|
attributes = {"missileLauncher", "nonProgressive"}
|
||||||
})
|
},
|
||||||
|
|
||||||
|
------------
|
||||||
|
-- EVENTS --
|
||||||
|
------------
|
||||||
|
eventSue = event("Saved Sue"),
|
||||||
|
eventFans = event("Activated Fans"),
|
||||||
|
eventKazuma = event("Saved Kazuma"),
|
||||||
|
eventOmega = event("Defeated Omega"),
|
||||||
|
eventToroko = event("Defeated Toroko+"),
|
||||||
|
eventCore = event("Defeated the Core"),
|
||||||
|
eventCurly = event("Saved Curly"),
|
||||||
|
eventRocket = event("Built Rocket")
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, t in pairs(data) do
|
for k, t in pairs(data) do
|
||||||
t.key = k
|
t.key = k
|
||||||
|
table.insert(t.attributes, k)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return data
|
local C = Class:extend()
|
||||||
|
|
||||||
|
function C:new()
|
||||||
|
self.itemData = _itemData()
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:getByKey(key)
|
||||||
|
for k, v in ipairs(self.itemData) do
|
||||||
|
if k == key then return v end
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:getEvents()
|
||||||
|
return self:getItemsByAttribute("event")
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:getOptionalItems()
|
||||||
|
return self:getItemsByAttribute("nonProgressive")
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:getMandatoryItems()
|
||||||
|
return _.difference(self.items, _.union(self:getOptionalItems(), self:getEvents()))
|
||||||
|
end
|
||||||
|
|
||||||
|
return C
|
||||||
|
|
37
src/database/location.lua
Normal file
37
src/database/location.lua
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
local C = Class:extend()
|
||||||
|
|
||||||
|
function C:new(name, map, event, region)
|
||||||
|
self.name = name
|
||||||
|
self.map = map
|
||||||
|
self.event = event
|
||||||
|
self.region = region
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:fill(item, items)
|
||||||
|
local old = self.item
|
||||||
|
self:setItem(item)
|
||||||
|
if self:canAccess(items) then return true end
|
||||||
|
self:setItem(old)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:canAccess(items)
|
||||||
|
if not self.region:canAccess(items) then return false end
|
||||||
|
return self.requirements == nil or self:requirements(items)
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:hasItem()
|
||||||
|
return self.item ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:setItem(item)
|
||||||
|
self.item = item
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:writeItem(tscFiles, item)
|
||||||
|
item = item or self.item
|
||||||
|
if self.map == nil or self.event == nil or item.script == nil then return end
|
||||||
|
tscFiles[self.map .. '.tsc']:placeItemAtLocation(item.script, self.event)
|
||||||
|
end
|
||||||
|
|
||||||
|
return C
|
|
@ -1,549 +0,0 @@
|
||||||
local data = {
|
|
||||||
firstCave1 = { -- locations available at the absolute beginning of the game. can't be returned to, but can't be left without obtaining both items
|
|
||||||
connections = {
|
|
||||||
mimigaVillage = {{"weaponSN"}}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
firstCapsule = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Cave",
|
|
||||||
event = "#0401"
|
|
||||||
},
|
|
||||||
gunsmithChest = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Pole",
|
|
||||||
event = "#0402"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
firstCave2 = { -- locations available on the return trip to first cave
|
|
||||||
connections = {
|
|
||||||
mimigaVillage = {{"weaponSN"}}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
gunsmith = {
|
|
||||||
requirements = {"polarStar", "eventCore"},
|
|
||||||
map = "Pole",
|
|
||||||
event = "#0303"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mimigaVillage = {
|
|
||||||
connections = {
|
|
||||||
firstCave2 = {{"weaponSN", "flight"}},
|
|
||||||
arthur = {{"arthursKey"}}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
yamashita = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Plant",
|
|
||||||
event = "#0401"
|
|
||||||
},
|
|
||||||
reservoir = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Pool",
|
|
||||||
event = "#0301"
|
|
||||||
},
|
|
||||||
mapChest = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Mimi",
|
|
||||||
event = "#0202"
|
|
||||||
},
|
|
||||||
assemblyHall = {
|
|
||||||
requirements = {{"juice"}},
|
|
||||||
map = "Comu",
|
|
||||||
event = "#0303"
|
|
||||||
},
|
|
||||||
mrLittle = { -- guaranteed to have the little man item, for simplicity's sake (more of an escort quest than fetch quest imo)
|
|
||||||
requirements = {{"locket"}},
|
|
||||||
map = "Cemet",
|
|
||||||
event = "#0301"
|
|
||||||
},
|
|
||||||
graveyard = {
|
|
||||||
requirements = {{"locket"}},
|
|
||||||
map = "Cemet",
|
|
||||||
event = "#0301"
|
|
||||||
},
|
|
||||||
mushroom = { -- placed in a chest, can't open unless curly has been saved
|
|
||||||
requirements = {{"locket", "eventCurly", "flight"}},
|
|
||||||
map = "Mapi",
|
|
||||||
event = "#0202"
|
|
||||||
},
|
|
||||||
maPignon = { -- no need to check the mushroom badge, just need to have it
|
|
||||||
requirements = {{"locket", "mushroomBadge", "weaponBoss", "flight"}},
|
|
||||||
map = "Mapi",
|
|
||||||
event = "#0501"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
arthur = {
|
|
||||||
connections = {
|
|
||||||
mimigaVillage = {{"arthursKey"}},
|
|
||||||
eggCorridor1 = {},
|
|
||||||
eggCorridor2 = {{"eventCore"}, -- also unlocks if you have access to the teleporter between grasstown and plantation, but that's logically redundant
|
|
||||||
grasstownWest = {},
|
|
||||||
upperSandZone = {{"weaponSN"}},
|
|
||||||
labyrinthB = {},
|
|
||||||
plantation = {{"teleportKey"}}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
risenBooster = {
|
|
||||||
requirements = {{"eventCore"}},
|
|
||||||
map = "Pens1",
|
|
||||||
event = "#0652"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
eggCorridor1 = {
|
|
||||||
connections = {
|
|
||||||
arthur = {}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
basil = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Eggs",
|
|
||||||
event = "#0403"
|
|
||||||
},
|
|
||||||
cthulhu = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Eggs",
|
|
||||||
event = "#0404"
|
|
||||||
},
|
|
||||||
eggItem = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Egg6",
|
|
||||||
event = "#0201"
|
|
||||||
},
|
|
||||||
observationChest = {
|
|
||||||
requirements = {},
|
|
||||||
map = "EggR",
|
|
||||||
event = "#0301"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
events = {
|
|
||||||
eventSue = {
|
|
||||||
requirements = {{"idCard", "weaponBoss"}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
grasstownWest = {
|
|
||||||
connections = {
|
|
||||||
arthur = {},
|
|
||||||
grasstownEast = {{"juice"}, {"flight"}} -- can also sequence break over with a damage boost!
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
keySpot = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Weed",
|
|
||||||
event = "#0700"
|
|
||||||
},
|
|
||||||
jellyCapsule = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Weed",
|
|
||||||
event = "#0701"
|
|
||||||
},
|
|
||||||
santa = {
|
|
||||||
requirements = {{"santaKey"}},
|
|
||||||
map = "Santa",
|
|
||||||
event = "#0501"
|
|
||||||
},
|
|
||||||
charcoal = {
|
|
||||||
requirements = {{"santaKey", "juice"}},
|
|
||||||
map = "Santa",
|
|
||||||
event = "#0302"
|
|
||||||
}
|
|
||||||
chaco = {
|
|
||||||
requirements = {{"santaKey"}},
|
|
||||||
map = "Chako",
|
|
||||||
event = "#0211"
|
|
||||||
},
|
|
||||||
kulala = {
|
|
||||||
requirements = {{"santaKey", "weaponBoss"}},
|
|
||||||
map = "Weed",
|
|
||||||
event = "0702"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
grasstownEast = {
|
|
||||||
connections = {
|
|
||||||
grasstownWest = {{"eventFans"}, {"flight"}},
|
|
||||||
plantation = {{"bomb", "weaponSN"}}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
kazuma1 = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Weed",
|
|
||||||
event = "#0800"
|
|
||||||
},
|
|
||||||
kazuma2 = {
|
|
||||||
requirements = {{"eventFans"}},
|
|
||||||
map = "Weed",
|
|
||||||
event = "#0801"
|
|
||||||
},
|
|
||||||
execution = {
|
|
||||||
requirements = {{"weaponSN"}},
|
|
||||||
map = "WeedD",
|
|
||||||
event = "#0305"
|
|
||||||
},
|
|
||||||
outsideHut = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Weed",
|
|
||||||
event = "#0303"
|
|
||||||
},
|
|
||||||
hutChest = {
|
|
||||||
requirements = {{"eventFans"}, {"flight"}},
|
|
||||||
map = "WeedB",
|
|
||||||
event = "#0301"
|
|
||||||
},
|
|
||||||
gumChest = {
|
|
||||||
requirements = {{"eventFans", "gumKey", "weaponBoss"}, {"flight", "gumKey", "weaponBoss"}},
|
|
||||||
map = "Frog",
|
|
||||||
event = "#0300"
|
|
||||||
},
|
|
||||||
malco = {
|
|
||||||
requirements = {{"eventFans", "juice", "charcoal", "gum"}},
|
|
||||||
map = "Malco",
|
|
||||||
event = "#0350"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
events = {
|
|
||||||
eventFans = {
|
|
||||||
requirements = {{"rustyKey", "weaponBoss"}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
upperSandZone = {
|
|
||||||
connections = {
|
|
||||||
arthur = {},
|
|
||||||
lowerSandZone = {{"eventOmega"}}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
curly = {
|
|
||||||
requirements = {{"polarStar"}},
|
|
||||||
map = "Curly",
|
|
||||||
event = "#0518"
|
|
||||||
},
|
|
||||||
panties = {
|
|
||||||
requirements = {},
|
|
||||||
map = "CurlyS",
|
|
||||||
event = "#0421"
|
|
||||||
},
|
|
||||||
curlyPup = {
|
|
||||||
requirements = {},
|
|
||||||
map = "CurlyS",
|
|
||||||
event = "#0401"
|
|
||||||
},
|
|
||||||
sandCapsule = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Sand",
|
|
||||||
event = "#0502"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
events = {
|
|
||||||
eventOmega = {
|
|
||||||
requirements = {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
lowerSandZone = {
|
|
||||||
connections = {
|
|
||||||
upperSandZone = {{"eventOmega"}},
|
|
||||||
labyrinthW = {{"puppy1", "puppy2", "puppy3", "puppy4", "puppy5", "weaponBoss"}, {"flight"}}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
chestPup = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Sand",
|
|
||||||
event = "#0421"
|
|
||||||
},
|
|
||||||
pupCapsule = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Sand",
|
|
||||||
event = "#0503"
|
|
||||||
},
|
|
||||||
darkPup = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Dark",
|
|
||||||
event = "#0401"
|
|
||||||
},
|
|
||||||
runPup = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Sand",
|
|
||||||
event = "#0422"
|
|
||||||
},
|
|
||||||
sleepyPup = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Sand",
|
|
||||||
event = "#0421"
|
|
||||||
},
|
|
||||||
jenka = {
|
|
||||||
requirements = {{"puppy:5"}},
|
|
||||||
map = "Jenka2",
|
|
||||||
event = "#0221"
|
|
||||||
},
|
|
||||||
king = {
|
|
||||||
requirements = {{"puppy:5", "weaponBoss"}},
|
|
||||||
map = "Gard",
|
|
||||||
event = "#0602"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
labyrinthB = {
|
|
||||||
connections = {
|
|
||||||
labyrinthW = {{"flight", "weaponBoss"}},
|
|
||||||
boulder = {{"flight"}},
|
|
||||||
arthur = {}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
fallenBooster = {
|
|
||||||
requirements = {},
|
|
||||||
map = "MazeB",
|
|
||||||
event = "#0502"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
labyrinthW = {
|
|
||||||
connections = {
|
|
||||||
lowerSandZone = {},
|
|
||||||
labyrinthB = {{"weaponBoss"}},
|
|
||||||
boulder = {},
|
|
||||||
labyrinthM = {{"flight"}}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
critterCapsule = {
|
|
||||||
requirements = {{"weaponBoss"}},
|
|
||||||
map = "MazeI",
|
|
||||||
event = "#0301"
|
|
||||||
},
|
|
||||||
turboChaba = {
|
|
||||||
requirements = {{"machineGun"}},
|
|
||||||
map = "MazeA",
|
|
||||||
event = "#0502"
|
|
||||||
},
|
|
||||||
snakeChaba = {
|
|
||||||
requirements = {{"fireball"}},
|
|
||||||
map = "MazeA",
|
|
||||||
event = "#0512"
|
|
||||||
},
|
|
||||||
whimChaba = {
|
|
||||||
requirements = {{"polarStar:2"}},
|
|
||||||
map = "MazeA",
|
|
||||||
event = "#0522"
|
|
||||||
},
|
|
||||||
armsBarrier = {
|
|
||||||
requirements = {{"flight"}},
|
|
||||||
map = "MazeO",
|
|
||||||
event = "#0401"
|
|
||||||
},
|
|
||||||
physician = {
|
|
||||||
requirements = {},
|
|
||||||
map = "MazeO",
|
|
||||||
event = "#0305"
|
|
||||||
},
|
|
||||||
puuBlack = {
|
|
||||||
requirements = {{"clinicKey", "weaponBoss"}},
|
|
||||||
map = "MazeD",
|
|
||||||
event = "#0401"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
boulder = {
|
|
||||||
connections = {
|
|
||||||
labyrinthB = {},
|
|
||||||
labyrinthW = {},
|
|
||||||
labyrinthM = {{"cureAll", "weaponBoss"}}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
boulderChest = {
|
|
||||||
requirements = {{"cureAll", "weaponBoss"}},
|
|
||||||
map = "MazeS",
|
|
||||||
event = "#0202"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
labyrinthM = {
|
|
||||||
connections = {
|
|
||||||
labyrinthW = {},
|
|
||||||
boulder = {{"cureAll", "weaponBoss"}},
|
|
||||||
darkPlace = {}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
darkPlace = {
|
|
||||||
connections = {
|
|
||||||
waterway = {{"airTank"}},
|
|
||||||
core = {{"cureAll"}},
|
|
||||||
labyrinthM = {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
core = {
|
|
||||||
connections = {
|
|
||||||
darkPlace = {}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
ropeSpot = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Almond",
|
|
||||||
event = "#0243"
|
|
||||||
},
|
|
||||||
curlyCorpse = {
|
|
||||||
requirements = {{"eventCore"},
|
|
||||||
map = "Almond",
|
|
||||||
event = "#1111"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
events = {
|
|
||||||
eventCore = {
|
|
||||||
requirements = {{"weaponBoss"}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
waterway = {
|
|
||||||
connections = {
|
|
||||||
darkPlace = {},
|
|
||||||
mimigaVillage = {{"weaponSN"}}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
ironhead = {
|
|
||||||
requirements = {{"weaponSN"}},
|
|
||||||
map = "Pool",
|
|
||||||
event = "#0412"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
events = {
|
|
||||||
eventCurly = {
|
|
||||||
requirements = {{"eventCore", "towRope"}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
eggCorridor2 = {
|
|
||||||
connections = {
|
|
||||||
arthur = {},
|
|
||||||
outerWall = {{"bomb"}}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
dragonChest = {
|
|
||||||
requirements = {{"weaponBoss"}},
|
|
||||||
map = "Eggs2",
|
|
||||||
event = "#0321"
|
|
||||||
},
|
|
||||||
sisters = {
|
|
||||||
requirements = {{"weaponBoss"}},
|
|
||||||
map = "EggR2",
|
|
||||||
event = "#0303"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
outerWall = {
|
|
||||||
connections = {
|
|
||||||
eggCorridor2 = {{"bomb"}},
|
|
||||||
plantation = {{"flight"}}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
clock = {
|
|
||||||
requirements = {}, --eventCurly? works like that in vanilla
|
|
||||||
map = "Clock",
|
|
||||||
event = "#0300"
|
|
||||||
},
|
|
||||||
littleHouse = {
|
|
||||||
requirements = {{"little", "flight"}},
|
|
||||||
map = "Little",
|
|
||||||
event = "#0204"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
plantation = {
|
|
||||||
connections = {
|
|
||||||
arthur = {{"teleportKey"}},
|
|
||||||
outerWall = {},
|
|
||||||
grasstownEast = {{"bomb", "weaponSN"}},
|
|
||||||
lastCave = {{"eventRocket", "booster:2", "weaponBoss"}}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
kanpachi = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Cent",
|
|
||||||
event = "#0268"
|
|
||||||
},
|
|
||||||
jail1 = {
|
|
||||||
requirements = {{"teleportKey"}},
|
|
||||||
map = "Jail1",
|
|
||||||
event = "#0301"
|
|
||||||
},
|
|
||||||
momorin = {
|
|
||||||
requirements = {{"letter", "booster1"}},
|
|
||||||
map = "Momo",
|
|
||||||
event = "#0201"
|
|
||||||
},
|
|
||||||
sprinkler = {
|
|
||||||
requirements = {{"mask"}},
|
|
||||||
map = "Cent",
|
|
||||||
event = "#0417"
|
|
||||||
},
|
|
||||||
megane = {
|
|
||||||
requirements = {{"brokenSprinkler", "mask"}},
|
|
||||||
map = "lounge",
|
|
||||||
event = "#0204"
|
|
||||||
},
|
|
||||||
itoh = {
|
|
||||||
requirements = {{"letter"}},
|
|
||||||
map = "Itoh",
|
|
||||||
event = "#0405"
|
|
||||||
},
|
|
||||||
topCapsule = {
|
|
||||||
requirements = {{"flight"}},
|
|
||||||
map = "Cent",
|
|
||||||
event = "#0501"
|
|
||||||
},
|
|
||||||
plantPup = {
|
|
||||||
requirements = {{"eventRocket"}},
|
|
||||||
map = "Cent",
|
|
||||||
event = "#0452"
|
|
||||||
},
|
|
||||||
curlyShroom = {
|
|
||||||
requirements = {{"eventCurly", "maPignon"}},
|
|
||||||
map = "Cent",
|
|
||||||
event = "#0324"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
events = {
|
|
||||||
eventRocket = {
|
|
||||||
requirements = {{"newSprinkler", "booster", "controller"}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
lastCave = {
|
|
||||||
connections = {
|
|
||||||
plantation = {},
|
|
||||||
balcony = {{"eventSue", "ironBond"}} --required to get into the endgame boss rush
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
redDemon = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Priso2",
|
|
||||||
event = "#0300",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
balcony = {
|
|
||||||
connections = {
|
|
||||||
lastCave = {}
|
|
||||||
},
|
|
||||||
locations = {
|
|
||||||
hellCapsule = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Hell1",
|
|
||||||
event = "#0401"
|
|
||||||
},
|
|
||||||
hellChest = {
|
|
||||||
requirements = {},
|
|
||||||
map = "Hell3",
|
|
||||||
event = "#0400"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
events = {
|
|
||||||
eventHellCurly = { --do you get to take curly with you in hell?
|
|
||||||
requirements = {{"eventCurly"}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
33
src/database/region.lua
Normal file
33
src/database/region.lua
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
local C = Class:extend()
|
||||||
|
|
||||||
|
function C:new(worldGraph, name)
|
||||||
|
self.locations = {}
|
||||||
|
self.world = worldGraph
|
||||||
|
self.name = name
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:canAccess(items)
|
||||||
|
return self.requirements == nil or self.requirements(items)
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:getLocation(key)
|
||||||
|
return self.locations[key]
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:getLocations()
|
||||||
|
return self.locations
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:getEmptyLocations()
|
||||||
|
return _.filter(self.locations, function(k,v) return not v:hasItem() end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:getFilledLocations()
|
||||||
|
return _.filter(self.locations, function(k,v) return v:hasItem() end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:writeItems(tscFiles)
|
||||||
|
for location in ipairs(self.locations) do location:writeItem(tscFiles) end
|
||||||
|
end
|
||||||
|
|
||||||
|
return C
|
479
src/database/world_graph.lua
Normal file
479
src/database/world_graph.lua
Normal file
|
@ -0,0 +1,479 @@
|
||||||
|
local Region = require 'region'
|
||||||
|
local Location = require 'location'
|
||||||
|
|
||||||
|
local firstCave = Region:extend()
|
||||||
|
function firstCave:new(worldGraph)
|
||||||
|
firstCave.super.new(self, worldGraph, "firstCave")
|
||||||
|
self.locations = {
|
||||||
|
"firstCapsule" = Location("First Cave Life Capsule", "Cave", "0401", self),
|
||||||
|
"gunsmithChest" = Location("Hermit Gunsmith Chest", "Pole", "0402", self),
|
||||||
|
"gunsmith" = Location("Tetsuzou", "Pole", "0303", self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.locations.gunsmith.requirements = function(items)
|
||||||
|
return self.world.regions.mimigaVillage:canAccess(items) and items:has("flight", "polarStar", "eventCore")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local mimigaVillage = Region:extend()
|
||||||
|
function mimigaVillage:new(worldGraph)
|
||||||
|
mimigaVillage.super.new(self, worldGraph, "mimigaVillage")
|
||||||
|
self.locations = {
|
||||||
|
"yamashita" = Location("Yamashita Farm", "Plant", "0401", self),
|
||||||
|
"reservoir" = Location("Reservoir", "Pool", "0301", self),
|
||||||
|
"mapChest" = Location("Mimiga Village Chest", "Mimi", "0202", self),
|
||||||
|
"assembly" = Location("Assembly Hall Fireplace", "Comu", "0303", self),
|
||||||
|
"mrLittle" = Location("Mr. Little (Graveyard)", "Cemet", "0202", self),
|
||||||
|
"grave" = Location("Arthur's Grave", "Cemet", "0301", self),
|
||||||
|
"mushroomChest" = Location("Storage? Chest", "Mapi", "0202", self),
|
||||||
|
"maPignon" = Location("Ma Pignon Boss", "Mapi", "0501", self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
if self.world.regions.firstCave:canAccess(items) and items:has("weaponSN") then return true end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self.locations.assembly.requirements = function(items) return items:has("juice") end
|
||||||
|
self.locations.mrLittle.requirements = function(items)
|
||||||
|
return self.world.regions.outerWall:canAccess(items) and items:has("flight", "locket")
|
||||||
|
end
|
||||||
|
self.locations.grave.requirements = function(items) return items:has("locket") end
|
||||||
|
self.locations.mushroomChest.requirements = function(items)
|
||||||
|
return items:has("flight", "locket", "eventCurly")
|
||||||
|
end
|
||||||
|
self.locations.maPignon.requirements = function(items)
|
||||||
|
-- stupid mushroom is invincible to the blade and machinegun for some reason
|
||||||
|
if items:has("flight", "locket", "mushroomBadge") then
|
||||||
|
if items:has("polarStar") or items:has("fireball") or items:has("bubbler")
|
||||||
|
or items:has("machineGun") or items:has("snake") or items:has("nemesis") then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self.locations.mrLittle:setItem(self.world.items:getByKey("mrLittle"))
|
||||||
|
end
|
||||||
|
|
||||||
|
local arthur = Region:extend()
|
||||||
|
function arthur:new(worldGraph)
|
||||||
|
arthur.super.new(self, worldGraph, "arthur")
|
||||||
|
self.locations = {
|
||||||
|
"risenBooster" = Location("Professor Booster", "Pens1", "0652", self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
if self.world.regions.mimigaVillage:canAccess(items) and items:has("arthursKey") then return true end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self.locations.booster.requirements = function(items) return items:has("eventCore") end
|
||||||
|
end
|
||||||
|
|
||||||
|
local eggCorridor1 = Region:extend()
|
||||||
|
function eggCorridor1:new(worldGraph)
|
||||||
|
eggCorridor1.super.new(self, worldGraph, "eggCorridor1")
|
||||||
|
self.locations = {
|
||||||
|
"basil" = Location("Basil Spot", "Eggs", "0403", self),
|
||||||
|
"cthulhu" = Location("Cthulhu's Abode", "Eggs", "0404", self),
|
||||||
|
"eggItem" = Location("Egg Chest", "Egg6", "0201", self),
|
||||||
|
"observationChest" = Location("Egg Observation Room Chest", "EggR", "0301", self),
|
||||||
|
"eventSue" = Location("Saved Sue", nil, nil, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items) return self.world.regions.arthur:canAccess(items) end
|
||||||
|
|
||||||
|
self.locations.eventSue.requirements = function(items) return items:has("idCard", "weaponBoss") end
|
||||||
|
self.locations.eventSue:setItem(self.world.items:getByKey("eventSue"))
|
||||||
|
end
|
||||||
|
|
||||||
|
local grasstownWest = Region:extend()
|
||||||
|
function grasstownWest:new(worldGraph)
|
||||||
|
grasstownWest.super.new(self, worldGraph, "grasstownWest")
|
||||||
|
self.locations = {
|
||||||
|
"keySpot" = Location("West Grasstown Floor", "Weed", "0700", self),
|
||||||
|
"jellyCapsule" = Location("West Grasstown Ceiling", "Weed", "0701", self),
|
||||||
|
"santa" = Location("Santa", "Santa", "0501", self),
|
||||||
|
"charcoal" = Location("Santa's Fireplace", "Santa", "0302", self),
|
||||||
|
"chaco" = Location("Chaco's Bed, where you two Had A Nap", "Chako", "0211", self),
|
||||||
|
"kulala" = Location("Kulala Chest", "Weed", "0702", self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
if self.world.regions.arthur:canAccess(items) then return true end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self.locations.santa.requirements = function(items) return items:has("santaKey") end
|
||||||
|
self.locations.charcoal.requirements = function(items) return items:has("santaKey", "juice") end
|
||||||
|
self.locations.chaco.requirements = function(items) return items:has("santaKey") end
|
||||||
|
self.locations.kulala.requirements = function(items) return items:has("santaKey", "weapon") end
|
||||||
|
end
|
||||||
|
|
||||||
|
local grasstownEast = Region:extend()
|
||||||
|
function grasstownEast:new(worldGraph)
|
||||||
|
grasstownEast.super.new(self, worldGraph, "grasstownEast")
|
||||||
|
self.locations = {
|
||||||
|
"kazuma1" = Location("Kazuma (Rusty Key)", "Weed", "0800", self),
|
||||||
|
"kazuma2" = Location("Kazuma (Gum Key)", "Weed", "0801", self),
|
||||||
|
"execution" = Location("Execution Chamber", "WeedD", "0305", self),
|
||||||
|
"outsideHut" = Location("Grasstown East Chest", "Weed", "0303", self),
|
||||||
|
"hutChest" = Location("Grasstown Hut", "WeedB", "0301", self),
|
||||||
|
"gumChest" = Location("Gum Chest", "Frog", "0300", self),
|
||||||
|
"malco" = Location("MALCO", "Malco", "0350", self),
|
||||||
|
"eventFans" = Location("Activated Grasstown Fans", nil, nil, self),
|
||||||
|
"eventKazuma" = Location("Saved Kazuma", nil, nil, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
if self.world.regions.grasstownWest:canAccess(items) then
|
||||||
|
if items:has("flight") or items:has("juice") then return true end
|
||||||
|
end
|
||||||
|
if self.world.regions.plantation:canAccess(items) and items:has("eventKazuma", "weaponSN") then return true end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self.locations.kazuma2.requirements = function(items) return items:has("eventFans") end
|
||||||
|
self.locations.execution.requirements = function(items) return items:has("weaponSN") end
|
||||||
|
self.locations.hutChest.requirements = function(items) return items:has("eventFans") or items:has("flight") end
|
||||||
|
self.locations.gumChest.requirements = function(items)
|
||||||
|
if items:has("gumKey", "weaponBoss") then
|
||||||
|
if items:has("eventFans") or items:has("flight") then return true end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
self.locations.malco.requirements = function(items) return items:has("eventFans", "juice", "charcoal", "gum") end
|
||||||
|
|
||||||
|
self.locations.eventFans.requirements = function(items) return items:has("rustyKey", "weaponBoss")
|
||||||
|
self.locations.eventFans:setItem(self.world.items:getByKey("eventFans"))
|
||||||
|
|
||||||
|
self.locations.eventKazuma.requirements = function(items) return items:has("bomb") end
|
||||||
|
self.locations.eventKazuma:setItem(self.world.items:getByKey("eventKazuma"))
|
||||||
|
end
|
||||||
|
|
||||||
|
local upperSandZone = Region:extend()
|
||||||
|
function upperSandZone:new(worldGraph)
|
||||||
|
upperSandZone.super.new(self, worldGraph, "upperSandZone")
|
||||||
|
self.locations = {
|
||||||
|
"curly" = Location("Curly Boss", "Curly", "0518", self),
|
||||||
|
"panties" = Location("Curly's Closet", "CurlyS", "0421", self),
|
||||||
|
"curlyPup" = Location("Puppy (Curly)", "CurlyS", "0401", self),
|
||||||
|
"sandCapsule" = Location("Polish Spot", "Sand", "0502", self),
|
||||||
|
"eventOmega" = Location("Defeated Omega", nil, nil, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
if self.world.regions.arthur:canAccess(items) and items:has("weaponSN") then return true end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self.locations.curly.requirements = function(items) return items:has("polarStar") end
|
||||||
|
|
||||||
|
self.locations.eventOmega.requirements = function(items) return items:has("weaponBoss") end
|
||||||
|
self.locations.eventOmega.setItem(self.world.items:getByKey("eventOmega"))
|
||||||
|
end
|
||||||
|
|
||||||
|
local lowerSandZone = Region:extend()
|
||||||
|
function lowerSandZone:new(worldGraph)
|
||||||
|
lowerSandZone.super.new(self, worldGraph, "lowerSandZone")
|
||||||
|
self.locations = {
|
||||||
|
"chestPup" = Location("Puppy (Chest)", "Sand", "0421", self),
|
||||||
|
"darkPup" = Location("Puppy (Dark)", "Dark", "0401", self),
|
||||||
|
"runPup" = Location("Puppy (Run)", "Sand", "0422", self),
|
||||||
|
"sleepyPup" = Location("Puppy (Sleep)", "Sand", "0421", self),
|
||||||
|
"pawCapsule" = Location("Pawprint Spot", "Sand", "0503", self),
|
||||||
|
"jenka" = Location("Jenka", "Jenka2", "0221", self),
|
||||||
|
"king" = Location("King", "Gard", "0602", self),
|
||||||
|
"eventToroko" = Location("Defeated Toroko+", nil, nil, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
if self.world.regions.upperSandZone:canAccess(items) and items:has("eventOmega") then return true end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self.locations.jenka.requirements = function(items) return items:count("puppy") == 5 end
|
||||||
|
self.locations.king.requirements = function(items) return items:has("eventToroko") end
|
||||||
|
|
||||||
|
self.locations.eventToroko.requirements = function(items)
|
||||||
|
return items:count("puppy") == 5 and items:has("weaponBoss")
|
||||||
|
end
|
||||||
|
self.locations.eventToroko:setItem(self.world.items:getByKey("eventToroko"))
|
||||||
|
end
|
||||||
|
|
||||||
|
local labyrinthW = Region:extend()
|
||||||
|
function labyrinthW:new(worldGraph)
|
||||||
|
labyrinthW.super.new(self, worldGraph, "labyrinthW")
|
||||||
|
self.locations = {
|
||||||
|
"mazeCapsule" = Location("Labyrinth Life Capsule", "MazeI", "0301", self),
|
||||||
|
"turboChaba" = Location("Chaba Chest (Machine Gun)", "MazeA", "0502", self),
|
||||||
|
"snakeChaba" = Location("Chaba Chest (Fireball)", "MazeA", "0512", self),
|
||||||
|
"whimChaba" = Location("Chaba Chest (Spur)", "MazeA", "0522", self),
|
||||||
|
"campChest" = Location("Camp Chest", "MazeO", "0401", self),
|
||||||
|
"physician" = Location("Dr. Gero", "MazeO", "0305", self),
|
||||||
|
"puuBlack" = Location("Puu Black Boss", "MazeD", "0401", self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
if self.world.regions.lowerSandZone:canAccess(items) and items:has("eventToroko") then return true end
|
||||||
|
if self.world.regions.labyrinthB:canAccess(items) and items:has("flight") then return true end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self.locations.mazeCapsule.requirements = function(items) return items:has("weapon") end
|
||||||
|
self.locations.turboChaba.requirements = function(items) return items:has("machineGun") end
|
||||||
|
self.locations.snakeChaba.requirements = function(items) return items:has("fireball") end
|
||||||
|
self.locations.whimChaba.requirements = function(items) return items:count("polarStar") == 2 end
|
||||||
|
self.locations.campChest.requirements = function(items) return items:has("flight") end
|
||||||
|
self.locations.puuBlack.requirements = function(items) return items:has("clinicKey", "weaponBoss") end
|
||||||
|
end
|
||||||
|
|
||||||
|
local labyrinthB = Region:extend()
|
||||||
|
function labyrinthB:new(worldGraph)
|
||||||
|
labyrinthB.super.new(self, worldGraph, "labyrinthB")
|
||||||
|
self.locations = {
|
||||||
|
"fallenBooster" = Location("Booster Chest", "MazeB", "0502", self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
if self.world.regions.arthur:canAccess(items) then return true end
|
||||||
|
if self.world.regions.labyrinthW:canAccess(items) then return true end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local boulder = Region:extend()
|
||||||
|
function boulder:new(worldGraph)
|
||||||
|
boulder.super.new(self, worldGraph, "boulder")
|
||||||
|
self.locations = { --include core locations since core access reqs are identical to boulder chamber
|
||||||
|
"boulderChest" = Location("Boulder Chest", "MazeS", "0202", self),
|
||||||
|
"coreSpot" = Location("Robot's Arm", "Almond", "0243", self),
|
||||||
|
"curlyCorpse" = Location("Drowned Curly", "Almond", "1111", self),
|
||||||
|
"eventCore" = Location("Defeated Core", nil, nil, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
if items:has("cureAll", "weaponBoss") then
|
||||||
|
if self.world.regions.labyrinthW:canAccess(items) then return true end
|
||||||
|
if self.world.regions.labyrinthB:canAccess(items) and items:has("flight") then return true end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self.locations.eventCore.setItem(self.world.items:getByKey("eventCore"))
|
||||||
|
end
|
||||||
|
|
||||||
|
local labyrinthM = Region:extend()
|
||||||
|
function labyrinthM:new(worldGraph)
|
||||||
|
labyrinthM.super.new(self, worldGraph, "labyrinthM")
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
if self.world.regions.boulder:canAccess(items) then return true end
|
||||||
|
if self.world.regions.labyrinthW:canAccess(items) and items:has("flight") then return true end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local waterway = Region:extend()
|
||||||
|
function waterway:new(worldGraph)
|
||||||
|
waterway.super.new(self, worldGraph, "waterway")
|
||||||
|
|
||||||
|
self.locations = {
|
||||||
|
"ironhead" = Location("Ironhead Boss", "Pool", "0412", self),
|
||||||
|
"eventCurly" = Location("Saved Curly", nil, nil, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items) return self.world.regions.labyrinthM:canAccess(items) and items:has("airTank", "weaponBoss") end
|
||||||
|
|
||||||
|
self.locations.eventCurly.requirements = function(items) return items:has("eventCore", "towRope") end
|
||||||
|
self.locations.eventCurly.setItem(self.world.items:getByKey("eventCurly"))
|
||||||
|
end
|
||||||
|
|
||||||
|
local eggCorridor2 = Region:extend()
|
||||||
|
function eggCorridor2:new(worldGraph)
|
||||||
|
eggCorridor2.super.new(self, worldGraph, "eggCorridor2")
|
||||||
|
|
||||||
|
self.locations = {
|
||||||
|
"dragonChest" = Location("Dragon Chest", "Eggs2", "0321", self),
|
||||||
|
"sisters" = Location("Sisters Boss", "EggR2", "0303", self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
if items:has("eventCore") and self.world.regions.arthur:canAccess(items) then return true end
|
||||||
|
if items:has("eventKazuma") and self.world.regions.outerWall:canAccess(items) then return true end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self.locations.dragonChest.requirements = function(items) return items:has("weapon") end
|
||||||
|
self.locations.sisters.requirements = function(items) return items:has("weaponBoss") end
|
||||||
|
end
|
||||||
|
|
||||||
|
local outerWall = Region:extend()
|
||||||
|
function outerWall:new(worldGraph)
|
||||||
|
outerWall.super.new(self, worldGraph, "outerWall")
|
||||||
|
|
||||||
|
self.locations = {
|
||||||
|
"clock" = Location("Clock Room", "Clock", "0300", self),
|
||||||
|
"littleHouse" = Location("Little House", "Little", "0204", self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
if items:has("eventKazuma", "flight") and self.world.regions.eggCorridor2:canAccess(items) then return true end
|
||||||
|
if items:has("teleportKey") and self.world.regions.plantation:canAccess(items) then return true end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self.locations.littleHouse.requirements = function(items) return items:has("flight") end
|
||||||
|
end
|
||||||
|
|
||||||
|
local plantation = Region:extend()
|
||||||
|
function plantation:new(worldGraph)
|
||||||
|
plantation.super.new(self, worldGraph, "plantation")
|
||||||
|
|
||||||
|
self.locations = {
|
||||||
|
"kanpachi" = Location("Kanpachi's Bucket", "Cent", "0268", self),
|
||||||
|
"jail1" = Location("Jail no. 1", "Jail1", "0301", self),
|
||||||
|
"momorin" = Location("Chivalry Sakamoto's Wife", "Momo", "0201", self),
|
||||||
|
"sprinkler" = Location("Broken Sprinkler", "Cent", "0417", self),
|
||||||
|
"megane" = Location("Megane", "lounge", "0204", self),
|
||||||
|
"itoh" = Location("Itoh", "Itoh", "0405", self),
|
||||||
|
"plantCeiling" = Location("Plantation Platforming Spot", "Cent", "0501", self),
|
||||||
|
"plantPup" = Location("Plantation Puppy", "Cent", "0452", self),
|
||||||
|
"curlyShroom" = Location("Jammed it into Curly's Mouth" "Cent", "0324", self),
|
||||||
|
"eventRocket" = Location("Built Rocket", nil, nil, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
if items:has("teleportKey") and self.world.regions.arthur:canAccess(items) then return true end
|
||||||
|
if self.world.regions.outerWall:canAccess(items) then return true end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self.locations.jail1.requirements = function(items) return items:has("letter") end
|
||||||
|
self.locations.momorin.requirements = function(items) return items:has("letter", "booster") end
|
||||||
|
self.locations.sprinkler.requirements = function(items) return items:has("mask") end
|
||||||
|
self.locations.megane.requirements = function(items) return items:has("brokenSprinkler", "mask") end
|
||||||
|
self.locations.itoh.requirements = function(items) return items:has("letter") end
|
||||||
|
self.locations.plantCeiling.requirements = function(items) return items:has("flight") end
|
||||||
|
self.locations.plantPup.requirements = function(items) return items:has("eventRocket") end
|
||||||
|
self.locations.curlyShroom.requirements = function(items) return items:has("eventCurly", "maPignon") end
|
||||||
|
|
||||||
|
self.locations.eventRocket.requirements = function(items)
|
||||||
|
return items:has("letter", "booster", "controller", "sprinkler")
|
||||||
|
end
|
||||||
|
self.locations.eventRocket.setItem(self.world.items:getByKey("eventRocket"))
|
||||||
|
end
|
||||||
|
|
||||||
|
local lastCave = Region:extend()
|
||||||
|
function lastCave:new(worldGraph)
|
||||||
|
lastCave.super.new(self, worldGraph, "lastCave")
|
||||||
|
|
||||||
|
self.locations = {
|
||||||
|
"redDemon" = Location("Red Demon Boss", "Priso2", "0300", self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items) return items:has("eventRocket", "weaponBoss") end
|
||||||
|
end
|
||||||
|
|
||||||
|
local endgame = Region:extend()
|
||||||
|
function endgame:new(worldGraph)
|
||||||
|
endgame.super.new(self, worldGraph, "endgame")
|
||||||
|
|
||||||
|
self.locations = {
|
||||||
|
"hellB1" = Location("Hell B1 Spot", "Hell1", "0401", self),
|
||||||
|
"hellB3" = Location("Hell B3 Chest", "Hell3", "0400", self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.requirements = function(items)
|
||||||
|
return items:has("eventSue", "ironBond") and self.world.regions.lastCave:canAccess(items) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local worldGraph = Class:extend()
|
||||||
|
|
||||||
|
function worldGraph:new(items)
|
||||||
|
self.regions = {
|
||||||
|
firstCave = firstCave(self),
|
||||||
|
mimigaVillage = mimigaVillage(self),
|
||||||
|
arthur = arthur(self),
|
||||||
|
eggCorridor1 = eggCorridor1(self),
|
||||||
|
grasstownWest = grasstownWest(self),
|
||||||
|
grasstownEast = grasstownEast(self),
|
||||||
|
upperSandZone = upperSandZone(self),
|
||||||
|
lowerSandZone = lowerSandZone(self),
|
||||||
|
labyrinthW = labyrinthW(self),
|
||||||
|
labyrinthB = labyrinthB(self),
|
||||||
|
boulder = boulder(self),
|
||||||
|
labyrinthM = labyrinthM(self),
|
||||||
|
waterway = waterway(self),
|
||||||
|
eggCorridor2 = eggCorridor2(self),
|
||||||
|
outerWall = outerWall(self),
|
||||||
|
plantation = plantation(self),
|
||||||
|
lastCave = lastCave(self),
|
||||||
|
endgame = endgame(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.items = items
|
||||||
|
end
|
||||||
|
|
||||||
|
function worldGraph:getLocations()
|
||||||
|
local locations = {}
|
||||||
|
for region in ipairs(self.regions) do
|
||||||
|
locations = _.union(locations, region:getLocations())
|
||||||
|
end
|
||||||
|
return locations
|
||||||
|
end
|
||||||
|
|
||||||
|
function worldGraph:getLocationsByRegion(...)
|
||||||
|
local locations = {}
|
||||||
|
for region in ipairs(self.regions) do
|
||||||
|
if _.contains({...}, region.name) then locations = _.union(locations, region:getLocations()) end
|
||||||
|
end
|
||||||
|
return locations
|
||||||
|
end
|
||||||
|
|
||||||
|
function worldGraph:getEmptyLocations()
|
||||||
|
local locations = {}
|
||||||
|
for region in ipairs(self.regions) do
|
||||||
|
locations = _.union(locations, region:getEmptyLocations())
|
||||||
|
end
|
||||||
|
return locations
|
||||||
|
end
|
||||||
|
|
||||||
|
function worldGraph:getFilledLocations()
|
||||||
|
local locations = {}
|
||||||
|
for region in ipairs(self.regions) do
|
||||||
|
locations = _.union(locations, region:getFilledLocations())
|
||||||
|
end
|
||||||
|
return locations
|
||||||
|
end
|
||||||
|
|
||||||
|
function worldGraph:writeItems(tscFiles)
|
||||||
|
for region in ipairs(self.regions) do region:writeItems(tscFiles) end
|
||||||
|
end
|
||||||
|
|
||||||
|
function worldGraph:collect(preCollectedItems)
|
||||||
|
local collected = preCollectedItems or {}
|
||||||
|
local availableLocations = self:getFilledLocations()
|
||||||
|
|
||||||
|
local foundItems
|
||||||
|
|
||||||
|
repeat
|
||||||
|
local accessible = {}
|
||||||
|
for location in ipairs(availableLocations) do
|
||||||
|
if location:canAccess(collected) then table.insert(accessible, location) end
|
||||||
|
end
|
||||||
|
|
||||||
|
availableLocations = _.difference(availableLocations, accessible)
|
||||||
|
|
||||||
|
foundItems = #accesible
|
||||||
|
for location in ipairs(accessible) do
|
||||||
|
table.insert(collected, location.item)
|
||||||
|
end
|
||||||
|
until foundItems == 0
|
||||||
|
|
||||||
|
return collected
|
||||||
|
end
|
||||||
|
|
||||||
|
return worldGraph
|
|
@ -12,6 +12,7 @@ lg = love.graphics
|
||||||
|
|
||||||
U = require 'util'
|
U = require 'util'
|
||||||
|
|
||||||
|
|
||||||
local LOG_LEVEL, _logCounts, _logLines = 3, nil, nil
|
local LOG_LEVEL, _logCounts, _logLines = 3, nil, nil
|
||||||
local function _log(level, prefix, text, ...)
|
local function _log(level, prefix, text, ...)
|
||||||
if LOG_LEVEL >= level then
|
if LOG_LEVEL >= level then
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
local ItemDeck = require 'item_deck'
|
local Items = require 'database.items'
|
||||||
local TscFile = require 'tsc_file'
|
local TscFile = require 'tsc_file'
|
||||||
local WorldGraph = require 'database.locations'
|
local WorldGraph = require 'database.world_graph'
|
||||||
|
|
||||||
local C = Class:extend()
|
local C = Class:extend()
|
||||||
|
|
||||||
local TSC_FILES = {}
|
local TSC_FILES = {}
|
||||||
do
|
do
|
||||||
local ITEM_DATA = require 'database.items'
|
for location in ipairs(WorldGraph():getLocations()) do
|
||||||
for k, v in pairs(ITEM_DATA) do
|
local filename = location.map .. '.tsc'
|
||||||
local filename = v.map .. '.tsc'
|
if not _.contains(TSC_FILES, filename) then
|
||||||
if _.contains(TSC_FILES, filename) == false then
|
|
||||||
table.insert(TSC_FILES, filename)
|
table.insert(TSC_FILES, filename)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -17,6 +16,8 @@ end
|
||||||
|
|
||||||
function C:new()
|
function C:new()
|
||||||
self._isCaveStoryPlus = false
|
self._isCaveStoryPlus = false
|
||||||
|
self.itemDeck = Items()
|
||||||
|
self.worldGraph = WorldGraph(itemDeck)
|
||||||
end
|
end
|
||||||
|
|
||||||
function C:randomize(path)
|
function C:randomize(path)
|
||||||
|
@ -29,12 +30,9 @@ function C:randomize(path)
|
||||||
self:_seedRngesus()
|
self:_seedRngesus()
|
||||||
local tscFiles = self:_createTscFiles(dirStage)
|
local tscFiles = self:_createTscFiles(dirStage)
|
||||||
-- self:_writePlaintext(tscFiles)
|
-- self:_writePlaintext(tscFiles)
|
||||||
local canNotBreakBlocks = self:_shuffleItems(tscFiles)
|
self:_shuffleItems(tscFiles)
|
||||||
self:_writeModifiedData(tscFiles)
|
-- self:_writeModifiedData(tscFiles)
|
||||||
self:_writePlaintext(tscFiles)
|
self:_writePlaintext(tscFiles)
|
||||||
if canNotBreakBlocks then
|
|
||||||
self:_copyModifiedFirstCave()
|
|
||||||
end
|
|
||||||
self:_writeLog()
|
self:_writeLog()
|
||||||
self:_unmountDirectory(path)
|
self:_unmountDirectory(path)
|
||||||
return self:_getStatusMessage()
|
return self:_getStatusMessage()
|
||||||
|
@ -100,37 +98,43 @@ function C:_writePlaintext(tscFiles)
|
||||||
end
|
end
|
||||||
|
|
||||||
function C:_shuffleItems(tscFiles)
|
function C:_shuffleItems(tscFiles)
|
||||||
local itemDeck = ItemDeck()
|
-- first fill puppies
|
||||||
local worldGraph = WorldGraph()
|
local puppies = self.itemDeck:getItemsByAttribute("puppy")
|
||||||
|
local sandZone = _.shuffle(self.worldGraph:getLocationsByRegion("upperSandZone", "lowerSandZone"))
|
||||||
|
self:_fastFillItems(puppies, sandZone)
|
||||||
|
|
||||||
-- first, place puppies in the sand zone
|
local mandatory = _.shuffle(self.itemDeck:getMandatoryItems())
|
||||||
for i=1, 5 do
|
local optional = _.shuffle(self.itemDeck:getOptionalItems())
|
||||||
local puppy = itemDeck:placeAnyByAttributes({"puppy"})
|
|
||||||
local puppySpot = worldGraph:getAnyByRegion({"lowerSandZone", "upperSandZone"})
|
|
||||||
|
|
||||||
placeItem(puppySpot, puppy)
|
-- next fill hell chests, which cannot have mandatory items
|
||||||
|
self:_fastFillItems(optional, self.worldGraph:getLocationsByRegion("endgame"))
|
||||||
|
|
||||||
|
self:_fillItems(mandatory, _.shuffle(self.worldGraph:getEmptyLocations()))
|
||||||
|
self:_fastFillItems(optional, _.shuffle(self.worldGraph:getEmptyLocations()))
|
||||||
|
|
||||||
|
worldGraph:writeItems()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- next, place weapon at hermit gunsmith and random item in first cave
|
function C:_fillItems(items, locations)
|
||||||
placeItem(worldGraph:get("gunsmithChest"), itemDeck:placeAnyByAttributes({"weaponSN"}))
|
local itemsLeft = _.clone(items)
|
||||||
placeItem(worldGraph:get("firstCapsule"), itemDeck:placeAny())
|
assert(#items <= #locations, 'Trying to fill more items than there are locations!')
|
||||||
|
|
||||||
-- for now, just implementing a forward fill - will do a better fill later
|
for item in ipairs(items) do
|
||||||
while itemDeck:remaining() > 0 do
|
local assumed = self.worldGraph:collect(_.remove(itemsLeft, item))
|
||||||
local location = worldGraph:getAnyAccessible(itemDeck:getPlacedItems())
|
local fillable = _.filter(locations, function(location, assumed) do
|
||||||
local item, itemIndex
|
return not location:hasItem() and location:canAccess(assumed) end)
|
||||||
|
assert(#fillable > 0, 'No available locations!')
|
||||||
while ~location do
|
fillable[1]:setItem(item)
|
||||||
item, itemIndex = itemDeck:getAnyByAttributes({"progression"})
|
end
|
||||||
location = worldGraph:getAnyAccessible(itemDeck:getPlacedItems(item))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if ~item then
|
function C:_fastFillItems(items, locations)
|
||||||
item, itemIndex = itemDeck:getAny()
|
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
|
end
|
||||||
itemDeck:place(item, itemIndex)
|
|
||||||
|
|
||||||
tscFiles[location.map]:placeItem(location.event, itemData.item.script)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
local C = Class:extend()
|
local C = Class:extend()
|
||||||
|
|
||||||
local ITEM_DATA = require 'database.items'
|
-- local ITEM_DATA = require 'database.items'
|
||||||
|
|
||||||
local OPTIONAL_REPLACES = {
|
-- local OPTIONAL_REPLACES = {
|
||||||
'Max health increased by ',
|
'Max health increased by ',
|
||||||
'Max life increased by ',
|
'Max life increased by ',
|
||||||
'<ACH0041', -- Cave Story+ only, trigger achievement.
|
'<ACH0041', -- Cave Story+ only, trigger achievement.
|
||||||
|
@ -37,6 +37,11 @@ function C:hasUnreplacedItems()
|
||||||
return #self._unreplaced >= 1
|
return #self._unreplaced >= 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function C:placeItemAtLocation(script, event)
|
||||||
|
local labelStart = self:_getLabelPositionRange(event)
|
||||||
|
self:_stringReplace(self._text, "<EVE$%d%d%d%d", script, event)
|
||||||
|
end
|
||||||
|
|
||||||
function C:replaceItem(replacement)
|
function C:replaceItem(replacement)
|
||||||
assert(self:hasUnreplacedItems())
|
assert(self:hasUnreplacedItems())
|
||||||
local key = self._unreplaced[#self._unreplaced].key
|
local key = self._unreplaced[#self._unreplaced].key
|
||||||
|
|
Loading…
Reference in a new issue