From 209f0b2264fd9d3a380922ec57490579878a93f8 Mon Sep 17 00:00:00 2001 From: Ryan Herriman Date: Sun, 10 Dec 2023 22:34:23 -0700 Subject: [PATCH 1/2] Allow loading of ALF files outside of asset bundle --- .../alf/bodhi-4mkf.alf | 0 .../alf/bwadi-4mkf.alf | 0 .../alf/bwadi-koth.alf | 0 .../alf/crescent-4mkf.alf | 0 .../alf/enso-4mkf.alf | 0 .../alf/grimoire-4mkf.alf | 0 .../alf/hawthorne-4mkf.alf | 0 .../alf/indra-4mkf.alf | 0 .../alf/io-4mkf.alf | 0 .../alf/logic/_koth-rules.alf | 0 .../alf/logic/capture-point.alf | 0 .../alf/logic/capture-rules.alf | 0 .../alf/logic/killfest.alf | 0 .../alf/logic/koth.alf | 0 .../alf/majuscule-4mkf.alf | 0 levels/avaraline-quirks-mode/alf/niflheim.alf | 8 +- .../alf/on-the-rocks-4mkf.alf | 0 .../alf/scimitar-4mkf.alf | 0 .../alf/stratocaster-hss-4mkf.alf | 0 .../alf/stratocaster-hss-koth.alf | 0 .../alf/telecaster-4mkf.alf | 0 .../alf/telecaster-captures.alf | 0 levels/avaraline-quirks-mode/set.json | 85 ++++++++++++++++++- levels/avaraline-strict-mode/set.json | 80 ----------------- src/compat/Resource.cpp | 27 ++++++ src/compat/Resource.h | 2 + src/game/CAvaraApp.cpp | 17 ++++ 27 files changed, 132 insertions(+), 87 deletions(-) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/bodhi-4mkf.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/bwadi-4mkf.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/bwadi-koth.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/crescent-4mkf.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/enso-4mkf.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/grimoire-4mkf.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/hawthorne-4mkf.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/indra-4mkf.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/io-4mkf.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/logic/_koth-rules.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/logic/capture-point.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/logic/capture-rules.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/logic/killfest.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/logic/koth.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/majuscule-4mkf.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/on-the-rocks-4mkf.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/scimitar-4mkf.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/stratocaster-hss-4mkf.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/stratocaster-hss-koth.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/telecaster-4mkf.alf (100%) rename levels/{avaraline-strict-mode => avaraline-quirks-mode}/alf/telecaster-captures.alf (100%) diff --git a/levels/avaraline-strict-mode/alf/bodhi-4mkf.alf b/levels/avaraline-quirks-mode/alf/bodhi-4mkf.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/bodhi-4mkf.alf rename to levels/avaraline-quirks-mode/alf/bodhi-4mkf.alf diff --git a/levels/avaraline-strict-mode/alf/bwadi-4mkf.alf b/levels/avaraline-quirks-mode/alf/bwadi-4mkf.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/bwadi-4mkf.alf rename to levels/avaraline-quirks-mode/alf/bwadi-4mkf.alf diff --git a/levels/avaraline-strict-mode/alf/bwadi-koth.alf b/levels/avaraline-quirks-mode/alf/bwadi-koth.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/bwadi-koth.alf rename to levels/avaraline-quirks-mode/alf/bwadi-koth.alf diff --git a/levels/avaraline-strict-mode/alf/crescent-4mkf.alf b/levels/avaraline-quirks-mode/alf/crescent-4mkf.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/crescent-4mkf.alf rename to levels/avaraline-quirks-mode/alf/crescent-4mkf.alf diff --git a/levels/avaraline-strict-mode/alf/enso-4mkf.alf b/levels/avaraline-quirks-mode/alf/enso-4mkf.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/enso-4mkf.alf rename to levels/avaraline-quirks-mode/alf/enso-4mkf.alf diff --git a/levels/avaraline-strict-mode/alf/grimoire-4mkf.alf b/levels/avaraline-quirks-mode/alf/grimoire-4mkf.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/grimoire-4mkf.alf rename to levels/avaraline-quirks-mode/alf/grimoire-4mkf.alf diff --git a/levels/avaraline-strict-mode/alf/hawthorne-4mkf.alf b/levels/avaraline-quirks-mode/alf/hawthorne-4mkf.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/hawthorne-4mkf.alf rename to levels/avaraline-quirks-mode/alf/hawthorne-4mkf.alf diff --git a/levels/avaraline-strict-mode/alf/indra-4mkf.alf b/levels/avaraline-quirks-mode/alf/indra-4mkf.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/indra-4mkf.alf rename to levels/avaraline-quirks-mode/alf/indra-4mkf.alf diff --git a/levels/avaraline-strict-mode/alf/io-4mkf.alf b/levels/avaraline-quirks-mode/alf/io-4mkf.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/io-4mkf.alf rename to levels/avaraline-quirks-mode/alf/io-4mkf.alf diff --git a/levels/avaraline-strict-mode/alf/logic/_koth-rules.alf b/levels/avaraline-quirks-mode/alf/logic/_koth-rules.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/logic/_koth-rules.alf rename to levels/avaraline-quirks-mode/alf/logic/_koth-rules.alf diff --git a/levels/avaraline-strict-mode/alf/logic/capture-point.alf b/levels/avaraline-quirks-mode/alf/logic/capture-point.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/logic/capture-point.alf rename to levels/avaraline-quirks-mode/alf/logic/capture-point.alf diff --git a/levels/avaraline-strict-mode/alf/logic/capture-rules.alf b/levels/avaraline-quirks-mode/alf/logic/capture-rules.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/logic/capture-rules.alf rename to levels/avaraline-quirks-mode/alf/logic/capture-rules.alf diff --git a/levels/avaraline-strict-mode/alf/logic/killfest.alf b/levels/avaraline-quirks-mode/alf/logic/killfest.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/logic/killfest.alf rename to levels/avaraline-quirks-mode/alf/logic/killfest.alf diff --git a/levels/avaraline-strict-mode/alf/logic/koth.alf b/levels/avaraline-quirks-mode/alf/logic/koth.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/logic/koth.alf rename to levels/avaraline-quirks-mode/alf/logic/koth.alf diff --git a/levels/avaraline-strict-mode/alf/majuscule-4mkf.alf b/levels/avaraline-quirks-mode/alf/majuscule-4mkf.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/majuscule-4mkf.alf rename to levels/avaraline-quirks-mode/alf/majuscule-4mkf.alf diff --git a/levels/avaraline-quirks-mode/alf/niflheim.alf b/levels/avaraline-quirks-mode/alf/niflheim.alf index d286f31c2..c708a239a 100644 --- a/levels/avaraline-quirks-mode/alf/niflheim.alf +++ b/levels/avaraline-quirks-mode/alf/niflheim.alf @@ -9,8 +9,6 @@ light.0.a="30" light.0.b="10" light.1.i="0.5" - gameLength="3750" - defaultLives="999" lightHull="131" mediumHull="132" heavyHull="133" @@ -24,15 +22,15 @@ missileArmed.c = "#333333" missileLaunched.c = "#b3ffcc" wallHeight="0" + pGameLength="3750" /> - + + - - diff --git a/levels/avaraline-strict-mode/alf/on-the-rocks-4mkf.alf b/levels/avaraline-quirks-mode/alf/on-the-rocks-4mkf.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/on-the-rocks-4mkf.alf rename to levels/avaraline-quirks-mode/alf/on-the-rocks-4mkf.alf diff --git a/levels/avaraline-strict-mode/alf/scimitar-4mkf.alf b/levels/avaraline-quirks-mode/alf/scimitar-4mkf.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/scimitar-4mkf.alf rename to levels/avaraline-quirks-mode/alf/scimitar-4mkf.alf diff --git a/levels/avaraline-strict-mode/alf/stratocaster-hss-4mkf.alf b/levels/avaraline-quirks-mode/alf/stratocaster-hss-4mkf.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/stratocaster-hss-4mkf.alf rename to levels/avaraline-quirks-mode/alf/stratocaster-hss-4mkf.alf diff --git a/levels/avaraline-strict-mode/alf/stratocaster-hss-koth.alf b/levels/avaraline-quirks-mode/alf/stratocaster-hss-koth.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/stratocaster-hss-koth.alf rename to levels/avaraline-quirks-mode/alf/stratocaster-hss-koth.alf diff --git a/levels/avaraline-strict-mode/alf/telecaster-4mkf.alf b/levels/avaraline-quirks-mode/alf/telecaster-4mkf.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/telecaster-4mkf.alf rename to levels/avaraline-quirks-mode/alf/telecaster-4mkf.alf diff --git a/levels/avaraline-strict-mode/alf/telecaster-captures.alf b/levels/avaraline-quirks-mode/alf/telecaster-captures.alf similarity index 100% rename from levels/avaraline-strict-mode/alf/telecaster-captures.alf rename to levels/avaraline-quirks-mode/alf/telecaster-captures.alf diff --git a/levels/avaraline-quirks-mode/set.json b/levels/avaraline-quirks-mode/set.json index 2810cb715..c1dfbb71b 100644 --- a/levels/avaraline-quirks-mode/set.json +++ b/levels/avaraline-quirks-mode/set.json @@ -1,4 +1,5 @@ { + "REQD": [{"Package": "avaraline-strict-mode"}], "LEDI": [ { "Alf": "air-voss.alf", @@ -10,6 +11,21 @@ "Name": "Baghdad 3: Electric Boogaloo", "Message": "The unwanted stepchild of all Baghdad clones." }, + { + "Alf": "bodhi-4mkf.alf", + "Name": "Bodhi [4MKF]", + "Message": "Sought a yogi, found a grizzly. Four minute killfest version." + }, + { + "Alf": "bwadi-4mkf.alf", + "Name": "Bwadi [4MKF]", + "Message": "A simple, open level with plenty of ammunition, updated for 2022. Four minute killfest version." + }, + { + "Alf": "bwadi-koth.alf", + "Name": "Bwadi [KOTH]", + "Message": "A simple, open level with plenty of ammunition, updated for 2022. King of the hill version." + }, { "Alf": "choke-daddy.alf", "Name": "Choke Daddy", @@ -20,14 +36,79 @@ "Name": "Choke Daddy Down", "Message": "A mash-up of Baghdad, Choke, and Showdown. Low gravity with extra powerful grenades and missiles. Five lives." }, + { + "Alf": "crescent-4mkf.alf", + "Name": "Crescent [4MKF]", + "Message": "Two fortnights hence. Four minute killfest version." + }, + { + "Alf": "enso-4mkf.alf", + "Name": "Ensō [4MKF]", + "Message": "Ink on paper. Four minute killfest version." + }, + { + "Alf": "grimoire-4mkf.alf", + "Name": "Grimoire [4MKF]", + "Message": "Purely for academic purposes, you understand. Four minute killfest version." + }, + { + "Alf": "hawthorne-4mkf.alf", + "Name": "Hawthorne [4MKF]", + "Message": "A small, enclosed level with moving blocks, updated for 2022. Four minute killfest version." + }, + { + "Alf": "indra-4mkf.alf", + "Name": "Indra [4MKF]", + "Message": "Tossing lightning from the back of an elephant. Four minute killfest version." + }, + { + "Alf": "io-4mkf.alf", + "Name": "I/O [4MKF]", + "Message": "Garbage in, garbage out. Four minute killfest version." + }, + { + "Alf": "majuscule-4mkf.alf", + "Name": "Majuscule [4MKF]", + "Message": "A mash-up of Coromoran and Fuchsia. Four minute killfest version." + }, { "Alf": "niflheim.alf", - "Name": "Niflheim", + "Name": "Niflheim [4MKF]", "Message": "Four minute Klondike killfest, with wig reveal! Patented Corpserot® missiles (a product of the Grimdark Corporation) are faster and more accurate at the expense of damage." }, + { + "Alf": "on-the-rocks-4mkf.alf", + "Name": "On the Rocks [4MKF]", + "Message": "The new original. Four minute killfest version." + }, + { + "Alf": "scimitar-4mkf.alf", + "Name": "Scimitar [4MKF]", + "Message": "Awash in sand and heat. Four minute killfest version." + }, + { + "Alf": "stratocaster-hss-4mkf.alf", + "Name": "Stratocaster HSS [4MKF]", + "Message": "Bucking the hum of the strum. Four minute killfest version." + }, + { + "Alf": "stratocaster-hss-koth.alf", + "Name": "Stratocaster HSS [KOTH]", + "Message": "Bucking the hum of the strum. King of the hill version." + }, + { + "Alf": "telecaster-4mkf.alf", + "Name": "Telecaster [4MKF]", + "Message": "A mash-up of Stratocaster and Tesla. Four minute killfest version." + }, + { + "Alf": "telecaster-captures.alf", + "Name": "Telecaster [Captures]", + "Message": "A mash-up of Stratocaster and Tesla. Captures version." + }, { "Alf": "watery-keep.alf", - "Name": "Watery Keep", + "Name": "Watery Keep [CTF]", "Message": "Ancient legend has it, water was transported here via a tube. Updated for 2022." } ], diff --git a/levels/avaraline-strict-mode/set.json b/levels/avaraline-strict-mode/set.json index 3c8fb73f7..751660666 100644 --- a/levels/avaraline-strict-mode/set.json +++ b/levels/avaraline-strict-mode/set.json @@ -10,86 +10,41 @@ "Name": "Bodhi", "Message": "Sought a yogi, found a grizzly." }, - { - "Alf": "bodhi-4mkf.alf", - "Name": "Bodhi [4MKF]", - "Message": "Sought a yogi, found a grizzly. Four minute killfest version." - }, { "Alf": "bwadi.alf", "Name": "Bwadi", "Message": "A simple, open level with plenty of ammunition, updated for 2022." }, - { - "Alf": "bwadi-4mkf.alf", - "Name": "Bwadi [4MKF]", - "Message": "A simple, open level with plenty of ammunition, updated for 2022. Four minute killfest version." - }, - { - "Alf": "bwadi-koth.alf", - "Name": "Bwadi [KOTH]", - "Message": "A simple, open level with plenty of ammunition, updated for 2022. King of the hill version." - }, { "Alf": "crescent.alf", "Name": "Crescent", "Message": "Two fortnights hence." }, - { - "Alf": "crescent-4mkf.alf", - "Name": "Crescent [4MKF]", - "Message": "Two fortnights hence. Four minute killfest version." - }, { "Alf": "enso.alf", "Name": "Ensō", "Message": "Ink on paper." }, - { - "Alf": "enso-4mkf.alf", - "Name": "Ensō [4MKF]", - "Message": "Ink on paper. Four minute killfest version." - }, { "Alf": "grimoire.alf", "Name": "Grimoire", "Message": "Purely for academic purposes, you understand." }, - { - "Alf": "grimoire-4mkf.alf", - "Name": "Grimoire [4MKF]", - "Message": "Purely for academic purposes, you understand. Four minute killfest version." - }, { "Alf": "hawthorne.alf", "Name": "Hawthorne", "Message": "A small, enclosed level with moving blocks, updated for 2022." }, - { - "Alf": "hawthorne-4mkf.alf", - "Name": "Hawthorne [4MKF]", - "Message": "A small, enclosed level with moving blocks, updated for 2022. Four minute killfest version." - }, { "Alf": "indra.alf", "Name": "Indra", "Message": "Tossing lightning from the back of an elephant." }, - { - "Alf": "indra-4mkf.alf", - "Name": "Indra [4MKF]", - "Message": "Tossing lightning from the back of an elephant. Four minute killfest version." - }, { "Alf": "io.alf", "Name": "I/O", "Message": "Garbage in, garbage out." }, - { - "Alf": "io-4mkf.alf", - "Name": "I/O [4MKF]", - "Message": "Garbage in, garbage out. Four minute killfest version." - }, { "Alf": "klondike.alf", "Name": "Klondike", @@ -100,60 +55,25 @@ "Name": "Majuscule", "Message": "A mash-up of Coromoran and Fuchsia." }, - { - "Alf": "majuscule-4mkf.alf", - "Name": "Majuscule [4MKF]", - "Message": "A mash-up of Coromoran and Fuchsia. Four minute killfest version." - }, { "Alf": "on-the-rocks.alf", "Name": "On the Rocks", "Message": "The new original." }, - { - "Alf": "on-the-rocks-4mkf.alf", - "Name": "On the Rocks [4MKF]", - "Message": "The new original. Four minute killfest version." - }, { "Alf": "scimitar.alf", "Name": "Scimitar", "Message": "Awash in sand and heat." }, - { - "Alf": "scimitar-4mkf.alf", - "Name": "Scimitar [4MKF]", - "Message": "Awash in sand and heat. Four minute killfest version." - }, { "Alf": "stratocaster-hss.alf", "Name": "Stratocaster HSS", "Message": "Bucking the hum of the strum." }, - { - "Alf": "stratocaster-hss-4mkf.alf", - "Name": "Stratocaster HSS [4MKF]", - "Message": "Bucking the hum of the strum. Four minute killfest version." - }, - { - "Alf": "stratocaster-hss-koth.alf", - "Name": "Stratocaster HSS [KOTH]", - "Message": "Bucking the hum of the strum. King of the hill version." - }, { "Alf": "telecaster.alf", "Name": "Telecaster", "Message": "A mash-up of Stratocaster and Tesla." - }, - { - "Alf": "telecaster-4mkf.alf", - "Name": "Telecaster [4MKF]", - "Message": "A mash-up of Stratocaster and Tesla. Four minute killfest version." - }, - { - "Alf": "telecaster-captures.alf", - "Name": "Telecaster [Captures]", - "Message": "A mash-up of Stratocaster and Tesla. Captures version." } ] } diff --git a/src/compat/Resource.cpp b/src/compat/Resource.cpp index 0e78f647e..d7afd6e6f 100644 --- a/src/compat/Resource.cpp +++ b/src/compat/Resource.cpp @@ -32,6 +32,8 @@ static std::string currentResource(""); static std::string currentBaseDir("rsrc"); +static std::vector currentExtPkgDirs({}); + static std::string currentLevelDir(""); void UseBaseFolder(std::string folder) { @@ -39,6 +41,14 @@ void UseBaseFolder(std::string folder) { LoadDefaultOggFiles(); } +void AddExternalPackage(std::string folder) { + currentExtPkgDirs.push_back(folder); +} + +void ClearExternalPackages() { + currentExtPkgDirs.clear(); +} + void UseLevelFolder(std::string folder) { currentLevelDir = folder; } @@ -397,6 +407,23 @@ std::string GetALFPath(std::string alfname) { buffa << ALFDIR << PATHSEP << alfname; char alfpath[PATH_MAX]; BundlePath(buffa.str().c_str(), alfpath); + + std::ifstream testFile(alfpath); + if (testFile.fail()) { + // Check external packages! + for (auto &pkg : currentExtPkgDirs) { + buffa.str(""); + buffa << LEVELDIR << PATHSEP << pkg << PATHSEP; + buffa << ALFDIR << PATHSEP << alfname; + char altalfpath[PATH_MAX]; + BundlePath(buffa.str().c_str(), altalfpath); + testFile.open(altalfpath); + if (!testFile.fail()) { + return std::string(altalfpath); + } + } + } + return std::string(alfpath); } diff --git a/src/compat/Resource.h b/src/compat/Resource.h index 85dd4be1c..39f2a5f13 100644 --- a/src/compat/Resource.h +++ b/src/compat/Resource.h @@ -27,6 +27,8 @@ void UseResFile(std::string filename); void UseBaseFolder(std::string folder); +void AddExternalPackage(std::string folder); +void ClearExternalPackages(); void UseLevelFolder(std::string folder); std::string OSTypeString(OSType t); OSType StringOSType(std::string s); diff --git a/src/game/CAvaraApp.cpp b/src/game/CAvaraApp.cpp index da6808d86..c8cadb6ba 100755 --- a/src/game/CAvaraApp.cpp +++ b/src/game/CAvaraApp.cpp @@ -277,6 +277,23 @@ OSErr CAvaraAppImpl::LoadLevel(std::string set, std::string levelTag, CPlayerMan if (setManifest == -1) return result; if (setManifest.find("LEDI") == setManifest.end()) return result; + if (setManifest.find("REQD") == setManifest.end()) { + ClearExternalPackages(); + } else { + for (auto &ext : setManifest["REQD"].items()) { + json pkg = ext.value(); + std::string pkgPath = pkg.value("Package", ""); + // TODO: Support version constraints? + if (!pkgPath.empty() && + pkgPath.rfind(".", 0) != 0 && + pkgPath.find("..") == std::string::npos && + pkgPath.find("/") == std::string::npos && + pkgPath.find("\\") == std::string::npos) { + AddExternalPackage(pkgPath); + } + } + } + json ledi = NULL; for (auto &ld : setManifest["LEDI"].items()) { if (ld.value()["Alf"] == levelTag) From 91f8e1da7b626933799bef7b04c196356fe1f51c Mon Sep 17 00:00:00 2001 From: Ryan Herriman Date: Wed, 13 Dec 2023 00:15:52 -0700 Subject: [PATCH 2/2] Level sets can inherit BSPs & default.avarascript Also added a new KOTH level for testing. --- .../alf/layout/moonlight.alf | 331 ++++++++++++++++++ .../avaraline-quirks-mode/alf/moonlight.alf | 14 + .../alf/telecaster-captures.alf | 10 +- .../avaraline-quirks-mode/alf/watery-keep.alf | 2 +- .../bsps/{3000.json => 3500.json} | 0 .../bsps/{3001.json => 3501.json} | 0 .../bsps/{3002.json => 3502.json} | 0 .../avaraline-quirks-mode/default.avarascript | 5 +- levels/avaraline-quirks-mode/set.json | 5 + src/compat/Resource.cpp | 60 +++- src/compat/Resource.h | 1 + src/level/Parser.cpp | 26 +- 12 files changed, 433 insertions(+), 21 deletions(-) create mode 100644 levels/avaraline-quirks-mode/alf/layout/moonlight.alf create mode 100644 levels/avaraline-quirks-mode/alf/moonlight.alf rename levels/avaraline-quirks-mode/bsps/{3000.json => 3500.json} (100%) rename levels/avaraline-quirks-mode/bsps/{3001.json => 3501.json} (100%) rename levels/avaraline-quirks-mode/bsps/{3002.json => 3502.json} (100%) diff --git a/levels/avaraline-quirks-mode/alf/layout/moonlight.alf b/levels/avaraline-quirks-mode/alf/layout/moonlight.alf new file mode 100644 index 000000000..bb2343701 --- /dev/null +++ b/levels/avaraline-quirks-mode/alf/layout/moonlight.alf @@ -0,0 +1,331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/levels/avaraline-quirks-mode/alf/moonlight.alf b/levels/avaraline-quirks-mode/alf/moonlight.alf new file mode 100644 index 000000000..6b66d67f9 --- /dev/null +++ b/levels/avaraline-quirks-mode/alf/moonlight.alf @@ -0,0 +1,14 @@ + + + + + + diff --git a/levels/avaraline-quirks-mode/alf/telecaster-captures.alf b/levels/avaraline-quirks-mode/alf/telecaster-captures.alf index 921203da9..37db729a7 100644 --- a/levels/avaraline-quirks-mode/alf/telecaster-captures.alf +++ b/levels/avaraline-quirks-mode/alf/telecaster-captures.alf @@ -22,7 +22,7 @@ pCaptureD="captureSize" pCaptureH="captureSize" pCaptureVizX="0" - pCaptureVizY="1.75" + pCaptureVizY="mGoodyOffset" pCaptureVizZ="0" /> @@ -35,7 +35,7 @@ pCaptureD="captureSize" pCaptureH="captureSize" pCaptureVizX="-outerCaptureX" - pCaptureVizY="outerCaptureY + 1.75" + pCaptureVizY="outerCaptureY + mGoodyOffset" pCaptureVizZ="-outerCaptureZ" /> @@ -50,7 +50,7 @@ pCaptureD="captureSize" pCaptureH="captureSize" pCaptureVizX="outerCaptureX" - pCaptureVizY="outerCaptureY + 1.75" + pCaptureVizY="outerCaptureY + mGoodyOffset" pCaptureVizZ="outerCaptureZ" /> @@ -65,7 +65,7 @@ pCaptureD="captureSize" pCaptureH="captureSize" pCaptureVizX="-outerCaptureZ" - pCaptureVizY="outerCaptureY + 1.75" + pCaptureVizY="outerCaptureY + mGoodyOffset" pCaptureVizZ="outerCaptureX" /> @@ -80,7 +80,7 @@ pCaptureD="captureSize" pCaptureH="captureSize" pCaptureVizX="outerCaptureZ" - pCaptureVizY="outerCaptureY + 1.75" + pCaptureVizY="outerCaptureY + mGoodyOffset" pCaptureVizZ="-outerCaptureX" /> diff --git a/levels/avaraline-quirks-mode/alf/watery-keep.alf b/levels/avaraline-quirks-mode/alf/watery-keep.alf index 16a9deaf9..3a2ac9c22 100644 --- a/levels/avaraline-quirks-mode/alf/watery-keep.alf +++ b/levels/avaraline-quirks-mode/alf/watery-keep.alf @@ -185,7 +185,7 @@ - + diff --git a/levels/avaraline-quirks-mode/bsps/3000.json b/levels/avaraline-quirks-mode/bsps/3500.json similarity index 100% rename from levels/avaraline-quirks-mode/bsps/3000.json rename to levels/avaraline-quirks-mode/bsps/3500.json diff --git a/levels/avaraline-quirks-mode/bsps/3001.json b/levels/avaraline-quirks-mode/bsps/3501.json similarity index 100% rename from levels/avaraline-quirks-mode/bsps/3001.json rename to levels/avaraline-quirks-mode/bsps/3501.json diff --git a/levels/avaraline-quirks-mode/bsps/3002.json b/levels/avaraline-quirks-mode/bsps/3502.json similarity index 100% rename from levels/avaraline-quirks-mode/bsps/3002.json rename to levels/avaraline-quirks-mode/bsps/3502.json diff --git a/levels/avaraline-quirks-mode/default.avarascript b/levels/avaraline-quirks-mode/default.avarascript index a17647e68..161fb0a19 100644 --- a/levels/avaraline-quirks-mode/default.avarascript +++ b/levels/avaraline-quirks-mode/default.avarascript @@ -17,8 +17,9 @@ mXLgMissile = 6 mXXLgMissile = 8 // Custom assets. -bspFlag = 3000 -bspSwirl = 3001 +bspFlag = 3500 +bspSwirl = 3501 +bspWateryKeepWater = 3502 snWaves = 3000 snWaves2 = 3001 snWaterStep = 3002 diff --git a/levels/avaraline-quirks-mode/set.json b/levels/avaraline-quirks-mode/set.json index c1dfbb71b..8954e5c41 100644 --- a/levels/avaraline-quirks-mode/set.json +++ b/levels/avaraline-quirks-mode/set.json @@ -66,6 +66,11 @@ "Name": "I/O [4MKF]", "Message": "Garbage in, garbage out. Four minute killfest version." }, + { + "Alf": "moonlight.alf", + "Name": "Moonlight [KOTH]", + "Message": "" + }, { "Alf": "majuscule-4mkf.alf", "Name": "Majuscule [4MKF]", diff --git a/src/compat/Resource.cpp b/src/compat/Resource.cpp index d7afd6e6f..b3a700f90 100644 --- a/src/compat/Resource.cpp +++ b/src/compat/Resource.cpp @@ -86,14 +86,14 @@ bool IsEquals(const std::string& str1, const std::string& str2) { Handle FindResource(SDL_RWops *file, OSType theType, short theID, std::string name) { uint32_t dataOffset = SDL_ReadBE32(file); uint32_t mapOffset = SDL_ReadBE32(file); - // uint32_t dataLen = + // uint32_t dataLen = SDL_ReadBE32(file); - // uint32_t mapLen = + // uint32_t mapLen = SDL_ReadBE32(file); SDL_RWseek(file, mapOffset + 22, 0); - //uint16_t forkAttrs = + //uint16_t forkAttrs = SDL_ReadBE16(file); uint16_t typeListOffset = SDL_ReadBE16(file); @@ -250,7 +250,7 @@ const char* PathForLevelSet(std::string set) { void LevelDirListing() { cf_dir_t dir; - char ldir[PATH_MAX]; + char ldir[PATH_MAX]; BundlePath(LEVELDIR, ldir); cf_dir_open(&dir, ldir); @@ -350,17 +350,32 @@ void LoadHullFromSetJSON(HullConfigRecord *hull, short resId) { bool GetBSPPath(int resId, char* dest) { std::stringstream relPath; + bool found = false; - // first check for the resource in the levelset directory + // First, check for the resource in the levelset directory. relPath << LEVELDIR << PATHSEP << currentLevelDir << PATHSEP; relPath << BSPSDIR << PATHSEP << resId << BSPSEXT; BundlePath(relPath, dest); - bool found = false; std::ifstream testFile(dest); if (!testFile.fail()) { found = true; } - // haven't found the BSP file yet, try the top-level bsps directory + + // Haven't found the BSP file yet, fall back and check required packages. + if (!found) { + for (auto &pkg : currentExtPkgDirs) { + relPath.str(""); + relPath << LEVELDIR << PATHSEP << pkg << PATHSEP; + relPath << BSPSDIR << PATHSEP << resId << BSPSEXT; + BundlePath(relPath, dest); + std::ifstream testFile(dest); + if (!testFile.fail()) { + found = true; + } + } + } + + // Still haven't found the BSP file, finally try the base BSP directory. if (!found) { relPath.str(""); relPath << currentBaseDir << PATHSEP << BSPSDIR << PATHSEP << resId << BSPSEXT; @@ -449,6 +464,35 @@ std::string GetDefaultScript() { return ""; } +std::vector GetExternalScripts() { + std::vector scripts = {}; + std::stringstream buffa; + + // Note that we are retrieving the scripts in reverse order, here! + for (auto pkg = currentExtPkgDirs.rbegin(); pkg != currentExtPkgDirs.rend(); ++pkg) { + buffa.str(""); + buffa << LEVELDIR << PATHSEP << *pkg << PATHSEP; + buffa << DEFAULTSCRIPT; + char temp[PATH_MAX]; + BundlePath(buffa.str().c_str(), temp); + std::ifstream t(temp); + if (t.good()) { + std::string defaultscript; + t.seekg(0, std::ios::end); + defaultscript.reserve(t.tellg()); + t.seekg(0, std::ios::beg); + + defaultscript.assign((std::istreambuf_iterator(t)), + std::istreambuf_iterator()); + scripts.push_back(defaultscript); + } else { + SDL_Log("There was an error opening %s", temp); + } + } + + return scripts; +} + std::string GetBaseScript() { std::stringstream buffa; buffa << currentBaseDir << PATHSEP << DEFAULTSCRIPT; @@ -521,7 +565,7 @@ void LoadOggFile(short resId, std::string filename, SoundCash &cash) { int error; stb_vorbis *v = stb_vorbis_open_filename(fullpath, &error, NULL); - + //stb_vorbis_info info = stb_vorbis_get_info(v); //SDL_Log("%d channels, %d samples/sec\n", info.channels, info.sample_rate); diff --git a/src/compat/Resource.h b/src/compat/Resource.h index 39f2a5f13..b26145c03 100644 --- a/src/compat/Resource.h +++ b/src/compat/Resource.h @@ -55,6 +55,7 @@ nlohmann::json GetBSPJSON(int resId); bool HasBSP(int resId); std::string GetALFPath(std::string alfname); std::string GetDefaultScript(); +std::vector GetExternalScripts(); std::string GetBaseScript(); void LoadHullFromSetJSON(HullConfigRecord *hull, short resId); void LoadDefaultOggFiles(); diff --git a/src/level/Parser.cpp b/src/level/Parser.cpp index 7b5f7e28e..1c0476f7e 100644 --- a/src/level/Parser.cpp +++ b/src/level/Parser.cpp @@ -1054,12 +1054,28 @@ void AllocParser() { stackP = stackMem; currentActor = NULL; + + // Load default script from "base" resource pack (Avara, Aftershock). std::string base = GetBaseScript(); - if (base.length() > 0) - RunThis((StringPtr)base.c_str()); + if (base.length() > 0) { + RunThis((StringPtr)base.c_str()); + } + + // Load default script from "external" resource packs required by the + // current level set. (If multiple are defined, they are loaded in + // *reverse* order.) + std::vector ext = GetExternalScripts(); + for (auto &extScript : ext) { + if (extScript.length() > 0) { + RunThis((StringPtr)extScript.c_str()); + } + } + + // Load default script for the current level set. std::string def = GetDefaultScript(); - if (def.length() > 0) - RunThis((StringPtr)def.c_str()); + if (def.length() > 0) { + RunThis((StringPtr)def.c_str()); + } } void DeallocParser() { @@ -1069,7 +1085,7 @@ void DeallocParser() { variableBase->Dispose(); if (programBase) programBase->Dispose(); - + stackP = NULL; symTable = NULL; variableBase = NULL;