basic missionlist and pmg

This commit is contained in:
RandomityGuy 2021-06-21 15:10:48 +05:30
parent 90f67366e0
commit 9a3635f242
12 changed files with 402 additions and 22 deletions

View file

@ -1,13 +1,56 @@
package src;
import mis.MisParser;
import mis.MissionElement.MissionElementScriptObject;
import mis.MissionElement.MissionElementType;
import mis.MisFile;
import mis.MissionElement.MissionElementSimGroup;
import src.ResourceLoader;
class Mission {
public var root:MissionElementSimGroup;
public var title:String;
public var artist:String;
public var description:String;
public var qualifyTime = Math.POSITIVE_INFINITY;
public var goldTime:Float = 0;
public var type:String;
public var path:String;
public var missionInfo:MissionElementScriptObject;
public function new() {}
public static function fromMissionInfo(path:String, mInfo:MissionElementScriptObject) {
var mission = new Mission();
mission.path = path;
mission.missionInfo = mInfo;
var missionInfo = mInfo;
mission.title = missionInfo.name;
mission.artist = missionInfo.artist == null ? '' : missionInfo.artist;
mission.description = missionInfo.desc == null ? '' : missionInfo.desc;
if (missionInfo.time != null && missionInfo.time != "0")
mission.qualifyTime = MisParser.parseNumber(missionInfo.time) / 1000;
if (missionInfo.goldtime != null) {
mission.goldTime = MisParser.parseNumber(missionInfo.goldtime) / 1000;
}
mission.type = missionInfo.type.toLowerCase();
mission.missionInfo = missionInfo;
return mission;
}
public function getPreviewImage() {
var basename = haxe.io.Path.withoutExtension(this.path);
if (ResourceLoader.fileSystem.exists(basename + ".png")) {
return ResourceLoader.getImage(basename + ".png").toTile();
}
if (ResourceLoader.fileSystem.exists(basename + ".jpg")) {
return ResourceLoader.getImage(basename + ".jpg").toTile();
}
return null;
}
public function getDifPath(rawElementPath:String) {
rawElementPath = rawElementPath.toLowerCase();
var path = StringTools.replace(rawElementPath.substring(rawElementPath.indexOf('data/')), "\"", "");

39
src/MissionList.hx Normal file
View file

@ -0,0 +1,39 @@
import mis.MisParser;
import src.ResourceLoader;
import src.Mission;
@:publicFields
class MissionList {
static var beginnerMissions:Array<Mission>;
static var intermediateMissions:Array<Mission>;
static var advancedMissions:Array<Mission>;
static var _build:Bool = false;
public function new() {}
public static function buildMissionList() {
if (_build)
return;
function parseDifficulty(difficulty:String) {
var difficultyFiles = ResourceLoader.fileSystem.dir("data/missions/" + difficulty);
var difficultyMissions = [];
for (file in difficultyFiles) {
if (file.extension == "mis") {
var misParser = new MisParser(file.getText());
var mInfo = misParser.parseMissionInfo();
var mission = Mission.fromMissionInfo(file.path, mInfo);
difficultyMissions.push(mission);
}
}
difficultyMissions.sort((a, b) -> Std.parseInt(a.missionInfo.level) - Std.parseInt(b.missionInfo.level));
return difficultyMissions;
}
beginnerMissions = parseDifficulty("beginner");
intermediateMissions = parseDifficulty("intermediate");
advancedMissions = parseDifficulty("advanced");
_build = true;
}
}

View file

@ -112,7 +112,8 @@ class Util {
'\\0' => '\x00',
'\\f' => '\x0C',
'\\n' => '\n',
'\\r' => '\r'
'\\r' => '\r',
"\\'" => "'"
];
for (obj => esc in specialCases) {

View file

@ -12,7 +12,7 @@ class Canvas extends GuiControl {
this.scene2d = scene;
this.position = new Vector();
this.extent = new Vector(scene.width, scene.height);
this.extent = new Vector(640, 480);
this.horizSizing = Width;
this.vertSizing = Height;
}

View file

@ -19,7 +19,9 @@ class GuiAnim extends GuiControl {
anim.setPosition(renderRect.position.x, renderRect.position.y);
anim.scaleX = renderRect.extent.x / anim.getFrame().width;
anim.scaleY = renderRect.extent.y / anim.getFrame().height;
if (!scene2d.contains(anim))
if (scene2d.contains(anim)) {
scene2d.removeChild(anim); // Refresh "layer"
}
scene2d.addChild(anim);
super.render(scene2d);
}

View file

@ -12,26 +12,28 @@ class GuiButton extends GuiAnim {
// 3 is disabled
public var pressedAction:GuiControl->Void = null;
public var disabled:Bool = false;
public function new(anim:Array<Tile>) {
super(anim);
}
public override function update(dt:Float, mouseState:MouseState) {
var renderRect = getRenderRectangle();
if (renderRect.inRect(mouseState.position)) {
if (renderRect.inRect(mouseState.position) && !disabled) {
if (Key.isDown(Key.MOUSE_LEFT)) {
this.anim.currentFrame = 2;
} else {
this.anim.currentFrame = 1;
}
} else
this.anim.currentFrame = 0;
this.anim.currentFrame = disabled ? 3 : 0;
super.update(dt, mouseState);
}
public override function onMouseRelease(mouseState:MouseState) {
super.onMouseRelease(mouseState);
if (this.pressedAction != null) {
if (this.pressedAction != null && !disabled) {
this.pressedAction(this);
}
}

View file

@ -89,13 +89,13 @@ class GuiControl {
}
if (this.horizSizing == HorizSizing.Width) {
if (this.parent != null)
rect.extent.x = parentRect.extent.x;
rect.extent.x = parentRect.extent.x * (this.extent.x / parent.extent.x);
else
rect.extent.x = Window.getInstance().width;
}
if (this.vertSizing == VertSizing.Height) {
if (this.parent != null)
rect.extent.y = parentRect.extent.y;
rect.extent.y = parentRect.extent.y * (this.extent.y / parent.extent.y);
else
rect.extent.y = Window.getInstance().height;
}
@ -138,6 +138,11 @@ class GuiControl {
ctrl.parent = this;
}
public function removeChild(ctrl:GuiControl) {
this.children.remove(ctrl);
ctrl.parent = null;
}
public function removeChildren() {
for (c in this.children) {
c.parent = null;

View file

@ -1,5 +1,6 @@
package gui;
import gui.GuiControl.MouseState;
import h2d.Scene;
import h2d.Tile;
import h2d.Bitmap;
@ -8,6 +9,8 @@ import h2d.Bitmap;
class GuiImage extends GuiControl {
var bmp:Bitmap;
public var pressedAction:GuiControl->Void = null;
public function new(texture:Tile) {
super();
this.bmp = new Bitmap(texture);
@ -16,9 +19,13 @@ class GuiImage extends GuiControl {
public override function render(scene2d:Scene) {
var renderRect = this.getRenderRectangle();
bmp.setPosition(renderRect.position.x, renderRect.position.y);
bmp.scaleX = renderRect.extent.x / bmp.tile.width;
bmp.scaleY = renderRect.extent.y / bmp.tile.height;
if (!scene2d.contains(bmp))
// bmp.scaleX = renderRect.extent.x / bmp.tile.width;
// bmp.scaleY = renderRect.extent.y / bmp.tile.height;
bmp.width = renderRect.extent.x;
bmp.height = renderRect.extent.y;
if (scene2d.contains(bmp)) {
scene2d.removeChild(bmp); // Refresh "layer"
}
scene2d.addChild(bmp);
super.render(scene2d);
}
@ -27,4 +34,11 @@ class GuiImage extends GuiControl {
super.dispose();
this.bmp.remove();
}
public override function onMouseRelease(mouseState:MouseState) {
super.onMouseRelease(mouseState);
if (this.pressedAction != null) {
this.pressedAction(this);
}
}
}

45
src/gui/GuiMLText.hx Normal file
View file

@ -0,0 +1,45 @@
package gui;
import gui.GuiText.Justification;
import h2d.HtmlText;
import h2d.Scene;
import hxd.res.BitmapFont;
import h2d.Text;
@:publicFields
class GuiMLText extends GuiControl {
var text:HtmlText;
var justify:Justification = Left;
public function new(font:BitmapFont, loadFontFunc:String->h2d.Font) {
super();
this.text = new HtmlText(font.toFont());
this.text.loadFont = loadFontFunc;
}
public override function render(scene2d:Scene) {
var renderRect = this.getRenderRectangle();
if (justify == Left) {
text.setPosition(renderRect.position.x, renderRect.position.y);
text.textAlign = Left;
}
if (justify == Right) {
text.setPosition(renderRect.position.x + renderRect.extent.x, renderRect.position.y);
text.textAlign = Right;
}
if (justify == Center) {
text.setPosition(renderRect.position.x + renderRect.extent.x / 2, renderRect.position.y);
text.textAlign = Center;
}
if (scene2d.contains(text))
scene2d.removeChild(text);
scene2d.addChild(text);
text.maxWidth = renderRect.extent.x;
super.render(scene2d);
}
public override function dispose() {
super.dispose();
this.text.remove();
}
}

View file

@ -34,7 +34,8 @@ class GuiText extends GuiControl {
text.setPosition(renderRect.position.x + renderRect.extent.x / 2, renderRect.position.y);
text.textAlign = Center;
}
if (!scene2d.contains(text))
if (scene2d.contains(text))
scene2d.removeChild(text);
scene2d.addChild(text);
super.render(scene2d);
}

View file

@ -1,9 +1,21 @@
package gui;
import haxe.io.Path;
import h2d.Scene;
import h2d.Text;
import src.Mission;
import hxd.res.BitmapFont;
import src.ResourceLoader;
import h3d.Vector;
import src.Util;
class PlayMissionGui extends GuiImage {
var currentSelection:Int = 0;
var currentCategory:String = "beginner";
var currentList:Array<Mission>;
var setSelectedFunc:Int->Void;
public function new() {
super(ResourceLoader.getImage("data/ui/background.jpg").toTile());
@ -12,6 +24,8 @@ class PlayMissionGui extends GuiImage {
this.extent = new Vector(640, 480);
this.position = new Vector(0, 0);
MissionList.buildMissionList();
var localContainer = new GuiControl();
localContainer.horizSizing = Center;
localContainer.vertSizing = Center;
@ -23,17 +37,32 @@ class PlayMissionGui extends GuiImage {
var normal = ResourceLoader.getImage('${path}_n.png').toTile();
var hover = ResourceLoader.getImage('${path}_h.png').toTile();
var pressed = ResourceLoader.getImage('${path}_d.png').toTile();
return [normal, hover, pressed];
var disabled = ResourceLoader.getImage('${path}_i.png').toTile();
return [normal, hover, pressed, disabled];
}
var setCategoryFunc:String->Void = null;
var tabAdvanced = new GuiImage(ResourceLoader.getImage("data/ui/play/tab_adv.png").toTile());
tabAdvanced.position = new Vector(410, 21);
tabAdvanced.extent = new Vector(166, 43);
tabAdvanced.pressedAction = (sender) -> {
currentList = MissionList.advancedMissions;
currentCategory = "advanced";
setSelectedFunc(0);
setCategoryFunc("advanced");
}
localContainer.addChild(tabAdvanced);
var tabIntermediate = new GuiImage(ResourceLoader.getImage("data/ui/play/tab_inter.png").toTile());
tabIntermediate.position = new Vector(213, 4);
tabIntermediate.extent = new Vector(205, 58);
tabIntermediate.pressedAction = (sender) -> {
currentList = MissionList.intermediateMissions;
currentCategory = "intermediate";
setSelectedFunc(0);
setCategoryFunc("intermediate");
}
localContainer.addChild(tabIntermediate);
var tabCustom = new GuiImage(ResourceLoader.getImage("data/ui/play/cust_tab.png").toTile());
@ -44,13 +73,13 @@ class PlayMissionGui extends GuiImage {
var pmBox = new GuiImage(ResourceLoader.getImage("data/ui/play/playgui.png").toTile());
pmBox.position = new Vector(0, 42);
pmBox.extent = new Vector(610, 351);
pmBox.horizSizing = Right;
pmBox.vertSizing = Bottom;
pmBox.horizSizing = Width;
pmBox.vertSizing = Height;
localContainer.addChild(pmBox);
var textWnd = new GuiImage(ResourceLoader.getImage("data/ui/play/text_window.png").toTile());
textWnd.horizSizing = Right;
textWnd.vertSizing = Bottom;
textWnd.horizSizing = Width;
textWnd.vertSizing = Height;
textWnd.position = new Vector(31, 29);
textWnd.extent = new Vector(276, 229);
pmBox.addChild(textWnd);
@ -65,8 +94,46 @@ class PlayMissionGui extends GuiImage {
levelWnd.extent = new Vector(258, 194);
pmPreview.addChild(levelWnd);
var domcasual24fontdata = ResourceLoader.loader.load("data/font/DomCasual24px.fnt");
var domcasual24 = new BitmapFont(domcasual24fontdata.entry);
@:privateAccess domcasual24.loader = ResourceLoader.loader;
var domcasual32fontdata = ResourceLoader.loader.load("data/font/DomCasual24px.fnt");
var domcasual32 = new BitmapFont(domcasual32fontdata.entry);
@:privateAccess domcasual32.loader = ResourceLoader.loader;
var arial14fontdata = ResourceLoader.loader.load("data/font/Arial14.fnt");
var arial14 = new BitmapFont(arial14fontdata.entry);
@:privateAccess arial14.loader = ResourceLoader.loader;
var arialBold14fontdata = ResourceLoader.loader.load("data/font/ArialBold14px.fnt");
var arialBold14 = new BitmapFont(arialBold14fontdata.entry);
@:privateAccess arialBold14.loader = ResourceLoader.loader;
// TODO texts
// var levelBkgnd = new GuiText()
var levelBkgnd = new GuiText(domcasual24);
levelBkgnd.position = new Vector(5, 156);
levelBkgnd.extent = new Vector(254, 24);
levelBkgnd.text.textColor = 0x000000;
levelBkgnd.justify = Center;
levelBkgnd.text.text = "Beginner Level 3";
levelWnd.addChild(levelBkgnd);
var levelFgnd = new GuiText(domcasual24);
levelFgnd.position = new Vector(4, 155);
levelFgnd.extent = new Vector(254, 24);
levelFgnd.text.textColor = 0xFFFFFF;
levelFgnd.justify = Center;
levelFgnd.text.text = "Beginner Level 3";
levelWnd.addChild(levelFgnd);
var noQualText = new GuiText(domcasual32);
noQualText.position = new Vector(0, 84);
noQualText.extent = new Vector(254, 32);
noQualText.text.textColor = 0xCCCCCC;
noQualText.justify = Center;
noQualText.text.text = "Not qualified!";
levelWnd.addChild(noQualText);
var pmPlay = new GuiButton(loadButtonImages("data/ui/play/play"));
pmPlay.position = new Vector(391, 257);
@ -76,11 +143,17 @@ class PlayMissionGui extends GuiImage {
var pmPrev = new GuiButton(loadButtonImages("data/ui/play/prev"));
pmPrev.position = new Vector(321, 260);
pmPrev.extent = new Vector(77, 58);
pmPrev.pressedAction = (sender) -> {
setSelectedFunc(currentSelection - 1);
}
pmBox.addChild(pmPrev);
var pmNext = new GuiButton(loadButtonImages("data/ui/play/next"));
pmNext.position = new Vector(507, 262);
pmNext.extent = new Vector(75, 60);
pmNext.pressedAction = (sender) -> {
setSelectedFunc(currentSelection + 1);
}
pmBox.addChild(pmNext);
var pmBack = new GuiButton(loadButtonImages("data/ui/play/back"));
@ -91,13 +164,162 @@ class PlayMissionGui extends GuiImage {
};
pmBox.addChild(pmBack);
function mlFontLoader(text:String) {
switch (text) {
case "DomCasual24":
return domcasual32.toFont();
case "Arial14":
return arial14.toFont();
case "ArialBold14":
return arialBold14.toFont();
default:
return null;
}
}
// TODO Pm description
var pmDescription = new GuiMLText(arial14, mlFontLoader);
pmDescription.position = new Vector(61, 52);
pmDescription.extent = new Vector(215, 174);
pmDescription.text.textColor = 0x000000;
// We're gonna use  to align shit lmao, its too hacky i know
var descText = '<font face="DomCasual24" color="#000000">Learn The Super Speed </font><br/><br/>' + 'ÂTest Align';
descText += '<br/><br/><font face="DomCasual24">Best Times:</font><br/>';
for (i in 0...3) {
descText += '<br/>ÂÂ<font face="ArialBold14">${i + 1}. Nardo Polo</font>';
}
pmDescription.text.text = descText;
pmBox.addChild(pmDescription);
// Oh god this is yet another hack cause I cant do that tab thing torque does so thats bruh
var pmDescriptionOther = new GuiMLText(arial14, mlFontLoader);
pmDescriptionOther.position = new Vector(61, 52);
pmDescriptionOther.extent = new Vector(215, 174);
pmDescriptionOther.text.textColor = 0x000000;
var descText2 = '<br/><br/>' + '<font opacity="0">ÂTest Align</font>';
descText2 += '<br/><br/><br/>';
for (i in 0...3) {
descText2 += '<br/>ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ<font face="ArialBold14">00:00.000</font>';
}
pmDescriptionOther.text.text = descText2;
pmBox.addChild(pmDescriptionOther);
var tabBeginner = new GuiImage(ResourceLoader.getImage("data/ui/play/tab_begin.png").toTile());
tabBeginner.position = new Vector(29, 2);
tabBeginner.extent = new Vector(184, 55);
tabBeginner.pressedAction = (sender) -> {
currentList = MissionList.beginnerMissions;
currentCategory = "beginner";
setSelectedFunc(0);
setCategoryFunc("beginner");
}
localContainer.addChild(tabBeginner);
currentList = MissionList.beginnerMissions;
// TODO actual tab buttons
setCategoryFunc = function(category:String) {
localContainer.removeChild(tabBeginner);
localContainer.removeChild(tabIntermediate);
localContainer.removeChild(tabAdvanced);
localContainer.removeChild(tabCustom);
localContainer.removeChild(pmBox);
if (category == "beginner") {
localContainer.addChild(tabIntermediate);
localContainer.addChild(tabAdvanced);
localContainer.addChild(tabCustom);
localContainer.addChild(pmBox);
localContainer.addChild(tabBeginner);
}
if (category == "intermediate") {
localContainer.addChild(tabBeginner);
localContainer.addChild(tabAdvanced);
localContainer.addChild(tabCustom);
localContainer.addChild(pmBox);
localContainer.addChild(tabIntermediate);
}
if (category == "advanced") {
localContainer.addChild(tabBeginner);
localContainer.addChild(tabIntermediate);
localContainer.addChild(tabCustom);
localContainer.addChild(pmBox);
localContainer.addChild(tabAdvanced);
}
this.render(cast(this.parent, Canvas).scene2d);
}
function splitTextWithPadding(textElement:Text, textStr:String) {
var maxWidth = textElement.maxWidth;
textElement.maxWidth = null;
var splits = [];
var currentText = "Â";
var textSplit = textStr.split(" ");
for (i in 0...textSplit.length) {
var prevText = currentText;
currentText += textSplit[i];
if (i != textSplit.length - 1)
currentText += " ";
textElement.text = currentText;
if (textElement.textWidth > maxWidth) {
splits.push(StringTools.trim(prevText));
currentText = "Â" + textSplit[i];
if (i != textSplit.length - 1)
currentText += " ";
}
}
textElement.maxWidth = maxWidth;
splits.push(currentText);
return splits.join('\n');
}
setSelectedFunc = function setSelected(index:Int) {
if (index > currentList.length - 1) {
index = currentList.length - 1;
}
if (index < 0) {
index = 0;
}
currentSelection = index;
if (index == 0) {
pmPrev.disabled = true;
} else
pmPrev.disabled = false;
if (index == currentList.length - 1) {
pmNext.disabled = true;
} else
pmNext.disabled = false;
var currentMission = currentList[currentSelection];
var descText = '<font face="DomCasual24" color="#000000">${currentMission.title}</font><br/><br/>'
+ splitTextWithPadding(pmDescription.text, Util.unescape(currentMission.description));
descText += '<br/><br/><font face="DomCasual24">Best Times:</font><br/>';
for (i in 0...3) {
descText += '<br/>ÂÂ<font face="ArialBold14">${i + 1}. Nardo Polo</font>';
}
pmDescription.text.text = descText;
var descText2 = '<br/><br/>'
+ '<font opacity="0">${splitTextWithPadding(pmDescriptionOther.text, Util.unescape(currentMission.description))}</font>';
descText2 += '<br/><br/><br/>';
for (i in 0...3) {
descText2 += '<br/>ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ<font face="ArialBold14">00:00.000</font>';
}
pmDescriptionOther.text.text = descText2;
pmPreview.bmp.tile = currentMission.getPreviewImage();
levelBkgnd.text.text = currentCategory.charAt(0).toUpperCase() + currentCategory.substr(1) + ' Level ${currentSelection + 1}';
levelFgnd.text.text = currentCategory.charAt(0).toUpperCase() + currentCategory.substr(1) + ' Level ${currentSelection + 1}';
noQualText.text.visible = false;
}
}
public override function render(scene2d:Scene) {
super.render(scene2d);
setSelectedFunc(0);
}
}

View file

@ -115,7 +115,6 @@ class MisParser {
if (elements.length != 1) {
// We expect there to be only one outer element; the MissionGroup SimGroup.
trace(elements);
throw new Exception("Mission file doesn't have exactly 1 outer element!");
}
@ -126,6 +125,13 @@ class MisParser {
return mf;
}
public function parseMissionInfo() {
var missionInfoIndex = this.text.indexOf("new ScriptObject(MissionInfo) {");
this.index = missionInfoIndex;
var mInfo:MissionElementScriptObject = cast readElement();
return mInfo;
}
function readElement() {
// Get information about the head
// elementHeadRegEx.lastIndex = this.index;