mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
marbleland support begin, attempt
This commit is contained in:
parent
aa93731f04
commit
018b4d8705
13 changed files with 353 additions and 68 deletions
|
|
@ -647,18 +647,18 @@ class DifBuilder {
|
|||
path = StringTools.replace(path, "data/", "");
|
||||
#end
|
||||
|
||||
if (ResourceLoader.fileSystem.exists(Path.directory(path) + "/" + tex + ".jpg")) {
|
||||
if (ResourceLoader.exists(Path.directory(path) + "/" + tex + ".jpg")) {
|
||||
return true;
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(Path.directory(path) + "/" + tex + ".png")) {
|
||||
if (ResourceLoader.exists(Path.directory(path) + "/" + tex + ".png")) {
|
||||
return true;
|
||||
}
|
||||
var prevDir = Path.directory(Path.directory(path));
|
||||
|
||||
if (ResourceLoader.fileSystem.exists(prevDir + "/" + tex + ".jpg")) {
|
||||
if (ResourceLoader.exists(prevDir + "/" + tex + ".jpg")) {
|
||||
return true;
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(prevDir + "/" + tex + ".png")) {
|
||||
if (ResourceLoader.exists(prevDir + "/" + tex + ".png")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -669,19 +669,19 @@ class DifBuilder {
|
|||
tex = tex.split('/')[1];
|
||||
}
|
||||
|
||||
if (ResourceLoader.fileSystem.exists(Path.directory(path) + "/" + tex + ".jpg")) {
|
||||
if (ResourceLoader.exists(Path.directory(path) + "/" + tex + ".jpg")) {
|
||||
return Path.directory(path) + "/" + tex + ".jpg";
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(Path.directory(path) + "/" + tex + ".png")) {
|
||||
if (ResourceLoader.exists(Path.directory(path) + "/" + tex + ".png")) {
|
||||
return Path.directory(path) + "/" + tex + ".png";
|
||||
}
|
||||
|
||||
var prevDir = Path.directory(Path.directory(path));
|
||||
|
||||
if (ResourceLoader.fileSystem.exists(prevDir + "/" + tex + ".jpg")) {
|
||||
if (ResourceLoader.exists(prevDir + "/" + tex + ".jpg")) {
|
||||
return prevDir + "/" + tex + ".jpg";
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(prevDir + "/" + tex + ".png")) {
|
||||
if (ResourceLoader.exists(prevDir + "/" + tex + ".png")) {
|
||||
return prevDir + "/" + tex + ".png";
|
||||
}
|
||||
|
||||
|
|
@ -729,7 +729,7 @@ class DifBuilder {
|
|||
var material:Material;
|
||||
var texture:Texture;
|
||||
if (canFindTex(grp)) {
|
||||
texture = ResourceLoader.getFileEntry(tex(grp)).toImage().toTexture();
|
||||
texture = ResourceLoader.getTexture(tex(grp)).resource;
|
||||
texture.wrap = Wrap.Repeat;
|
||||
texture.mipMap = Nearest;
|
||||
var exactName = StringTools.replace(texture.name, "data/", "");
|
||||
|
|
|
|||
|
|
@ -471,7 +471,7 @@ class DtsObject extends GameObject {
|
|||
}
|
||||
|
||||
function parseIfl(path:String) {
|
||||
var text = ResourceLoader.fileSystem.get(path).getText();
|
||||
var text = ResourceLoader.getFileEntry(path).entry.getText();
|
||||
var lines = text.split('\n');
|
||||
var keyframes = [];
|
||||
for (line in lines) {
|
||||
|
|
|
|||
68
src/Http.hx
Normal file
68
src/Http.hx
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
package src;
|
||||
|
||||
import src.Console;
|
||||
import sys.thread.FixedThreadPool;
|
||||
|
||||
typedef HttpRequest = {
|
||||
var url:String;
|
||||
var callback:haxe.io.Bytes->Void;
|
||||
var errCallback:String->Void;
|
||||
};
|
||||
|
||||
class Http {
|
||||
#if sys
|
||||
static var threadPool:sys.thread.FixedThreadPool;
|
||||
static var requests:sys.thread.Deque<HttpRequest> = new sys.thread.Deque<HttpRequest>();
|
||||
static var responses:sys.thread.Deque<() -> Void> = new sys.thread.Deque<() -> Void>();
|
||||
#end
|
||||
|
||||
public static function init() {
|
||||
#if sys
|
||||
threadPool = new sys.thread.FixedThreadPool(4);
|
||||
threadPool.run(() -> threadLoop());
|
||||
threadPool.run(() -> threadLoop());
|
||||
threadPool.run(() -> threadLoop());
|
||||
threadPool.run(() -> threadLoop());
|
||||
#end
|
||||
}
|
||||
|
||||
#if sys
|
||||
static function threadLoop() {
|
||||
while (true) {
|
||||
var req = requests.pop(true);
|
||||
var http = new sys.Http(req.url);
|
||||
http.onError = (e) -> {
|
||||
responses.add(() -> req.errCallback(e));
|
||||
};
|
||||
http.onBytes = (b) -> {
|
||||
responses.add(() -> req.callback(b));
|
||||
};
|
||||
hl.Gc.blocking(true); // Wtf is this shit
|
||||
http.request(false);
|
||||
hl.Gc.blocking(false);
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
public static function get(url:String, callback:haxe.io.Bytes->Void, errCallback:String->Void):Void {
|
||||
var req = {
|
||||
url: url,
|
||||
callback: callback,
|
||||
errCallback: errCallback
|
||||
};
|
||||
#if sys
|
||||
requests.add(req);
|
||||
#else
|
||||
js.Browser.window.fetch(url).then(r -> r.arrayBuffer().then(b -> callback(haxe.io.Bytes.ofData(b))), e -> errCallback(e.toString()));
|
||||
#end
|
||||
}
|
||||
|
||||
public static function loop() {
|
||||
#if sys
|
||||
var resp = responses.pop(false);
|
||||
if (resp != null) {
|
||||
resp();
|
||||
}
|
||||
#end
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package;
|
||||
|
||||
import src.Marbleland;
|
||||
import src.Console;
|
||||
import hxd.Key;
|
||||
import src.Util;
|
||||
|
|
@ -18,6 +19,7 @@ import hxd.res.DefaultFont;
|
|||
import h2d.Text;
|
||||
import h3d.Vector;
|
||||
import src.ProfilerUI;
|
||||
import src.Http;
|
||||
|
||||
class Main extends hxd.App {
|
||||
var marbleGame:MarbleGame;
|
||||
|
|
@ -66,10 +68,13 @@ class Main extends hxd.App {
|
|||
#end
|
||||
|
||||
try {
|
||||
Http.init();
|
||||
haxe.MainLoop.add(() -> Http.loop());
|
||||
Settings.init();
|
||||
ResourceLoader.init(s2d, () -> {
|
||||
AudioManager.init();
|
||||
AudioManager.playShell();
|
||||
Marbleland.init();
|
||||
marbleGame = new MarbleGame(s2d, s3d);
|
||||
MarbleGame.canvas.setContent(new MainMenuGui());
|
||||
|
||||
|
|
|
|||
|
|
@ -181,6 +181,8 @@ class MarbleWorld extends Scheduler {
|
|||
|
||||
public var _ready:Bool = false;
|
||||
|
||||
var _loadBegin:Bool = false;
|
||||
|
||||
var _loadingLength:Int = 0;
|
||||
|
||||
var _resourcesLoaded:Int = 0;
|
||||
|
|
@ -207,7 +209,15 @@ class MarbleWorld extends Scheduler {
|
|||
Console.log("*** LOADING MISSION: " + mission.path);
|
||||
this.loadingGui = new LoadingGui(this.mission.title, this.mission.game);
|
||||
MarbleGame.canvas.setContent(this.loadingGui);
|
||||
if (this.mission.isClaMission) {
|
||||
this.mission.download(() -> loadBegin());
|
||||
} else {
|
||||
loadBegin();
|
||||
}
|
||||
}
|
||||
|
||||
function loadBegin() {
|
||||
_loadBegin = true;
|
||||
function scanMission(simGroup:MissionElementSimGroup) {
|
||||
for (element in simGroup.elements) {
|
||||
if ([
|
||||
|
|
@ -249,8 +259,12 @@ class MarbleWorld extends Scheduler {
|
|||
}
|
||||
|
||||
public function loadMusic(onFinish:Void->Void) {
|
||||
var musicFileName = 'sound/music/' + this.mission.missionInfo.music;
|
||||
ResourceLoader.load(musicFileName).entry.load(onFinish);
|
||||
if (this.mission.missionInfo.music != null) {
|
||||
var musicFileName = 'sound/music/' + this.mission.missionInfo.music;
|
||||
ResourceLoader.load(musicFileName).entry.load(onFinish);
|
||||
} else {
|
||||
onFinish();
|
||||
}
|
||||
}
|
||||
|
||||
public function postInit() {
|
||||
|
|
@ -1031,7 +1045,7 @@ class MarbleWorld extends Scheduler {
|
|||
public function addDtsObject(obj:DtsObject, onFinish:Void->Void) {
|
||||
function parseIfl(path:String, onFinish:Array<String>->Void) {
|
||||
ResourceLoader.load(path).entry.load(() -> {
|
||||
var text = ResourceLoader.fileSystem.get(path).getText();
|
||||
var text = ResourceLoader.getFileEntry(path).entry.getText();
|
||||
var lines = text.split('\n');
|
||||
var keyframes = [];
|
||||
for (line in lines) {
|
||||
|
|
@ -1294,7 +1308,7 @@ class MarbleWorld extends Scheduler {
|
|||
});
|
||||
#end
|
||||
} else {
|
||||
if (this._resourcesLoaded < _loadingLength)
|
||||
if (this._resourcesLoaded < _loadingLength || !this._loadBegin)
|
||||
return;
|
||||
if (!_ready && !postInited) {
|
||||
postInited = true;
|
||||
|
|
@ -2002,22 +2016,12 @@ class MarbleWorld extends Scheduler {
|
|||
this.replay.name = MarbleGame.instance.recordingName;
|
||||
#if hl
|
||||
sys.FileSystem.createDirectory(haxe.io.Path.join([Settings.settingsDir, "data", "replays"]));
|
||||
var replayPath = haxe.io.Path.join([
|
||||
Settings.settingsDir,
|
||||
"data",
|
||||
"replays",
|
||||
'${this.replay.name}.mbr'
|
||||
]);
|
||||
var replayPath = haxe.io.Path.join([Settings.settingsDir, "data", "replays", '${this.replay.name}.mbr']);
|
||||
if (sys.FileSystem.exists(replayPath)) {
|
||||
var count = 1;
|
||||
var found = false;
|
||||
while (!found) {
|
||||
replayPath = haxe.io.Path.join([
|
||||
Settings.settingsDir,
|
||||
"data",
|
||||
"replays",
|
||||
'${this.replay.name} (${count}).mbr'
|
||||
]);
|
||||
replayPath = haxe.io.Path.join([Settings.settingsDir, "data", "replays", '${this.replay.name} (${count}).mbr']);
|
||||
if (!sys.FileSystem.exists(replayPath)) {
|
||||
this.replay.name += ' (${count})';
|
||||
found = true;
|
||||
|
|
@ -2066,7 +2070,8 @@ class MarbleWorld extends Scheduler {
|
|||
}
|
||||
}
|
||||
|
||||
this.playGui.dispose();
|
||||
if (this.playGui != null)
|
||||
this.playGui.dispose();
|
||||
scene.removeChildren();
|
||||
|
||||
for (interior in this.interiors) {
|
||||
|
|
@ -2091,7 +2096,8 @@ class MarbleWorld extends Scheduler {
|
|||
textureResource.release();
|
||||
}
|
||||
|
||||
sky.dispose();
|
||||
if (sky != null)
|
||||
sky.dispose();
|
||||
|
||||
this._disposed = true;
|
||||
AudioManager.stopAllSounds();
|
||||
|
|
|
|||
84
src/Marbleland.hx
Normal file
84
src/Marbleland.hx
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
package src;
|
||||
|
||||
import haxe.io.BytesInput;
|
||||
import haxe.zip.Reader;
|
||||
import hxd.res.Image;
|
||||
import hxd.BitmapData;
|
||||
import haxe.Json;
|
||||
import src.Mission;
|
||||
import src.Http;
|
||||
import src.ResourceLoader;
|
||||
|
||||
class Marbleland {
|
||||
public static var goldMissions = [];
|
||||
public static var ultraMissions = [];
|
||||
public static var platinumMissions = [];
|
||||
|
||||
public static function init() {
|
||||
Http.get('https://raw.githubusercontent.com/Vanilagy/MarbleBlast/master/src/assets/customs_gold.json', (b) -> {
|
||||
parseMissionList(b.toString(), "gold");
|
||||
}, (e) -> {});
|
||||
Http.get('https://raw.githubusercontent.com/Vanilagy/MarbleBlast/master/src/assets/customs_ultra.json', (b) -> {
|
||||
parseMissionList(b.toString(), "ultra");
|
||||
}, (e) -> {});
|
||||
Http.get('https://raw.githubusercontent.com/Vanilagy/MarbleBlast/master/src/assets/customs_platinum.json', (b) -> {
|
||||
parseMissionList(b.toString(), "platinum");
|
||||
}, (e) -> {});
|
||||
}
|
||||
|
||||
static function parseMissionList(s:String, game:String) {
|
||||
var claJson:Array<Dynamic> = Json.parse(s);
|
||||
|
||||
for (missionData in claJson) {
|
||||
var mission = new Mission();
|
||||
mission.id = missionData.id;
|
||||
mission.path = 'missions/' + missionData.baseName;
|
||||
#if (hl && !android)
|
||||
mission.path = 'data/' + mission.path;
|
||||
#end
|
||||
mission.path = mission.path.toLowerCase();
|
||||
mission.title = missionData.name;
|
||||
mission.artist = missionData.artist != null ? missionData.artist : "Unknown Author";
|
||||
mission.description = missionData.desc != null ? missionData.desc : "";
|
||||
mission.qualifyTime = missionData.qualifyingTime != null ? missionData.qualifyingTime / 1000 : Math.POSITIVE_INFINITY;
|
||||
mission.goldTime = missionData.goldTime != null ? missionData.goldTime / 1000 : 0;
|
||||
mission.game = missionData.modification;
|
||||
if (missionData.modification == 'platinum')
|
||||
mission.goldTime = missionData.platinumTime != null ? missionData.platinumTime / 1000 : mission.goldTime;
|
||||
mission.ultimateTime = missionData.ultimateTime != null ? missionData.ultimateTime / 1000 : 0;
|
||||
mission.hasEgg = missionData.hasEgg;
|
||||
mission.isClaMission = true;
|
||||
|
||||
switch (game) {
|
||||
case 'gold':
|
||||
goldMissions.push(mission);
|
||||
case 'ultra':
|
||||
ultraMissions.push(mission);
|
||||
case 'platinum':
|
||||
platinumMissions.push(mission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function getMissionImage(id:Int, cb:Image->Void) {
|
||||
Http.get('https://marbleland.vani.ga/api/level/${id}/image?width=258&height=194', (imageBytes) -> {
|
||||
var res = new Image(new hxd.fs.BytesFileSystem.BytesFileEntry('${id}.png', imageBytes));
|
||||
cb(res);
|
||||
}, (e) -> {
|
||||
cb(null);
|
||||
});
|
||||
}
|
||||
|
||||
public static function download(id:Int, cb:Array<haxe.zip.Entry>->Void) {
|
||||
Http.get('https://marbleblast.vani.ga/api/custom/${id}.zip', (zipData -> {
|
||||
var reader = new Reader(new BytesInput(zipData));
|
||||
var entries:Array<haxe.zip.Entry> = null;
|
||||
try {
|
||||
entries = [for (x in reader.read()) x];
|
||||
} catch (e) {}
|
||||
cb(entries);
|
||||
}), (e) -> {
|
||||
cb(null);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package src;
|
||||
|
||||
import gui.Canvas;
|
||||
import gui.MessageBoxOkDlg;
|
||||
import haxe.Json;
|
||||
import mis.MissionElement.MissionElementItem;
|
||||
import haxe.io.BytesBuffer;
|
||||
|
|
@ -15,6 +17,8 @@ import hxd.res.Image;
|
|||
import src.Resource;
|
||||
import src.Util;
|
||||
import src.Console;
|
||||
import src.Marbleland;
|
||||
import src.MarbleGame;
|
||||
|
||||
class Mission {
|
||||
public var root:MissionElementSimGroup;
|
||||
|
|
@ -45,7 +49,7 @@ class Mission {
|
|||
public function new() {}
|
||||
|
||||
public function load() {
|
||||
var misParser = new MisParser(ResourceLoader.fileSystem.get(this.path).getText());
|
||||
var misParser = new MisParser(ResourceLoader.getFileEntry(this.path).entry.getText());
|
||||
var contents = misParser.parse();
|
||||
root = contents.root;
|
||||
|
||||
|
|
@ -60,6 +64,8 @@ class Mission {
|
|||
} else if (element._type == MissionElementType.SimGroup && !this.hasEgg) {
|
||||
scanMission(cast element);
|
||||
}
|
||||
if (element._name == 'MissionInfo')
|
||||
missionInfo = cast element;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -153,10 +159,17 @@ class Mission {
|
|||
onLoaded(Tile.fromBitmap(img));
|
||||
return null;
|
||||
} else {
|
||||
Console.error("Preview image not found for " + this.path);
|
||||
var img = new BitmapData(1, 1);
|
||||
img.setPixel(0, 0, 0);
|
||||
onLoaded(Tile.fromBitmap(img));
|
||||
Marbleland.getMissionImage(this.id, (im) -> {
|
||||
if (im != null) {
|
||||
onLoaded(im.toTile());
|
||||
} else {
|
||||
Console.error("Preview image not found for " + this.path);
|
||||
var img = new BitmapData(1, 1);
|
||||
img.setPixel(0, 0, 0);
|
||||
onLoaded(Tile.fromBitmap(img));
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -175,15 +188,20 @@ class Mission {
|
|||
#if (js || android)
|
||||
path = StringTools.replace(path, "data/", "");
|
||||
#end
|
||||
if (ResourceLoader.fileSystem.exists(path))
|
||||
if (ResourceLoader.exists(path))
|
||||
return path;
|
||||
if (StringTools.contains(path, 'interiors_mbg/'))
|
||||
path = StringTools.replace(path, 'interiors_mbg/', 'interiors/');
|
||||
var dirpath = path.substring(0, path.lastIndexOf('/') + 1);
|
||||
if (ResourceLoader.fileSystem.exists(path))
|
||||
if (ResourceLoader.exists(path))
|
||||
return path;
|
||||
if (ResourceLoader.fileSystem.exists(dirpath + fname))
|
||||
if (ResourceLoader.exists(dirpath + fname))
|
||||
return dirpath + fname;
|
||||
if (game == 'gold') {
|
||||
path = StringTools.replace(path, 'interiors/', 'interiors_mbg/');
|
||||
if (ResourceLoader.exists(path))
|
||||
return path;
|
||||
}
|
||||
Console.error("Interior resource not found: " + rawElementPath);
|
||||
return "";
|
||||
}
|
||||
|
|
@ -200,4 +218,17 @@ class Mission {
|
|||
|
||||
return alarmStart;
|
||||
}
|
||||
|
||||
public function download(onFinish:Void->Void) {
|
||||
if (this.isClaMission) {
|
||||
Marbleland.download(this.id, (zipEntries) -> {
|
||||
if (zipEntries != null) {
|
||||
ResourceLoader.loadZip(zipEntries);
|
||||
onFinish();
|
||||
} else {
|
||||
MarbleGame.canvas.pushDialog(new MessageBoxOkDlg("Failed to download mission"));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,22 +110,4 @@ class MissionList {
|
|||
|
||||
_build = true;
|
||||
}
|
||||
|
||||
static function parseCLAList() {
|
||||
var claJson:Array<Dynamic> = Json.parse(ResourceLoader.fileSystem.get("data/cla_list.json").getText());
|
||||
|
||||
for (missionData in claJson) {
|
||||
var mission = new Mission();
|
||||
mission.id = missionData.id;
|
||||
mission.artist = missionData.artist;
|
||||
mission.title = missionData.name;
|
||||
mission.description = missionData.desc;
|
||||
mission.qualifyTime = missionData.time;
|
||||
mission.goldTime = missionData.goldTime;
|
||||
mission.path = missionData.baseName;
|
||||
mission.isClaMission = true;
|
||||
|
||||
customMissions.push(mission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package src;
|
||||
|
||||
import hxd.res.Any;
|
||||
import hxd.fs.BytesFileSystem.BytesFileEntry;
|
||||
#if (js || android)
|
||||
import fs.ManifestLoader;
|
||||
import fs.ManifestBuilder;
|
||||
|
|
@ -43,6 +45,7 @@ class ResourceLoader {
|
|||
static var textureCache:Map<String, Resource<Texture>> = new Map();
|
||||
static var imageCache:Map<String, Resource<Image>> = new Map();
|
||||
static var audioCache:Map<String, Resource<Sound>> = new Map();
|
||||
static var zipFilesystem:Map<String, BytesFileEntry> = new Map();
|
||||
|
||||
// static var threadPool:FixedThreadPool = new FixedThreadPool(4);
|
||||
|
||||
|
|
@ -256,9 +259,9 @@ class ResourceLoader {
|
|||
#if (js || android)
|
||||
path = StringTools.replace(path, "data/", "");
|
||||
#end
|
||||
if (ResourceLoader.fileSystem.exists(path))
|
||||
if (ResourceLoader.exists(path))
|
||||
return path;
|
||||
if (ResourceLoader.fileSystem.exists(dirpath + fname))
|
||||
if (ResourceLoader.exists(dirpath + fname))
|
||||
return dirpath + fname;
|
||||
return "";
|
||||
}
|
||||
|
|
@ -271,6 +274,9 @@ class ResourceLoader {
|
|||
#if (js || android)
|
||||
path = StringTools.replace(path, "data/", "");
|
||||
#end
|
||||
if (zipFilesystem.exists(path.toLowerCase())) {
|
||||
return new hxd.res.Any(loader, zipFilesystem.get(path.toLowerCase()));
|
||||
}
|
||||
return ResourceLoader.loader.load(path);
|
||||
}
|
||||
|
||||
|
|
@ -284,7 +290,10 @@ class ResourceLoader {
|
|||
var itr:Dif;
|
||||
// var lock = new Lock();
|
||||
// threadPool.run(() -> {
|
||||
itr = Dif.LoadFromBuffer(fileSystem.get(path).getBytes());
|
||||
if (zipFilesystem.exists(path.toLowerCase()))
|
||||
itr = Dif.LoadFromBuffer(zipFilesystem.get(path.toLowerCase()).getBytes());
|
||||
else
|
||||
itr = Dif.LoadFromBuffer(fileSystem.get(path).getBytes());
|
||||
var itrresource = new Resource(itr, path, interiorResources, dif -> {});
|
||||
interiorResources.set(path, itrresource);
|
||||
// lock.release();
|
||||
|
|
@ -296,6 +305,7 @@ class ResourceLoader {
|
|||
|
||||
public static function loadDts(path:String) {
|
||||
path = getProperFilepath(path);
|
||||
|
||||
if (dtsResources.exists(path))
|
||||
return dtsResources.get(path);
|
||||
else {
|
||||
|
|
@ -314,6 +324,18 @@ class ResourceLoader {
|
|||
|
||||
public static function getTexture(path:String) {
|
||||
path = getProperFilepath(path);
|
||||
if (zipFilesystem.exists(path.toLowerCase())) {
|
||||
var img = new hxd.res.Image(zipFilesystem.get(path.toLowerCase()));
|
||||
Image.setupTextureFlags = (texObj) -> {
|
||||
texObj.flags.set(MipMapped);
|
||||
}
|
||||
var tex = img.toTexture();
|
||||
tex.mipMap = Nearest;
|
||||
var textureresource = new Resource(tex, path, textureCache, tex -> tex.dispose());
|
||||
textureCache.set(path, textureresource);
|
||||
|
||||
return textureresource;
|
||||
}
|
||||
if (textureCache.exists(path))
|
||||
return textureCache.get(path);
|
||||
if (fileSystem.exists(path)) {
|
||||
|
|
@ -336,6 +358,12 @@ class ResourceLoader {
|
|||
#if (js || android)
|
||||
path = StringTools.replace(path, "data/", "");
|
||||
#end
|
||||
if (zipFilesystem.exists(path.toLowerCase())) {
|
||||
var fentry = new hxd.res.Image(zipFilesystem.get(path.toLowerCase()));
|
||||
var imageresource = new Resource(fentry, path, imageCache, img -> {});
|
||||
imageCache.set(path, imageresource);
|
||||
return imageresource;
|
||||
}
|
||||
if (imageCache.exists(path))
|
||||
return imageCache.get(path);
|
||||
if (fileSystem.exists(path)) {
|
||||
|
|
@ -379,10 +407,20 @@ class ResourceLoader {
|
|||
#if (js || android)
|
||||
path = StringTools.replace(path, "data/", "");
|
||||
#end
|
||||
if (zipFilesystem.exists(path.toLowerCase())) {
|
||||
var fentry = zipFilesystem.get(path.toLowerCase());
|
||||
return new hxd.res.Any(loader, fentry);
|
||||
}
|
||||
var file = loader.load(path);
|
||||
return file;
|
||||
}
|
||||
|
||||
public static function exists(path:String) {
|
||||
if (zipFilesystem.exists(path.toLowerCase()))
|
||||
return true;
|
||||
return fileSystem.exists(path);
|
||||
}
|
||||
|
||||
public static function clearInteriorResources() {
|
||||
interiorResources = new Map();
|
||||
}
|
||||
|
|
@ -405,4 +443,17 @@ class ResourceLoader {
|
|||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
public static function loadZip(entries:Array<haxe.zip.Entry>) {
|
||||
zipFilesystem.clear(); // We are only allowed to load one zip
|
||||
for (entry in entries) {
|
||||
var fname = entry.fileName.toLowerCase();
|
||||
// fname = "data/" + fname;
|
||||
if (exists(fname))
|
||||
continue;
|
||||
Console.log("Loaded zip entry: " + fname);
|
||||
var zfe = new BytesFileEntry(fname, entry.data);
|
||||
zipFilesystem.set(fname, zfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,8 +72,8 @@ class Sky extends Object {
|
|||
#if (js || android)
|
||||
dmlPath = StringTools.replace(dmlPath, "data/", "");
|
||||
#end
|
||||
if (ResourceLoader.fileSystem.exists(dmlPath)) {
|
||||
var dmlFileEntry = ResourceLoader.fileSystem.get(dmlPath);
|
||||
if (ResourceLoader.exists(dmlPath)) {
|
||||
var dmlFileEntry = ResourceLoader.getFileEntry(dmlPath).entry;
|
||||
dmlFileEntry.load(() -> {
|
||||
var dmlFile = dmlFileEntry.getText();
|
||||
var dmlDirectory = Path.directory(dmlPath);
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class DtsFile {
|
|||
public function new() {}
|
||||
|
||||
public function read(filepath:String) {
|
||||
var f = ResourceLoader.fileSystem.get(filepath);
|
||||
var f = ResourceLoader.getFileEntry(filepath).entry;
|
||||
var bytes = f.getBytes();
|
||||
var br = new BytesReader(bytes);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package gui;
|
||||
|
||||
import src.Marbleland;
|
||||
import h2d.filter.DropShadow;
|
||||
import src.Replay;
|
||||
import haxe.ds.Option;
|
||||
|
|
@ -50,6 +51,9 @@ class PlayMissionGui extends GuiImage {
|
|||
#if js
|
||||
var previewTimeoutHandle:Option<Int> = None;
|
||||
#end
|
||||
#if hl
|
||||
var previewToken:Int = 0;
|
||||
#end
|
||||
|
||||
public function new() {
|
||||
MissionList.buildMissionList();
|
||||
|
|
@ -195,7 +199,7 @@ class PlayMissionGui extends GuiImage {
|
|||
pmSearch.position = new Vector(315, 325);
|
||||
pmSearch.extent = new Vector(43, 43);
|
||||
pmSearch.pressedAction = (e) -> {
|
||||
MarbleGame.canvas.pushDialog(new SearchGui(currentGame));
|
||||
MarbleGame.canvas.pushDialog(new SearchGui(currentGame, currentCategory == "custom"));
|
||||
}
|
||||
pmBox.addChild(pmSearch);
|
||||
|
||||
|
|
@ -420,6 +424,18 @@ class PlayMissionGui extends GuiImage {
|
|||
pmDifficultyTopCTab2.vertSizing = Bottom;
|
||||
pmDifficultyTopC2.addChild(pmDifficultyTopCTab2);
|
||||
|
||||
var pmDifficultyUltraCustom = new GuiButtonText(loadButtonImages("data/ui/play/difficulty_highlight-120"), markerFelt24);
|
||||
pmDifficultyUltraCustom.position = new Vector(277, 164);
|
||||
pmDifficultyUltraCustom.ratio = -1 / 16;
|
||||
pmDifficultyUltraCustom.setExtent(new Vector(120, 31));
|
||||
pmDifficultyUltraCustom.txtCtrl.text.text = " Custom";
|
||||
pmDifficultyUltraCustom.pressedAction = (e) -> {
|
||||
currentList = Marbleland.goldMissions;
|
||||
currentCategory = "custom";
|
||||
setCategoryFunc("ultra", "custom");
|
||||
}
|
||||
pmDifficultyCtrl.addChild(pmDifficultyUltraCustom);
|
||||
|
||||
var pmDifficultyUltraAdvanced = new GuiButtonText(loadButtonImages("data/ui/play/difficulty_highlight-120"), markerFelt24);
|
||||
pmDifficultyUltraAdvanced.position = new Vector(277, 134);
|
||||
pmDifficultyUltraAdvanced.ratio = -1 / 16;
|
||||
|
|
@ -456,6 +472,18 @@ class PlayMissionGui extends GuiImage {
|
|||
}
|
||||
pmDifficultyCtrl.addChild(pmDifficultyUltraIntermediate);
|
||||
|
||||
var pmDifficultyGoldCustom = new GuiButtonText(loadButtonImages("data/ui/play/difficulty_highlight-120"), markerFelt24);
|
||||
pmDifficultyGoldCustom.position = new Vector(37, 164);
|
||||
pmDifficultyGoldCustom.ratio = -1 / 16;
|
||||
pmDifficultyGoldCustom.setExtent(new Vector(120, 31));
|
||||
pmDifficultyGoldCustom.txtCtrl.text.text = " Custom";
|
||||
pmDifficultyGoldCustom.pressedAction = (e) -> {
|
||||
currentList = Marbleland.goldMissions;
|
||||
currentCategory = "custom";
|
||||
setCategoryFunc("gold", "custom");
|
||||
}
|
||||
pmDifficultyCtrl.addChild(pmDifficultyGoldCustom);
|
||||
|
||||
var pmDifficultyGoldAdvanced = new GuiButtonText(loadButtonImages("data/ui/play/difficulty_highlight-120"), markerFelt24);
|
||||
pmDifficultyGoldAdvanced.position = new Vector(37, 134);
|
||||
pmDifficultyGoldAdvanced.ratio = -1 / 16;
|
||||
|
|
@ -741,7 +769,12 @@ class PlayMissionGui extends GuiImage {
|
|||
currentList = MissionList.missionList["platinum"]["beginner"];
|
||||
|
||||
setCategoryFunc = function(game:String, category:String, ?doRender:Bool = true) {
|
||||
currentList = "category" == "custom" ? MissionList.customMissions : MissionList.missionList[game][category];
|
||||
currentList = category == "custom" ? (switch (game) {
|
||||
case 'gold': Marbleland.goldMissions;
|
||||
case 'platinum': Marbleland.platinumMissions;
|
||||
case 'ultra': Marbleland.ultraMissions;
|
||||
default: MissionList.customMissions;
|
||||
}) : MissionList.missionList[game][category];
|
||||
@:privateAccess pmDifficulty.anim.frames = loadButtonImages('data/ui/play/difficulty_${category}');
|
||||
pmDifficultyMarble.bmp.tile = ResourceLoader.getResource('data/ui/play/marble_${game}.png', ResourceLoader.getImage, this.imageResources).toTile();
|
||||
|
||||
|
|
@ -889,13 +922,13 @@ class PlayMissionGui extends GuiImage {
|
|||
var scoreTextTime = '<p align="right"><font color="${scoreColor}" face="MarkerFelt18">${Util.formatTime(score.time)}</font></p>';
|
||||
rightText += scoreTextTime;
|
||||
|
||||
descText += '<font color="#F4E4CE" face="MarkerFelt18">${i + 1}. <font color="#FFFFFF">${score.name}</font></font><br/>';
|
||||
descText += '<font color="#F4E4CE" face="MarkerFelt18">${i + 1}. <font color="#FFFFFF">${StringTools.htmlEscape(score.name)}</font></font><br/>';
|
||||
}
|
||||
|
||||
pmDescriptionRight.text.text = rightText;
|
||||
} else {
|
||||
descText += '<font color="#F4EFE3" face="MarkerFelt18"><p align="center">Author: ${currentMission.artist}</p></font>';
|
||||
descText += '<font color="#F4E4CE" face="MarkerFelt18">${currentMission.description}</font>';
|
||||
descText += '<font color="#F4EFE3" face="MarkerFelt18"><p align="center">Author: ${StringTools.htmlEscape(currentMission.artist)}</p></font>';
|
||||
descText += '<font color="#F4E4CE" face="MarkerFelt18">${StringTools.htmlEscape(currentMission.description)}</font>';
|
||||
pmDescriptionRight.text.text = '';
|
||||
}
|
||||
pmDescription.text.text = descText;
|
||||
|
|
@ -947,7 +980,10 @@ class PlayMissionGui extends GuiImage {
|
|||
}
|
||||
#end
|
||||
#if hl
|
||||
var pTok = previewToken++;
|
||||
var prevpath = currentMission.getPreviewImage(prevImg -> {
|
||||
if (pTok + 1 != previewToken)
|
||||
return;
|
||||
pmPreview.bmp.tile = prevImg;
|
||||
}); // Shit be sync
|
||||
if (prevpath != pmPreview.bmp.tile.getTexture().name) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package gui;
|
||||
|
||||
import src.Marbleland;
|
||||
import h2d.Tile;
|
||||
import hxd.BitmapData;
|
||||
import src.MarbleGame;
|
||||
|
|
@ -9,7 +10,7 @@ import src.ResourceLoader;
|
|||
import src.Settings;
|
||||
|
||||
class SearchGui extends GuiImage {
|
||||
public function new(game:String) {
|
||||
public function new(game:String, isCustom:Bool) {
|
||||
var img = ResourceLoader.getImage("data/ui/search/window.png");
|
||||
super(img.resource.toTile());
|
||||
|
||||
|
|
@ -19,8 +20,29 @@ class SearchGui extends GuiImage {
|
|||
this.extent = new Vector(487, 463);
|
||||
|
||||
var missionList = [];
|
||||
for (diff in MissionList.missionList[game]) {
|
||||
for (mis in diff) {
|
||||
if (!isCustom) {
|
||||
for (diff in MissionList.missionList[game]) {
|
||||
for (mis in diff) {
|
||||
missionList.push({
|
||||
mis: mis,
|
||||
name: mis.title,
|
||||
artist: mis.artist,
|
||||
path: mis.path
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var customsList = switch (game) {
|
||||
case 'gold':
|
||||
Marbleland.goldMissions;
|
||||
case 'platinum':
|
||||
Marbleland.platinumMissions;
|
||||
case 'ultra':
|
||||
Marbleland.ultraMissions;
|
||||
default:
|
||||
MissionList.customMissions;
|
||||
};
|
||||
for (mis in customsList) {
|
||||
missionList.push({
|
||||
mis: mis,
|
||||
name: mis.title,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue