mirror of
https://github.com/cave-story-randomizer/cave-story-randomizer
synced 2025-01-03 10:46:49 +00:00
Added Randomizer class.
This commit is contained in:
parent
809f472a57
commit
18158264cd
|
@ -48,6 +48,7 @@ finished the rocket. +5 HP.
|
||||||
initial descent. +5 HP.
|
initial descent. +5 HP.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
** MISSILE EXPANSIONS **
|
** MISSILE EXPANSIONS **
|
||||||
These each give +5 Max Missile Launcher Ammo. Your max ammo carries over to
|
These each give +5 Max Missile Launcher Ammo. Your max ammo carries over to
|
||||||
the Super Missile Launcher. You'll have 30 missile ammo if you find them all,
|
the Super Missile Launcher. You'll have 30 missile ammo if you find them all,
|
||||||
|
@ -75,6 +76,89 @@ concealing a chest containing this massive expansion of 24 Misisles.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-----------------
|
||||||
|
- 3-01 Weapons -
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
- Polar Star
|
||||||
|
You find this weapon at the very beginning of the game. It's not the strongest
|
||||||
|
weapon, but it's definitely one of the easiest to use and useful in a wide
|
||||||
|
variety of situations. Keep it when Curly asks you to trade in the Sand Zone
|
||||||
|
if you want the Snake or Spur weapons later.
|
||||||
|
|
||||||
|
- Machine Gun
|
||||||
|
Given to you by Curly Brace if you trade her the Polar Star. Keep the Polar
|
||||||
|
Star when she asks you by choosing "No" if you want the Snake or Spur later in
|
||||||
|
the game. The Machine Gun is still an excellent weapon, though, and perfect
|
||||||
|
for your first time through the game as it's not only the easiest Polar Star
|
||||||
|
trade-off weapon to obtain but Level 3 allows you to float upwards in the
|
||||||
|
air as long as you have ammo, vastly increasing your mobility. It has an ammo
|
||||||
|
count of 100 but auto-recharges, and the recharge rate vastly skyrockets once
|
||||||
|
you get the Turbocharge key item which only works with the Machine Gun.
|
||||||
|
|
||||||
|
- Snake
|
||||||
|
Obtained by keeping the Polar Star when Curly asks you to trade and then giving
|
||||||
|
both the Polar Star and Fireball weapons to Chaba (the Gaudi shopkeep in the
|
||||||
|
Labyrinth) when you reach him. It's unique in that it's the only weapon in the
|
||||||
|
game capable of passing through walls. It's very similar to the Wave Beam in
|
||||||
|
early Metroid games.
|
||||||
|
|
||||||
|
- Spur
|
||||||
|
Unique weapon considered by many to be the ultimate weapon in the game, and it
|
||||||
|
probably should be considering how long you have to keep the Polar Star if you
|
||||||
|
want this. You'll need to get the Booster 2.0 and fly back into the very first
|
||||||
|
area of the game--before the Mimiga Village--and revisit the hermit weaponsmith
|
||||||
|
with your original Polar Star to earn the Spur. Instead of levelling up
|
||||||
|
through crystals, it "gains levels" the longer you keep the shot button held
|
||||||
|
down, and is the only weapon that has a different effect at MAX level compared
|
||||||
|
to Level 3.
|
||||||
|
|
||||||
|
- Missile Launcher
|
||||||
|
You recieve this early in the game, in the Egg Corridor. It's the only weapon
|
||||||
|
with limited ammo that doesn't automatically replenish, but it's also very
|
||||||
|
powerful. Easy to use, mostly works like a longer-ranged and more powerful
|
||||||
|
version of the Polar Star.
|
||||||
|
|
||||||
|
- Super Missile Launcher
|
||||||
|
Found in the Boulder Chamber, this is an upgrade to your Missile Launcher which
|
||||||
|
basically makes every aspect of it better, though it takes a bit more EXP to
|
||||||
|
level up. Besides raw damage, the most noticeable upgrade from the standard
|
||||||
|
Missile Launcher is the velocity of the missiles, or the speed at which they
|
||||||
|
travel across the screen. Also, the missiles launched by this weapon are gold
|
||||||
|
in color.
|
||||||
|
|
||||||
|
- Fireball
|
||||||
|
Given to you by Santa (the Mimiga with a strange name, not the Christmas guy)
|
||||||
|
in the Bushlands for helping him get back into his house. This can be a decent
|
||||||
|
alternative to the Polar Star or Machine Gun early in the game, as it's the
|
||||||
|
only weapon other than the Polar Star you'll find with truly unlimited ammo for
|
||||||
|
awhile. It shoots balls of plasma that bounce around along the ground, great
|
||||||
|
for grounded enemies and for use around slopes, and its rapidity mixed with its
|
||||||
|
good power for its point in the game makes it good against many bosses.
|
||||||
|
|
||||||
|
- Bubbline (aka Bubbler)
|
||||||
|
A very unique hidden weapon obtainable by taking a Jelly Juice jar back to the
|
||||||
|
assembly hall in Mimiga Village and putting out the fireplace there. It's
|
||||||
|
called the Bubbler in the English fan-translation of the PC version of Cave
|
||||||
|
Story. It has a lot of potential use at Level 3 but is otherwise pretty under-
|
||||||
|
whelming. It has an ammo supply of 100 which regenerates on its own slowly.
|
||||||
|
|
||||||
|
- Blade
|
||||||
|
Very powerful weapon given to you by King at a certain point in the story. Its
|
||||||
|
rapidity is very low (except for rapid releases of Level 1 or 2 shots in a
|
||||||
|
strong enemy or boss's face) and it has a short range, but the damage is huge
|
||||||
|
and it has infinite ammo.
|
||||||
|
|
||||||
|
- Nemesis
|
||||||
|
Special weapon of great strength that can be obtained by trading King's Blade
|
||||||
|
to Mister Little. The weapon is unique in that levelling it up outright causes
|
||||||
|
it to weaken in every possible way, and it only takes 1 exp to level it up both
|
||||||
|
levels. Luckily, this also means that taking a hit from just about anything
|
||||||
|
will guarantee resetting it to Level 1, at which point it's at its strongest.
|
||||||
|
Overall, it's probably a more similar weapon to the Polar Star than anything
|
||||||
|
else, even the weapons that you actually trade the Polar Star for. Infinite
|
||||||
|
ammo.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
** KEY ITEMS **
|
** KEY ITEMS **
|
||||||
|
|
85
src/main.lua
85
src/main.lua
|
@ -20,17 +20,7 @@ function logNotice(...) _log(3, 'NOTICE: ', ...) end
|
||||||
function logInfo(...) _log(4, 'INFO: ', ...) end
|
function logInfo(...) _log(4, 'INFO: ', ...) end
|
||||||
function logDebug(...) _log(5, 'DEBUG: ', ...) end
|
function logDebug(...) _log(5, 'DEBUG: ', ...) end
|
||||||
|
|
||||||
local TSC_FILES = {}
|
local randomizer = require 'randomizer'()
|
||||||
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
|
|
||||||
|
|
||||||
local background
|
local background
|
||||||
local font
|
local font
|
||||||
local screen
|
local screen
|
||||||
|
@ -46,78 +36,7 @@ function love.load()
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.directorydropped(path)
|
function love.directorydropped(path)
|
||||||
-- Mount.
|
status = randomizer:randomize(path)
|
||||||
local mountPath = 'mounted-data'
|
|
||||||
assert(lf.mount(path, mountPath))
|
|
||||||
local dirStage = '/' .. mountPath
|
|
||||||
do
|
|
||||||
local items = lf.getDirectoryItems(dirStage)
|
|
||||||
local containsData = _.contains(items, 'data')
|
|
||||||
if containsData then
|
|
||||||
dirStage = dirStage .. '/data'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
do
|
|
||||||
local items = lf.getDirectoryItems(dirStage)
|
|
||||||
local containsStage = _.contains(items, 'Stage')
|
|
||||||
if containsStage then
|
|
||||||
dirStage = dirStage .. '/Stage'
|
|
||||||
else
|
|
||||||
status = "Could not find \"data\" subfolder.\n\nMaybe try dropping your Cave Story \"data\" folder in directly?"
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Offer tribute to RNGesus.
|
|
||||||
local seed = tostring(os.time())
|
|
||||||
math.randomseed(seed)
|
|
||||||
logNotice(('Offering seed "%s" to RNGesus'):format(seed))
|
|
||||||
|
|
||||||
-- Create TscFile objects.
|
|
||||||
local tscFiles = {}
|
|
||||||
for _, filename in ipairs(TSC_FILES) do
|
|
||||||
local path = dirStage .. '/' .. filename
|
|
||||||
local TscFile = require 'tsc_file'
|
|
||||||
tscFiles[filename] = TscFile(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Create ItemDeck.
|
|
||||||
local ItemDeck = require 'item_deck'
|
|
||||||
local itemDeck = ItemDeck()
|
|
||||||
|
|
||||||
-- Place random weapon in either First Cave or Hermit Gunsmith.
|
|
||||||
local firstArea = _.sample({'Cave.tsc', 'Pole.tsc'})
|
|
||||||
tscFiles[firstArea]:replaceItem(itemDeck:getWeapon())
|
|
||||||
|
|
||||||
-- Replace all items.
|
|
||||||
for _, tscFile in pairs(tscFiles) do
|
|
||||||
while tscFile:hasUnreplacedItems() do
|
|
||||||
tscFile:replaceItem(itemDeck:getAny())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local sourcePath = lf.getSourceBaseDirectory()
|
|
||||||
|
|
||||||
-- Create /data/Stage if it doesn't already exist.
|
|
||||||
local command = ('mkdir "%s"'):format(sourcePath .. '/data/Stage')
|
|
||||||
os.execute(command) -- HERE BE DRAGONS!!!
|
|
||||||
|
|
||||||
-- Write modified files.
|
|
||||||
for filename, tscFile in pairs(tscFiles) do
|
|
||||||
local path = sourcePath .. '/data/Stage/' .. filename
|
|
||||||
tscFile:writeTo(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Unmount.
|
|
||||||
assert(lf.unmount(path))
|
|
||||||
print("\n")
|
|
||||||
|
|
||||||
-- Update status
|
|
||||||
status = [[Randomized data successfully created!
|
|
||||||
|
|
||||||
Next overwrite the files in your copy of Cave Story with the versions in the newly created "data" folder. Don't forget to save a backup of the originals!
|
|
||||||
|
|
||||||
Then play and have a fun!]]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.keypressed(key)
|
function love.keypressed(key)
|
||||||
|
|
105
src/randomizer.lua
Normal file
105
src/randomizer.lua
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
local ItemDeck = require 'item_deck'
|
||||||
|
local TscFile = require 'tsc_file'
|
||||||
|
|
||||||
|
local C = Class:extend()
|
||||||
|
|
||||||
|
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 C:randomize(path)
|
||||||
|
local success, dirStage = self:_mountDirectory(path)
|
||||||
|
if not success then
|
||||||
|
return "Could not find \"data\" subfolder.\n\nMaybe try dropping your Cave Story \"data\" folder in directly?"
|
||||||
|
end
|
||||||
|
self:_seedRngesus()
|
||||||
|
local tscFiles = self:_createTscFiles(dirStage)
|
||||||
|
self:_shuffleItems(tscFiles)
|
||||||
|
self:_writeModifiedData(tscFiles)
|
||||||
|
self:_unmountDirectory(path)
|
||||||
|
return [[Randomized data successfully created!
|
||||||
|
|
||||||
|
Next overwrite the files in your copy of Cave Story with the versions in the newly created "data" folder. Don't forget to save a backup of the originals!
|
||||||
|
|
||||||
|
Then play and have a fun!]]
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:_mountDirectory(path)
|
||||||
|
local mountPath = 'mounted-data'
|
||||||
|
assert(lf.mount(path, mountPath))
|
||||||
|
local dirStage = '/' .. mountPath
|
||||||
|
|
||||||
|
local items = lf.getDirectoryItems(dirStage)
|
||||||
|
local containsData = _.contains(items, 'data')
|
||||||
|
if containsData then
|
||||||
|
dirStage = dirStage .. '/data'
|
||||||
|
end
|
||||||
|
|
||||||
|
local items = lf.getDirectoryItems(dirStage)
|
||||||
|
local containsStage = _.contains(items, 'Stage')
|
||||||
|
if containsStage then
|
||||||
|
dirStage = dirStage .. '/Stage'
|
||||||
|
else
|
||||||
|
return false, ''
|
||||||
|
end
|
||||||
|
|
||||||
|
return true, dirStage
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:_seedRngesus()
|
||||||
|
local seed = tostring(os.time())
|
||||||
|
math.randomseed(seed)
|
||||||
|
logNotice(('Offering seed "%s" to RNGesus'):format(seed))
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:_createTscFiles(dirStage)
|
||||||
|
local tscFiles = {}
|
||||||
|
for _, filename in ipairs(TSC_FILES) do
|
||||||
|
local path = dirStage .. '/' .. filename
|
||||||
|
tscFiles[filename] = TscFile(path)
|
||||||
|
end
|
||||||
|
return tscFiles
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:_shuffleItems(tscFiles)
|
||||||
|
local itemDeck = ItemDeck()
|
||||||
|
|
||||||
|
-- Place random weapon in either First Cave or Hermit Gunsmith.
|
||||||
|
local firstArea = _.sample({'Cave.tsc', 'Pole.tsc'})
|
||||||
|
tscFiles[firstArea]:replaceItem(itemDeck:getWeapon())
|
||||||
|
|
||||||
|
-- Replace all items.
|
||||||
|
for _, tscFile in pairs(tscFiles) do
|
||||||
|
while tscFile:hasUnreplacedItems() do
|
||||||
|
tscFile:replaceItem(itemDeck:getAny())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:_writeModifiedData(tscFiles)
|
||||||
|
local sourcePath = lf.getSourceBaseDirectory()
|
||||||
|
|
||||||
|
-- Create /data/Stage if it doesn't already exist.
|
||||||
|
local command = ('mkdir "%s"'):format(sourcePath .. '/data/Stage')
|
||||||
|
os.execute(command) -- HERE BE DRAGONS!!!
|
||||||
|
|
||||||
|
-- Write modified files.
|
||||||
|
for filename, tscFile in pairs(tscFiles) do
|
||||||
|
local path = sourcePath .. '/data/Stage/' .. filename
|
||||||
|
tscFile:writeTo(path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function C:_unmountDirectory(path)
|
||||||
|
assert(lf.unmount(path))
|
||||||
|
print("\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
return C
|
Loading…
Reference in a new issue