turn mbp back into mbg

This commit is contained in:
RandomityGuy 2026-04-01 18:32:04 +01:00
parent c7c328fb22
commit 67b17c98b2
39 changed files with 1900 additions and 8935 deletions

View file

@ -103,9 +103,9 @@ class Analytics {
language: language(),
referrer: referrer(),
screen: screen(),
title: "MBHaxe Platinum",
title: "MBHaxe Gold",
url: "/",
website: "e6da43f0-fc6a-49cb-a4a9-4b7e7745e538",
website: "737bbe05-ad2e-43a5-820b-4e3014f5683e",
name: eventName
}
};
@ -120,7 +120,7 @@ class Analytics {
return js.Browser.window.location.hostname;
#end
#if hl
return "marbleblast.randomityguy.me";
return "marbleblastgold.randomityguy.me";
#end
}

View file

@ -133,20 +133,10 @@ class CameraController extends Object {
public function enableSpectate() {
spectate = true;
if (@:privateAccess this.level.playGui.setSpectateMenu(true)) {
if (Util.isTouchDevice()) {
MarbleGame.instance.touchInput.setSpectatorControls(true);
MarbleGame.instance.touchInput.setSpectatorControlsVisibility(false);
}
}
}
public function stopSpectate() {
spectate = false;
@:privateAccess this.level.playGui.setSpectateMenu(false);
if (Util.isTouchDevice()) {
MarbleGame.instance.touchInput.setSpectatorControls(false);
}
}
public function orbit(mouseX:Float, mouseY:Float, isTouch:Bool = false) {
@ -263,315 +253,6 @@ class CameraController extends Object {
return Math.pow(Math.abs(value), 1.6) * (value >= 0 ? 1 : -1);
}
function doOverviewCamera(currentTime:Float, dt:Float) {
var angle = Util.adjustedMod(2 * currentTime * Math.PI / 100.0, 2 * Math.PI);
var distance = overviewWidth.multiply(2.0 / 3.0);
var offset = new Vector(Math.sin(angle) * distance.x, Math.cos(angle) * distance.y);
var position = overviewCenter.add(offset);
var top = overviewCenter.z + (overviewWidth.z / 2) + overviewHeight;
position.z = top;
var posDist = Math.sqrt((position.x - overviewCenter.x) * (position.x - overviewCenter.x)
+ (position.y - overviewCenter.y) * (position.y - overviewCenter.y));
var upOffset = Math.tan(0.5) * posDist / 2;
// position.load(position.add(new Vector(0, 0, upOffset)));
var camera = level.scene.camera;
camera.pos.load(position);
camera.target.load(overviewCenter);
camera.up.x = 0;
camera.up.y = 0;
camera.up.z = 1;
}
function doSpectateCamera(currentTime:Float, dt:Float) {
var camera = level.scene.camera;
var lerpt = 1 - Math.pow(0.5, dt / 0.016); // Math.min(1, 1 - Math.pow(0.6, dt / 0.032)); // hxd.Math.min(1, 1 - Math.pow(0.6, dt * 600));
var gamepadX = applyNonlinearScale(rescaleDeadZone(Gamepad.getAxis(Settings.gamepadSettings.cameraXAxis), Settings.gamepadSettings.axisDeadzone));
var gamepadY = rescaleDeadZone(Gamepad.getAxis(Settings.gamepadSettings.cameraYAxis), Settings.gamepadSettings.axisDeadzone);
if (gamepadX != 0.0 || gamepadY != 0.0) {
wasLastGamepadInput = true;
}
var cameraPitchDelta = (Key.isDown(Settings.controlsSettings.camBackward) ? 1 : 0)
- (Key.isDown(Settings.controlsSettings.camForward) ? 1 : 0)
+ gamepadY;
if (Settings.gamepadSettings.invertYAxis || Settings.controlsSettings.invertYAxis)
cameraPitchDelta = -cameraPitchDelta;
var cameraYawDelta = (Key.isDown(Settings.controlsSettings.camRight) ? 1 : 0) - (Key.isDown(Settings.controlsSettings.camLeft) ? 1 : 0) + gamepadX;
if (Settings.gamepadSettings.invertXAxis)
cameraYawDelta = -cameraYawDelta;
if (MarbleGame.instance.paused) {
cameraYawDelta = 0;
cameraPitchDelta = 0;
}
var gamePadSensitivity = 1.0;
if (wasLastGamepadInput) {
gamePadSensitivity = Settings.gamepadSettings.cameraSensitivity; // It defaults to 0.6
}
var deltaX = 0.75 * 5 * cameraYawDelta * dt * gamePadSensitivity;
var deltaY = 0.75 * 5 * cameraPitchDelta * dt * gamePadSensitivity;
if (spectateMarbleIndex != -1) {
// Center the pitch
if (Util.isTouchDevice()) { // Do this only on touch devices
if (!Settings.controlsSettings.alwaysFreeLook
&& !Key.isDown(Settings.controlsSettings.freelook)
&& !MarbleGame.instance.touchInput.cameraInput.pressed
&& deltaY == 0.0) {
var rescaledY = deltaY;
if (rescaledY <= 0.0)
rescaledY = 0.4 - rescaledY * -0.75;
else
rescaledY = rescaledY * 1.1 + 0.4;
var movePitchDelta = (rescaledY - CameraPitch);
var movePitchSpeed = computePitchSpeedFromDelta(Math.abs(movePitchDelta)) * dt * 0.8;
if (movePitchDelta <= 0.0) {
movePitchDelta = -movePitchDelta;
if (movePitchDelta < movePitchSpeed)
movePitchSpeed = movePitchDelta;
movePitchDelta = -movePitchSpeed;
movePitchSpeed = movePitchDelta;
} else if (movePitchSpeed > movePitchDelta) {
movePitchSpeed = movePitchDelta;
}
deltaY = movePitchSpeed;
}
}
}
nextCameraYaw += deltaX;
nextCameraPitch += deltaY;
var limits = spectateMarbleIndex == -1 ? 0.0001 : Math.PI / 4;
nextCameraPitch = Math.max(-Math.PI / 2 + limits, Math.min(Math.PI / 2 - 0.0001, nextCameraPitch));
CameraYaw = nextCameraYaw; // Util.lerp(CameraYaw, nextCameraYaw, lerpt);
CameraPitch = nextCameraPitch; // Util.lerp(CameraPitch, nextCameraPitch, lerpt);
CameraPitch = Math.max(-Math.PI / 2 + limits, Math.min(Math.PI / 2 - 0.0001, CameraPitch)); // Util.clamp(CameraPitch, -Math.PI / 12, Math.PI / 2);
function getRotQuat(v1:Vector, v2:Vector) {
function orthogonal(v:Vector) {
var x = Math.abs(v.x);
var y = Math.abs(v.y);
var z = Math.abs(v.z);
var other = x < y ? (x < z ? new Vector(1, 0, 0) : new Vector(0, 0, 1)) : (y < z ? new Vector(0, 1, 0) : new Vector(0, 0, 1));
return v.cross(other);
}
var u = v1.normalized();
var v = v2.normalized();
if (u.multiply(-1).equals(v)) {
var q = new Quat();
var o = orthogonal(u).normalized();
q.x = o.x;
q.y = o.y;
q.z = o.z;
q.w = 0;
return q;
}
var half = u.add(v).normalized();
var q = new Quat();
q.w = u.dot(half);
var vr = u.cross(half);
q.x = vr.x;
q.y = vr.y;
q.z = vr.z;
return q;
}
var orientationQuat = level.getOrientationQuat(currentTime);
if (spectateMarbleIndex == -1) {
@:privateAccess level.playGui.setSpectateMenuText(0);
var up = new Vector(0, 0, 1);
up.transform(orientationQuat.toMatrix());
var directionVector = new Vector(1, 0, 0);
var q1 = new Quat();
q1.initRotateAxis(0, 1, 0, CameraPitch);
directionVector.transform(q1.toMatrix());
q1.initRotateAxis(0, 0, 1, CameraYaw);
directionVector.transform(q1.toMatrix());
directionVector.transform(orientationQuat.toMatrix());
var dy = Gamepad.getAxis(Settings.gamepadSettings.moveYAxis) * CameraSpeed * dt;
var dx = -Gamepad.getAxis(Settings.gamepadSettings.moveXAxis) * CameraSpeed * dt;
if (Key.isDown(Settings.controlsSettings.forward)) {
dy += CameraSpeed * dt;
}
if (Key.isDown(Settings.controlsSettings.backward)) {
dy -= CameraSpeed * dt;
}
if (Key.isDown(Settings.controlsSettings.left)) {
dx += CameraSpeed * dt;
}
if (Key.isDown(Settings.controlsSettings.right)) {
dx -= CameraSpeed * dt;
}
if (MarbleGame.instance.touchInput.movementInput.pressed) {
dx = -MarbleGame.instance.touchInput.movementInput.value.x * CameraSpeed * dt;
dy = -MarbleGame.instance.touchInput.movementInput.value.y * CameraSpeed * dt;
}
if ((!Util.isTouchDevice() && Key.isDown(Settings.controlsSettings.powerup))
|| (Util.isTouchDevice() && MarbleGame.instance.touchInput.powerupButton.pressed)
|| Gamepad.isDown(Settings.gamepadSettings.powerup)) {
dx *= 2;
dy *= 2;
}
if (Key.isPressed(Settings.controlsSettings.blast)
|| (MarbleGame.instance.touchInput.blastbutton.pressed && MarbleGame.instance.touchInput.blastbutton.didPressIt)
|| Gamepad.isPressed(Settings.gamepadSettings.blast)) {
var freeMarbleIndex = -1;
MarbleGame.instance.touchInput.blastbutton.didPressIt = false;
for (i in 0...level.marbles.length) {
var marble = level.marbles[i];
@:privateAccess if ((marble.connection != null && !marble.connection.spectator)) {
freeMarbleIndex = i;
break;
}
}
spectateMarbleIndex = freeMarbleIndex;
MarbleGame.instance.touchInput.setSpectatorControlsVisibility(true);
return;
}
var sideDir = directionVector.cross(up);
var moveDir = directionVector.multiply(dy).add(sideDir.multiply(dx));
camera.pos.load(camera.pos.add(moveDir));
camera.up = up;
camera.target = camera.pos.add(directionVector);
} else {
@:privateAccess level.playGui.setSpectateMenuText(1);
if (Key.isPressed(Settings.controlsSettings.left)
|| (Util.isTouchDevice()
&& MarbleGame.instance.touchInput.leftButton.pressed
&& MarbleGame.instance.touchInput.leftButton.didPressIt)) {
if (Util.isTouchDevice())
MarbleGame.instance.touchInput.leftButton.didPressIt = false;
spectateMarbleIndex = (spectateMarbleIndex - 1 + level.marbles.length) % level.marbles.length;
@:privateAccess while (level.marbles[spectateMarbleIndex].connection == null
|| level.marbles[spectateMarbleIndex].connection.spectator) {
spectateMarbleIndex = (spectateMarbleIndex - 1 + level.marbles.length) % level.marbles.length;
}
}
if (Key.isPressed(Settings.controlsSettings.right)
|| (Util.isTouchDevice()
&& MarbleGame.instance.touchInput.rightButton.pressed
&& MarbleGame.instance.touchInput.rightButton.didPressIt)) {
if (Util.isTouchDevice())
MarbleGame.instance.touchInput.rightButton.didPressIt = false;
spectateMarbleIndex = (spectateMarbleIndex + 1 + level.marbles.length) % level.marbles.length;
@:privateAccess while (level.marbles[spectateMarbleIndex].connection == null
|| level.marbles[spectateMarbleIndex].connection.spectator) {
spectateMarbleIndex = (spectateMarbleIndex + 1 + level.marbles.length) % level.marbles.length;
}
}
if (Key.isPressed(Settings.controlsSettings.blast)
|| (MarbleGame.instance.touchInput.blastbutton.pressed && MarbleGame.instance.touchInput.blastbutton.didPressIt)
|| Gamepad.isPressed(Settings.gamepadSettings.blast)) {
if (Util.isTouchDevice())
MarbleGame.instance.touchInput.blastbutton.didPressIt = false;
spectateMarbleIndex = -1;
MarbleGame.instance.touchInput.setSpectatorControlsVisibility(false);
return;
}
if (@:privateAccess level.marbles.length <= spectateMarbleIndex) {
spectateMarbleIndex = -1;
MarbleGame.instance.touchInput.setSpectatorControlsVisibility(false);
return;
}
var marblePosition = @:privateAccess level.marbles[spectateMarbleIndex].lastRenderPos;
var up = new Vector(0, 0, 1);
up.transform(orientationQuat.toMatrix());
var directionVector = new Vector(1, 0, 0);
var cameraVerticalTranslation = new Vector(0, 0, 0.3);
var q1 = new Quat();
q1.initRotateAxis(0, 1, 0, CameraPitch);
directionVector.transform(q1.toMatrix());
cameraVerticalTranslation.transform(q1.toMatrix());
q1.initRotateAxis(0, 0, 1, CameraYaw);
directionVector.transform(q1.toMatrix());
cameraVerticalTranslation.transform(q1.toMatrix());
directionVector.transform(orientationQuat.toMatrix());
cameraVerticalTranslation.transform(orientationQuat.toMatrix());
camera.up = up;
camera.pos = marblePosition.sub(directionVector.multiply(CameraDistance));
camera.target = marblePosition.add(cameraVerticalTranslation);
var closeness = 0.1;
var rayCastOrigin = marblePosition.add(level.marbles[spectateMarbleIndex].currentUp.multiply(marble._radius));
var processedShapes = [];
for (i in 0...3) {
var rayCastDirection = camera.pos.sub(rayCastOrigin);
rayCastDirection = rayCastDirection.add(rayCastDirection.normalized().multiply(2));
var rayCastLen = rayCastDirection.length();
var results = level.collisionWorld.rayCast(rayCastOrigin, rayCastDirection.normalized(), rayCastLen);
var firstHit:octree.IOctreeObject.RayIntersectionData = null;
var firstHitDistance = 1e8;
for (result in results) {
if (!processedShapes.contains(result.object)
&& (firstHit == null || (rayCastOrigin.distance(result.point) < firstHitDistance))) {
firstHit = result;
firstHitDistance = rayCastOrigin.distance(result.point);
}
}
if (firstHit != null)
processedShapes.push(firstHit.object);
if (firstHit != null) {
if (firstHitDistance < CameraDistance) {
// camera.pos = marblePosition.sub(directionVector.multiply(firstHit.distance * 0.7));
var plane = new Plane(firstHit.normal.x, firstHit.normal.y, firstHit.normal.z, firstHit.point.dot(firstHit.normal));
var normal = firstHit.normal.multiply(-1);
// var position = firstHit.point;
var projected = plane.project(camera.pos.toPoint());
var dist = plane.distance(camera.pos.toPoint());
if (dist >= closeness)
continue;
camera.pos = projected.toVector().add(normal.multiply(-closeness));
var forwardVec = marblePosition.sub(camera.pos).normalized();
var rightVec = camera.up.cross(forwardVec).normalized();
var upVec = forwardVec.cross(rightVec);
camera.target = marblePosition.add(upVec.multiply(0.3));
camera.up = upVec;
continue;
}
}
break;
}
}
this.setPosition(camera.pos.x, camera.pos.y, camera.pos.z);
}
function rescaleDeadZone(value:Float, deadZone:Float) {
if (deadZone >= value) {
if (-deadZone <= value)
@ -587,16 +268,6 @@ class CameraController extends Object {
// this.level.scene.camera.target = marblePosition.add(cameraVerticalTranslation);
// camera.position.add(cameraVerticalTranslation);
if (overview) {
doOverviewCamera(currentTime, dt);
return;
}
if (spectate) {
doSpectateCamera(currentTime, dt);
return;
}
var camera = level.scene.camera;
var lerpt = 1 - Math.pow(0.5, dt / 0.016); // Math.min(1, 1 - Math.pow(0.6, dt / 0.032)); // hxd.Math.min(1, 1 - Math.pow(0.6, dt * 600));

View file

@ -278,7 +278,6 @@ class Marble extends GameObject {
var forcefield:DtsObject;
var helicopter:DtsObject;
var megaHelicopter:DtsObject;
var superBounceEnableTime:Float = -1e8;
var shockAbsorberEnableTime:Float = -1e8;
var helicopterEnableTime:Float = -1e8;
@ -569,21 +568,9 @@ class Marble extends GameObject {
this.helicopter.y = 1e8;
this.helicopter.z = 1e8;
this.megaHelicopter = new DtsObject();
this.megaHelicopter.dtsPath = "data/shapes/items/megahelicopter.dts";
this.megaHelicopter.useInstancing = false;
this.megaHelicopter.identifier = "MegaHelicopter";
this.megaHelicopter.showSequences = true;
this.megaHelicopter.isBoundingBoxCollideable = false;
// this.addChild(this.helicopter);
this.megaHelicopter.x = 1e8;
this.megaHelicopter.y = 1e8;
this.megaHelicopter.z = 1e8;
var worker = new ResourceLoaderWorker(onFinish);
worker.addTask(fwd -> level.addDtsObject(this.forcefield, fwd));
worker.addTask(fwd -> level.addDtsObject(this.helicopter, fwd));
worker.addTask(fwd -> level.addDtsObject(this.megaHelicopter, fwd));
worker.run();
loadMarbleAttributes();
@ -2418,49 +2405,43 @@ class Marble extends GameObject {
move.d = new Vector();
move.d.x = Gamepad.getAxis(Settings.gamepadSettings.moveYAxis);
move.d.y = -Gamepad.getAxis(Settings.gamepadSettings.moveXAxis);
if (@:privateAccess !MarbleGame.instance.world.playGui.isChatFocused()) {
if (Key.isDown(Settings.controlsSettings.forward)) {
move.d.x -= 1;
}
if (Key.isDown(Settings.controlsSettings.backward)) {
move.d.x += 1;
}
if (Key.isDown(Settings.controlsSettings.left)) {
move.d.y += 1;
}
if (Key.isDown(Settings.controlsSettings.right)) {
move.d.y -= 1;
}
move.d.x = Util.clamp(move.d.x, -1, 1);
move.d.y = Util.clamp(move.d.y, -1, 1);
if (Key.isDown(Settings.controlsSettings.jump)
|| MarbleGame.instance.touchInput.jumpButton.pressed
|| Gamepad.isDown(Settings.gamepadSettings.jump)) {
move.jump = true;
}
if ((!Util.isTouchDevice() && Key.isDown(Settings.controlsSettings.powerup))
|| (Util.isTouchDevice() && MarbleGame.instance.touchInput.powerupButton.pressed)
|| Gamepad.isDown(Settings.gamepadSettings.powerup)) {
move.powerup = true;
}
if (Key.isDown(Settings.controlsSettings.blast)
|| (MarbleGame.instance.touchInput.blastbutton.pressed)
|| Gamepad.isDown(Settings.gamepadSettings.blast))
move.blast = true;
if (Key.isDown(Settings.controlsSettings.forward)) {
move.d.x -= 1;
}
if (Key.isDown(Settings.controlsSettings.backward)) {
move.d.x += 1;
}
if (Key.isDown(Settings.controlsSettings.left)) {
move.d.y += 1;
}
if (Key.isDown(Settings.controlsSettings.right)) {
move.d.y -= 1;
}
move.d.x = Util.clamp(move.d.x, -1, 1);
move.d.y = Util.clamp(move.d.y, -1, 1);
if (Key.isDown(Settings.controlsSettings.jump)
|| MarbleGame.instance.touchInput.jumpButton.pressed
|| Gamepad.isDown(Settings.gamepadSettings.jump)) {
move.jump = true;
}
if ((!Util.isTouchDevice() && Key.isDown(Settings.controlsSettings.powerup))
|| (Util.isTouchDevice() && MarbleGame.instance.touchInput.powerupButton.pressed)
|| Gamepad.isDown(Settings.gamepadSettings.powerup)) {
move.powerup = true;
}
if (Key.isDown(Settings.controlsSettings.respawn) || Gamepad.isDown(Settings.gamepadSettings.respawn)) {
move.respawn = true;
if (Net.isMP) {
@:privateAccess Key.keyPressed[Settings.controlsSettings.respawn] = 0;
Gamepad.releaseKey(Settings.gamepadSettings.respawn);
}
if (Key.isDown(Settings.controlsSettings.respawn) || Gamepad.isDown(Settings.gamepadSettings.respawn)) {
move.respawn = true;
if (Net.isMP) {
@:privateAccess Key.keyPressed[Settings.controlsSettings.respawn] = 0;
Gamepad.releaseKey(Settings.gamepadSettings.respawn);
}
}
if (MarbleGame.instance.touchInput.movementInput.pressed) {
move.d.y = -MarbleGame.instance.touchInput.movementInput.value.x;
move.d.x = MarbleGame.instance.touchInput.movementInput.value.y;
}
if (MarbleGame.instance.touchInput.movementInput.pressed) {
move.d.y = -MarbleGame.instance.touchInput.movementInput.value.x;
move.d.x = MarbleGame.instance.touchInput.movementInput.value.y;
}
return move;
}
@ -2606,30 +2587,16 @@ class Marble extends GameObject {
this.forcefield.y = 1e8;
this.forcefield.z = 1e8;
}
if (megaEnabled) {
this.helicopter.setPosition(1e8, 1e8, 1e8);
if (helicopterEnabled) {
this.megaHelicopter.setPosition(x, y, z);
this.megaHelicopter.setRotationQuat(this.level.getOrientationQuat(timeState.currentAttemptTime));
if (selfMarble)
this.helicopterSound.pause = false;
} else {
this.megaHelicopter.setPosition(1e8, 1e8, 1e8);
if (selfMarble)
this.helicopterSound.pause = true;
}
if (helicopterEnabled) {
this.helicopter.setPosition(x, y, z);
this.helicopter.setRotationQuat(this.level.getOrientationQuat(timeState.currentAttemptTime));
if (selfMarble)
this.helicopterSound.pause = false;
} else {
this.megaHelicopter.setPosition(1e8, 1e8, 1e8);
if (helicopterEnabled) {
this.helicopter.setPosition(x, y, z);
this.helicopter.setRotationQuat(this.level.getOrientationQuat(timeState.currentAttemptTime));
if (selfMarble)
this.helicopterSound.pause = false;
} else {
this.helicopter.setPosition(1e8, 1e8, 1e8);
if (selfMarble)
this.helicopterSound.pause = true;
}
this.helicopter.setPosition(1e8, 1e8, 1e8);
if (selfMarble)
this.helicopterSound.pause = true;
}
}

View file

@ -1,10 +1,6 @@
package src;
import gui.JoinServerGui;
import gui.MPPreGameDlg;
import gui.MPExitGameDlg;
import gui.GuiControl;
import gui.MPPlayMissionGui;
import gui.MainMenuGui;
#if !js
import gui.ReplayCenterGui;
@ -33,7 +29,6 @@ import src.Debug;
import src.Gamepad;
import src.Analytics;
import net.Net;
import net.MasterServerClient;
import net.NetCommands;
@:publicFields
@ -210,7 +205,6 @@ class MarbleGame {
}
public function update(dt:Float) {
MasterServerClient.process();
Net.checkPacketTimeout(dt);
if (world != null) {
if (world._disposed) {
@ -255,10 +249,6 @@ class MarbleGame {
if (((Key.isPressed(Key.ESCAPE) #if js && paused #end) || Gamepad.isPressed(["start"]))
&& world.finishTime == null
&& world._ready) {
if (MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1] is MPPreGameDlg
|| (Net.isMP && paused && !(MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1] is MPExitGameDlg))) {
return; // don't pause
}
handlePauseGame();
}
}
@ -287,47 +277,22 @@ class MarbleGame {
}
public function showPauseUI() {
if (world.isMultiplayer) {
exitGameDlg = new MPExitGameDlg(() -> {
canvas.popDialog(exitGameDlg);
paused = !paused;
var w = getWorld();
w.setCursorLock(true);
}, () -> {
canvas.popDialog(exitGameDlg);
quitMission(Net.isClient);
if (Net.isMP && Net.isClient) {
Net.disconnect();
canvas.setContent(new JoinServerGui());
}
});
} else {
exitGameDlg = new ExitGameDlg((sender) -> {
canvas.popDialog(exitGameDlg);
var w = getWorld();
if (MarbleGame.instance.toRecord) {
MarbleGame.canvas.pushDialog(new ReplayNameDlg(() -> {
quitMission();
}));
} else {
quitMission(Net.isClient);
if (Net.isMP && Net.isClient) {
Net.disconnect();
}
}
}, (sender) -> {
canvas.popDialog(exitGameDlg);
paused = !paused;
var w = getWorld();
w.setCursorLock(true);
}, (sender) -> {
canvas.popDialog(exitGameDlg);
var w = getWorld();
w.restart(w.marble, true);
// world.setCursorLock(true);
paused = !paused;
});
}
exitGameDlg = new ExitGameDlg((sender) -> {
canvas.popDialog(exitGameDlg);
var w = getWorld();
quitMission(Net.isClient);
}, (sender) -> {
canvas.popDialog(exitGameDlg);
paused = !paused;
var w = getWorld();
w.setCursorLock(true);
}, (sender) -> {
canvas.popDialog(exitGameDlg);
var w = getWorld();
w.restart(w.marble, true);
// world.setCursorLock(true);
paused = !paused;
});
canvas.pushDialog(exitGameDlg);
}
@ -378,18 +343,12 @@ class MarbleGame {
if (world.isWatching) {
canvas.setContent(Type.createInstance(replayEndClass, []));
} else {
if (Net.isMP) {
var lobby = new MPPlayMissionGui(Net.isHost);
canvas.setContent(lobby);
} else {
if (!world.mission.isClaMission && !world.mission.isCustom) {
PlayMissionGui.currentCategoryStatic = world.mission.type;
PlayMissionGui.currentSelectionStatic = world.mission.index;
PlayMissionGui.currentGameStatic = world.mission.game;
}
var pmg = new PlayMissionGui();
canvas.setContent(pmg);
if (!world.mission.isClaMission && !world.mission.isCustom) {
PlayMissionGui.currentCategoryStatic = world.mission.type;
PlayMissionGui.currentSelectionStatic = world.mission.index;
}
var pmg = new PlayMissionGui();
canvas.setContent(pmg);
}
world.dispose();
world = null;

View file

@ -4,7 +4,6 @@ import net.NetPacket.ExplodableUpdatePacket;
import net.TrapdoorPredictionStore;
import shapes.Explodable;
import net.ExplodablePredictionStore;
import gui.MPPreGameDlg;
import src.Radar;
import rewind.InputRecorder;
import net.NetPacket.ScoreboardPacket;
@ -12,12 +11,9 @@ import net.NetPacket.PowerupPickupPacket;
import net.Move;
import net.NetPacket.GemSpawnPacket;
import net.BitStream.OutputBitStream;
import net.MasterServerClient;
import gui.MarbleSelectGui;
import gui.MPPlayMissionGui;
import collision.CollisionPool;
import net.GemPredictionStore;
import modes.HuntMode;
import net.NetPacket.MarbleNetFlags;
import net.PowerupPredictionStore;
import net.MarblePredictionStore;
@ -295,7 +291,7 @@ class MarbleWorld extends Scheduler {
public function initLoading() {
Console.log("*** LOADING MISSION: " + mission.path);
this.loadingGui = new LoadingGui(this.mission.title, this.mission.game, this.isMultiplayer);
this.loadingGui = new LoadingGui(this.mission.title);
MarbleGame.canvas.setContent(this.loadingGui);
if (this.mission.isClaMission) {
this.mission.download(() -> loadBegin());
@ -367,39 +363,22 @@ class MarbleWorld extends Scheduler {
public function postInit() {
// Add the sky at the last so that cubemap reflections work
this.playGui.init(this.scene2d, this.mission.game.toLowerCase(), () -> {
this.scene.addChild(this.sky);
this.playGui.init(this.scene2d);
this.scene.addChild(this.sky);
if (this.isMultiplayer) {
// Add us
if (Net.isHost) {
this.playGui.addPlayer(0, Settings.highscoreName.substr(0, 15), true);
} else {
this.playGui.addPlayer(Net.clientId, Settings.highscoreName.substr(0, 15), true);
}
for (client in Net.clientIdMap) {
this.playGui.addPlayer(client.id, client.name.substr(0, 15), false);
}
}
this._ready = true;
var musicFileName = 'data/sound/music/' + this.mission.missionInfo.music;
if (ResourceLoader.exists(musicFileName))
AudioManager.playMusic(ResourceLoader.getResource(musicFileName, ResourceLoader.getAudio, this.soundResources), this.mission.missionInfo.music);
else
AudioManager.playShell();
MarbleGame.canvas.clearContent();
if (this.endPad != null)
this.endPad.generateCollider();
this._ready = true;
var musicFileName = 'data/sound/music/' + this.mission.missionInfo.music;
if (ResourceLoader.exists(musicFileName))
AudioManager.playMusic(ResourceLoader.getResource(musicFileName, ResourceLoader.getAudio, this.soundResources), this.mission.missionInfo.music);
else
AudioManager.playShell();
MarbleGame.canvas.clearContent();
if (this.endPad != null)
this.endPad.generateCollider();
if (this.isMultiplayer) {
this.playGui.formatGemHuntCounter(0);
this.playGui.formatCountdownTimer(0, 0);
} else {
this.playGui.formatGemCounter(this.gemCount, this.totalGems);
}
Console.log("MISSION LOADED");
start();
});
this.playGui.formatGemCounter(this.gemCount, this.totalGems);
Console.log("MISSION LOADED");
start();
}
public function initScene(onFinish:Void->Void) {
@ -491,7 +470,6 @@ class MarbleWorld extends Scheduler {
"sound/bumperding1.wav",
"sound/bumper1.wav",
"sound/jump.wav",
"sound/mega_roll.wav",
"sound/bouncehard1.wav",
"sound/bouncehard2.wav",
"sound/bouncehard3.wav",
@ -500,8 +478,6 @@ class MarbleWorld extends Scheduler {
"sound/ready.wav",
"sound/set.wav",
"sound/go.wav",
"sound/alarm.wav",
"sound/alarm_timeout.wav",
"sound/missinggems.wav",
"shapes/images/glow_bounce.dts",
"shapes/images/glow_bounce.png",
@ -514,32 +490,8 @@ class MarbleWorld extends Scheduler {
"shapes/items/gem.dts", // Ew ew
"shapes/items/gemshine.png",
"shapes/items/enviro1.jpg",
"shapes/balls/base.marble.png"
];
if (this.game == "ultra" || Net.isMP) {
marblefiles.push("shapes/balls/pack1/marble20.normal.png");
marblefiles.push("shapes/balls/pack1/marble18.normal.png");
marblefiles.push("shapes/balls/pack1/marble01.normal.png");
marblefiles.push("sound/blast.wav");
}
// Hacky
if (client == null) {
marblefiles.push(StringTools.replace(Settings.optionsSettings.marbleModel, "data/", ""));
if (Settings.optionsSettings.marbleCategoryIndex == 0)
marblefiles.push("shapes/balls/" + Settings.optionsSettings.marbleSkin + ".marble.png");
else
marblefiles.push("shapes/balls/pack1/" + Settings.optionsSettings.marbleSkin + ".marble.png");
} else {
var marbleDts = MarbleSelectGui.marbleData[client.getMarbleCatId()][client.getMarbleId()].dts; // FIXME
marblefiles.push(StringTools.replace(marbleDts, "data/", ""));
var marbleSkin = MarbleSelectGui.marbleData[client.getMarbleCatId()][client.getMarbleId()].skin;
if (client.getMarbleCatId() == 0)
marblefiles.push("shapes/balls/" + marbleSkin + ".marble.png");
else
marblefiles.push("shapes/balls/pack1/" + marbleSkin + ".marble.png");
}
var gameModeFiles = this.gameMode.getPreloadFiles();
for (file in marblefiles) {
@ -602,7 +554,6 @@ class MarbleWorld extends Scheduler {
}
public function showPreGame() {
MarbleGame.canvas.pushDialog(new MPPreGameDlg());
this.setCursorLock(false);
if (Util.isTouchDevice()) {
MarbleGame.instance.touchInput.setControlsEnabled(false);
@ -622,8 +573,6 @@ class MarbleWorld extends Scheduler {
this.initMarble(cc, () -> {
var addedMarble = clientMarbles.get(cc);
this.restart(addedMarble); // spawn it
this.playGui.addPlayer(cc.id, cc.getName(), false);
this.playGui.redrawPlayerList();
// Sort all the marbles so that they are updated in a deterministic order
this.marbles.sort((a, b) -> @:privateAccess {
@ -639,8 +588,6 @@ class MarbleWorld extends Scheduler {
this.initMarble(cc, () -> {
var addedMarble = clientMarbles.get(cc);
this.restart(addedMarble); // spawn it
this.playGui.addPlayer(cc.id, cc.getName(), false);
this.playGui.redrawPlayerList();
// Sort all the marbles so that they are updated in a deterministic order
this.marbles.sort((a, b) -> @:privateAccess {
@ -779,17 +726,6 @@ class MarbleWorld extends Scheduler {
this.marble.mode = Start;
sky.follow = marble.camera;
if (isMultiplayer) {
for (client => marble in clientMarbles) {
this.cancel(marble.oobSchedule);
var marbleStartQuat = this.gameMode.getSpawnTransform();
marble.setMarblePosition(marbleStartQuat.position.x, marbleStartQuat.position.y, marbleStartQuat.position.z);
marble.reset();
marble.setMode(Start);
}
this.playGui.resetPlayerScores();
}
var missionInfo:MissionElementScriptObject = cast this.mission.root.elements.filter((element) -> element._type == MissionElementType.ScriptObject
&& element._name == "MissionInfo")[0];
if (missionInfo.starthelptext != null)
@ -936,14 +872,8 @@ class MarbleWorld extends Scheduler {
for (client => marble in this.clientMarbles)
marble.setMode(Play);
this.playGui.redrawPlayerList(); // Update spectators display
this.playGui.setCenterText('go');
this.playGui.doStateChangeSound('go');
var huntMode = cast(this.gameMode, HuntMode);
huntMode.freeSpawns();
}
}
if (this.multiplayerStarted) {
@ -1400,96 +1330,7 @@ class MarbleWorld extends Scheduler {
this.gameMode.onRestart();
}
public function getWorldStateForClientJoin() {
var packets = [];
// First, gem spawn packet
var bs = new OutputBitStream();
bs.writeByte(GemSpawn);
var packet = new GemSpawnPacket();
var hunt = cast(this.gameMode, HuntMode);
if (@:privateAccess hunt.activeGemSpawnGroup != null) {
var activeGemIds = [];
for (gemId in @:privateAccess hunt.activeGemSpawnGroup) {
if (@:privateAccess hunt.gemSpawnPoints[gemId].gem != null && @:privateAccess !hunt.gemSpawnPoints[gemId].gem.pickedUp) {
activeGemIds.push(gemId);
}
}
packet.gemIds = activeGemIds;
packet.serialize(bs);
packets.push(bs.getBytes());
}
// Marble states
for (marb in this.marbles) {
var oldFlags = @:privateAccess marb.netFlags;
@:privateAccess marb.netFlags = MarbleNetFlags.DoBlast | MarbleNetFlags.DoMega | MarbleNetFlags.DoHelicopter | MarbleNetFlags.DoShockAbsorber | MarbleNetFlags.DoSuperBounce | MarbleNetFlags.PickupPowerup | MarbleNetFlags.GravityChange | MarbleNetFlags.UsePowerup;
if (oldFlags & MarbleNetFlags.UpdateTrapdoor > 0) {
@:privateAccess marb.netFlags |= MarbleNetFlags.UpdateTrapdoor;
}
var innerMove = @:privateAccess marb.lastMove;
if (innerMove == null) {
innerMove = new Move();
innerMove.d = new Vector(0, 0);
}
var motionDir = @:privateAccess marb.moveMotionDir;
if (motionDir == null) {
motionDir = marb.getMarbleAxis()[1];
}
var move = new NetMove(innerMove, motionDir, timeState, timeState.ticks, 65535);
packets.push(@:privateAccess marb.packUpdate(move, timeState));
@:privateAccess marb.netFlags = oldFlags;
}
// Powerup states
for (powerup in this.powerUps) {
if (powerup.currentOpacity != 1.0) { // it must be picked up or something
if (@:privateAccess powerup.pickupClient != -1) {
var b = new OutputBitStream();
b.writeByte(NetPacketType.PowerupPickup);
var pickupPacket = new PowerupPickupPacket();
pickupPacket.clientId = @:privateAccess powerup.pickupClient;
pickupPacket.serverTicks = @:privateAccess powerup.pickupTicks;
pickupPacket.powerupItemId = powerup.netIndex;
pickupPacket.serialize(b);
packets.push(b.getBytes());
}
}
}
// Explosion states
for (exp in this.explodables) {
if (this.timeState.ticks < (exp.lastContactTick + exp.renewTime >> 5)) {
var b = new OutputBitStream();
b.writeByte(NetPacketType.ExplodableUpdate);
var explPacket = new ExplodableUpdatePacket();
explPacket.explodableId = exp.netId;
explPacket.serverTicks = timeState.ticks;
explPacket.serialize(b);
packets.push(b.getBytes());
}
}
// Scoreboard!
var b = new OutputBitStream();
b.writeByte(NetPacketType.ScoreBoardInfo);
var sbPacket = new ScoreboardPacket();
for (player in @:privateAccess this.playGui.playerList) {
sbPacket.scoreBoard.set(player.id, player.score);
sbPacket.rBoard.set(player.id, player.r);
sbPacket.yBoard.set(player.id, player.y);
sbPacket.bBoard.set(player.id, player.b);
}
sbPacket.serialize(b);
packets.push(b.getBytes());
return packets;
}
public function getWorldStateForClientJoin() {}
inline function hasPredictionFlag(mask:Int, clientId:Int):Bool {
return (mask & (1 << clientId)) != 0;
@ -1600,14 +1441,6 @@ class MarbleWorld extends Scheduler {
t.update(advanceTimeState);
}
var huntMode:HuntMode = cast this.gameMode;
if (@:privateAccess huntMode.activeGemSpawnGroup != null) {
for (activeGem in @:privateAccess huntMode.activeGemSpawnGroup) {
var g = @:privateAccess huntMode.gemSpawnPoints[activeGem].gem;
if (g != null && g.pickUpClient != -1 && marbleNeedsPrediction & (1 << g.pickUpClient) > 0)
huntMode.setGemHiddenStatus(activeGem, gemPredictions.getState(activeGem));
}
}
// }
// }
@ -1710,13 +1543,7 @@ class MarbleWorld extends Scheduler {
return -1;
}
public function spawnHuntGemsClientSide(gemIds:Array<Int>, expireds:Array<Bool>) {
if (this.isMultiplayer && Net.isClient) {
var huntMode:HuntMode = cast this.gameMode;
huntMode.setActiveSpawnSphere(gemIds, expireds);
// radar.blink();
}
}
public function spawnHuntGemsClientSide(gemIds:Array<Int>, expireds:Array<Bool>) {}
public function removePlayer(cc:GameConnection) {
var otherMarble = this.clientMarbles[cc];
@ -1726,7 +1553,6 @@ class MarbleWorld extends Scheduler {
this.scene.removeChild(otherMarble);
this.collisionWorld.removeMarbleEntity(otherMarble.collider);
this.collisionWorld.removeMovingEntity(otherMarble.collider);
this.playGui.removePlayer(cc.id);
this.clientMarbles.remove(cc);
otherMarble.dispose();
this.marbles.remove(otherMarble);
@ -1877,17 +1703,6 @@ class MarbleWorld extends Scheduler {
this.tickSchedule(timeState.currentAttemptTime);
if (Key.isPressed(Settings.controlsSettings.blast)
|| (MarbleGame.instance.touchInput.blastbutton.pressed)
|| Gamepad.isPressed(Settings.gamepadSettings.blast)
&& !this.isWatching
&& this.game == "ultra") {
this.marble.useBlast(timeState);
if (this.isRecording) {
this.replay.recordMarbleStateFlags(false, false, false, true);
}
}
if (this.isWatching && this.replay.currentPlaybackFrame.marbleStateFlags.has(UsedBlast))
this.marble.useBlast(timeState);
@ -2305,7 +2120,7 @@ class MarbleWorld extends Scheduler {
}
if (finishTime != null)
this.timeState.gameplayClock = finishTime.gameplayClock;
playGui.formatTimer(this.timeState.gameplayClock, determineClockColor(this.timeState.gameplayClock));
playGui.formatTimer(this.timeState.gameplayClock);
if (!this.isWatching && this.isRecording)
this.replay.recordTimeState(timeState.currentAttemptTime, timeState.gameplayClock, this.bonusTime);
@ -2313,14 +2128,11 @@ class MarbleWorld extends Scheduler {
public function updateBlast(marble:Marble, timestate:TimeState) {
if (Net.isMP) {
if (this.marble == marble) {
this.playGui.setBlastValue(marble.blastTicks / (25000 >> 5));
}
if (this.marble == marble) {}
} else if (this.game == "ultra") {
if (marble.blastAmount < 1) {
marble.blastAmount = Util.clamp(marble.blastAmount + (timeState.dt / 25), 0, 1);
}
this.playGui.setBlastValue(marble.blastAmount);
}
}
@ -2455,6 +2267,7 @@ class MarbleWorld extends Scheduler {
var pointercontainer = js.Browser.document.querySelector("#pointercontainer");
pointercontainer.hidden = false;
#end
var wasRecording = this.isRecording;
this.schedule(this.timeState.currentAttemptTime + 3, () -> {
this.isRecording = false; // Stop recording here
}, "stopRecordingTimeout");
@ -2475,10 +2288,15 @@ class MarbleWorld extends Scheduler {
#end
}
if (MarbleGame.instance.toRecord) {
MarbleGame.canvas.pushDialog(new ReplayNameDlg(endGameCode));
} else {
endGameCode();
if (this.isRecording) {
this.isRecording = false; // Stop recording here if we haven't already
this.clearScheduleId("stopRecordingTimeout");
}
if (wasRecording) {
this.saveReplay();
}
}
endGameCode();
}, (sender) -> {
var restartGameCode = () -> {
MarbleGame.canvas.popDialog(egg);
@ -2492,26 +2310,16 @@ class MarbleWorld extends Scheduler {
// @:privateAccess playGui.playGuiCtrl.render(scene2d);
}
if (MarbleGame.instance.toRecord) {
MarbleGame.canvas.pushDialog(new ReplayNameDlg(() -> {
this.isRecording = true;
restartGameCode();
}));
} else {
restartGameCode();
}
}, (sender) -> {
var nextLevelCode = () -> {
var nextMission = mission.getNextMission();
if (nextMission != null) {
MarbleGame.instance.playMission(nextMission);
if (this.isRecording) {
this.clearScheduleId("stopRecordingTimeout");
}
if (wasRecording) {
this.saveReplay();
this.isRecording = true; // Start a new recording for the restarted game
}
}
if (MarbleGame.instance.toRecord) {
MarbleGame.canvas.pushDialog(new ReplayNameDlg(nextLevelCode));
} else {
nextLevelCode();
}
}, mission, finishTime, this.replay.write());
restartGameCode();
}, mission, finishTime);
MarbleGame.canvas.pushDialog(egg);
this.setCursorLock(false);
return 0;
@ -2560,13 +2368,6 @@ class MarbleWorld extends Scheduler {
public function addBonusTime(t:Float) {
this.bonusTime += t;
if (t > 0) {
this.playGui.addMiddleMessage('-${t}s', 0x99ff99);
} else if (t < 0) {
this.playGui.addMiddleMessage('+${- t}s', 0xff9999);
} else {
this.playGui.addMiddleMessage('+0s', 0xcccccc);
}
}
/** Get the current interpolated orientation quaternion. */
@ -2818,33 +2619,26 @@ class MarbleWorld extends Scheduler {
}
public function saveReplay() {
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']);
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']);
if (!sys.FileSystem.exists(replayPath)) {
this.replay.name += ' (${count})';
found = true;
} else {
count++;
}
}
}
var replayBytes = this.replay.write();
sys.io.File.saveBytes(replayPath, replayBytes);
var defaultFilename = '${this.mission.title} ${this.finishTime == null ? "Unfinished Run" : Std.string(this.finishTime.gameplayClock)}.mbr';
#if hl
hxd.File.saveAs(replayBytes, {
title: 'Save Replay',
fileTypes: [
{
name: "Replay (*.mbr)",
extensions: ["mbr"]
}
],
defaultPath: defaultFilename
});
#end
#if js
var replayBytes = this.replay.write();
var blob = new js.html.Blob([replayBytes.getData()], {
type: 'application/octet-stream'
});
var url = js.html.URL.createObjectURL(blob);
var fname = '${this.replay.name}.mbr';
var fname = defaultFilename;
var element = js.Browser.document.createElement('a');
element.setAttribute('href', url);
element.setAttribute('download', fname);

View file

@ -4,12 +4,13 @@ import haxe.Json;
import mis.MisParser;
import src.ResourceLoader;
import src.Mission;
import src.Console;
import src.MissionList;
import src.Util;
@:publicFields
class MissionList {
static var missionList:Map<String, Map<String, Array<Mission>>>;
static var beginnerMissions:Array<Mission>;
static var intermediateMissions:Array<Mission>;
static var advancedMissions:Array<Mission>;
static var customMissions:Array<Mission>;
static var missions:Map<String, Mission>;
@ -23,110 +24,58 @@ class MissionList {
return;
missions = new Map<String, Mission>();
missionList = [];
function parseDifficulty(game:String, mispath:String, difficulty:String) {
function parseDifficulty(difficulty:String) {
#if (hl && !android)
var difficultyFiles = ResourceLoader.fileSystem.dir('data/${mispath}/' + difficulty);
var difficultyFiles = ResourceLoader.fileSystem.dir("data/missions/" + difficulty);
#end
#if (js || android)
var difficultyFiles = ResourceLoader.fileSystem.dir('${mispath}/' + difficulty);
var difficultyFiles = ResourceLoader.fileSystem.dir("missions/" + difficulty);
#end
var difficultyMissions = [];
for (file in difficultyFiles) {
if (file.extension == "mis") {
var misParser = new MisParser(file.getText());
var misParser = new MisParser(Util.toASCII(file.getBytes()));
var mInfo = misParser.parseMissionInfo();
var mission = Mission.fromMissionInfo(file.path, mInfo);
if (game != "custom")
mission.game = game;
else if (mInfo.game != null && mInfo.game != "")
mission.game = mInfo.game.toLowerCase();
else
mission.game = game; // Last case scenario
if (game == "custom")
mission.isCustom = true;
// do egg thing
if (StringTools.contains(file.getText().toLowerCase(), 'datablock = "easteregg"')) { // Ew
mission.hasEgg = true;
}
mission.game = "gold";
missions.set(file.path, mission);
difficultyMissions.push(mission);
}
if (file.isDirectory) {
var retdir = parseDifficulty(difficulty + "/" + file.name);
difficultyMissions = difficultyMissions.concat(retdir);
}
}
difficultyMissions.sort((a, b) -> Std.parseInt(a.missionInfo.level) - Std.parseInt(b.missionInfo.level));
for (i in 0...difficultyMissions.length) {
difficultyMissions[i].index = i;
}
for (i in 0...difficultyMissions.length - 1) {
@:privateAccess difficultyMissions[i].next = difficultyMissions[i + 1];
}
return difficultyMissions;
}
var goldMissions:Map<String, Array<Mission>> = [];
var platinumMissions:Map<String, Array<Mission>> = [];
var ultraMissions:Map<String, Array<Mission>> = [];
var multiplayerMissions:Map<String, Array<Mission>> = [];
goldMissions.set("beginner", parseDifficulty("gold", "missions_mbg", "beginner"));
goldMissions.set("intermediate", parseDifficulty("gold", "missions_mbg", "intermediate"));
goldMissions.set("advanced", parseDifficulty("gold", "missions_mbg", "advanced"));
platinumMissions.set("beginner", parseDifficulty("platinum", "missions_mbp", "beginner"));
platinumMissions.set("intermediate", parseDifficulty("platinum", "missions_mbp", "intermediate"));
platinumMissions.set("advanced", parseDifficulty("platinum", "missions_mbp", "advanced"));
platinumMissions.set("expert", parseDifficulty("platinum", "missions_mbp", "expert"));
ultraMissions.set("beginner", parseDifficulty("ultra", "missions_mbu", "beginner"));
ultraMissions.set("intermediate", parseDifficulty("ultra", "missions_mbu", "intermediate"));
ultraMissions.set("advanced", parseDifficulty("ultra", "missions_mbu", "advanced"));
multiplayerMissions.set("beginner", parseDifficulty("multiplayer", "multiplayer/hunt", "beginner"));
multiplayerMissions.set("intermediate", parseDifficulty("multiplayer", "multiplayer/hunt", "intermediate"));
multiplayerMissions.set("advanced", parseDifficulty("multiplayer", "multiplayer/hunt", "advanced"));
customMissions = parseDifficulty("custom", "missions", "custom");
@:privateAccess goldMissions["beginner"][goldMissions["beginner"].length - 1].next = goldMissions["intermediate"][0];
@:privateAccess goldMissions["intermediate"][goldMissions["intermediate"].length - 1].next = goldMissions["advanced"][0];
@:privateAccess goldMissions["advanced"][goldMissions["advanced"].length - 1].next = goldMissions["beginner"][0];
@:privateAccess platinumMissions["beginner"][platinumMissions["beginner"].length - 1].next = platinumMissions["intermediate"][0];
@:privateAccess platinumMissions["intermediate"][platinumMissions["intermediate"].length - 1].next = platinumMissions["advanced"][0];
@:privateAccess platinumMissions["advanced"][platinumMissions["advanced"].length - 1].next = platinumMissions["expert"][0];
@:privateAccess platinumMissions["expert"][platinumMissions["expert"].length - 1].next = platinumMissions["beginner"][0];
@:privateAccess ultraMissions["beginner"][ultraMissions["beginner"].length - 1].next = ultraMissions["intermediate"][0];
@:privateAccess ultraMissions["intermediate"][ultraMissions["intermediate"].length - 1].next = ultraMissions["advanced"][0];
@:privateAccess ultraMissions["advanced"][ultraMissions["advanced"].length - 1].next = ultraMissions["beginner"][0];
// Hypercube uses MBG logic
ultraMissions["advanced"][ultraMissions["advanced"].length - 1].game = "gold";
missionList.set("gold", goldMissions);
missionList.set("platinum", platinumMissions);
missionList.set("ultra", ultraMissions);
missionList.set("multiplayer", multiplayerMissions);
Console.log("Loaded MissionList");
Console.log("Gold Beginner: " + goldMissions["beginner"].length);
Console.log("Gold Intermediate: " + goldMissions["intermediate"].length);
Console.log("Gold Advanced: " + goldMissions["advanced"].length);
Console.log("Platinum Beginner: " + platinumMissions["beginner"].length);
Console.log("Platinum Intermediate: " + platinumMissions["intermediate"].length);
Console.log("Platinum Advanced: " + platinumMissions["advanced"].length);
Console.log("Platinum Expert: " + platinumMissions["expert"].length);
Console.log("Ultra Beginner: " + ultraMissions["beginner"].length);
Console.log("Ultra Intermediate: " + ultraMissions["intermediate"].length);
Console.log("Ultra Advanced: " + ultraMissions["advanced"].length);
Console.log("Multiplayer Beginner: " + multiplayerMissions["beginner"].length);
Console.log("Multiplayer Intermediate: " + multiplayerMissions["intermediate"].length);
Console.log("Multiplayer Advanced: " + multiplayerMissions["advanced"].length);
Console.log("Custom: " + customMissions.length);
beginnerMissions = parseDifficulty("beginner");
intermediateMissions = parseDifficulty("intermediate");
advancedMissions = parseDifficulty("advanced");
customMissions = parseDifficulty("custom");
// parseCLAList();
_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);
}
}
}

View file

@ -222,6 +222,7 @@ class Settings {
public static var levelStatistics:Map<String, PlayStatistics> = [];
public static var progression = [24, 24, 52];
public static var highscoreName = "";
public static var userId = "";
@ -276,6 +277,7 @@ class Settings {
controls: controlsSettings,
touch: touchSettings,
gamepad: gamepadSettings,
progression: progression,
stats: playStatistics,
server: serverSettings,
highscoreName: highscoreName,
@ -461,6 +463,7 @@ class Settings {
optionsSettings.rewindTimescale = 1;
}
#end
progression = json.progression;
highscoreName = json.highscoreName;
if (highscoreName == null) {
highscoreName = "";

View file

@ -1,8 +1,5 @@
package gui;
import src.Leaderboards;
import hxd.BitmapData;
import h2d.Tile;
import src.MarbleGame;
import src.Settings.Score;
import src.Settings.Settings;
@ -19,8 +16,7 @@ class EndGameGui extends GuiControl {
var scoreSubmitted:Bool = false;
public function new(continueFunc:GuiControl->Void, restartFunc:GuiControl->Void, nextLevelFunc:GuiControl->Void, mission:Mission, timeState:TimeState,
replayData:haxe.io.Bytes) {
public function new(continueFunc:GuiControl->Void, restartFunc:GuiControl->Void, mission:Mission, timeState:TimeState) {
super();
this.horizSizing = Width;
this.vertSizing = Height;
@ -35,57 +31,30 @@ class EndGameGui extends GuiControl {
return [normal, hover, pressed];
}
var pg = new GuiImage(ResourceLoader.getResource("data/ui/endgame/base.png", ResourceLoader.getImage, this.imageResources).toTile());
var pg = new GuiImage(ResourceLoader.getResource("data/ui/play/playgui.png", ResourceLoader.getImage, this.imageResources).toTile());
pg.horizSizing = Center;
pg.vertSizing = Center;
pg.position = new Vector(28, 20);
pg.extent = new Vector(584, 440);
pg.position = new Vector(77, 9);
pg.extent = new Vector(485, 461);
var continueButton = new GuiButton(loadButtonImages("data/ui/endgame/continue"));
continueButton.horizSizing = Right;
continueButton.vertSizing = Bottom;
continueButton.position = new Vector(460, 307);
continueButton.extent = new Vector(104, 54);
continueButton.position = new Vector(333, 386);
continueButton.extent = new Vector(113, 47);
continueButton.accelerator = hxd.Key.ENTER;
continueButton.gamepadAccelerator = ["A"];
continueButton.pressedAction = (e) -> continueFunc(continueButton);
continueButton.pressedAction = (e) -> continueFunc(this);
var restartButton = new GuiButton(loadButtonImages("data/ui/endgame/replay"));
restartButton.horizSizing = Right;
restartButton.vertSizing = Bottom;
restartButton.position = new Vector(460, 363);
restartButton.extent = new Vector(104, 54);
restartButton.position = new Vector(51, 388);
restartButton.extent = new Vector(104, 48);
restartButton.gamepadAccelerator = ["B"];
restartButton.pressedAction = (e) -> restartFunc(restartButton);
var nextLevel = new GuiControl();
nextLevel.position = new Vector(326, 307);
nextLevel.extent = new Vector(130, 110);
var temprev = new BitmapData(1, 1);
temprev.setPixel(0, 0, 0);
var tmpprevtile = Tile.fromBitmap(temprev);
var nextLevelPreview = new GuiImage(tmpprevtile);
nextLevelPreview.position = new Vector(-15, 0);
nextLevelPreview.extent = new Vector(160, 110);
nextLevel.addChild(nextLevelPreview);
mission.getNextMission()?.getPreviewImage(t -> {
nextLevelPreview.bmp.tile = t;
});
var nextLevelBtn = new GuiButton(loadButtonImages('data/ui/endgame/level_window'));
nextLevelBtn.horizSizing = Width;
nextLevelBtn.vertSizing = Height;
nextLevelBtn.position = new Vector(0, 0);
nextLevelBtn.extent = new Vector(130, 110);
nextLevelBtn.gamepadAccelerator = ["X"];
nextLevelBtn.pressedAction = (e) -> nextLevelFunc(nextLevelBtn);
nextLevel.addChild(nextLevelBtn);
restartButton.pressedAction = (e) -> restartFunc(this);
function setButtonStates(enabled:Bool) {
nextLevelBtn.disabled = !enabled;
continueButton.disabled = !enabled;
restartButton.disabled = !enabled;
}
@ -98,9 +67,7 @@ class EndGameGui extends GuiControl {
var domcasual32fontdata = ResourceLoader.getFileEntry("data/font/DomCasualD.fnt");
var domcasual32b = new BitmapFont(domcasual32fontdata.entry);
@:privateAccess domcasual32b.loader = ResourceLoader.loader;
var domcasual32 = domcasual32b.toSdfFont(cast 28 * Settings.uiScale, MultiChannel);
var domcasual64 = domcasual32b.toSdfFont(cast 58 * Settings.uiScale, MultiChannel);
var domcasual24 = domcasual32b.toSdfFont(cast 20 * Settings.uiScale, MultiChannel);
var domcasual32 = domcasual32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var expo50fontdata = ResourceLoader.getFileEntry("data/font/EXPON.fnt");
var expo50b = new BitmapFont(expo50fontdata.entry);
@ -110,12 +77,8 @@ class EndGameGui extends GuiControl {
function mlFontLoader(text:String) {
switch (text) {
case "DomCasual24":
return domcasual24;
case "DomCasual32":
return domcasual32;
case "DomCasual64":
return domcasual64;
case "Arial14":
return arial14;
case "Expo32":
@ -125,261 +88,84 @@ class EndGameGui extends GuiControl {
}
}
var egResult = new GuiMLText(domcasual32, mlFontLoader);
egResult.position = new Vector(313, 54);
egResult.extent = new Vector(244, 69);
egResult.text.text = '<font face="DomCasual64" color="#FFFFFF"><p align="right">${Util.formatTime(timeState.gameplayClock)}</p></font>';
egResult.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
pg.addChild(egResult);
var egFirstLine = new GuiMLText(domcasual24, mlFontLoader);
egFirstLine.position = new Vector(340, 150);
egFirstLine.extent = new Vector(210, 25);
egFirstLine.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0x777777
};
pg.addChild(egFirstLine);
var egSecondLine = new GuiMLText(domcasual24, mlFontLoader);
egSecondLine.position = new Vector(341, 178);
egSecondLine.extent = new Vector(209, 25);
egSecondLine.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0x777777
};
pg.addChild(egSecondLine);
var egThirdLine = new GuiMLText(domcasual24, mlFontLoader);
egThirdLine.position = new Vector(341, 206);
egThirdLine.extent = new Vector(209, 25);
egThirdLine.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0x777777
};
pg.addChild(egThirdLine);
var egFourthLine = new GuiMLText(domcasual24, mlFontLoader);
egFourthLine.position = new Vector(341, 234);
egFourthLine.extent = new Vector(209, 25);
egFourthLine.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0x777777
};
pg.addChild(egFourthLine);
var egFifthLine = new GuiMLText(domcasual24, mlFontLoader);
egFifthLine.position = new Vector(341, 262);
egFifthLine.extent = new Vector(209, 25);
egFifthLine.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0x777777
};
pg.addChild(egFifthLine);
var egFirstLineScore = new GuiMLText(domcasual24, mlFontLoader);
egFirstLineScore.position = new Vector(475, 150);
egFirstLineScore.extent = new Vector(210, 25);
egFirstLineScore.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0x777777
};
pg.addChild(egFirstLineScore);
var egSecondLineScore = new GuiMLText(domcasual24, mlFontLoader);
egSecondLineScore.position = new Vector(476, 178);
egSecondLineScore.extent = new Vector(209, 25);
egSecondLineScore.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0x777777
};
pg.addChild(egSecondLineScore);
var egThirdLineScore = new GuiMLText(domcasual24, mlFontLoader);
egThirdLineScore.position = new Vector(476, 206);
egThirdLineScore.extent = new Vector(209, 25);
egThirdLineScore.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0x777777
};
pg.addChild(egThirdLineScore);
var egFourthLineScore = new GuiMLText(domcasual24, mlFontLoader);
egFourthLineScore.position = new Vector(476, 234);
egFourthLineScore.extent = new Vector(209, 25);
egFourthLineScore.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0x777777
};
pg.addChild(egFourthLineScore);
var egFifthLineScore = new GuiMLText(domcasual24, mlFontLoader);
egFifthLineScore.position = new Vector(476, 262);
egFifthLineScore.extent = new Vector(209, 25);
egFifthLineScore.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0x777777
};
pg.addChild(egFifthLineScore);
var egTitleText = new GuiMLText(expo50, mlFontLoader);
egTitleText.text.textColor = 0xffff00;
egTitleText.text.text = '<font color="#FFFFFF" face="DomCasual64">Your Time:</font>';
egTitleText.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
egTitleText.position = new Vector(34, 54);
egTitleText.extent = new Vector(247, 69);
pg.addChild(egTitleText);
var egTopThreeText = new GuiMLText(domcasual32, mlFontLoader);
egTopThreeText.position = new Vector(341, 114);
egTopThreeText.extent = new Vector(209, 34);
egTopThreeText.text.text = '<font face="DomCasual32" color="#FFFFFF">Top 5 Times:</font>'; // Make toggleable 3-5
egTopThreeText.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
pg.addChild(egTopThreeText);
var text = '<font color="#FFFFFF" face="DomCasual32"><p align="center">';
// Check for ultimate time TODO
if (mission.ultimateTime > 0 && timeState.gameplayClock < mission.ultimateTime) {
text += 'You beat the <font color="#FFDD22">Ultimate</font> Time!';
} else {
if (mission.goldTime > 0 && timeState.gameplayClock < mission.goldTime) {
if (mission.game == "gold" || mission.game.toLowerCase() == "ultra")
text += 'You beat the <font color="#FFCC00">Gold</font> Time!';
else
text += 'You beat the <font color="#CCCCCC">Platinum</font> Time!';
} else {
if (mission.qualifyTime > timeState.gameplayClock) {
text += "You beat the Par Time!";
} else {
text += '<font color="#F55555">You didn\'t pass the Par Time!</font>';
}
}
}
text += '</p></font>';
var congrats = new GuiMLText(expo50, mlFontLoader);
congrats.text.textColor = 0xffff00;
congrats.text.text = 'Final Time: <font color="#FFF090">${Util.formatTime(timeState.gameplayClock)}</font>';
congrats.text.filter = new DropShadow(1.414, 0.785, 0, 1, 0, 0.4, 1, true);
congrats.position = new Vector(43, 24);
congrats.extent = new Vector(408, 50);
pg.addChild(congrats);
var finishMessage = new GuiMLText(expo32, mlFontLoader);
finishMessage.text.textColor = 0x00ff00;
finishMessage.text.text = text;
finishMessage.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
var qualified = mission.qualifyTime > timeState.gameplayClock;
if (qualified)
finishMessage.text.text = timeState.gameplayClock < mission.goldTime ? 'You beat the <font color="#FFFF00">GOLD</font> time!' : "You've qualified!";
else
finishMessage.text.text = '<font color="#FF0000">You failed to qualify!</font>';
finishMessage.text.filter = new DropShadow(1, 0.785, 0, 1, 0, 0.4, 1, true);
// finishMessage.justify = Center;
finishMessage.position = new Vector(25, 120);
finishMessage.extent = new Vector(293, 211);
finishMessage.position = new Vector(155, 74);
if (timeState.gameplayClock < mission.goldTime) {
finishMessage.position.x = 110;
}
if (!qualified)
finishMessage.position.x = 125;
finishMessage.extent = new Vector(400, 100);
pg.addChild(finishMessage);
var qualified = mission.qualifyTime > timeState.gameplayClock;
var scoreData:Array<Score> = Settings.getScores(mission.path);
while (scoreData.length < 5) {
scoreData.push({name: "Matan W.", time: 5999.999});
while (scoreData.length < 3) {
scoreData.push({name: "Nardo Polo", time: 5999.999});
}
egFirstLine.text.text = '<p align="left"><font color="#EEC884">1. </font>${StringTools.htmlEscape(scoreData[0].name)}</p>';
egSecondLine.text.text = '<p align="left"><font color="#CDCDCD">2. </font>${StringTools.htmlEscape(scoreData[1].name)}</p>';
egThirdLine.text.text = '<p align="left"><font color="#C9AFA0">3. </font>${StringTools.htmlEscape(scoreData[2].name)}</p>';
egFourthLine.text.text = '<p align="left"><font color="#A4A4A4">4. </font>${StringTools.htmlEscape(scoreData[3].name)}</p>';
egFifthLine.text.text = '<p align="left"><font color="#949494">5. </font>${StringTools.htmlEscape(scoreData[4].name)}</p>';
var lineelems = [
egFirstLineScore,
egSecondLineScore,
egThirdLineScore,
egFourthLineScore,
egFifthLineScore
];
for (i in 0...5) {
if (scoreData[i].time < mission.ultimateTime) {
lineelems[i].text.text = '<font color="#FFDD22">${Util.formatTime(scoreData[i].time)}</font>';
} else {
if (scoreData[i].time < mission.goldTime) {
if (mission.game == "gold" || mission.game.toLowerCase() == "ultra")
lineelems[i].text.text = '<font color="#FFCC00">${Util.formatTime(scoreData[i].time)}</font>';
else
lineelems[i].text.text = '<font color="#CCCCCC">${Util.formatTime(scoreData[i].time)}</font>';
} else {
lineelems[i].text.text = '${Util.formatTime(scoreData[i].time)}';
}
}
}
var leftColumn = new GuiMLText(domcasual24, mlFontLoader);
var leftColumn = new GuiMLText(domcasual32, mlFontLoader);
leftColumn.text.lineSpacing = 5;
leftColumn.text.textColor = 0xFFFFFF;
leftColumn.text.text = 'Par Time:<br/>${mission.game == "gold" || mission.game.toLowerCase() == "ultra" ? '<font color="#FFCC00">Gold Time:</font>' : '<font color="#CCCCCC">Platinum Time:</font>'}<br/>${mission.ultimateTime != 0 ? '<font color="#FFDD22">Ultimate Time:</font><br/>' : ''}<font face="Arial14"><br/></font><font color="#FFFFFF" face="DomCasual24">Time Passed:<br/>Clock Bonuses:</font>';
leftColumn.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0x777777
};
leftColumn.position = new Vector(25, 165);
leftColumn.extent = new Vector(293, 211);
leftColumn.text.textColor = 0x000000;
leftColumn.text.text = 'Qualify Time:<br/>Gold Time:<br/>Elapsed Time:<br/>Bonus Time:<br/><font face="Arial14"><br/></font>Best Times:<br/>';
for (i in 0...3) {
leftColumn.text.text += '${i + 1}. ${scoreData[i].name}<br/>';
}
leftColumn.text.filter = new DropShadow(1.414, 0.785, 0xffffff, 1, 0, 0.4, 1, true);
leftColumn.position = new Vector(108, 113);
leftColumn.extent = new Vector(208, 50);
pg.addChild(leftColumn);
var elapsedTime = Math.max(timeState.currentAttemptTime - 3.5, 0);
var bonusTime = Math.max(0, Std.int((elapsedTime - timeState.gameplayClock) * 1000) / 1000);
var rightColumn = new GuiMLText(domcasual24, mlFontLoader);
var rightColumn = new GuiMLText(domcasual32, mlFontLoader);
rightColumn.text.lineSpacing = 5;
rightColumn.text.textColor = 0xFFFFFF;
rightColumn.text.text = '${Util.formatTime(mission.qualifyTime == Math.POSITIVE_INFINITY ? 5999.999 : mission.qualifyTime)}<br/><font color="${mission.game == "gold" || mission.game.toLowerCase() == "ultra" ? '#FFCC00' : '#CCCCCC'}">${Util.formatTime(mission.goldTime)}</font><br/>${mission.ultimateTime != 0 ? '<font color="#FFDD22">${Util.formatTime(mission.ultimateTime)}</font><br/>' : ''}<font face="Arial14"><br/></font><font color="#FFFFFF" face="DomCasual24">${Util.formatTime(elapsedTime)}<br/>${Util.formatTime(bonusTime)}</font>';
rightColumn.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0x777777
};
rightColumn.position = new Vector(235, 165);
rightColumn.extent = new Vector(293, 211);
rightColumn.text.textColor = 0x000000;
rightColumn.text.text = '${Util.formatTime(mission.qualifyTime == Math.POSITIVE_INFINITY ? 5999.999 : mission.qualifyTime)}<br/><br/>${Util.formatTime(elapsedTime)}<br/>${Util.formatTime(bonusTime)}<br/><font face="Arial14"><br/></font><br/>';
for (i in 0...3) {
if (scoreData[i].time < mission.goldTime)
rightColumn.text.text += '<br/>';
else
rightColumn.text.text += '${Util.formatTime(scoreData[i].time)}<br/>';
}
rightColumn.text.filter = new DropShadow(1.414, 0.785, 0xffffff, 1, 0, 0.4, 1, true);
rightColumn.position = new Vector(274, 113);
rightColumn.extent = new Vector(208, 50);
pg.addChild(rightColumn);
var rightColumnGold = new GuiMLText(domcasual32, mlFontLoader);
rightColumnGold.text.lineSpacing = 5;
rightColumnGold.text.textColor = 0xFFFF00;
rightColumnGold.text.text = '<br/>${Util.formatTime(mission.goldTime)}<br/><br/><br/><font face="Arial14"><br/></font><br/>';
for (i in 0...3) {
if (scoreData[i].time < mission.goldTime)
rightColumnGold.text.text += '${Util.formatTime(scoreData[i].time)}<br/>';
else
rightColumnGold.text.text += '<br/>';
}
rightColumnGold.text.filter = new DropShadow(1.414, 0.785, 0x00000, 1, 0, 0.4, 1, true);
rightColumnGold.position = new Vector(274, 113);
rightColumnGold.extent = new Vector(208, 50);
pg.addChild(rightColumnGold);
pg.addChild(continueButton);
pg.addChild(restartButton);
pg.addChild(nextLevel);
pg.addChild(egFirstLine);
pg.addChild(egSecondLine);
pg.addChild(egThirdLine);
pg.addChild(egFourthLine);
pg.addChild(egFifthLine);
this.addChild(pg);
@ -388,15 +174,14 @@ class EndGameGui extends GuiControl {
var idx = scoreTimes.indexOf(timeState.gameplayClock);
// if (Settings.progression[mission.difficultyIndex] == mission.index && qualified) {
// Settings.progression[mission.difficultyIndex]++;
// }
if (mission.difficultyIndex != -1) {
if (Settings.progression[mission.difficultyIndex] == mission.index && qualified) {
Settings.progression[mission.difficultyIndex]++;
}
}
Settings.save();
var rewindUsed = MarbleGame.instance.world.rewindUsed;
var cheatsUsed = MarbleGame.instance.world.cheatsUsed;
if (idx <= 4) {
if (idx <= 2) {
setButtonStates(false);
var end = new EnterNameDlg(idx, (name) -> {
setButtonStates(true);
@ -407,64 +192,32 @@ class EndGameGui extends GuiControl {
scoreData.push(myScore);
scoreData.sort((a, b) -> a.time == b.time ? 0 : (a.time > b.time ? 1 : -1));
egFirstLine.text.text = '<p align="left"><font color="#EEC884">1. </font>${scoreData[0].name}</p>';
egSecondLine.text.text = '<p align="left"><font color="#CDCDCD">2. </font>${scoreData[1].name}</p>';
egThirdLine.text.text = '<p align="left"><font color="#C9AFA0">3. </font>${scoreData[2].name}</p>';
egFourthLine.text.text = '<p align="left"><font color="#A4A4A4">4. </font>${scoreData[3].name}</p>';
egFifthLine.text.text = '<p align="left"><font color="#949494">5. </font>${scoreData[4].name}</p>';
for (i in 0...5) {
if (scoreData[i].time < mission.ultimateTime) {
lineelems[i].text.text = '<font color="#FFDD22">${Util.formatTime(scoreData[i].time)}</font>';
} else {
if (scoreData[i].time < mission.goldTime) {
lineelems[i].text.text = '<font color="${mission.game == "gold" || mission.game.toLowerCase() == "ultra" ? '#FFCC00' : '#CCCCCC'}">${Util.formatTime(scoreData[i].time)}</font>';
} else {
lineelems[i].text.text = '${Util.formatTime(scoreData[i].time)}';
}
}
leftColumn.text.text = 'Qualify Time:<br/>Gold Time:<br/>Elapsed Time:<br/>Bonus Time:<br/><font face="Arial14"><br/></font>Best Times:<br/>';
for (i in 0...3) {
leftColumn.text.text += '${i + 1}. ${scoreData[i].name}<br/>';
}
if (!cheatsUsed) { // dont submit or save if we have cheated
Settings.saveScore(mission.path, myScore);
var lbPath = mission.path;
if (mission.isClaMission)
lbPath = 'custom/${mission.id}';
Leaderboards.submitScore(lbPath, myScore.time, rewindUsed, (sendReplay, rowId) -> {
if (sendReplay && !mission.isClaMission) {
Leaderboards.submitReplay(rowId, replayData);
}
});
rightColumn.text.text = '${Util.formatTime(mission.qualifyTime == Math.POSITIVE_INFINITY ? 5999.999 : mission.qualifyTime)}<br/><br/>${Util.formatTime(elapsedTime)}<br/>${Util.formatTime(bonusTime)}<br/><font face="Arial14"><br/></font><br/>';
for (i in 0...3) {
if (scoreData[i].time < mission.goldTime)
rightColumn.text.text += '<br/>';
else
rightColumn.text.text += '${Util.formatTime(scoreData[i].time)}<br/>';
}
rightColumnGold.text.text = '<br/>${Util.formatTime(mission.goldTime)}<br/><br/><br/><font face="Arial14"><br/></font><br/>';
for (i in 0...3) {
if (scoreData[i].time < mission.goldTime)
rightColumnGold.text.text += '${Util.formatTime(scoreData[i].time)}<br/>';
else
rightColumnGold.text.text += '<br/>';
}
Settings.saveScore(mission.path, myScore);
scoreSubmitted = true;
});
this.addChild(end);
} else {
// Check if we can submit LB scores
var lbPath = mission.path;
if (mission.isClaMission)
lbPath = 'custom/${mission.id}';
Leaderboards.getScores(lbPath, All, (scores) -> {
var hasMyScore = false;
var myTopScoreLB = 0.0;
for (score in scores) {
if (score.name == Settings.highscoreName) {
hasMyScore = true;
myTopScoreLB = score.score;
break;
}
}
if (!cheatsUsed) {
if (!hasMyScore || (hasMyScore && myTopScoreLB > timeState.gameplayClock)) {
Leaderboards.submitScore(lbPath, timeState.gameplayClock, rewindUsed, (sendReplay, rowId) -> {
if (sendReplay && !mission.isClaMission) {
Leaderboards.submitReplay(rowId, replayData);
}
});
}
}
});
}
}
}

View file

@ -1,8 +1,5 @@
package gui;
import h2d.Tile;
import hxd.BitmapData;
import h2d.filter.DropShadow;
import src.Settings;
import hxd.res.BitmapFont;
import h3d.Vector;
@ -33,75 +30,67 @@ class EnterNameDlg extends GuiControl {
var domcasual32b = new BitmapFont(domcasual32fontdata.entry);
@:privateAccess domcasual32b.loader = ResourceLoader.loader;
var domcasual32 = domcasual32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var domcasual48 = domcasual32b.toSdfFont(cast 42 * Settings.uiScale, MultiChannel);
var expo50fontdata = ResourceLoader.getFileEntry("data/font/EXPON.fnt");
var expo50b = new BitmapFont(expo50fontdata.entry);
@:privateAccess expo50b.loader = ResourceLoader.loader;
var expo50 = expo50b.toSdfFont(cast 35 * Settings.uiScale, MultiChannel);
var expo32 = expo50b.toSdfFont(cast 24 * Settings.uiScale, MultiChannel);
function mlFontLoader(text:String) {
switch (text) {
case "DomCasual32":
return domcasual32;
case "DomCasual48":
return domcasual48;
case "Arial14":
return arial14;
case "Expo50":
return expo50;
default:
return null;
}
}
var dlg = new GuiImage(ResourceLoader.getResource("data/ui/endgame/enternamebox.png", ResourceLoader.getImage, this.imageResources).toTile());
var dlg = new GuiImage(ResourceLoader.getResource("data/ui/common/dialog.png", ResourceLoader.getImage, this.imageResources).toTile());
dlg.horizSizing = Center;
dlg.vertSizing = Center;
dlg.position = new Vector(110, 112);
dlg.extent = new Vector(420, 256);
dlg.position = new Vector(112, 111);
dlg.extent = new Vector(416, 257);
this.addChild(dlg);
var enterNameEdit = new GuiTextInput(domcasual32);
enterNameEdit.text.textColor = 0;
enterNameEdit.text.selectionColor.setColor(0xFFFFFFFF);
enterNameEdit.text.selectionTile = h2d.Tile.fromColor(0x808080, 0, hxd.Math.ceil(enterNameEdit.text.font.lineHeight));
enterNameEdit.position = new Vector(28, 130);
enterNameEdit.extent = new Vector(363, 38);
enterNameEdit.position = new Vector(87, 136);
enterNameEdit.extent = new Vector(255, 36);
enterNameEdit.text.text = Settings.highscoreName;
haxe.Timer.delay(() -> {
enterNameEdit.text.focus();
}, 5);
var okbutton = new GuiButton(loadButtonImages("data/ui/endgame/ok"));
okbutton.position = new Vector(151, 184);
okbutton.extent = new Vector(110, 55);
var okbutton = new GuiButton(loadButtonImages("data/ui/common/ok"));
okbutton.position = new Vector(163, 182);
okbutton.extent = new Vector(78, 59);
okbutton.accelerator = hxd.Key.ENTER;
okbutton.gamepadAccelerator = ["A"];
okbutton.pressedAction = (sender) -> {
MarbleGame.canvas.popDialog(this);
Settings.highscoreName = enterNameEdit.text.text;
if (StringTools.trim(Settings.highscoreName) == "")
Settings.highscoreName = "Player";
okFunc(Settings.highscoreName);
okFunc(enterNameEdit.text.text);
}
dlg.addChild(okbutton);
var wnd = new GuiImage(ResourceLoader.getResource("data/ui/endgame/window.png", ResourceLoader.getImage, this.imageResources).toTile());
wnd.horizSizing = Width;
wnd.vertSizing = Height;
wnd.position = new Vector(16, 119);
wnd.extent = new Vector(388, 56);
var wnd = new GuiImage(ResourceLoader.getResource("data/ui/common/window.png", ResourceLoader.getImage, this.imageResources).toTile());
wnd.position = new Vector(58, 124);
wnd.extent = new Vector(295, 55);
dlg.addChild(wnd);
var enterNameText = new GuiMLText(domcasual32, mlFontLoader);
enterNameText.text.textColor = 0xFFFFFF;
enterNameText.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
enterNameText.position = new Vector(37, 23);
enterNameText.extent = new Vector(345, 85);
enterNameText.text.textColor = 0;
enterNameText.position = new Vector(41, 30);
enterNameText.extent = new Vector(345, 14);
// enterNameText.justify = Center;
if (place != -1)
enterNameText.text.text = '<font face="Arial14"><br/></font><p align="center"><font face="DomCasual48">Well Done!<br/></font><font face="DomCasual32">You have the${["", " second", " third", " fourth", " fifth"][place]} top time!</font></p>';
else
enterNameText.text.text = '<p align="center"><font face="DomCasual32">Enter your desired display name</font></p>';
enterNameText.text.text = '<font face="Arial14"><br/></font><p align="center"><font face="Expo50">Congratulations!<br/></font>You got the${["", " 2nd", " 3rd"][place]} best time!</p>';
dlg.addChild(enterNameText);
dlg.addChild(enterNameEdit);

View file

@ -1,6 +1,5 @@
package gui;
import src.MarbleGame;
import hxd.res.BitmapFont;
import h3d.Vector;
import src.ResourceLoader;
@ -25,57 +24,53 @@ class ExitGameDlg extends GuiControl {
var dialogImg = new GuiImage(ResourceLoader.getResource("data/ui/common/dialog.png", ResourceLoader.getImage, this.imageResources).toTile());
dialogImg.horizSizing = Center;
dialogImg.vertSizing = Center;
dialogImg.position = new Vector(162, 160);
dialogImg.extent = new Vector(315, 160);
dialogImg.position = new Vector(134, 148);
dialogImg.extent = new Vector(388, 186);
var overlay = new GuiImage(ResourceLoader.getResource("data/ui/common/quitfromthislvl_overlay.png", ResourceLoader.getImage, this.imageResources)
.toTile());
overlay.horizSizing = Right;
overlay.vertSizing = Bottom;
overlay.position = new Vector(36, 22);
overlay.extent = new Vector(235, 42);
var domcasual32fontdata = ResourceLoader.getFileEntry("data/font/DomCasualD.fnt");
var domcasual32b = new BitmapFont(domcasual32fontdata.entry);
@:privateAccess domcasual32b.loader = ResourceLoader.loader;
var domcasual32 = domcasual32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var exitGameText = new GuiText(domcasual32);
exitGameText.text.textColor = 0x000000;
exitGameText.text.text = "Exit from this Level?";
exitGameText.justify = Center;
exitGameText.position = new Vector(95, 46);
exitGameText.extent = new Vector(198, 23);
exitGameText.horizSizing = Center;
exitGameText.vertSizing = Bottom;
var yesButton = new GuiButton(loadButtonImages("data/ui/common/yes"));
yesButton.position = new Vector(19, 103);
yesButton.extent = new Vector(86, 40);
yesButton.vertSizing = Top;
yesButton.position = new Vector(47, 107);
yesButton.extent = new Vector(88, 52);
yesButton.vertSizing = Bottom;
yesButton.horizSizing = Right;
yesButton.pressedAction = (e) -> yesFunc(this);
yesButton.accelerator = hxd.Key.ENTER;
yesButton.gamepadAccelerator = ["A"];
yesButton.pressedAction = (sender) -> yesFunc(yesButton);
var noButton = new GuiButton(loadButtonImages("data/ui/common/no"));
noButton.position = new Vector(105, 102);
noButton.extent = new Vector(86, 40);
noButton.vertSizing = Top;
noButton.position = new Vector(151, 107);
noButton.extent = new Vector(83, 55);
noButton.vertSizing = Bottom;
noButton.horizSizing = Right;
noButton.pressedAction = (e) -> noFunc(this);
noButton.gamepadAccelerator = ["B"];
noButton.pressedAction = (sender) -> noFunc(noButton);
var restartButton = new GuiButton(loadButtonImages("data/ui/common/restart"));
restartButton.position = new Vector(214, 104);
restartButton.extent = new Vector(86, 40);
restartButton.vertSizing = Top;
restartButton.position = new Vector(249, 107);
restartButton.extent = new Vector(103, 56);
restartButton.vertSizing = Bottom;
restartButton.horizSizing = Right;
restartButton.pressedAction = (e) -> restartFunc(this);
restartButton.gamepadAccelerator = ["X"];
restartButton.pressedAction = (sender) -> restartFunc(restartButton);
dialogImg.addChild(overlay);
dialogImg.addChild(exitGameText);
dialogImg.addChild(yesButton);
dialogImg.addChild(noButton);
dialogImg.addChild(restartButton);
this.addChild(dialogImg);
var jukeboxButton = new GuiButton(loadButtonImages("data/ui/jukebox/jb_pausemenu"));
jukeboxButton.vertSizing = Top;
jukeboxButton.horizSizing = Left;
jukeboxButton.position = new Vector(439, 403);
jukeboxButton.extent = new Vector(187, 65);
jukeboxButton.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(new JukeboxDlg());
}
this.addChild(jukeboxButton);
}
}

View file

@ -48,6 +48,7 @@ class GuiObjectShow extends GuiControl {
var props = parent.getProperties(this.sceneBitmap);
props.isAbsolute = true;
this.sceneBitmap.setPosition(off.x, off.y);
this.sceneBitmap.visible = this.visible;
}
super.render(scene2d, parent);
var renderRect = this.getRenderRectangle();
@ -62,6 +63,11 @@ class GuiObjectShow extends GuiControl {
sceneBitmap.height = renderRect.extent.y;
}
public function setVisible(val:Bool) {
this.visible = val;
this.sceneBitmap.visible = val;
}
public override function update(dt:Float, mouseState:MouseState) {
super.update(dt, mouseState);
timeState.currentAttemptTime += dt;

View file

@ -1,6 +1,5 @@
package gui;
import h2d.Scene;
import h3d.shader.AlphaChannel;
import src.DtsObject;
import hxd.res.BitmapFont;
@ -12,30 +11,42 @@ import src.Settings;
import src.Util;
class HelpCreditsGui extends GuiImage {
var manualPageList:GuiTextListCtrl;
var page = 0;
var hcText:GuiMLText;
var hcText2:GuiMLText;
var startPadCtrl:GuiObjectShow;
var endPadCtrl:GuiObjectShow;
var gem1Ctrl:GuiObjectShow;
var gem2Ctrl:GuiObjectShow;
var gem3Ctrl:GuiObjectShow;
var superSpeedCtrl:GuiObjectShow;
var superJumpCtrl:GuiObjectShow;
var shockAbsorberCtrl:GuiObjectShow;
var helicopterCtrl:GuiObjectShow;
var timeTravelCtrl:GuiObjectShow;
var antiGravityCtrl:GuiObjectShow;
var ductFanCtrl:GuiObjectShow;
var tornadoCtrl:GuiObjectShow;
var trapdoorCtrl:GuiObjectShow;
var oilSlickCtrl:GuiObjectShow;
var landMineCtrl:GuiObjectShow;
var bumperCtrl:GuiObjectShow;
var superBounceCtrl:GuiObjectShow;
public function new() {
function chooseBg() {
var rand = Math.random();
if (rand >= 0 && rand <= 0.244)
return ResourceLoader.getImage('data/ui/backgrounds/gold/${cast (Math.floor(Util.lerp(1, 12, Math.random())), Int)}.jpg');
if (rand > 0.244 && rand <= 0.816)
return ResourceLoader.getImage('data/ui/backgrounds/platinum/${cast (Math.floor(Util.lerp(1, 28, Math.random())), Int)}.jpg');
return ResourceLoader.getImage('data/ui/backgrounds/ultra/${cast (Math.floor(Util.lerp(1, 9, Math.random())), Int)}.jpg');
}
var img = chooseBg();
var img = ResourceLoader.getImage("data/ui/background.jpg");
super(img.resource.toTile());
this.position = new Vector(0, 0);
this.position = new Vector();
this.extent = new Vector(640, 480);
this.horizSizing = Width;
this.vertSizing = Height;
var wnd = new GuiImage(ResourceLoader.getResource("data/ui/manual/window.png", ResourceLoader.getImage, this.imageResources).toTile());
wnd.position = new Vector(0, 0);
wnd.extent = new Vector(640, 480);
wnd.horizSizing = Center;
wnd.vertSizing = Center;
this.addChild(wnd);
var helpGui = new GuiImage(ResourceLoader.getResource("data/ui/help/help_gui.png", ResourceLoader.getImage, this.imageResources).toTile());
helpGui.horizSizing = Center;
helpGui.vertSizing = Center;
helpGui.position = new Vector(15, 10);
helpGui.extent = new Vector(609, 460);
this.addChild(helpGui);
function loadButtonImages(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
@ -44,97 +55,409 @@ class HelpCreditsGui extends GuiImage {
return [normal, hover, pressed];
}
var homeButton = new GuiButton(loadButtonImages("data/ui/manual/home"));
homeButton.position = new Vector(274, 385);
homeButton.extent = new Vector(94, 46);
var nextButton = new GuiButton(loadButtonImages("data/ui/play/next"));
nextButton.position = new Vector(482, 376);
nextButton.extent = new Vector(75, 60);
nextButton.pressedAction = (sender) -> nextPage();
helpGui.addChild(nextButton);
var prevButton = new GuiButton(loadButtonImages("data/ui/play/prev"));
prevButton.position = new Vector(58, 383);
prevButton.extent = new Vector(77, 58);
prevButton.pressedAction = (sender) -> previousPage();
helpGui.addChild(prevButton);
var homeButton = new GuiButton(loadButtonImages("data/ui/play/back"));
homeButton.position = new Vector(278, 378);
homeButton.extent = new Vector(79, 61);
homeButton.accelerator = hxd.Key.ESCAPE;
homeButton.gamepadAccelerator = ["B"];
homeButton.pressedAction = (sender) -> {
MarbleGame.canvas.setContent(new MainMenuGui());
}
wnd.addChild(homeButton);
helpGui.addChild(homeButton);
var helpWindow = new GuiImage(ResourceLoader.getResource("data/ui/help/help_window.png", ResourceLoader.getImage, this.imageResources).toTile());
helpWindow.position = new Vector(30, 31);
helpWindow.extent = new Vector(549, 338);
helpGui.addChild(helpWindow);
var arial14fontdata = ResourceLoader.getFileEntry("data/font/arial.fnt");
var arial14b = new BitmapFont(arial14fontdata.entry);
@:privateAccess arial14b.loader = ResourceLoader.loader;
var arial14 = arial14b.toSdfFont(cast 11.7 * Settings.uiScale, MultiChannel);
var arial14 = arial14b.toSdfFont(cast 12 * Settings.uiScale, MultiChannel);
var pagefiles = [];
for (i in 1...23) {
var pg = ResourceLoader.load('ui/manual/pages/${i}.txt').entry;
pagefiles.push(pg);
}
var pagetxt = pagefiles.map(x -> x.getText());
var pageheadings = pagetxt.map(x -> x.substr(0, x.indexOf("\n")));
var domcasual32fontdata = ResourceLoader.getFileEntry("data/font/DomCasualD.fnt");
var domcasual32b = new BitmapFont(domcasual32fontdata.entry);
@:privateAccess domcasual32b.loader = ResourceLoader.loader;
var domcasual32 = domcasual32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var scrollCtrl1 = new GuiControl();
scrollCtrl1.position = new Vector(29, 24);
scrollCtrl1.extent = new Vector(176, 352);
wnd.addChild(scrollCtrl1);
manualPageList = new GuiTextListCtrl(arial14, pageheadings);
manualPageList.position = new Vector(0, 0);
manualPageList.extent = new Vector(176, 352);
manualPageList.scrollable = true;
scrollCtrl1.addChild(manualPageList);
var scrollCtrl2 = new GuiScrollCtrl(ResourceLoader.getResource("data/ui/common/philscroll.png", ResourceLoader.getImage, this.imageResources)
.toTile());
scrollCtrl2.position = new Vector(219, 28);
scrollCtrl2.extent = new Vector(386, 342);
scrollCtrl2.childrenHandleScroll = true;
wnd.addChild(scrollCtrl2);
var arial14fontdata = ResourceLoader.getFileEntry("data/font/arial.fnt");
var arial14b = new BitmapFont(arial14fontdata.entry);
@:privateAccess arial14b.loader = ResourceLoader.loader;
var arial14 = arial14b.toSdfFont(cast 14 * Settings.uiScale, MultiChannel);
var markerFelt32fontdata = ResourceLoader.getFileEntry("data/font/MarkerFelt.fnt");
var markerFelt32b = new BitmapFont(markerFelt32fontdata.entry);
@:privateAccess markerFelt32b.loader = ResourceLoader.loader;
var markerFelt32 = markerFelt32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var markerFelt24 = markerFelt32b.toSdfFont(cast 18 * Settings.uiScale, MultiChannel);
var markerFelt18 = markerFelt32b.toSdfFont(cast 14 * Settings.uiScale, MultiChannel);
var expo50fontdata = ResourceLoader.getFileEntry("data/font/EXPON.fnt");
var expo50b = new BitmapFont(expo50fontdata.entry);
@:privateAccess expo50b.loader = ResourceLoader.loader;
var expo50 = expo50b.toSdfFont(cast 35 * Settings.uiScale, MultiChannel);
var expo32 = expo50b.toSdfFont(cast 24 * Settings.uiScale, MultiChannel);
function mlFontLoader(text:String) {
switch (text) {
case "MarkerFelt32":
return markerFelt32;
case "MarkerFelt24":
return markerFelt24;
case "MarkerFelt18":
return markerFelt18;
case "Arial16":
case "DomCasual32":
return domcasual32;
case "Arial14":
return arial14;
case "Expo32":
return expo32;
case "Expo50":
return expo50;
default:
return null;
}
}
var manualContent = new GuiMLText(arial14, mlFontLoader);
manualContent.position = new Vector(0, 20);
manualContent.extent = new Vector(376, 322);
manualContent.text.textColor = 0;
manualContent.scrollable = true;
scrollCtrl2.addChild(manualContent);
hcText = new GuiMLText(domcasual32, mlFontLoader);
hcText.position = new Vector(40, 24);
hcText.extent = new Vector(488, 274);
hcText.text.textColor = 0;
hcText.text.lineSpacing = 5;
helpWindow.addChild(hcText);
manualPageList.onSelectedFunc = (idx) -> {
if (idx != -1) {
var txt = pagetxt[idx];
var txtlines = txt.split('\n');
txtlines[0] = '<br/><font face="MarkerFelt32"><p align="center">${txtlines[0]}</p></font>';
var finaltxt = txtlines.join('<br/>') + '<br/>';
manualContent.text.text = finaltxt;
scrollCtrl2.setScrollMax(manualContent.text.textHeight);
scrollCtrl2.updateScrollVisual();
}
};
hcText2 = new GuiMLText(domcasual32, mlFontLoader);
hcText2.position = new Vector(40, 24);
hcText2.extent = new Vector(488, 274);
hcText2.text.textColor = 0;
hcText2.text.lineSpacing = 5;
helpWindow.addChild(hcText2);
startPadCtrl = buildObjectShow("data/shapes/pads/startarea.dts", new Vector(30, 82), new Vector(79, 66), 8, 0.5);
helpWindow.addChild(startPadCtrl);
endPadCtrl = buildObjectShow("data/shapes/pads/endarea.dts", new Vector(31, 146), new Vector(79, 66), 8, 0.5);
helpWindow.addChild(endPadCtrl);
gem1Ctrl = buildObjectShow("data/shapes/items/gem.dts", new Vector(17, 234), new Vector(79, 66), 2.5, 0.4);
helpWindow.addChild(gem1Ctrl);
gem2Ctrl = buildObjectShow("data/shapes/items/gem.dts", new Vector(43, 215), new Vector(79, 66), 2.5, 0.4, ["base.gem" => "purple.gem"]);
helpWindow.addChild(gem2Ctrl);
gem3Ctrl = buildObjectShow("data/shapes/items/gem.dts", new Vector(45, 250), new Vector(79, 66), 2.5, 0.4, ["base.gem" => "green.gem"]);
helpWindow.addChild(gem3Ctrl);
superSpeedCtrl = buildObjectShow("data/shapes/items/superspeed.dts", new Vector(30, 73), new Vector(79, 66), 3.5, 0.35);
helpWindow.addChild(superSpeedCtrl);
superJumpCtrl = buildObjectShow("data/shapes/items/superjump.dts", new Vector(31, 137), new Vector(79, 66), 3.5, 0.35);
helpWindow.addChild(superJumpCtrl);
shockAbsorberCtrl = buildObjectShow("data/shapes/items/shockabsorber.dts", new Vector(33, 204), new Vector(72, 61), 3.5, 0.35);
helpWindow.addChild(shockAbsorberCtrl);
superBounceCtrl = buildObjectShow("data/shapes/items/superbounce.dts", new Vector(35, 260), new Vector(72, 61), 3.5, 0.35);
helpWindow.addChild(superBounceCtrl);
helicopterCtrl = buildObjectShow("data/shapes/images/helicopter.dts", new Vector(30, 82), new Vector(79, 66), 2, 0.35);
helpWindow.addChild(helicopterCtrl);
timeTravelCtrl = buildObjectShow("data/shapes/items/timetravel.dts", new Vector(31, 146), new Vector(79, 66), 3.5, 0.35);
helpWindow.addChild(timeTravelCtrl);
antiGravityCtrl = buildObjectShow("data/shapes/items/antigravity.dts", new Vector(35, 217), new Vector(72, 61), 3.5, 0.35);
helpWindow.addChild(antiGravityCtrl);
ductFanCtrl = buildObjectShow("data/shapes/hazards/ductfan.dts", new Vector(30, 82), new Vector(79, 66), 4, 0.5);
helpWindow.addChild(ductFanCtrl);
tornadoCtrl = buildObjectShow("data/shapes/hazards/tornado.dts", new Vector(26, 155), new Vector(91, 66), 18, 0.35);
for (mat in tornadoCtrl.sceneObject.materials) {
mat.blendMode = None;
}
helpWindow.addChild(tornadoCtrl);
trapdoorCtrl = buildObjectShow("data/shapes/hazards/trapdoor.dts", new Vector(35, 217), new Vector(77, 76), 8, 0.35);
helpWindow.addChild(trapdoorCtrl);
oilSlickCtrl = buildObjectShow("data/shapes/hazards/oilslick.dts", new Vector(35, 217), new Vector(77, 76), 8, 0.35);
helpWindow.addChild(oilSlickCtrl);
landMineCtrl = buildObjectShow("data/shapes/hazards/landmine.dts", new Vector(26, 155), new Vector(91, 66), 1.5, 0.35);
helpWindow.addChild(landMineCtrl);
bumperCtrl = buildObjectShow("data/shapes/bumpers/pball_round.dts", new Vector(30, 82), new Vector(79, 66), 1.8, 0.5);
helpWindow.addChild(bumperCtrl);
redrawPage();
}
public override function render(scene2d:Scene, ?parent:h2d.Flow) {
super.render(scene2d, parent);
function redrawPage() {
page = cast Util.adjustedMod(page, 12);
manualPageList.onSelectedFunc(0);
if (page == 0) {
hcText2.text.text = "";
hcText.text.text = '<font face="Arial14"><br/></font><font face="Expo50"><p align="center">Overview</p></font><br/>'
+
"Roll your marble through a rich cartoon landscape of moving platforms and dangerous hazards. Along the way find power ups to increase your speed, jumping ability or flight power, and use them to collect the hidden gems and race to the finish for the fastest time.";
}
if (page == 1) {
hcText2.text.text = "";
hcText.text.text = '<font face="Arial14"><br/></font><font face="Expo50"><p align="center">Basic Controls</p></font><br/>'
+
formatText("The marble can be moved forward, back, left and right by pressing <func:bind moveforward>, <func:bind movebackward>, <func:bind moveleft> and <func:bind moveright>, respectively. Pressing <func:bind jump> causes the marble to jump, and pressing <func:bind mouseFire> uses whatever powerup you currently have available. All movement is relative to the view direction.");
}
if (page == 2) {
startPadCtrl.setVisible(false);
endPadCtrl.setVisible(false);
gem1Ctrl.setVisible(false);
gem2Ctrl.setVisible(false);
gem3Ctrl.setVisible(false);
hcText2.text.text = "";
hcText.text.text = '<font face="Arial14"><br/></font><font face="Expo50"><p align="center">Camera Controls</p></font><br/>'
+
formatText("The camera direction can be changed by moving the mouse or by pressing <func:bind panUp>, <func:bind panDown>, <func:bind turnLeft> or <func:bind turnRight>. In order to look up and down freely with the mouse, hold down <func:bind freelook>. You can turn free look on always from the Mouse pane of the Control Options screen.");
startPadCtrl.render(MarbleGame.canvas.scene2d);
endPadCtrl.render(MarbleGame.canvas.scene2d);
gem1Ctrl.render(MarbleGame.canvas.scene2d);
gem2Ctrl.render(MarbleGame.canvas.scene2d);
gem3Ctrl.render(MarbleGame.canvas.scene2d);
}
if (page == 3) {
startPadCtrl.setVisible(true);
endPadCtrl.setVisible(true);
gem1Ctrl.setVisible(true);
gem2Ctrl.setVisible(true);
gem3Ctrl.setVisible(true);
superJumpCtrl.setVisible(false);
superSpeedCtrl.setVisible(false);
shockAbsorberCtrl.setVisible(false);
superBounceCtrl.setVisible(false);
hcText.text.text = '<font face="Arial14"><br/></font><font face="Expo50"><p align="center">Goals</p></font><br/>';
hcText2.position = new Vector(110, 41);
hcText2.extent = new Vector(418, 274);
hcText2.text.text = "<br/><br/>Start Pad - this is where you start the level.<br/><br/>End Pad - roll your marble here to end the level.<br/><br/>Gems - if a level has gems, you must pick them all up before you can exit.";
startPadCtrl.render(MarbleGame.canvas.scene2d);
endPadCtrl.render(MarbleGame.canvas.scene2d);
gem1Ctrl.render(MarbleGame.canvas.scene2d);
gem2Ctrl.render(MarbleGame.canvas.scene2d);
gem3Ctrl.render(MarbleGame.canvas.scene2d);
hcText2.render(MarbleGame.canvas.scene2d, @:privateAccess hcText2.parent._flow);
superJumpCtrl.render(MarbleGame.canvas.scene2d);
superSpeedCtrl.render(MarbleGame.canvas.scene2d);
shockAbsorberCtrl.render(MarbleGame.canvas.scene2d);
superBounceCtrl.render(MarbleGame.canvas.scene2d);
}
if (page == 4) {
startPadCtrl.setVisible(false);
endPadCtrl.setVisible(false);
gem1Ctrl.setVisible(false);
gem2Ctrl.setVisible(false);
gem3Ctrl.setVisible(false);
superJumpCtrl.setVisible(true);
superSpeedCtrl.setVisible(true);
shockAbsorberCtrl.setVisible(true);
superBounceCtrl.setVisible(true);
helicopterCtrl.setVisible(false);
timeTravelCtrl.setVisible(false);
antiGravityCtrl.setVisible(false);
hcText.text.text = '<font face="Arial14"><br/></font><font face="Expo50"><p align="center">Bonus Items (1/2)</p></font><br/>';
hcText2.position = new Vector(110, 30);
hcText2.extent = new Vector(418, 274);
hcText2.text.text = "<br/><br/>Super Speed PowerUp - gives you a burst of speed.<br/><br/>Super Jump PowerUp - gives you a big jump up.<br/><br/>Shock Absorber PowerUp - absorbs bounce impacts.<br/><br/>Super Bounce PowerUp - makes you bounce higher.";
startPadCtrl.render(MarbleGame.canvas.scene2d);
endPadCtrl.render(MarbleGame.canvas.scene2d);
gem1Ctrl.render(MarbleGame.canvas.scene2d);
gem2Ctrl.render(MarbleGame.canvas.scene2d);
gem3Ctrl.render(MarbleGame.canvas.scene2d);
hcText2.render(MarbleGame.canvas.scene2d, @:privateAccess hcText2.parent._flow);
superJumpCtrl.render(MarbleGame.canvas.scene2d);
superSpeedCtrl.render(MarbleGame.canvas.scene2d);
shockAbsorberCtrl.render(MarbleGame.canvas.scene2d);
superBounceCtrl.render(MarbleGame.canvas.scene2d);
helicopterCtrl.render(MarbleGame.canvas.scene2d);
timeTravelCtrl.render(MarbleGame.canvas.scene2d);
antiGravityCtrl.render(MarbleGame.canvas.scene2d);
}
if (page == 5) {
superJumpCtrl.setVisible(false);
superSpeedCtrl.setVisible(false);
shockAbsorberCtrl.setVisible(false);
superBounceCtrl.setVisible(false);
helicopterCtrl.setVisible(true);
timeTravelCtrl.setVisible(true);
antiGravityCtrl.setVisible(true);
ductFanCtrl.setVisible(false);
tornadoCtrl.setVisible(false);
trapdoorCtrl.setVisible(false);
hcText.text.text = '<font face="Arial14"><br/></font><font face="Expo50"><p align="center">Bonus Items (2/2)</p></font><br/>';
hcText2.position = new Vector(110, 35);
hcText2.extent = new Vector(418, 274);
hcText2.text.text = "<br/><br/>Gyrocopter PowerUp - slows your fall in the air.<br/><br/>Time Travel - takes some time off the clock.<br/><br/>Gravity Modifier - Changes the direction of \"down\" - the new down is in the direction of the arrow.";
hcText2.render(MarbleGame.canvas.scene2d, @:privateAccess hcText2.parent._flow);
superJumpCtrl.render(MarbleGame.canvas.scene2d);
superSpeedCtrl.render(MarbleGame.canvas.scene2d);
shockAbsorberCtrl.render(MarbleGame.canvas.scene2d);
superBounceCtrl.render(MarbleGame.canvas.scene2d);
helicopterCtrl.render(MarbleGame.canvas.scene2d);
timeTravelCtrl.render(MarbleGame.canvas.scene2d);
antiGravityCtrl.render(MarbleGame.canvas.scene2d);
ductFanCtrl.render(MarbleGame.canvas.scene2d);
tornadoCtrl.render(MarbleGame.canvas.scene2d);
trapdoorCtrl.render(MarbleGame.canvas.scene2d);
}
if (page == 6) {
helicopterCtrl.setVisible(false);
timeTravelCtrl.setVisible(false);
antiGravityCtrl.setVisible(false);
ductFanCtrl.setVisible(true);
tornadoCtrl.setVisible(true);
trapdoorCtrl.setVisible(true);
bumperCtrl.setVisible(false);
landMineCtrl.setVisible(false);
oilSlickCtrl.setVisible(false);
hcText.text.text = '<font face="Arial14"><br/></font><font face="Expo50"><p align="center">Hazards (1/2)</p></font><br/>';
hcText2.position = new Vector(110, 38);
hcText2.extent = new Vector(418, 274);
hcText2.text.text = "<br/><br/>Duct Fan - be careful this doesn't blow you away!<br/><br/>Tornado - it'll pull you in and spit you out.<br/><br/>Trap Door - keep moving when you're rolling over one of these.";
hcText2.render(MarbleGame.canvas.scene2d, @:privateAccess hcText2.parent._flow);
helicopterCtrl.render(MarbleGame.canvas.scene2d);
timeTravelCtrl.render(MarbleGame.canvas.scene2d);
antiGravityCtrl.render(MarbleGame.canvas.scene2d);
ductFanCtrl.render(MarbleGame.canvas.scene2d);
tornadoCtrl.render(MarbleGame.canvas.scene2d);
trapdoorCtrl.render(MarbleGame.canvas.scene2d);
bumperCtrl.render(MarbleGame.canvas.scene2d);
landMineCtrl.render(MarbleGame.canvas.scene2d);
oilSlickCtrl.render(MarbleGame.canvas.scene2d);
}
if (page == 7) {
ductFanCtrl.setVisible(false);
tornadoCtrl.setVisible(false);
trapdoorCtrl.setVisible(false);
bumperCtrl.setVisible(true);
landMineCtrl.setVisible(true);
oilSlickCtrl.setVisible(true);
hcText.text.text = '<font face="Arial14"><br/></font><font face="Expo50"><p align="center">Hazards (2/2)</p></font><br/>';
hcText2.position = new Vector(110, 30);
hcText2.extent = new Vector(418, 274);
hcText2.text.text = "<br/><br/>Bumper - this'll bounce you if you touch it.<br/><br/>Land Mine - Warning! Explodes on contact!<br/><br/>Oil Slick - you won't have much traction on these surfaces";
hcText2.render(MarbleGame.canvas.scene2d, @:privateAccess hcText2.parent._flow);
ductFanCtrl.render(MarbleGame.canvas.scene2d);
tornadoCtrl.render(MarbleGame.canvas.scene2d);
trapdoorCtrl.render(MarbleGame.canvas.scene2d);
bumperCtrl.render(MarbleGame.canvas.scene2d);
landMineCtrl.render(MarbleGame.canvas.scene2d);
oilSlickCtrl.render(MarbleGame.canvas.scene2d);
}
if (page == 8) {
bumperCtrl.setVisible(false);
landMineCtrl.setVisible(false);
oilSlickCtrl.setVisible(false);
hcText2.text.text = "";
hcText.text.text = '<font face="Arial14"><br/></font><font face="Expo50"><p align="center">About GarageGames</p></font><br/>'
+
"GarageGames is a unique Internet publishing label for independent games and gamemakers. Our mission is to provide the independent developer with tools, knowledge, co-conspirators - whatever is needed to unleash the creative spirit and get great innovative independent games to market.";
bumperCtrl.render(MarbleGame.canvas.scene2d);
landMineCtrl.render(MarbleGame.canvas.scene2d);
oilSlickCtrl.render(MarbleGame.canvas.scene2d);
}
if (page == 9) {
hcText2.text.text = "";
hcText.text.text = '<font face="Arial14"><br/></font><font face="Expo50"><p align="center">About the Torque</p></font><br/>'
+
"The Torque Game Engine (TGE) is a full featured AAA title engine with the latest in scripting, geometry, particle effects, animation and texturing, as well as award winning multi-player networking code. For $100 per programmer, you get the source to the engine!";
}
if (page == 10) {
hcText.text.text = '<font face="Arial14"><br/></font><font face="Expo50"><p align="center">The Marble Blast Team</p></font><br/>'
+ "ÂAlex Swanson<br/>ÂJeff Tunnell<br/>ÂLiam Ryan<br/>ÂRick Overman<br/>ÂTimothy Clarke<br/>ÂPat Wilson";
hcText2.position = new Vector(343, 24);
hcText2.extent = new Vector(155, 274);
hcText2.text.text = '<font face="Arial14"><br/></font><font face="Expo50"><p align="center"> </p></font><br/>'
+ "Mark Frohnmayer<br/>Brian Hahn<br/>Tim Gift<br/>Kevin Ryan<br/>Jay Moore<br/>John Quigley";
hcText2.render(MarbleGame.canvas.scene2d, @:privateAccess hcText2.parent._flow);
}
if (page == 11) {
hcText2.text.text = "";
hcText.text.text = '<font face="Arial14"><br/></font><font face="Expo50"><p align="center">Special Thanks</p></font><br/>'
+ "We'd like to thank Nullsoft, for the SuperPiMP Install System, "
+ "and Markus F.X.J. Oberhumer, Laszlo Molnar and the rest of the UPX team for the UPX executable packer."
+ " Thanks also to Kurtis Seebaldt for his work on integrating Ogg/Vorbis streaming into the Torque engine, and to the Ogg/Vorbis team.";
}
}
function nextPage() {
page++;
redrawPage();
}
function previousPage() {
page--;
redrawPage();
}
function formatText(text:String) {
var start = 0;
var pos = text.indexOf("<func:", start);
while (pos != -1) {
var end = text.indexOf(">", start + 5);
if (end == -1)
break;
var pre = text.substr(0, pos);
var post = text.substr(end + 1);
var func = text.substr(pos + 6, end - (pos + 6));
var funcdata = func.split(' ').map(x -> x.toLowerCase());
var val = "";
if (funcdata[0] == "bind") {
if (funcdata[1] == "moveforward")
val = Util.getKeyForButton(Settings.controlsSettings.forward);
if (funcdata[1] == "movebackward")
val = Util.getKeyForButton(Settings.controlsSettings.backward);
if (funcdata[1] == "moveleft")
val = Util.getKeyForButton(Settings.controlsSettings.left);
if (funcdata[1] == "moveright")
val = Util.getKeyForButton(Settings.controlsSettings.right);
if (funcdata[1] == "panup")
val = Util.getKeyForButton(Settings.controlsSettings.camForward);
if (funcdata[1] == "pandown")
val = Util.getKeyForButton(Settings.controlsSettings.camBackward);
if (funcdata[1] == "turnleft")
val = Util.getKeyForButton(Settings.controlsSettings.camLeft);
if (funcdata[1] == "turnright")
val = Util.getKeyForButton(Settings.controlsSettings.camRight);
if (funcdata[1] == "jump")
val = Util.getKeyForButton(Settings.controlsSettings.jump);
if (funcdata[1] == "mousefire")
val = Util.getKeyForButton(Settings.controlsSettings.powerup);
if (funcdata[1] == "freelook")
val = Util.getKeyForButton(Settings.controlsSettings.freelook);
}
start = val.length + pos;
text = pre + val + post;
pos = text.indexOf("<func:", start);
}
return text;
}
function buildObjectShow(dtsPath:String, position:Vector, extent:Vector, dist:Float = 5, pitch:Float = 0, matnameOverride:Map<String, String> = null) {
var oShow = new GuiObjectShow();
var dtsObj = new DtsObject();
dtsObj.dtsPath = dtsPath;
dtsObj.ambientRotate = true;
dtsObj.ambientSpinFactor /= -2;
dtsObj.showSequences = false;
dtsObj.useInstancing = false;
if (matnameOverride != null) {
for (key => value in matnameOverride) {
dtsObj.matNameOverride.set(key, value);
}
}
dtsObj.init(null, () -> {}); // The lambda is not gonna run async anyway
for (mat in dtsObj.materials) {
mat.mainPass.enableLights = false;
if (mat.blendMode != Alpha && mat.blendMode != Add)
mat.mainPass.addShader(new AlphaChannel());
}
oShow.sceneObject = dtsObj;
oShow.position = position;
oShow.extent = extent;
oShow.renderDistance = dist;
oShow.renderPitch = pitch;
return oShow;
}
}

View file

@ -1,349 +0,0 @@
package gui;
import net.MasterServerClient;
import net.MasterServerClient.RemoteServerInfo;
import net.Net;
import h2d.filter.DropShadow;
import hxd.res.BitmapFont;
import src.MarbleGame;
import src.ResourceLoader;
import h3d.Vector;
import src.Util;
import src.Settings;
class JoinServerGui extends GuiImage {
public function new() {
function chooseBg() {
var rand = Math.random();
if (rand >= 0 && rand <= 0.244)
return ResourceLoader.getImage('data/ui/backgrounds/gold/${cast (Math.floor(Util.lerp(1, 12, Math.random())), Int)}.jpg');
if (rand > 0.244 && rand <= 0.816)
return ResourceLoader.getImage('data/ui/backgrounds/platinum/${cast (Math.floor(Util.lerp(1, 28, Math.random())), Int)}.jpg');
return ResourceLoader.getImage('data/ui/backgrounds/ultra/${cast (Math.floor(Util.lerp(1, 9, Math.random())), Int)}.jpg');
}
var img = chooseBg();
super(img.resource.toTile());
function loadButtonImages(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed];
}
function loadButtonImagesExt(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
var disabled = ResourceLoader.getResource('${path}_i.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed, disabled];
}
var markerFelt32fontdata = ResourceLoader.getFileEntry("data/font/MarkerFelt.fnt");
var markerFelt32b = new BitmapFont(markerFelt32fontdata.entry);
@:privateAccess markerFelt32b.loader = ResourceLoader.loader;
var markerFelt32 = markerFelt32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var markerFelt24 = markerFelt32b.toSdfFont(cast 18 * Settings.uiScale, MultiChannel);
var markerFelt18 = markerFelt32b.toSdfFont(cast 14 * Settings.uiScale, MultiChannel);
function mlFontLoader(text:String) {
switch (text) {
case "MarkerFelt32":
return markerFelt32;
case "MarkerFelt24":
return markerFelt24;
case "MarkerFelt18":
return markerFelt18;
default:
return null;
}
}
this.horizSizing = Width;
this.vertSizing = Height;
this.position = new Vector();
this.extent = new Vector(640, 480);
var passwordPopup = new GuiControl();
passwordPopup.position = new Vector(0, 0);
passwordPopup.extent = new Vector(640, 480);
passwordPopup.horizSizing = Width;
passwordPopup.vertSizing = Height;
var passwordWindow = new GuiImage(ResourceLoader.getResource("data/ui/mp/join/window2.png", ResourceLoader.getImage, this.imageResources).toTile());
passwordWindow.horizSizing = Center;
passwordWindow.vertSizing = Center;
passwordWindow.position = new Vector(144, 199);
passwordWindow.extent = new Vector(508, 202);
passwordPopup.addChild(passwordWindow);
var passwordTitle = new GuiText(markerFelt32);
passwordTitle.position = new Vector(22, 28);
passwordTitle.extent = new Vector(463, 14);
passwordTitle.text.textColor = 0xFFFFFF;
passwordTitle.horizSizing = Center;
passwordTitle.justify = Center;
passwordTitle.text.text = "Password Required";
passwordTitle.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
passwordWindow.addChild(passwordTitle);
var passwordBar = new GuiImage(ResourceLoader.getResource("data/ui/mp/join/textbar.png", ResourceLoader.getImage, this.imageResources).toTile());
passwordBar.position = new Vector(22, 73);
passwordBar.extent = new Vector(463, 47);
passwordWindow.addChild(passwordBar);
var passwordInput = new GuiTextInput(markerFelt24);
passwordInput.position = new Vector(30, 79);
passwordInput.extent = new Vector(447, 38);
passwordInput.horizSizing = Center;
passwordInput.text.textColor = 0;
passwordWindow.addChild(passwordInput);
var passwordCancel = new GuiButton(loadButtonImages("data/ui/mp/join/cancel"));
passwordCancel.position = new Vector(29, 126);
passwordCancel.extent = new Vector(94, 45);
passwordCancel.pressedAction = (e) -> {
passwordInput.text.text = "";
MarbleGame.canvas.popDialog(passwordPopup, false);
}
passwordWindow.addChild(passwordCancel);
var passwordJoin = new GuiButton(loadButtonImages("data/ui/mp/join/join"));
passwordJoin.position = new Vector(385, 126);
passwordJoin.extent = new Vector(94, 45);
passwordWindow.addChild(passwordJoin);
var window = new GuiImage(ResourceLoader.getResource("data/ui/mp/join/window.png", ResourceLoader.getImage, this.imageResources).toTile());
window.horizSizing = Center;
window.vertSizing = Center;
window.position = new Vector(-60, 5);
window.extent = new Vector(759, 469);
var serverInfoContainer = new GuiControl();
serverInfoContainer.position = new Vector(520, 58);
serverInfoContainer.extent = new Vector(210, 166);
window.addChild(serverInfoContainer);
var serverInfo = new GuiMLText(markerFelt24, mlFontLoader);
serverInfo.position = new Vector(0, 0);
serverInfo.extent = new Vector(210, 166);
serverInfo.text.text = '<p align="center">Select a Server</p>';
serverInfo.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
serverInfo.text.textColor = 0xFFFFFF;
serverInfoContainer.addChild(serverInfo);
var serverListContainer = new GuiControl();
serverListContainer.position = new Vector(30, 80);
serverListContainer.extent = new Vector(475, 290);
window.addChild(serverListContainer);
function imgLoader(path:String) {
var t = switch (path) {
case "ready":
ResourceLoader.getResource("data/ui/mp/play/Ready.png", ResourceLoader.getImage, this.imageResources).toTile();
case "notready":
ResourceLoader.getResource("data/ui/mp/play/NotReady.png", ResourceLoader.getImage, this.imageResources).toTile();
case "pc":
ResourceLoader.getResource("data/ui/mp/play/platform_desktop_white.png", ResourceLoader.getImage, this.imageResources).toTile();
case "mac":
ResourceLoader.getResource("data/ui/mp/play/platform_mac_white.png", ResourceLoader.getImage, this.imageResources).toTile();
case "web":
ResourceLoader.getResource("data/ui/mp/play/platform_web_white.png", ResourceLoader.getImage, this.imageResources).toTile();
case "android":
ResourceLoader.getResource("data/ui/mp/play/platform_android_white.png", ResourceLoader.getImage, this.imageResources).toTile();
case "unknown":
ResourceLoader.getResource("data/ui/mp/play/platform_unknown_white.png", ResourceLoader.getImage, this.imageResources).toTile();
case _:
return null;
};
if (t != null)
t.scaleToSize(t.width * (Settings.uiScale), t.height * (Settings.uiScale));
return t;
}
var ourServerList:Array<RemoteServerInfo> = [];
var curSelection = -1;
var serverList = new GuiMLTextListCtrl(markerFelt18, [], imgLoader);
serverList.position = new Vector(0, 0);
serverList.extent = new Vector(475, 63);
serverList.scrollable = true;
serverList.textYOffset = -6;
serverList.onSelectedFunc = (sel) -> {
curSelection = sel;
if (curSelection == -1) {
serverInfo.text.text = '<p align="center">Select a Server</p><p align="center">or Host your own</p>';
} else {
var server = ourServerList[curSelection];
serverInfo.text.text = '<p align="center">${StringTools.htmlEscape(server.name)}</p><p align="center"><font face="MarkerFelt18" color="#DDDDEE">Hosted by ${StringTools.htmlEscape(server.host)}</font></p><p align="left">${StringTools.htmlEscape(server.description)}</p>';
}
}
serverListContainer.addChild(serverList);
var serverDisplays = [];
var platformToString = ["unknown", "pc", "mac", "web", "android"];
function updateServerListDisplay() {
serverDisplays = ourServerList.map(x ->
'<img src="${platformToString[x.platform]}"></img><font color="#FFFFFF">${StringTools.htmlEscape(x.name)} <offset value="${400 * Settings.uiScale}">${x.players}/${x.maxPlayers}</offset></font>');
serverList.setTexts(serverDisplays);
}
MasterServerClient.connectToMasterServer(() -> {
MasterServerClient.instance.getServerList((servers) -> {
ourServerList = servers;
updateServerListDisplay();
});
});
var hostBtn = new GuiButton(loadButtonImages("data/ui/mp/join/host"));
hostBtn.position = new Vector(521, 379);
hostBtn.extent = new Vector(93, 45);
hostBtn.pressedAction = (e) -> {
Net.hostServer(Settings.serverSettings.name, Settings.serverSettings.description, Settings.serverSettings.maxPlayers,
Settings.serverSettings.password, () -> {
MarbleGame.canvas.setContent(new MPPlayMissionGui(true));
});
}
window.addChild(hostBtn);
var joinFunc = (password:String) -> {
if (curSelection != -1) {
var selectedServerVersion = ourServerList[curSelection].version;
if (selectedServerVersion != MarbleGame.currentVersion) {
var pup = new MessageBoxOkDlg("You are using a different version of the game than the server. Please update your game.");
MarbleGame.canvas.pushDialog(pup);
return;
}
MarbleGame.canvas.setContent(new MPMessageGui("Please Wait", "Connecting"));
var failed = true;
haxe.Timer.delay(() -> {
if (MarbleGame.canvas.content is MPMessageGui) {
var loadGui:MPMessageGui = cast MarbleGame.canvas.content;
if (loadGui != null) {
loadGui.setTexts("Error", "Failed to connect to server");
}
}
}, 15000);
Net.joinServer(ourServerList[curSelection].id, password, () -> {
failed = false;
Net.remoteServerInfo = ourServerList[curSelection];
});
}
}
var joinBtn = new GuiButton(loadButtonImages("data/ui/mp/join/join"));
joinBtn.position = new Vector(628, 379);
joinBtn.extent = new Vector(93, 45);
joinBtn.pressedAction = (e) -> {
if (curSelection != -1) {
if (ourServerList[curSelection].passworded) {
MarbleGame.canvas.pushDialog(passwordPopup);
} else {
joinFunc("");
}
}
}
window.addChild(joinBtn);
var usernameBtn = new GuiButton(loadButtonImages("data/ui/mp/join/username"));
usernameBtn.position = new Vector(216, 379);
usernameBtn.extent = new Vector(125, 45);
usernameBtn.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(new EnterNameDlg(-1, (n) -> {}));
}
window.addChild(usernameBtn);
passwordJoin.pressedAction = (e) -> {
joinFunc(passwordInput.text.text);
}
var refreshing = false;
var refreshBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/join/refresh/refresh-1"));
refreshBtn.position = new Vector(126, 379);
refreshBtn.extent = new Vector(45, 45);
refreshBtn.pressedAction = (e) -> {
if (refreshing)
return;
refreshBtn.disabled = true;
refreshing = true;
MasterServerClient.connectToMasterServer(() -> {
MasterServerClient.instance.getServerList((servers) -> {
ourServerList = servers;
updateServerListDisplay();
refreshing = false;
refreshBtn.disabled = false;
});
}, () -> {
refreshing = false;
refreshBtn.disabled = false;
});
}
window.addChild(refreshBtn);
var serverSettingsBtn = new GuiButton(loadButtonImages("data/ui/mp/play/settings"));
serverSettingsBtn.position = new Vector(171, 379);
serverSettingsBtn.extent = new Vector(45, 45);
serverSettingsBtn.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(new MPServerDlg());
}
window.addChild(serverSettingsBtn);
var exitBtn = new GuiButton(loadButtonImages("data/ui/mp/join/leave"));
exitBtn.position = new Vector(32, 379);
exitBtn.extent = new Vector(93, 45);
exitBtn.pressedAction = (e) -> {
MarbleGame.canvas.setContent(new MainMenuGui());
}
window.addChild(exitBtn);
var titleText = new GuiText(markerFelt32);
titleText.position = new Vector(30, 20);
titleText.extent = new Vector(647, 30);
titleText.justify = Center;
titleText.text.text = "Join Server";
titleText.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
titleText.text.textColor = 0xFFFFFF;
window.addChild(titleText);
var listTitle = new GuiText(markerFelt24);
listTitle.position = new Vector(30, 48);
listTitle.extent = new Vector(480, 22);
listTitle.text.textColor = 0xDDDDEE;
listTitle.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
listTitle.text.text = " Server Name Players";
window.addChild(listTitle);
this.addChild(window);
if (StringTools.trim(Settings.highscoreName).length == 0
|| Settings.highscoreName == ""
|| Settings.highscoreName == "Player"
|| Settings.highscoreName == null) {
haxe.Timer.delay(() -> MarbleGame.canvas.pushDialog(new EnterNameDlg(-1, (n) -> {})), 50); // Pls enter name
}
}
}

View file

@ -5,23 +5,12 @@ import h3d.Vector;
import src.ResourceLoader;
import src.MarbleGame;
import src.Settings;
import src.Util;
class LoadingGui extends GuiImage {
public var setProgress:Float->Void;
public function new(missionName:String, game:String, isMultiplayer:Bool = false) {
function chooseBg() {
if (game == "gold")
return ResourceLoader.getImage('data/ui/backgrounds/gold/${cast (Math.floor(Util.lerp(1, 12, Math.random())), Int)}.jpg');
if (game == "platinum")
return ResourceLoader.getImage('data/ui/backgrounds/platinum/${cast (Math.floor(Util.lerp(1, 28, Math.random())), Int)}.jpg');
if (game == "ultra")
return ResourceLoader.getImage('data/ui/backgrounds/ultra/${cast (Math.floor(Util.lerp(1, 9, Math.random())), Int)}.jpg');
return ResourceLoader.getImage('data/ui/backgrounds/platinum/${cast (Math.floor(Util.lerp(1, 28, Math.random())), Int)}.jpg');
}
var img = chooseBg();
public function new(missionName:String) {
var img = ResourceLoader.getImage("data/ui/background.jpg");
super(img.resource.toTile());
this.horizSizing = Width;
this.vertSizing = Height;
@ -47,16 +36,16 @@ class LoadingGui extends GuiImage {
var domcasual32 = domcasual32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var mapName = new GuiText(domcasual32);
mapName.position = new Vector(6, 33);
mapName.extent = new Vector(456, 14);
mapName.position = new Vector(134, 78);
mapName.extent = new Vector(323, 32);
mapName.text.text = missionName;
mapName.text.textColor = 0;
mapName.justify = Center;
var progress = new GuiProgress();
progress.vertSizing = Top;
progress.position = new Vector(194, 145);
progress.extent = new Vector(225, 56);
progress.vertSizing = Bottom;
progress.position = new Vector(153, 133);
progress.extent = new Vector(269, 78);
progress.progress = 0.5;
setProgress = (progressPz) -> {
@ -64,20 +53,19 @@ class LoadingGui extends GuiImage {
}
var cancelButton = new GuiButton(loadButtonImages("data/ui/loading/cancel"));
cancelButton.position = new Vector(333, 243);
cancelButton.extent = new Vector(112, 59);
cancelButton.position = new Vector(320, 233);
cancelButton.extent = new Vector(88, 50);
cancelButton.pressedAction = (sender) -> {
MarbleGame.instance.quitMission();
}
var overlay = new GuiImage(ResourceLoader.getResource("data/ui/loading/overlay.png", ResourceLoader.getImage, this.imageResources).toTile());
overlay.position = new Vector(188, 139);
overlay.extent = new Vector(242, 75);
overlay.position = new Vector(151, 131);
overlay.extent = new Vector(278, 86);
loadingGui.addChild(mapName);
loadingGui.addChild(progress);
if (!isMultiplayer)
loadingGui.addChild(cancelButton);
loadingGui.addChild(cancelButton);
loadingGui.addChild(overlay);
this.addChild(loadingGui);

View file

@ -1,313 +0,0 @@
package gui;
import net.NetCommands;
import net.Net;
import h3d.shader.AlphaChannel;
import hxd.res.BitmapFont;
import src.MarbleGame;
import src.ResourceLoader;
import h3d.Vector;
import src.Settings;
import src.DtsObject;
class MPEndGameGui extends GuiImage {
public function new() {
var img = ResourceLoader.getImage('data/ui/exit/black.png');
super(img.resource.toTile());
this.horizSizing = Width;
this.vertSizing = Height;
this.position = new Vector(0, 0);
this.extent = new Vector(640, 480);
var domcasual24fontdata = ResourceLoader.getFileEntry("data/font/DomCasualD.fnt");
var domcasual24b = new BitmapFont(domcasual24fontdata.entry);
@:privateAccess domcasual24b.loader = ResourceLoader.loader;
var domcasual24 = domcasual24b.toSdfFont(cast 20 * Settings.uiScale, MultiChannel);
var domcasual36 = domcasual24b.toSdfFont(cast 32 * Settings.uiScale, MultiChannel);
var arial14fontdata = ResourceLoader.getFileEntry("data/font/arial.fnt");
var arial14b = new BitmapFont(arial14fontdata.entry);
@:privateAccess arial14b.loader = ResourceLoader.loader;
var arial14 = arial14b.toSdfFont(cast 12 * Settings.uiScale, MultiChannel);
var arialb14fontdata = ResourceLoader.getFileEntry("data/font/Arial Bold.fnt");
var arialb14b = new BitmapFont(arialb14fontdata.entry);
@:privateAccess arialb14b.loader = ResourceLoader.loader;
var arialBold14 = arialb14b.toSdfFont(cast 12 * Settings.uiScale, MultiChannel);
var markerFelt32fontdata = ResourceLoader.getFileEntry("data/font/MarkerFelt.fnt");
var markerFelt32b = new BitmapFont(markerFelt32fontdata.entry);
@:privateAccess markerFelt32b.loader = ResourceLoader.loader;
var markerFelt32 = markerFelt32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var markerFelt24 = markerFelt32b.toSdfFont(cast 20 * Settings.uiScale, MultiChannel);
var markerFelt20 = markerFelt32b.toSdfFont(cast 18.5 * Settings.uiScale, MultiChannel);
var markerFelt18 = markerFelt32b.toSdfFont(cast 17 * Settings.uiScale, MultiChannel);
var markerFelt26 = markerFelt32b.toSdfFont(cast 22 * Settings.uiScale, MultiChannel);
var expo50fontdata = ResourceLoader.getFileEntry("data/font/EXPON.fnt");
var expo50b = new BitmapFont(expo50fontdata.entry);
@:privateAccess expo50b.loader = ResourceLoader.loader;
var expo50 = expo50b.toSdfFont(cast 35 * Settings.uiScale, MultiChannel);
function mlFontLoader(text:String) {
switch (text) {
case "DomCasual24":
return domcasual24;
case "Arial14":
return arial14;
case "ArialBold14":
return arialBold14;
case "MarkerFelt32":
return markerFelt32;
case "MarkerFelt24":
return markerFelt24;
case "MarkerFelt18":
return markerFelt18;
case "MarkerFelt20":
return markerFelt20;
case "MarkerFelt26":
return markerFelt26;
default:
return null;
}
}
function loadButtonImages(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed];
}
function loadButtonImagesExt(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
var disabled = ResourceLoader.getResource('${path}_i.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed, disabled];
}
var sidebar = new GuiImage(ResourceLoader.getResource("data/ui/mp/end/window.png", ResourceLoader.getImage, this.imageResources).toTile());
sidebar.position = new Vector(587, 141);
sidebar.extent = new Vector(53, 198);
sidebar.horizSizing = Left;
sidebar.vertSizing = Center;
this.addChild(sidebar);
var lobbyBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/end/lobby"));
lobbyBtn.position = new Vector(5, 53);
lobbyBtn.extent = new Vector(49, 49);
lobbyBtn.vertSizing = Top;
lobbyBtn.pressedAction = (e) -> {
MarbleGame.instance.quitMission();
}
if (Net.isClient) {
lobbyBtn.disabled = true;
}
sidebar.addChild(lobbyBtn);
var restartBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/end/restart"));
restartBtn.position = new Vector(5, 7);
restartBtn.extent = new Vector(49, 49);
restartBtn.pressedAction = (e) -> {
MarbleGame.canvas.popDialog(this);
MarbleGame.instance.paused = false;
NetCommands.completeRestartGame();
}
if (Net.isClient) {
restartBtn.disabled = true;
}
sidebar.addChild(restartBtn);
var exitBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/end/exit"));
exitBtn.position = new Vector(5, 99);
exitBtn.extent = new Vector(49, 49);
exitBtn.vertSizing = Top;
exitBtn.horizSizing = Left;
exitBtn.pressedAction = (e) -> {
MarbleGame.canvas.popDialog(this);
MarbleGame.instance.paused = false;
MarbleGame.instance.quitMission();
Net.disconnect();
MarbleGame.canvas.setContent(new JoinServerGui());
}
sidebar.addChild(exitBtn);
var middleCtrl = new GuiControl();
middleCtrl.horizSizing = Center;
middleCtrl.vertSizing = Height;
middleCtrl.position = new Vector(-80, 0);
middleCtrl.extent = new Vector(800, 480);
this.addChild(middleCtrl);
var hasPlatinum = false;
var scores = @:privateAccess MarbleGame.instance.world.playGui.playerList;
for (player in scores) {
if (player.p > 0) {
hasPlatinum = true;
break;
}
}
var headerML = new GuiText(domcasual36);
headerML.position = new Vector(25, 83);
headerML.extent = new Vector(750, 14);
headerML.horizSizing = Width;
headerML.text.textColor = 0xFFFFFF;
headerML.text.text = ' Name Score ${hasPlatinum ? " " : ""} Marble';
middleCtrl.addChild(headerML);
var ourRank = scores.indexOf(scores.filter(x -> x.us == true)[0]) + 1;
var rankSuffix = ourRank == 1 ? "st" : (ourRank == 2 ? "nd" : (ourRank == 3 ? "rd" : "th"));
var col0 = 0xCFB52B;
var col1 = 0xCDCDCD;
var col2 = 0xD19275;
var col3 = 0xFFEE99;
var rankColor = ourRank == 1 ? col0 : (ourRank == 2 ? col1 : (ourRank == 3 ? col2 : col3));
var titleML = new GuiText(expo50);
titleML.position = new Vector(25, 6);
titleML.extent = new Vector(750, 14);
titleML.justify = Center;
titleML.horizSizing = Width;
titleML.text.textColor = rankColor;
titleML.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
titleML.text.text = 'You have won ' + ourRank + rankSuffix + ' place!';
middleCtrl.addChild(titleML);
var redGem = buildObjectShow("data/shapes/items/gem.dts", new Vector(365, 65), new Vector(64, 64), 2.5, 0, ["base.gem" => "red.gem"]);
middleCtrl.addChild(redGem);
var yellowGem = buildObjectShow("data/shapes/items/gem.dts", new Vector(417, 65), new Vector(64, 64), 2.5, 0, ["base.gem" => "yellow.gem"]);
middleCtrl.addChild(yellowGem);
var blueGem = buildObjectShow("data/shapes/items/gem.dts", new Vector(469, 65), new Vector(64, 64), 2.5, 0, ["base.gem" => "blue.gem"]);
middleCtrl.addChild(blueGem);
if (hasPlatinum) {
var platinumGem = buildObjectShow("data/shapes/items/gem.dts", new Vector(521, 65), new Vector(64, 64), 2.5, 0, ["base.gem" => "platinum.gem"]);
middleCtrl.addChild(platinumGem);
}
var playerContainer = new GuiControl();
playerContainer.horizSizing = Center;
playerContainer.vertSizing = Height;
playerContainer.position = new Vector(25, 125);
playerContainer.extent = new Vector(750, 275);
middleCtrl.addChild(playerContainer);
var idx = 0;
function addPlayer(rank:Int, playerName:String, score:Int, r:Int, y:Int, b:Int, p:Int, marbleCat:Int, marbleSel:Int) {
var container = new GuiControl();
container.position = new Vector(0, 44 * idx);
container.extent = new Vector(750, 44);
var playerNameT = new GuiText(domcasual36);
playerNameT.text.textColor = 0xFFFFFF;
playerNameT.text.text = '${rank}. ${playerName}';
playerNameT.position = new Vector(0, 3);
playerNameT.extent = new Vector(300, 14);
container.addChild(playerNameT);
var playerScore = new GuiText(domcasual36);
playerScore.text.textColor = 0xFFFFFF;
playerScore.text.text = '${score}';
playerScore.position = new Vector(287, 3);
playerScore.extent = new Vector(310, 14);
container.addChild(playerScore);
var playerR = new GuiText(domcasual36);
playerR.text.textColor = 0xFF0000;
playerR.text.text = '${r}';
playerR.justify = Center;
playerR.position = new Vector(348, 3);
playerR.extent = new Vector(52, 14);
container.addChild(playerR);
var playerY = new GuiText(domcasual36);
playerY.text.textColor = 0xFFFF00;
playerY.text.text = '${y}';
playerY.justify = Center;
playerY.position = new Vector(400, 3);
playerY.extent = new Vector(52, 14);
container.addChild(playerY);
var playerB = new GuiText(domcasual36);
playerB.text.textColor = 0x4040FF;
playerB.text.text = '${b}';
playerB.justify = Center;
playerB.position = new Vector(452, 3);
playerB.extent = new Vector(52, 14);
container.addChild(playerB);
if (hasPlatinum) {
var playerB = new GuiText(domcasual36);
playerB.text.textColor = 0xCCCCCC;
playerB.text.text = '${p}';
playerB.justify = Center;
playerB.position = new Vector(504, 3);
playerB.extent = new Vector(52, 14);
container.addChild(playerB);
}
var marble = buildObjectShow(MarbleSelectGui.marbleData[marbleCat][marbleSel].dts, new Vector((hasPlatinum ? 52 : 0) + 524, -10),
new Vector(64, 64), 2.4, 0, [
"base.marble" => MarbleSelectGui.marbleData[marbleCat][marbleSel].skin + ".marble"
]);
container.addChild(marble);
playerContainer.addChild(container);
idx += 1;
}
var r = 1;
for (player in scores) {
var cat = Settings.optionsSettings.marbleCategoryIndex;
var marb = Settings.optionsSettings.marbleIndex;
if (!player.us) {
var c = Net.clientIdMap[player.id];
cat = c.marbleCatId;
marb = c.marbleId;
}
addPlayer(r, player.name, player.score, player.r, player.y, player.b, player.p, cat, marb);
r += 1;
}
}
function buildObjectShow(dtsPath:String, position:Vector, extent:Vector, dist:Float = 5, pitch:Float = 0, matnameOverride:Map<String, String> = null) {
var oShow = new GuiObjectShow();
var dtsObj = new DtsObject();
dtsObj.dtsPath = dtsPath;
dtsObj.ambientRotate = true;
dtsObj.ambientSpinFactor /= -2;
dtsObj.showSequences = false;
dtsObj.useInstancing = false;
if (matnameOverride != null) {
for (key => value in matnameOverride) {
dtsObj.matNameOverride.set(key, value);
}
}
dtsObj.init(null, () -> {}); // The lambda is not gonna run async anyway
for (mat in dtsObj.materials) {
mat.mainPass.enableLights = false;
mat.mainPass.culling = None;
if (mat.blendMode != Alpha && mat.blendMode != Add)
mat.mainPass.addShader(new AlphaChannel());
}
oShow.sceneObject = dtsObj;
oShow.position = position;
oShow.extent = extent;
oShow.renderDistance = dist;
oShow.renderPitch = pitch;
return oShow;
}
}

View file

@ -1,173 +0,0 @@
package gui;
import net.NetCommands;
import h2d.filter.DropShadow;
import net.Net;
import src.MarbleGame;
import hxd.res.BitmapFont;
import h3d.Vector;
import src.ResourceLoader;
import src.Settings;
import hxd.Key;
class MPExitGameDlg extends GuiControl {
public function new(resumeFunc:() -> Void, exitFunc:() -> Void) {
super();
this.horizSizing = Width;
this.vertSizing = Height;
this.position = new Vector();
this.extent = new Vector(640, 480);
function loadButtonImages(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed];
}
function loadButtonImagesExt(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
var disabled = ResourceLoader.getResource('${path}_i.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed, disabled];
}
var dialogImg = new GuiImage(ResourceLoader.getResource("data/ui/mp/team/teamjoin.png", ResourceLoader.getImage, this.imageResources).toTile());
dialogImg.horizSizing = Center;
dialogImg.vertSizing = Center;
dialogImg.position = new Vector(146, 115);
dialogImg.extent = new Vector(347, 250);
this.addChild(dialogImg);
var partialRestart = new GuiButton(loadButtonImagesExt("data/ui/mp/exit/partial"));
partialRestart.position = new Vector(133, 80);
partialRestart.extent = new Vector(94, 45);
partialRestart.vertSizing = Top;
partialRestart.pressedAction = (e) -> {
MarbleGame.instance.paused = false;
NetCommands.partialRestartGame();
MarbleGame.canvas.popDialog(this);
}
dialogImg.addChild(partialRestart);
if (!Net.isHost) {
partialRestart.disabled = true;
}
var disconnectBtn = new GuiButton(Net.isHost ? loadButtonImages("data/ui/mp/exit/levelselect") : loadButtonImages("data/ui/mp/exit/disconnect"));
disconnectBtn.position = new Vector(22, 132);
disconnectBtn.extent = new Vector(114, 45);
disconnectBtn.vertSizing = Top;
disconnectBtn.pressedAction = (e) -> exitFunc();
dialogImg.addChild(disconnectBtn);
var resumeBtn = new GuiButton(loadButtonImages("data/ui/mp/exit/resume"));
resumeBtn.position = new Vector(133, 132);
resumeBtn.extent = new Vector(94, 45);
resumeBtn.vertSizing = Top;
resumeBtn.pressedAction = (e) -> resumeFunc();
dialogImg.addChild(resumeBtn);
var serverSettingsBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/play/settings"));
serverSettingsBtn.position = new Vector(155, 184);
serverSettingsBtn.extent = new Vector(45, 45);
serverSettingsBtn.vertSizing = Top;
serverSettingsBtn.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(new MPServerDlg());
};
dialogImg.addChild(serverSettingsBtn);
if (!Net.isHost) {
serverSettingsBtn.disabled = true;
}
var kickBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/play/kick"));
kickBtn.position = new Vector(68, 184);
kickBtn.extent = new Vector(45, 45);
kickBtn.vertSizing = Top;
kickBtn.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(new MPKickBanDlg());
}
dialogImg.addChild(kickBtn);
if (!Net.isHost) {
kickBtn.disabled = true;
}
var optionsBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/play/playersettings"));
optionsBtn.position = new Vector(242, 184);
optionsBtn.extent = new Vector(45, 45);
optionsBtn.vertSizing = Top;
optionsBtn.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(new OptionsDlg(true));
}
dialogImg.addChild(optionsBtn);
var quickspawnBtn = new GuiButton(loadButtonImages("data/ui/mp/exit/respawn"));
quickspawnBtn.position = new Vector(224, 132);
quickspawnBtn.extent = new Vector(104, 45);
quickspawnBtn.vertSizing = Top;
quickspawnBtn.pressedAction = (e) -> {
MarbleGame.instance.paused = false;
@:privateAccess Key.keyPressed[Settings.controlsSettings.respawn] = Key.getFrame() - 1; // jank
MarbleGame.canvas.popDialog(this);
}
dialogImg.addChild(quickspawnBtn);
var completeRestart = new GuiButton(loadButtonImagesExt("data/ui/mp/exit/complete"));
completeRestart.position = new Vector(224, 80);
completeRestart.extent = new Vector(104, 45);
completeRestart.vertSizing = Top;
completeRestart.pressedAction = (e) -> {
MarbleGame.instance.paused = false;
NetCommands.completeRestartGame();
MarbleGame.canvas.popDialog(this);
}
dialogImg.addChild(completeRestart);
if (!Net.isHost) {
completeRestart.disabled = true;
}
var markerFelt32fontdata = ResourceLoader.getFileEntry("data/font/MarkerFelt.fnt");
var markerFelt32b = new BitmapFont(markerFelt32fontdata.entry);
@:privateAccess markerFelt32b.loader = ResourceLoader.loader;
var markerFelt32 = markerFelt32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var markerFelt38 = markerFelt32b.toSdfFont(cast 31 * Settings.uiScale, MultiChannel);
var exitTitle = new GuiText(markerFelt38);
exitTitle.position = new Vector(8, 28);
exitTitle.extent = new Vector(331, 30);
exitTitle.justify = Center;
exitTitle.text.text = "Ingame Options";
exitTitle.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
dialogImg.addChild(exitTitle);
var restartTitle = new GuiText(markerFelt32);
restartTitle.position = new Vector(20, 88);
restartTitle.extent = new Vector(114, 14);
restartTitle.justify = Center;
restartTitle.text.text = "Restart:";
restartTitle.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
dialogImg.addChild(restartTitle);
var jukeboxButton = new GuiButton(loadButtonImages("data/ui/jukebox/jb_pausemenu"));
jukeboxButton.vertSizing = Top;
jukeboxButton.horizSizing = Left;
jukeboxButton.position = new Vector(439, 403);
jukeboxButton.extent = new Vector(187, 65);
jukeboxButton.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(new JukeboxDlg());
}
this.addChild(jukeboxButton);
}
}

View file

@ -1,116 +0,0 @@
package gui;
import net.ClientConnection;
import net.NetCommands;
import net.Net;
import h2d.filter.DropShadow;
import hxd.res.BitmapFont;
import h3d.prim.Polygon;
import h3d.scene.Mesh;
import h3d.shader.AlphaChannel;
import src.MarbleGame;
import h3d.Vector;
import src.ResourceLoader;
import src.DtsObject;
import src.Settings;
import src.ResourceLoaderWorker;
class MPKickBanDlg extends GuiImage {
public function new() {
var img = ResourceLoader.getImage("data/ui/mp/kickban/window.png");
super(img.resource.toTile());
this.horizSizing = Center;
this.vertSizing = Center;
this.position = new Vector(226, 137);
this.extent = new Vector(409, 316);
function loadButtonImages(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed];
}
function loadButtonImagesExt(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
var disabled = ResourceLoader.getResource('${path}_i.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed, disabled];
}
var markerFelt32fontdata = ResourceLoader.getFileEntry("data/font/MarkerFelt.fnt");
var markerFelt32b = new BitmapFont(markerFelt32fontdata.entry);
@:privateAccess markerFelt32b.loader = ResourceLoader.loader;
var markerFelt32 = markerFelt32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var markerFelt24 = markerFelt32b.toSdfFont(cast 20 * Settings.uiScale, MultiChannel);
var markerFelt20 = markerFelt32b.toSdfFont(cast 18.5 * Settings.uiScale, MultiChannel);
var markerFelt18 = markerFelt32b.toSdfFont(cast 17 * Settings.uiScale, MultiChannel);
var markerFelt26 = markerFelt32b.toSdfFont(cast 22 * Settings.uiScale, MultiChannel);
var closeBtn = new GuiButton(loadButtonImages("data/ui/mp/team/close"));
closeBtn.position = new Vector(247, 254);
closeBtn.extent = new Vector(94, 45);
closeBtn.vertSizing = Bottom;
closeBtn.horizSizing = Right;
closeBtn.pressedAction = (e) -> {
MarbleGame.canvas.popDialog(this);
}
this.addChild(closeBtn);
var kickBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/kickban/kick"));
kickBtn.position = new Vector(77, 254);
kickBtn.extent = new Vector(94, 45);
kickBtn.vertSizing = Bottom;
kickBtn.horizSizing = Right;
kickBtn.disabled = true;
this.addChild(kickBtn);
var kickTitle = new GuiText(markerFelt32);
kickTitle.text.textColor = 0xFFFFFF;
kickTitle.text.text = "Kick Players";
kickTitle.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
kickTitle.justify = Center;
kickTitle.position = new Vector(11, 17);
kickTitle.extent = new Vector(388, 14);
this.addChild(kickTitle);
var playerNames = [];
var playerIds = [];
for (c in Net.clients) {
playerNames.push(c.getName());
playerIds.push(c.id);
}
var kickPlayerId = -1;
var playerList = new GuiTextListCtrl(markerFelt18, playerNames, 0);
playerList.position = new Vector(120, 60);
playerList.extent = new Vector(188, 180);
playerList.scrollable = true;
playerList.textYOffset = -6;
playerList.onSelectedFunc = (sel) -> {
kickBtn.disabled = false;
kickPlayerId = playerIds[sel];
}
this.addChild(playerList);
kickBtn.pressedAction = (e) -> {
if (Net.clientIdMap.exists(kickPlayerId)) {
var playerToKick = kickPlayerId;
playerNames.remove(Net.clientIdMap.get(playerToKick).getName());
playerIds.remove(playerToKick);
playerList.setTexts(playerNames);
kickBtn.disabled = true;
NetCommands.getKickedClient(Net.clientIdMap.get(playerToKick));
var cc = cast(Net.clientIdMap.get(playerToKick), ClientConnection);
cc.socket.close();
}
}
}
}

View file

@ -1,238 +0,0 @@
package gui;
import net.Net;
import net.NetCommands;
import h2d.filter.DropShadow;
import hxd.res.BitmapFont;
import h3d.prim.Polygon;
import h3d.scene.Mesh;
import h3d.shader.AlphaChannel;
import src.MarbleGame;
import h3d.Vector;
import src.ResourceLoader;
import src.DtsObject;
import src.Settings;
import src.ResourceLoaderWorker;
class MPMarbleSelectGui extends GuiImage {
public function new() {
var img = ResourceLoader.getImage("data/ui/mp/team/teamcreate.png");
super(img.resource.toTile());
this.horizSizing = Center;
this.vertSizing = Center;
this.position = new Vector(73, -59);
this.extent = new Vector(493, 361);
var categoryNames = ["Official Marbles", "MBUltra"];
var curSelection:Int = Settings.optionsSettings.marbleIndex;
var curCategorySelection:Int = Settings.optionsSettings.marbleCategoryIndex;
function loadButtonImages(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
var disabled = ResourceLoader.getResource('${path}_i.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed, disabled];
}
var markerFelt32fontdata = ResourceLoader.getFileEntry("data/font/MarkerFelt.fnt");
var markerFelt32b = new BitmapFont(markerFelt32fontdata.entry);
@:privateAccess markerFelt32b.loader = ResourceLoader.loader;
var markerFelt32 = markerFelt32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var markerFelt24 = markerFelt32b.toSdfFont(cast 18 * Settings.uiScale, MultiChannel);
var markerFelt28 = markerFelt32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var selectBtn = new GuiButton(loadButtonImages("data/ui/mp/play/choose"));
selectBtn.horizSizing = Center;
selectBtn.vertSizing = Top;
selectBtn.position = new Vector(199, 270);
selectBtn.extent = new Vector(95, 45);
selectBtn.pressedAction = (e) -> {
Settings.optionsSettings.marbleIndex = curSelection;
Settings.optionsSettings.marbleCategoryIndex = curCategorySelection;
Settings.optionsSettings.marbleSkin = MarbleSelectGui.marbleData[curCategorySelection][curSelection].skin;
Settings.optionsSettings.marbleModel = MarbleSelectGui.marbleData[curCategorySelection][curSelection].dts;
Settings.optionsSettings.marbleShader = MarbleSelectGui.marbleData[curCategorySelection][curSelection].shader;
Settings.save();
MarbleGame.canvas.popDialog(this);
// Transmit changes to the server/clients
if (Net.isClient) {
NetCommands.setPlayerData(Net.clientId, Settings.highscoreName, Settings.optionsSettings.marbleIndex,
Settings.optionsSettings.marbleCategoryIndex, true);
}
if (Net.isHost) {
var b = Net.sendPlayerInfosBytes();
for (cc in Net.clients) {
cc.sendBytes(b);
}
}
}
this.addChild(selectBtn);
var marbleShow = buildObjectShow(MarbleSelectGui.marbleData[curCategorySelection][curSelection].dts, new Vector(171, 97), new Vector(150, 150), 2.6,
0, [
"base.marble" => MarbleSelectGui.marbleData[curCategorySelection][curSelection].skin + ".marble"
]);
marbleShow.horizSizing = Center;
marbleShow.vertSizing = Bottom;
marbleShow.visible = true;
this.addChild(marbleShow);
var titleText = new GuiMLText(markerFelt28, null);
titleText.text.textColor = 0xFFFFFF;
titleText.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
titleText.horizSizing = Center;
titleText.vertSizing = Bottom;
titleText.position = new Vector(140, 67);
titleText.extent = new Vector(213, 27);
titleText.text.text = '<p align="center">${categoryNames[curCategorySelection]}</p>';
this.addChild(titleText);
var marbleText = new GuiMLText(markerFelt24, null);
marbleText.text.textColor = 0xFFFFFF;
marbleText.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
marbleText.horizSizing = Center;
marbleText.vertSizing = Bottom;
marbleText.position = new Vector(86, 243);
marbleText.extent = new Vector(320, 22);
marbleText.text.text = '<p align="center">${MarbleSelectGui.marbleData[curCategorySelection][curSelection].name}</p>';
this.addChild(marbleText);
var changeMarbleText = new GuiImage(ResourceLoader.getResource("data/ui/play/change_marble_text.png", ResourceLoader.getImage, this.imageResources)
.toTile());
changeMarbleText.horizSizing = Center;
changeMarbleText.position = new Vector(96, 26);
changeMarbleText.extent = new Vector(300, 39);
this.addChild(changeMarbleText);
function setMarbleSelection(idx:Int, categoryIdx:Int) {
if (categoryIdx < 0)
categoryIdx = MarbleSelectGui.marbleData.length + categoryIdx;
if (categoryIdx >= MarbleSelectGui.marbleData.length)
categoryIdx -= MarbleSelectGui.marbleData.length;
if (idx < 0)
idx = MarbleSelectGui.marbleData[categoryIdx].length + idx;
if (idx >= MarbleSelectGui.marbleData[categoryIdx].length)
idx -= MarbleSelectGui.marbleData[categoryIdx].length;
curSelection = idx;
curCategorySelection = categoryIdx;
var marble = MarbleSelectGui.marbleData[categoryIdx][idx];
titleText.text.text = '<p align="center">${categoryNames[curCategorySelection]}</p>';
marbleText.text.text = '<p align="center">${marble.name}</p>';
var dtsObj = new DtsObject();
dtsObj.dtsPath = marble.dts;
dtsObj.ambientRotate = true;
dtsObj.ambientSpinFactor /= -2;
dtsObj.showSequences = false;
dtsObj.useInstancing = false;
dtsObj.matNameOverride.set("base.marble", marble.skin + ".marble");
ResourceLoader.load(dtsObj.dtsPath).entry.load(() -> {
var dtsFile = ResourceLoader.loadDts(dtsObj.dtsPath);
var directoryPath = haxe.io.Path.directory(dtsObj.dtsPath);
var texToLoad = [];
for (i in 0...dtsFile.resource.matNames.length) {
var matName = dtsObj.matNameOverride.exists(dtsFile.resource.matNames[i]) ? dtsObj.matNameOverride.get(dtsFile.resource.matNames[i]) : dtsFile.resource.matNames[i];
var fullNames = ResourceLoader.getFullNamesOf(directoryPath + '/' + matName).filter(x -> haxe.io.Path.extension(x) != "dts");
var fullName = fullNames.length > 0 ? fullNames[0] : null;
if (fullName != null) {
texToLoad.push(fullName);
}
}
var worker = new ResourceLoaderWorker(() -> {
dtsObj.init(null, () -> {}); // The lambda is not gonna run async anyway
for (mat in dtsObj.materials) {
mat.mainPass.enableLights = false;
mat.mainPass.culling = None;
if (mat.blendMode != Alpha && mat.blendMode != Add)
mat.mainPass.addShader(new AlphaChannel());
}
marbleShow.changeObject(dtsObj);
});
for (texPath in texToLoad) {
worker.loadFile(texPath);
}
worker.run();
});
}
var nextBtn = new GuiButton(loadButtonImages("data/ui/mp/play/next"));
nextBtn.position = new Vector(296, 270);
nextBtn.extent = new Vector(75, 45);
nextBtn.pressedAction = (e) -> {
setMarbleSelection(curSelection + 1, curCategorySelection);
}
this.addChild(nextBtn);
var prevBtn = new GuiButton(loadButtonImages("data/ui/mp/play/prev"));
prevBtn.position = new Vector(123, 270);
prevBtn.extent = new Vector(75, 45);
prevBtn.pressedAction = (e) -> {
setMarbleSelection(curSelection - 1, curCategorySelection);
}
var nextCategoryBtn = new GuiButton(loadButtonImages("data/ui/mp/play/nextcat"));
nextCategoryBtn.position = new Vector(371, 270);
nextCategoryBtn.extent = new Vector(85, 45);
nextCategoryBtn.pressedAction = (e) -> {
setMarbleSelection(0, curCategorySelection + 1);
}
this.addChild(nextCategoryBtn);
var prevCategoryBtn = new GuiButton(loadButtonImages("data/ui/mp/play/prevcat"));
prevCategoryBtn.position = new Vector(37, 270);
prevCategoryBtn.extent = new Vector(85, 45);
prevCategoryBtn.pressedAction = (e) -> {
setMarbleSelection(0, curCategorySelection - 1);
}
this.addChild(prevCategoryBtn);
setMarbleSelection(curSelection, curCategorySelection);
this.addChild(prevBtn);
}
function buildObjectShow(dtsPath:String, position:Vector, extent:Vector, dist:Float = 5, pitch:Float = 0, matnameOverride:Map<String, String> = null) {
var oShow = new GuiObjectShow();
var dtsObj = new DtsObject();
dtsObj.dtsPath = dtsPath;
dtsObj.ambientRotate = true;
dtsObj.ambientSpinFactor /= -2;
dtsObj.showSequences = false;
dtsObj.useInstancing = false;
if (matnameOverride != null) {
for (key => value in matnameOverride) {
dtsObj.matNameOverride.set(key, value);
}
}
dtsObj.init(null, () -> {}); // The lambda is not gonna run async anyway
for (mat in dtsObj.materials) {
mat.mainPass.enableLights = false;
mat.mainPass.culling = None;
if (mat.blendMode != Alpha && mat.blendMode != Add)
mat.mainPass.addShader(new AlphaChannel());
}
oShow.sceneObject = dtsObj;
oShow.position = position;
oShow.extent = extent;
oShow.renderDistance = dist;
oShow.renderPitch = pitch;
return oShow;
}
}

View file

@ -1,106 +0,0 @@
package gui;
import net.Net;
import hxd.res.BitmapFont;
import src.ResourceLoader;
import h3d.Vector;
import src.MarbleGame;
import src.Util;
import src.Settings;
class MPMessageGui extends GuiImage {
public function new(titleText:String, msgText:String) {
function chooseBg() {
var rand = Math.random();
if (rand >= 0 && rand <= 0.244)
return ResourceLoader.getImage('data/ui/backgrounds/gold/${cast (Math.floor(Util.lerp(1, 12, Math.random())), Int)}.jpg');
if (rand > 0.244 && rand <= 0.816)
return ResourceLoader.getImage('data/ui/backgrounds/platinum/${cast (Math.floor(Util.lerp(1, 28, Math.random())), Int)}.jpg');
return ResourceLoader.getImage('data/ui/backgrounds/ultra/${cast (Math.floor(Util.lerp(1, 9, Math.random())), Int)}.jpg');
}
var img = chooseBg();
super(img.resource.toTile());
function loadButtonImages(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed];
}
var markerFelt32fontdata = ResourceLoader.getFileEntry("data/font/MarkerFelt.fnt");
var markerFelt32b = new BitmapFont(markerFelt32fontdata.entry);
@:privateAccess markerFelt32b.loader = ResourceLoader.loader;
var markerFelt48 = markerFelt32b.toSdfFont(cast 42 * Settings.uiScale, MultiChannel);
var markerFelt28 = markerFelt32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
this.horizSizing = Width;
this.vertSizing = Height;
this.position = new Vector(0, 0);
this.extent = new Vector(640, 480);
var container = new GuiControl();
container.horizSizing = Center;
container.vertSizing = Center;
container.position = new Vector(80, 60);
container.extent = new Vector(640, 480);
this.addChild(container);
var wnd = new GuiImage(ResourceLoader.getResource("data/ui/mp/window.png", ResourceLoader.getImage, this.imageResources).toTile());
wnd.position = new Vector(64, 91);
wnd.extent = new Vector(511, 297);
wnd.horizSizing = Center;
wnd.vertSizing = Center;
container.addChild(wnd);
var title = new GuiText(markerFelt48);
title.text.text = titleText;
title.text.textColor = 0xFFFFFF;
title.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
title.horizSizing = Center;
title.position = new Vector(47, 26);
title.extent = new Vector(416, 14);
title.justify = Center;
wnd.addChild(title);
var msg = new GuiText(markerFelt28);
msg.text.text = msgText;
msg.text.textColor = 0xFFFFFF;
msg.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
msg.horizSizing = Relative;
msg.vertSizing = Relative;
msg.position = new Vector(15, 136);
msg.extent = new Vector(483, 65);
msg.justify = Center;
wnd.addChild(msg);
var cancelBtn = new GuiButton(loadButtonImages('data/ui/mp/join/cancel'));
cancelBtn.position = new Vector(208, 210);
cancelBtn.extent = new Vector(94, 45);
cancelBtn.horizSizing = Center;
cancelBtn.vertSizing = Top;
cancelBtn.pressedAction = (e) -> {
Net.disconnect();
MarbleGame.canvas.setContent(new JoinServerGui());
}
wnd.addChild(cancelBtn);
setTexts = (t, m) -> {
title.text.text = t;
msg.text.text = m;
}
}
public dynamic function setTexts(titleText:String, msgText:String) {}
}

View file

@ -1,748 +0,0 @@
package gui;
import src.Marbleland;
import h2d.Scene;
import hxd.Key;
import gui.GuiControl.MouseState;
import h2d.Tile;
import hxd.BitmapData;
import h2d.filter.DropShadow;
import hxd.res.BitmapFont;
import src.MarbleGame;
import src.ResourceLoader;
import h3d.Vector;
import src.Util;
import src.Settings;
import src.Mission;
import src.MissionList;
import net.ClientConnection.NetPlatform;
import net.Net;
import net.NetCommands;
import haxe.ds.Option;
class MPPlayMissionGui extends GuiImage {
static var currentSelectionStatic:Int = -1;
static var currentCategoryStatic:String = "beginner";
public static var allChats:Array<String> = [];
static var setLevelFn:(String, Int) -> Void;
static var playSelectedLevel:(String, Int) -> Void;
static var setLevelStr:String->Void;
var currentSelection:Int = 0;
var currentCategory:String = "beginner";
var currentList:Array<Mission>;
var setSelectedFunc:Int->Void;
var setScoreHover:Bool->Void;
var setCategoryFunc:(String, ?String, ?Bool) -> Void;
var buttonHoldFunc:(dt:Float, mouseState:MouseState) -> Void;
var buttonCooldown:Float = 0.5;
var maxButtonCooldown:Float = 0.5;
#if js
var previewTimeoutHandle:Option<Int> = None;
#end
#if hl
var previewToken:Int = 0;
#end
var playerListCtrl:GuiMLTextListCtrl;
var chatInput:GuiTextInput;
var chatScroll:GuiScrollCtrl;
var chatBox:GuiMLText;
public function new(isHost:Bool = true) {
MissionList.buildMissionList();
function chooseBg() {
var rand = Math.random();
if (rand >= 0 && rand <= 0.244)
return ResourceLoader.getImage('data/ui/backgrounds/gold/${cast (Math.floor(Util.lerp(1, 12, Math.random())), Int)}.jpg');
if (rand > 0.244 && rand <= 0.816)
return ResourceLoader.getImage('data/ui/backgrounds/platinum/${cast (Math.floor(Util.lerp(1, 28, Math.random())), Int)}.jpg');
return ResourceLoader.getImage('data/ui/backgrounds/ultra/${cast (Math.floor(Util.lerp(1, 9, Math.random())), Int)}.jpg');
}
var img = chooseBg();
super(img.resource.toTile());
if (currentSelectionStatic == -1) {
currentSelectionStatic = 0;
}
// currentSelection = currentSelectionStatic;
// currentCategory = currentCategoryStatic;
MarbleGame.instance.toRecord = false;
function loadButtonImages(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed];
}
function loadButtonImagesExt(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
var disabled = ResourceLoader.getResource('${path}_i.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed, disabled];
}
var domcasual24fontdata = ResourceLoader.getFileEntry("data/font/DomCasualD.fnt");
var domcasual24b = new BitmapFont(domcasual24fontdata.entry);
@:privateAccess domcasual24b.loader = ResourceLoader.loader;
var domcasual24 = domcasual24b.toSdfFont(cast 20 * Settings.uiScale, MultiChannel);
var domcasual32 = domcasual24b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var arial14fontdata = ResourceLoader.getFileEntry("data/font/arial.fnt");
var arial14b = new BitmapFont(arial14fontdata.entry);
@:privateAccess arial14b.loader = ResourceLoader.loader;
var arial14 = arial14b.toSdfFont(cast 12 * Settings.uiScale, MultiChannel);
var arialb14fontdata = ResourceLoader.getFileEntry("data/font/Arial Bold.fnt");
var arialb14b = new BitmapFont(arialb14fontdata.entry);
@:privateAccess arialb14b.loader = ResourceLoader.loader;
var arialBold14 = arialb14b.toSdfFont(cast 12 * Settings.uiScale, MultiChannel);
var markerFelt32fontdata = ResourceLoader.getFileEntry("data/font/MarkerFelt.fnt");
var markerFelt32b = new BitmapFont(markerFelt32fontdata.entry);
@:privateAccess markerFelt32b.loader = ResourceLoader.loader;
var markerFelt32 = markerFelt32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var markerFelt24 = markerFelt32b.toSdfFont(cast 20 * Settings.uiScale, MultiChannel);
var markerFelt20 = markerFelt32b.toSdfFont(cast 18.5 * Settings.uiScale, MultiChannel);
var markerFelt18 = markerFelt32b.toSdfFont(cast 17 * Settings.uiScale, MultiChannel);
var markerFelt26 = markerFelt32b.toSdfFont(cast 22 * Settings.uiScale, MultiChannel);
function mlFontLoader(text:String) {
switch (text) {
case "DomCasual24":
return domcasual24;
case "Arial14":
return arial14;
case "ArialBold14":
return arialBold14;
case "MarkerFelt32":
return markerFelt32;
case "MarkerFelt24":
return markerFelt24;
case "MarkerFelt18":
return markerFelt18;
case "MarkerFelt20":
return markerFelt20;
case "MarkerFelt26":
return markerFelt26;
default:
return null;
}
}
this.horizSizing = Width;
this.vertSizing = Height;
this.position = new Vector();
this.extent = new Vector(640, 480);
var window = new GuiImage(ResourceLoader.getResource("data/ui/mp/play/window.png", ResourceLoader.getImage, this.imageResources).toTile());
window.horizSizing = Center;
window.vertSizing = Center;
window.position = new Vector(-60, 5);
window.extent = new Vector(800, 600);
var leaveBtn = new GuiButton(loadButtonImages("data/ui/mp/play/leave"));
leaveBtn.position = new Vector(59, 514);
leaveBtn.extent = new Vector(93, 44);
leaveBtn.pressedAction = (e) -> {
Net.disconnect();
MarbleGame.canvas.setContent(new JoinServerGui());
}
window.addChild(leaveBtn);
var searchBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/play/search"));
searchBtn.position = new Vector(255, 514);
searchBtn.extent = new Vector(44, 44);
searchBtn.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(new MPSearchGui(currentCategory == "custom"));
}
window.addChild(searchBtn);
if (Net.isClient)
searchBtn.disabled = true;
var kickBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/play/kick"));
kickBtn.position = new Vector(304, 514);
kickBtn.extent = new Vector(44, 44);
kickBtn.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(new MPKickBanDlg());
}
window.addChild(kickBtn);
if (Net.isClient)
kickBtn.disabled = true;
var serverSettingsBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/play/settings"));
serverSettingsBtn.position = new Vector(157, 514);
serverSettingsBtn.extent = new Vector(44, 44);
serverSettingsBtn.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(new MPServerDlg());
}
window.addChild(serverSettingsBtn);
if (Net.isClient)
serverSettingsBtn.disabled = true;
var marbleSelectBtn = new GuiButton(loadButtonImages("data/ui/mp/play/marble"));
marbleSelectBtn.position = new Vector(206, 514);
marbleSelectBtn.extent = new Vector(44, 44);
marbleSelectBtn.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(new MPMarbleSelectGui());
}
window.addChild(marbleSelectBtn);
var temprev = new BitmapData(1, 1);
temprev.setPixel(0, 0, 0);
var tmpprevtile = Tile.fromBitmap(temprev);
var pmPreview = new GuiImage(tmpprevtile);
pmPreview.position = new Vector(485, 44);
pmPreview.extent = new Vector(248, 187);
window.addChild(pmPreview);
var difficultyPopover = new GuiControl();
difficultyPopover.horizSizing = Width;
difficultyPopover.vertSizing = Height;
difficultyPopover.position = new Vector();
difficultyPopover.extent = new Vector(640, 480);
var difficultyPopoverInner = new GuiImage(tmpprevtile);
difficultyPopoverInner.horizSizing = Center;
difficultyPopoverInner.vertSizing = Center;
difficultyPopoverInner.position = new Vector();
difficultyPopoverInner.extent = new Vector(800, 600);
difficultyPopoverInner.pressedAction = (e) -> {
MarbleGame.canvas.popDialog(difficultyPopover, false);
}
difficultyPopover.addChild(difficultyPopoverInner);
var difficultySelector = new GuiButton(loadButtonImagesExt("data/ui/mp/play/difficulty_beginner"));
difficultySelector.position = new Vector(161, 47);
difficultySelector.extent = new Vector(204, 44);
if (isHost)
difficultySelector.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(difficultyPopover);
};
else
difficultySelector.disabled = true;
window.addChild(difficultySelector);
var difficultyCloseButton = new GuiButton(loadButtonImages("data/ui/mp/play/difficultymenu"));
difficultyCloseButton.position = new Vector(129, 61);
difficultyCloseButton.extent = new Vector(268, 193);
difficultyPopoverInner.addChild(difficultyCloseButton);
var catFuncBuilder = (cat:String) -> {
return () -> {
currentList = MissionList.missionList["multiplayer"][cat];
currentCategory = cat;
setCategoryFunc(cat);
}
}
var beginnerFn = catFuncBuilder("beginner");
var intermediateFn = catFuncBuilder("intermediate");
var advancedFn = catFuncBuilder("advanced");
var customFn = catFuncBuilder("custom");
var difficulty0 = new GuiButtonText(loadButtonImages("data/ui/mp/play/difficultysel"), markerFelt24);
difficulty0.position = new Vector(43, 42);
difficulty0.ratio = -1 / 16;
difficulty0.setExtent(new Vector(180, 31));
difficulty0.txtCtrl.text.text = "Intermediate";
difficulty0.pressedAction = (e) -> {
intermediateFn();
}
difficultyCloseButton.addChild(difficulty0);
var difficulty1 = new GuiButtonText(loadButtonImages("data/ui/mp/play/difficultysel"), markerFelt24);
difficulty1.position = new Vector(43, 72);
difficulty1.ratio = -1 / 16;
difficulty1.setExtent(new Vector(180, 31));
difficulty1.txtCtrl.text.text = "Advanced";
difficulty1.pressedAction = (e) -> {
advancedFn();
}
difficultyCloseButton.addChild(difficulty1);
var difficulty2 = new GuiButtonText(loadButtonImages("data/ui/mp/play/difficultysel"), markerFelt24);
difficulty2.position = new Vector(43, 116);
difficulty2.ratio = -1 / 16;
difficulty2.setExtent(new Vector(180, 31));
difficulty2.txtCtrl.text.text = "Custom";
difficulty2.pressedAction = (e) -> {
customFn();
}
difficultyCloseButton.addChild(difficulty2);
var pmPreviewFrame = new GuiImage(ResourceLoader.getResource('data/ui/mp/play/levelframe.png', ResourceLoader.getImage, this.imageResources).toTile());
pmPreviewFrame.position = new Vector(0, 0);
pmPreviewFrame.extent = new Vector(248, 187);
pmPreview.addChild(pmPreviewFrame);
var prevBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/play/prev"));
prevBtn.position = new Vector(491, 514);
prevBtn.extent = new Vector(73, 44);
prevBtn.gamepadAccelerator = ["dpadLeft"];
prevBtn.pressedAction = (sender) -> {
NetCommands.setLobbyLevelIndex(currentCategory, currentSelection - 1);
}
if (isHost)
window.addChild(prevBtn);
var nextBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/play/next"));
nextBtn.position = new Vector(659, 514);
nextBtn.extent = new Vector(73, 44);
nextBtn.gamepadAccelerator = ["dpadRight"];
nextBtn.pressedAction = (sender) -> {
NetCommands.setLobbyLevelIndex(currentCategory, currentSelection + 1);
}
if (isHost)
window.addChild(nextBtn);
var playBtn = new GuiButton(loadButtonImages("data/ui/mp/play/play"));
playBtn.position = new Vector(565, 514);
playBtn.extent = new Vector(93, 44);
playBtn.pressedAction = (sender) -> {
NetCommands.toggleReadiness(Net.isClient ? Net.clientId : 0);
// MarbleGame.instance.playMission(currentList[currentSelection], true);
}
window.addChild(playBtn);
var pmDescContainer = new GuiControl();
pmDescContainer.position = new Vector(43, 99);
pmDescContainer.extent = new Vector(427, 99);
window.addChild(pmDescContainer);
var pmDesc = new GuiMLText(markerFelt18, mlFontLoader);
pmDesc.position = new Vector(0, 0);
pmDesc.extent = new Vector(427, 99);
pmDesc.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
pmDesc.text.lineSpacing = -1;
pmDescContainer.addChild(pmDesc);
var parTime = new GuiMLText(markerFelt18, mlFontLoader);
parTime.position = new Vector(43, 190);
parTime.extent = new Vector(416, 44);
parTime.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
parTime.text.lineSpacing = -1;
window.addChild(parTime);
function imgLoader(path:String) {
var t = switch (path) {
case "ready":
ResourceLoader.getResource("data/ui/mp/play/Ready.png", ResourceLoader.getImage, this.imageResources).toTile();
case "notready":
ResourceLoader.getResource("data/ui/mp/play/NotReady.png", ResourceLoader.getImage, this.imageResources).toTile();
case "pc":
ResourceLoader.getResource("data/ui/mp/play/platform_desktop_white.png", ResourceLoader.getImage, this.imageResources).toTile();
case "mac":
ResourceLoader.getResource("data/ui/mp/play/platform_mac_white.png", ResourceLoader.getImage, this.imageResources).toTile();
case "web":
ResourceLoader.getResource("data/ui/mp/play/platform_web_white.png", ResourceLoader.getImage, this.imageResources).toTile();
case "android":
ResourceLoader.getResource("data/ui/mp/play/platform_android_white.png", ResourceLoader.getImage, this.imageResources).toTile();
case "unknown":
ResourceLoader.getResource("data/ui/mp/play/platform_unknown_white.png", ResourceLoader.getImage, this.imageResources).toTile();
case _:
return null;
};
if (t != null)
t.scaleToSize(t.width * (Settings.uiScale), t.height * (Settings.uiScale));
return t;
}
var playersBox = new GuiControl();
playersBox.position = new Vector(463, 279);
playersBox.extent = new Vector(305, 229);
window.addChild(playersBox);
playerListCtrl = new GuiMLTextListCtrl(markerFelt18, [], imgLoader);
playerListCtrl.position = new Vector(0, 26);
playerListCtrl.extent = new Vector(305, 203);
playerListCtrl.scrollable = true;
playerListCtrl.textYOffset = -6;
playersBox.addChild(playerListCtrl);
var playerListTitle = new GuiText(markerFelt24);
playerListTitle.position = new Vector(7, 0);
playerListTitle.extent = new Vector(275, 22);
playerListTitle.text.text = "Players";
playerListTitle.text.textColor = 0xBDCFE4;
playerListTitle.justify = Center;
playerListTitle.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
playersBox.addChild(playerListTitle);
chatScroll = new GuiScrollCtrl(ResourceLoader.getResource("data/ui/common/philscroll.png", ResourceLoader.getImage, this.imageResources).toTile());
chatScroll.position = new Vector(47, 282);
chatScroll.extent = new Vector(407, 193);
chatScroll.childrenHandleScroll = true;
chatScroll.scrollToBottom = true;
window.addChild(chatScroll);
chatBox = new GuiMLText(markerFelt18, mlFontLoader);
chatBox.text.textColor = 0x000000;
chatBox.horizSizing = Width;
chatBox.position = new Vector(0, 0);
chatBox.extent = new Vector(396, 1184);
chatScroll.addChild(chatBox);
var chatInputContainer = new GuiControl();
chatInputContainer.position = new Vector(50, 476);
chatInputContainer.extent = new Vector(402, 30);
window.addChild(chatInputContainer);
chatInput = new GuiTextInput(markerFelt18);
chatInput.text.textColor = 0x000000;
chatInput.horizSizing = Width;
chatInput.position = new Vector(50, 0);
chatInput.extent = new Vector(352, 30);
chatInputContainer.addChild(chatInput);
@:privateAccess chatInput.text.interactive.forceAnywherefocus = true;
var chatInputFocusTxt = new GuiText(markerFelt18);
chatInputFocusTxt.position = new Vector(0, 0);
chatInputFocusTxt.extent = new Vector(50, 30);
chatInputFocusTxt.text.text = "Chat:";
chatInputFocusTxt.text.textColor = 0x000000;
chatInputFocusTxt.justify = Center;
chatInputContainer.addChild(chatInputFocusTxt);
chatInput.text.onKeyDown = (e) -> {
if (e.keyCode == Key.ENTER) {
if (StringTools.trim(chatInput.text.text) != "") {
var sendText = '<font color="#F29515">${StringTools.htmlEscape(Settings.highscoreName.substr(0, 20))}:</font> ${StringTools.htmlEscape(chatInput.text.text.substr(0, 100))}';
if (Net.isClient) {
NetCommands.sendChatMessage(StringTools.htmlEscape(sendText));
}
if (Net.isHost) {
NetCommands.sendServerChatMessage(StringTools.htmlEscape(sendText));
}
}
chatInput.text.text = "";
haxe.Timer.delay(() -> chatInput.text.focus(), 10);
}
@:privateAccess Key.keyPressed[e.keyCode] = 0; // consume keys
}
this.addChild(window);
buttonHoldFunc = (dt:Float, mouseState:MouseState) -> {
var prevBox = prevBtn.getRenderRectangle();
var nextBox = nextBtn.getRenderRectangle();
if (prevBox.inRect(mouseState.position) && mouseState.button == Key.MOUSE_LEFT) {
if (buttonCooldown <= 0) {
prevBtn.pressedAction(new GuiEvent(prevBtn));
buttonCooldown = maxButtonCooldown;
maxButtonCooldown *= 0.75;
}
}
if (nextBox.inRect(mouseState.position) && mouseState.button == Key.MOUSE_LEFT) {
if (buttonCooldown <= 0) {
nextBtn.pressedAction(new GuiEvent(nextBtn));
buttonCooldown = maxButtonCooldown;
maxButtonCooldown *= 0.75;
}
}
if (buttonCooldown > 0 && mouseState.button == Key.MOUSE_LEFT)
buttonCooldown -= dt;
if (mouseState.button != Key.MOUSE_LEFT) {
maxButtonCooldown = 0.5;
buttonCooldown = maxButtonCooldown;
}
}
setCategoryFunc = function(category:String, ?sort:String = null, ?doRender:Bool = true) {
if (category == "custom") {
currentList = Marbleland.multiplayerMissions;
} else
currentList = MissionList.missionList["multiplayer"][category];
@:privateAccess difficultySelector.anim.frames = loadButtonImagesExt('data/ui/mp/play/difficulty_${category}');
if (category == "beginner") {
difficulty0.txtCtrl.text.text = "Intermediate";
difficulty1.txtCtrl.text.text = "Advanced";
difficulty2.txtCtrl.text.text = "Custom";
difficulty0.pressedAction = (e) -> {
intermediateFn();
}
difficulty1.pressedAction = (e) -> {
advancedFn();
}
difficulty2.pressedAction = (e) -> {
customFn();
}
}
if (category == "intermediate") {
difficulty0.txtCtrl.text.text = "Beginner";
difficulty1.txtCtrl.text.text = "Advanced";
difficulty2.txtCtrl.text.text = "Custom";
difficulty0.pressedAction = (e) -> {
beginnerFn();
}
difficulty1.pressedAction = (e) -> {
advancedFn();
}
difficulty2.pressedAction = (e) -> {
customFn();
}
}
if (category == "custom") {
difficulty0.txtCtrl.text.text = "Beginner";
difficulty1.txtCtrl.text.text = "Intermediate";
difficulty2.txtCtrl.text.text = "Advanced";
difficulty0.pressedAction = (e) -> {
beginnerFn();
}
difficulty1.pressedAction = (e) -> {
intermediateFn();
}
difficulty2.pressedAction = (e) -> {
advancedFn();
}
}
if (sort != null) {
currentList = currentList.copy(); // Don't modify the originals
if (sort == "alpha") {
currentList.sort((x, y) -> x.title > y.title ? 1 : (x.title < y.title ? -1 : 0));
}
if (sort == "date") {
currentList.sort((x, y) -> x.addedAt > y.addedAt ? 1 : (x.addedAt < y.addedAt ? -1 : 0));
}
}
currentCategoryStatic = currentCategory;
NetCommands.setLobbyLevelIndex(category, 0);
// if (doRender)
// this.render(cast(this.parent, Canvas).scene2d);
}
setSelectedFunc = function setSelected(index:Int) {
if (index > currentList.length - 1) {
index = currentList.length - 1;
}
if (index < 0) {
index = 0;
}
currentSelection = index;
currentSelectionStatic = currentSelection;
var currentMission = currentList[currentSelection];
if (index == 0) {
prevBtn.disabled = true;
} else
prevBtn.disabled = false;
if (index == Math.max(currentList.length - 1, 0)) {
nextBtn.disabled = true;
} else
nextBtn.disabled = false;
// if (currentCategory != "custom"
// && Settings.progression[["beginner", "intermediate", "advanced", "expert"].indexOf(currentCategory)] < currentSelection) {
// noQualText.text.visible = true;
// filt.matrix.identity();
// filt.matrix.colorGain(0, 96 / 255);
// pmPlay.disabled = true;
// } else {
playBtn.disabled = false;
// }
if (currentMission == null) {
currentMission = new Mission();
currentMission.title = "";
currentMission.description = "";
currentMission.path = "bruh";
currentSelection = -1;
}
pmDesc.text.text = '<font face="MarkerFelt32" color="#E3F3FF"><p align="center">#${currentSelection + 1}: ${StringTools.htmlEscape(currentMission.title)}</p></font>'
+ '<font face="MarkerFelt18" color="#CEE0F4">${StringTools.htmlEscape(currentMission.description)}</font>';
parTime.text.text = '<font face="MarkerFelt24" color="#E3F3FF">Duration: <font color="#FFFFFF">${Util.formatTime(currentMission.qualifyTime)}</font></font><br/>'
+ '<font face="MarkerFelt24" color="#E3F3FF">Author: <font color="#FFFFFF">${StringTools.htmlEscape(currentMission.artist)}</font></font>';
// pmPreview.bmp.tile = tmpprevtile;
#if js
switch (previewTimeoutHandle) {
case None:
previewTimeoutHandle = Some(js.Browser.window.setTimeout(() -> {
var prevpath = currentMission.getPreviewImage(prevImg -> {
pmPreview.bmp.tile = prevImg;
});
if (prevpath != pmPreview.bmp.tile.getTexture().name) {
pmPreview.bmp.tile = tmpprevtile;
}
}, 75));
case Some(previewTimeoutHandle_id):
js.Browser.window.clearTimeout(previewTimeoutHandle_id);
previewTimeoutHandle = Some(js.Browser.window.setTimeout(() -> {
var prevpath = currentMission.getPreviewImage(prevImg -> {
pmPreview.bmp.tile = prevImg;
});
if (prevpath != pmPreview.bmp.tile.getTexture().name) {
pmPreview.bmp.tile = tmpprevtile;
}
}, 75));
}
#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) {
pmPreview.bmp.tile = tmpprevtile;
}
#end
}
playSelectedLevel = (cat:String, index:Int) -> {
// if (custSelected) {
// NetCommands.playCustomLevel(MPCustoms.missionList[custSelectedIdx].path);
// } else {
if (cat == "custom") {
var curMission = Marbleland.multiplayerMissions[index]; // mission[index];
MarbleGame.instance.playMission(curMission, true);
} else {
var curMission = MissionList.missionList["multiplayer"][cat][index]; // mission[index];
MarbleGame.instance.playMission(curMission, true);
}
// }
}
setLevelFn = (cat:String, index:Int) -> {
if (currentCategory != cat) {
currentCategory = cat;
setCategoryFunc(cat);
}
setSelectedFunc(index);
}
currentList = MissionList.missionList["multiplayer"]["beginner"];
// setCategoryFunc(currentCategoryStatic, null, false);
if (Net.isHost) {
NetCommands.setLobbyLevelIndex(currentCategoryStatic, currentSelectionStatic);
} else {
setCategoryFunc(currentCategoryStatic, null, false);
}
updateLobbyNames();
redrawChat();
haxe.Timer.delay(() -> {
this.chatScroll.updateScrollVisual();
}, 50);
}
public override function render(scene2d:Scene, ?parent:h2d.Flow) {
super.render(scene2d, parent);
setSelectedFunc(currentSelectionStatic);
}
public override function update(dt:Float, mouseState:MouseState) {
super.update(dt, mouseState);
buttonHoldFunc(dt, mouseState);
if (Key.isPressed(Key.LEFT))
setSelectedFunc(currentSelection - 1);
if (Key.isPressed(Key.RIGHT))
setSelectedFunc(currentSelection + 1);
}
inline function platformToString(platform:NetPlatform) {
return switch (platform) {
case Unknown: return "unknown";
case Android: return "android";
case MacOS: return "mac";
case PC: return "pc";
case Web: return "web";
}
}
public function updateLobbyNames() {
var playerListArr = [];
if (Net.isHost) {
playerListArr.push({
name: Settings.highscoreName,
platform: Net.getPlatform(),
ready: Net.lobbyHostReady
});
}
if (Net.isClient) {
playerListArr.push({
name: Settings.highscoreName,
platform: Net.getPlatform(),
ready: Net.lobbyClientReady
});
}
if (Net.clientIdMap != null) {
for (c => v in Net.clientIdMap) {
playerListArr.push({
name: v.name,
platform: v.platform,
ready: v.lobbyReady
});
}
}
var playerListCompiled = playerListArr.map(player ->
'<img src="${platformToString(player.platform)}"></img><font color="#FFFFFF">${StringTools.htmlEscape(player.name)}<offset value="${220 * Settings.uiScale}">${player.ready ? "Ready" : ""}</offset></font>');
playerListCtrl.setTexts(playerListCompiled);
// if (!showingCustoms)
// playerList.setTexts(playerListArr.map(player -> {
// return '<img src="${player.state ? "ready" : "notready"}"></img><img src="${platformToString(player.platform)}"></img>${player.name}';
// }));
}
public static function addChatMessage(s:String) {
var realText = StringTools.htmlEscape(s);
allChats.push(realText);
if (allChats.length > 100) {
allChats = allChats.slice(allChats.length - 100);
}
if (MarbleGame.canvas.content is MPPlayMissionGui) {
var mpp = cast(MarbleGame.canvas.content, MPPlayMissionGui);
mpp.redrawChat();
}
}
public function redrawChat() {
var joined = allChats.join("<br/>");
this.chatBox.text.text = StringTools.replace(joined, '#F29515', '#000000');
this.chatScroll.setScrollMax(chatBox.text.textHeight);
this.chatScroll.updateScrollVisual();
}
}

View file

@ -1,329 +0,0 @@
package gui;
import net.NetCommands;
import h2d.filter.DropShadow;
import net.Net;
import src.MarbleGame;
import hxd.res.BitmapFont;
import h3d.Vector;
import src.ResourceLoader;
import src.Settings;
import src.Console;
import net.MasterServerClient;
class MPPreGameDlg extends GuiControl {
public function new() {
super();
this.horizSizing = Width;
this.vertSizing = Height;
this.position = new Vector();
this.extent = new Vector(640, 480);
function loadButtonImages(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed];
}
function loadButtonImagesExt(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
var disabled = ResourceLoader.getResource('${path}_i.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed, disabled];
}
var markerFelt32fontdata = ResourceLoader.getFileEntry("data/font/MarkerFelt.fnt");
var markerFelt32b = new BitmapFont(markerFelt32fontdata.entry);
@:privateAccess markerFelt32b.loader = ResourceLoader.loader;
var markerFelt32 = markerFelt32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var markerFelt24 = markerFelt32b.toSdfFont(cast 20 * Settings.uiScale, MultiChannel);
var markerFelt20 = markerFelt32b.toSdfFont(cast 18.5 * Settings.uiScale, MultiChannel);
var markerFelt18 = markerFelt32b.toSdfFont(cast 17 * Settings.uiScale, MultiChannel);
var markerFelt26 = markerFelt32b.toSdfFont(cast 22 * Settings.uiScale, MultiChannel);
var dialogImg = new GuiImage(ResourceLoader.getResource("data/ui/mp/pre/window.png", ResourceLoader.getImage, this.imageResources).toTile());
dialogImg.horizSizing = Center;
dialogImg.vertSizing = Center;
dialogImg.position = new Vector(0, 0);
dialogImg.extent = new Vector(640, 480);
this.addChild(dialogImg);
var leaveBtn = new GuiButton(loadButtonImages("data/ui/mp/pre/leave"));
leaveBtn.horizSizing = Left;
leaveBtn.vertSizing = Top;
leaveBtn.position = new Vector(499, 388);
leaveBtn.extent = new Vector(94, 45);
leaveBtn.pressedAction = (e) -> {
MarbleGame.instance.quitMission(true);
if (Net.isMP && Net.isClient) {
Net.disconnect();
MarbleGame.canvas.setContent(new JoinServerGui());
}
}
dialogImg.addChild(leaveBtn);
var playBtn = new GuiButton(loadButtonImagesExt("data/ui/mp/pre/play"));
playBtn.horizSizing = Right;
playBtn.vertSizing = Top;
playBtn.position = new Vector(406, 388);
playBtn.extent = new Vector(94, 45);
playBtn.buttonType = Toggle;
playBtn.disabled = true;
playBtn.pressedAction = (e) -> {
for (id => client in Net.clientIdMap) {
client.state = GAME;
}
if (Settings.serverSettings.forceSpectators) {
for (id => client in Net.clientIdMap) {
client.spectator = true; // Make them spectator
}
}
var b = Net.sendPlayerInfosBytes(); // Update spectator status
for (cc in Net.clients) {
cc.sendBytes(b);
}
if (MarbleGame.instance.world != null) {
Console.log('All are ready, starting');
MarbleGame.instance.world.allClientsReady();
}
Net.serverInfo.state = "PLAYING";
MasterServerClient.instance.sendServerInfo(Net.serverInfo); // notify the server of the playing state
}
if (Net.isHost)
dialogImg.addChild(playBtn);
var readyBtn = new GuiButton(loadButtonImages("data/ui/mp/pre/ready"));
readyBtn.horizSizing = Right;
readyBtn.vertSizing = Top;
readyBtn.position = new Vector(53, 394);
readyBtn.extent = new Vector(133, 33);
readyBtn.buttonType = Toggle;
dialogImg.addChild(readyBtn);
var kickBtn = new GuiButton(loadButtonImages("data/ui/mp/play/kick"));
kickBtn.horizSizing = Right;
kickBtn.vertSizing = Bottom;
kickBtn.position = new Vector(360, 388);
kickBtn.extent = new Vector(45, 45);
kickBtn.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(new MPKickBanDlg());
}
if (Net.isHost)
dialogImg.addChild(kickBtn);
var spectateBtn = new GuiButton(loadButtonImages("data/ui/mp/pre/spectate"));
spectateBtn.horizSizing = Right;
spectateBtn.vertSizing = Top;
spectateBtn.position = new Vector(190, 394);
spectateBtn.extent = new Vector(127, 33);
spectateBtn.buttonType = Toggle;
spectateBtn.pressedAction = (e) -> {
NetCommands.toggleSpectate(Net.isHost ? 0 : Net.clientId);
updatePlayerList();
}
dialogImg.addChild(spectateBtn);
var serverTitle = new GuiText(markerFelt24);
serverTitle.text.textColor = 0xFFFFFF;
serverTitle.position = new Vector(60, 59);
serverTitle.extent = new Vector(525, 30);
serverTitle.text.text = Net.isHost ? Settings.serverSettings.name : Net.connectedServerInfo.name;
serverTitle.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
serverTitle.justify = Center;
dialogImg.addChild(serverTitle);
var serverDesc = new GuiText(markerFelt24);
serverDesc.text.textColor = 0xFFFFFF;
serverDesc.position = new Vector(60, 92);
serverDesc.extent = new Vector(525, 66);
serverDesc.text.text = Net.isHost ? Settings.serverSettings.description : Net.connectedServerInfo.description;
serverDesc.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
serverDesc.justify = Center;
dialogImg.addChild(serverDesc);
var levelName = new GuiText(markerFelt24);
levelName.text.textColor = 0xFFFFFF;
levelName.position = new Vector(60, 158);
levelName.extent = new Vector(525, 22);
levelName.text.text = MarbleGame.instance.world.mission.title;
levelName.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
dialogImg.addChild(levelName);
var levelDesc = new GuiMLText(markerFelt18, null);
levelDesc.text.textColor = 0xFFFFFF;
levelDesc.position = new Vector(60, 185);
levelDesc.extent = new Vector(516, 63);
levelDesc.text.text = StringTools.htmlEscape(MarbleGame.instance.world.mission.description);
levelDesc.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
dialogImg.addChild(levelDesc);
var playerTitle = new GuiText(markerFelt18);
playerTitle.text.textColor = 0xDDDDEE;
playerTitle.position = new Vector(60, 263);
playerTitle.extent = new Vector(525, 14);
playerTitle.text.text = "Player Status";
playerTitle.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
dialogImg.addChild(playerTitle);
var playerListContainer = new GuiScrollCtrl(ResourceLoader.getResource("data/ui/common/philscroll.png", ResourceLoader.getImage, this.imageResources)
.toTile());
playerListContainer.position = new Vector(57, 286);
playerListContainer.extent = new Vector(525, 99);
playerListContainer.childrenHandleScroll = true;
// playerList.maxScrollY = 394 * Settings.uiScale;
dialogImg.addChild(playerListContainer);
var playerListLeft = new GuiTextListCtrl(markerFelt18, [], 0xFFFFFF, {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
color: 0,
alpha: 1
});
playerListLeft.selectedColor = 0xFFFFFF;
playerListLeft.selectedFillColor = 0x6092E5;
playerListLeft.selectedFillColorAlpha = 0.0;
playerListLeft.horizSizing = Width;
playerListLeft.position = new Vector(-1, -1);
playerListLeft.extent = new Vector(525, 2880);
playerListLeft.scrollable = true;
playerListLeft.textYOffset = -6;
playerListContainer.addChild(playerListLeft);
var playerListRight = new GuiTextListCtrl(markerFelt18, [], 0xFFFFFF, {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
color: 0,
alpha: 1
});
playerListRight.selectedColor = 0xFFFFFF;
playerListRight.selectedFillColor = 0x6092E5;
playerListRight.selectedFillColorAlpha = 0.0;
playerListRight.horizSizing = Width;
playerListRight.position = new Vector(420, -1);
playerListRight.extent = new Vector(300, 2880);
playerListRight.scrollable = true;
playerListRight.textYOffset = -6;
playerListContainer.addChild(playerListRight);
playerListContainer.setScrollMax(playerListLeft.calculateFullHeight());
this.updatePlayerList = () -> {
var allReady = true;
var playerListArr = [];
if (Net.isHost) {
playerListArr.push({
name: Settings.highscoreName,
ready: Net.lobbyHostReady,
spectate: Net.hostSpectate
});
spectateBtn.anim.currentFrame = Net.hostSpectate ? 2 : 0;
readyBtn.anim.currentFrame = Net.lobbyHostReady ? 2 : 0;
}
if (Net.isClient) {
playerListArr.push({
name: Settings.highscoreName,
ready: Net.lobbyClientReady,
spectate: Net.clientSpectate
});
spectateBtn.anim.currentFrame = Net.clientSpectate ? 2 : 0;
readyBtn.anim.currentFrame = Net.lobbyClientReady ? 2 : 0;
spectateBtn.pressed = Net.clientSpectate;
readyBtn.pressed = Net.lobbyClientReady;
}
if (Net.clientIdMap != null) {
for (c => v in Net.clientIdMap) {
playerListArr.push({
name: v.name,
ready: v.lobbyReady,
spectate: v.spectator
});
}
}
for (p in playerListArr) {
if (!p.ready) {
allReady = false;
break;
}
}
playBtn.disabled = !allReady;
if (playerListArr.length > 1) {
spectateBtn.anim.visible = true;
spectateBtn.disabled = false;
} else {
spectateBtn.anim.visible = false;
spectateBtn.disabled = true;
}
var playerListCompiled = playerListArr.map(player -> player.spectate ? '[S] ${player.name}' : player.name);
var playerListStateCompiled = playerListArr.map(player -> player.ready ? "[Ready]" : "[Waiting]");
playerListLeft.setTexts(playerListCompiled);
playerListRight.setTexts(playerListStateCompiled);
playerListContainer.setScrollMax(playerListLeft.calculateFullHeight());
if (playerListArr.length == 1) {
// Disable spectating
Net.hostSpectate = false;
Net.clientSpectate = false;
}
// if (!showingCustoms)
// playerList.setTexts(playerListArr.map(player -> {
// return '<img src="${player.state ? "ready" : "notready"}"></img><img src="${platformToString(player.platform)}"></img>${player.name}';
// }));
}
readyBtn.pressedAction = (e) -> {
NetCommands.toggleReadiness(Net.isHost ? 0 : Net.clientId);
updatePlayerList();
}
// Make everyone un-lobby ready (again!)
for (c in Net.clients) {
c.lobbyReady = false;
c.spectator = false;
}
Net.hostSpectate = false;
Net.lobbyClientReady = false;
Net.lobbyHostReady = false;
if (Net.isHost) {
var b = Net.sendPlayerInfosBytes();
for (cc in Net.clients) {
cc.sendBytes(b);
}
}
updatePlayerList();
}
public dynamic function updatePlayerList() {}
}

View file

@ -1,282 +0,0 @@
package gui;
import net.NetCommands;
import src.Marbleland;
import h2d.Tile;
import hxd.BitmapData;
import src.MarbleGame;
import hxd.res.BitmapFont;
import h3d.Vector;
import src.ResourceLoader;
import src.Settings;
import src.MissionList;
class MPSearchGui extends GuiImage {
public function new(isCustom:Bool) {
var img = ResourceLoader.getImage("data/ui/mp/search/window.png");
super(img.resource.toTile());
this.horizSizing = Center;
this.vertSizing = Center;
this.position = new Vector(76, 8);
this.extent = new Vector(487, 463);
var missionList = [];
if (!isCustom) {
for (diffName => diff in MissionList.missionList["multiplayer"]) {
for (mis in diff) {
missionList.push({
mis: mis,
name: mis.title,
artist: mis.artist,
path: mis.path,
difficulty: diffName,
});
}
}
} else {
var customsList = Marbleland.multiplayerMissions;
for (mis in customsList) {
missionList.push({
mis: mis,
name: mis.title,
artist: mis.artist,
path: mis.path,
difficulty: "custom"
});
}
}
var displayList = missionList.map(x -> x.name);
displayList.sort((x, y) -> (x > y) ? 1 : (x == y ? 0 : -1));
missionList.sort((x, y) -> x.name > y.name ? 1 : (x.name == y.name ? 0 : -1));
var retrieveMissionList = missionList;
var searchMissionList:GuiTextListCtrl = null;
var scrollCtrl:GuiScrollCtrl = null;
var currentSortBy = "title";
function sortBy(type:String, txt:String = "") {
if (type == "title") {
retrieveMissionList = missionList.filter(x -> StringTools.contains(x.name.toLowerCase(), txt.toLowerCase()));
displayList = retrieveMissionList.map(x -> x.name);
displayList.sort((x, y) -> (x > y) ? 1 : (x == y ? 0 : -1));
retrieveMissionList.sort((x, y) -> x.name > y.name ? 1 : (x.name == y.name ? 0 : -1));
}
if (type == "artist") {
retrieveMissionList = missionList.filter(x -> StringTools.contains(x.artist.toLowerCase(), txt.toLowerCase()));
retrieveMissionList.sort((x, y) -> x.artist > y.artist ? 1 : (x.artist == y.artist ? 0 : -1));
displayList = retrieveMissionList.map(x -> '${x.name} By ${x.artist}');
}
if (type == "file") {
retrieveMissionList = missionList.filter(x -> StringTools.contains(x.path.toLowerCase(), txt.toLowerCase()));
retrieveMissionList.sort((x, y) -> x.path > y.path ? 1 : (x.path == y.path ? 0 : -1));
var idxofslash = 0;
displayList = retrieveMissionList.map(x -> {
var idxofslash = 0;
var slashcount = 0;
for (i in 0...x.path.length) {
if (x.path.charCodeAt(x.path.length - i - 1) == '/'.code) {
slashcount++;
if (slashcount == 2) {
idxofslash = x.path.length - i - 1;
break;
}
}
}
return '${x.path.substr(idxofslash + 1)}';
});
}
searchMissionList.setTexts(displayList);
scrollCtrl.setScrollMax(searchMissionList.calculateFullHeight());
}
function loadButtonImages(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
var disabledObj = ResourceLoader.getResource('${path}_i.png', ResourceLoader.getImage, this.imageResources);
var disabled = disabledObj != null ? disabledObj.toTile() : null;
return [normal, hover, pressed, disabled];
}
var markerFelt32fontdata = ResourceLoader.getFileEntry("data/font/MarkerFelt.fnt");
var markerFelt32b = new BitmapFont(markerFelt32fontdata.entry);
@:privateAccess markerFelt32b.loader = ResourceLoader.loader;
var markerFelt32 = markerFelt32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var markerFelt24 = markerFelt32b.toSdfFont(cast 18 * Settings.uiScale, MultiChannel);
var markerFelt18 = markerFelt32b.toSdfFont(cast 14 * Settings.uiScale, MultiChannel);
var domcasual32fontdata = ResourceLoader.getFileEntry("data/font/DomCasualD.fnt");
var domcasual32b = new BitmapFont(domcasual32fontdata.entry);
@:privateAccess domcasual32b.loader = ResourceLoader.loader;
var domcasual32 = domcasual32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var domcasual64 = domcasual32b.toSdfFont(cast 58 * Settings.uiScale, MultiChannel);
var domcasual24 = domcasual32b.toSdfFont(cast 20 * Settings.uiScale, MultiChannel);
var searchCancel = new GuiButton(loadButtonImages("data/ui/mp/search/cancel"));
searchCancel.vertSizing = Top;
searchCancel.position = new Vector(21, 395);
searchCancel.extent = new Vector(94, 45);
searchCancel.pressedAction = (e) -> {
MarbleGame.canvas.popDialog(this);
}
this.addChild(searchCancel);
var selectedIdx:Int = -1;
var searchPlay = new GuiButton(loadButtonImages("data/ui/mp/search/play"));
searchPlay.position = new Vector(370, 395);
searchPlay.extent = new Vector(94, 45);
searchPlay.disabled = true;
searchPlay.pressedAction = (e) -> {
if (selectedIdx != -1) {
var mis = retrieveMissionList[selectedIdx];
if (mis.difficulty == "custom") {
var idx = Marbleland.multiplayerMissions.indexOf(mis.mis);
NetCommands.setLobbyLevelIndex(mis.difficulty, idx);
} else {
var idx = MissionList.missionList["multiplayer"][mis.difficulty].indexOf(mis.mis);
NetCommands.setLobbyLevelIndex(mis.difficulty, idx);
}
MarbleGame.canvas.popDialog(this);
}
}
this.addChild(searchPlay);
var searchTitle = new GuiText(domcasual24);
searchTitle.position = new Vector(52, 23);
searchTitle.extent = new Vector(64, 25);
searchTitle.text.textColor = 0x696969;
searchTitle.text.text = "Title:";
this.addChild(searchTitle);
var searchEdit = new GuiTextInput(domcasual24);
searchEdit.text.textColor = 0;
searchEdit.text.selectionColor.setColor(0xFFFFFFFF);
searchEdit.text.selectionTile = h2d.Tile.fromColor(0x808080, 0, hxd.Math.ceil(searchEdit.text.font.lineHeight));
searchEdit.position = new Vector(91, 23);
searchEdit.extent = new Vector(373, 29);
searchEdit.onTextChange = (txt) -> {
sortBy(currentSortBy, txt);
};
this.addChild(searchEdit);
scrollCtrl = new GuiScrollCtrl(ResourceLoader.getResource("data/ui/common/philscroll.png", ResourceLoader.getImage, this.imageResources).toTile());
scrollCtrl.position = new Vector(18, 68);
scrollCtrl.extent = new Vector(447, 317);
scrollCtrl.childrenHandleScroll = true;
this.addChild(scrollCtrl);
searchMissionList = new GuiTextListCtrl(markerFelt24, displayList, 0xFFFFFF);
searchMissionList.selectedColor = 0xFFFFFF;
searchMissionList.selectedFillColor = 0x7585E3;
searchMissionList.horizSizing = Width;
searchMissionList.position = new Vector(4, -1);
searchMissionList.extent = new Vector(432, 2880);
searchMissionList.textYOffset = -6;
searchMissionList.scrollable = true;
searchMissionList.onSelectedFunc = (sel) -> {
selectedIdx = sel;
if (retrieveMissionList.length <= selectedIdx || selectedIdx < 0) {
searchPlay.disabled = true;
} else {
searchPlay.disabled = false;
}
}
scrollCtrl.addChild(searchMissionList);
scrollCtrl.setScrollMax(searchMissionList.calculateFullHeight());
var optionsPopup:GuiButton = null;
var searchOptions = new GuiButton(loadButtonImages("data/ui/mp/search/options"));
searchOptions.vertSizing = Top;
searchOptions.horizSizing = Right;
searchOptions.position = new Vector(121, 398);
searchOptions.extent = new Vector(94, 45);
searchOptions.pressedAction = (e) -> {
MarbleGame.canvas.pushDialog(optionsPopup);
}
this.addChild(searchOptions);
var temprev = new BitmapData(1, 1);
temprev.setPixel(0, 0, 0);
var tmpprevtile = Tile.fromBitmap(temprev);
optionsPopup = new GuiButton([tmpprevtile, tmpprevtile, tmpprevtile]);
optionsPopup.horizSizing = Width;
optionsPopup.vertSizing = Height;
optionsPopup.position = new Vector(0, 0);
optionsPopup.extent = new Vector(640, 480);
optionsPopup.pressedAction = (e) -> {
MarbleGame.canvas.popDialog(optionsPopup, false);
}
var optionsPopupInner = new GuiControl();
optionsPopupInner.horizSizing = Center;
optionsPopupInner.vertSizing = Center;
optionsPopupInner.position = new Vector(80, 7);
optionsPopupInner.extent = new Vector(480, 465);
optionsPopup.addChild(optionsPopupInner);
var optionsBgR = ResourceLoader.getResource('data/ui/mp/play/moremenu.png', ResourceLoader.getImage, this.imageResources).toTile();
var optionsBg = new GuiImage(optionsBgR);
optionsBg.position = new Vector(0, 281);
optionsBg.extent = new Vector(348, 148);
optionsPopupInner.addChild(optionsBg);
var searchByFile = new GuiButton(loadButtonImages("data/ui/mp/search/file"));
searchByFile.buttonType = Radio;
searchByFile.position = new Vector(229, 45);
searchByFile.extent = new Vector(67, 45);
searchByFile.pressedAction = (e) -> {
searchTitle.text.text = "File:";
currentSortBy = "file";
sortBy("file");
};
optionsBg.addChild(searchByFile);
var searchByartist = new GuiButton(loadButtonImages("data/ui/mp/search/artist"));
searchByartist.buttonType = Radio;
searchByartist.position = new Vector(159, 45);
searchByartist.extent = new Vector(71, 45);
searchByartist.pressedAction = (e) -> {
searchTitle.text.text = "Artist:";
currentSortBy = "artist";
sortBy("artist");
};
optionsBg.addChild(searchByartist);
var searchByTitle = new GuiButton(loadButtonImages("data/ui/mp/search/name"));
searchByTitle.buttonType = Radio;
searchByTitle.position = new Vector(92, 45);
searchByTitle.extent = new Vector(68, 45);
searchByTitle.pressed = true;
searchByTitle.pressedAction = (e) -> {
searchTitle.text.text = "Title:";
currentSortBy = "title";
sortBy("title");
};
optionsBg.addChild(searchByTitle);
var searchRandom = new GuiButton(loadButtonImages("data/ui/mp/search/random"));
searchRandom.vertSizing = Top;
searchRandom.position = new Vector(44, 45);
searchRandom.extent = new Vector(44, 44);
searchRandom.pressedAction = (e) -> {
var mis = retrieveMissionList[Math.floor(Math.random() * missionList.length)];
if (mis.difficulty == "custom") {
var idx = Marbleland.multiplayerMissions.indexOf(mis.mis);
NetCommands.setLobbyLevelIndex(mis.difficulty, idx);
} else {
var idx = MissionList.missionList["multiplayer"][mis.difficulty].indexOf(mis.mis);
NetCommands.setLobbyLevelIndex(mis.difficulty, idx);
}
}
optionsBg.addChild(searchRandom);
}
}

View file

@ -1,361 +0,0 @@
package gui;
import net.MasterServerClient;
import net.Net;
import h2d.filter.DropShadow;
import src.Marbleland;
import h2d.Tile;
import hxd.BitmapData;
import src.MarbleGame;
import hxd.res.BitmapFont;
import h3d.Vector;
import src.ResourceLoader;
import src.Settings;
import src.MissionList;
import net.NetCommands;
class MPServerDlg extends GuiImage {
public function new() {
var img = ResourceLoader.getImage("data/ui/mp/settings/serversettings.png");
super(img.resource.toTile());
this.horizSizing = Center;
this.vertSizing = Center;
this.position = new Vector(100, 17);
this.extent = new Vector(440, 486);
function loadButtonImages(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}_h.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}_d.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed];
}
var markerFelt32fontdata = ResourceLoader.getFileEntry("data/font/MarkerFelt.fnt");
var markerFelt32b = new BitmapFont(markerFelt32fontdata.entry);
@:privateAccess markerFelt32b.loader = ResourceLoader.loader;
var markerFelt32 = markerFelt32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var markerFelt24 = markerFelt32b.toSdfFont(cast 20 * Settings.uiScale, MultiChannel);
var markerFelt20 = markerFelt32b.toSdfFont(cast 18.5 * Settings.uiScale, MultiChannel);
var markerFelt18 = markerFelt32b.toSdfFont(cast 17 * Settings.uiScale, MultiChannel);
var markerFelt26 = markerFelt32b.toSdfFont(cast 22 * Settings.uiScale, MultiChannel);
var cancelBtn = new GuiButton(loadButtonImages("data/ui/mp/join/cancel"));
cancelBtn.vertSizing = Top;
cancelBtn.horizSizing = Left;
cancelBtn.position = new Vector(123, 424);
cancelBtn.extent = new Vector(94, 45);
cancelBtn.pressedAction = (e) -> {
MarbleGame.canvas.popDialog(this);
}
this.addChild(cancelBtn);
var saveBtn = new GuiButton(loadButtonImages("data/ui/mp/join/save"));
saveBtn.horizSizing = Left;
saveBtn.vertSizing = Top;
saveBtn.position = new Vector(223, 424);
saveBtn.extent = new Vector(94, 45);
this.addChild(saveBtn);
var title = new GuiText(markerFelt32);
title.text.text = "Server Settings";
title.text.textColor = 0xFFFFFF;
title.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
title.justify = Center;
title.position = new Vector(11, 21);
title.extent = new Vector(418, 14);
title.horizSizing = Width;
this.addChild(title);
// var showPwdTitle = new GuiText(markerFelt18);
// showPwdTitle.text.text = "Show Password";
// showPwdTitle.text.textColor = 0xFFFFFF;
// showPwdTitle.text.filter = new DropShadow(1.414, 0.785, 0x0000000F, 1, 0, 0.4, 1, true);
// showPwdTitle.position = new Vector(259, 94);
// showPwdTitle.extent = new Vector(129, 14);
// showPwdTitle.horizSizing = Left;
// this.addChild(showPwdTitle);
// var showPasswords = new GuiButton(loadButtonImages("data/ui/mp/lb_chkbx"));
// showPasswords.buttonType = Toggle;
// showPasswords.horizSizing = Left;
// showPasswords.position = new Vector(389, 86);
// showPasswords.extent = new Vector(31, 31);
// this.addChild(showPasswords);
// State variables
var curServerName = Settings.serverSettings.name;
var curServerPassword = Settings.serverSettings.password;
var curServerDescription = Settings.serverSettings.description;
var curServerMaxPlayers = Settings.serverSettings.maxPlayers;
var curServerForceSpectators = Settings.serverSettings.forceSpectators;
var curServerQuickRespawn = Settings.serverSettings.quickRespawn;
var curServerCompetitive = Settings.serverSettings.competitiveMode;
var curServerOldSpawns = Settings.serverSettings.oldSpawns;
saveBtn.pressedAction = (e) -> {
Settings.serverSettings.name = curServerName;
Settings.serverSettings.password = curServerPassword;
Settings.serverSettings.description = curServerDescription;
Settings.serverSettings.maxPlayers = curServerMaxPlayers;
Settings.serverSettings.forceSpectators = curServerForceSpectators;
Settings.serverSettings.quickRespawn = curServerQuickRespawn;
Settings.serverSettings.competitiveMode = curServerCompetitive;
Settings.serverSettings.oldSpawns = curServerOldSpawns;
if (Net.isHost) {
Net.serverInfo.name = curServerName;
Net.serverInfo.description = curServerDescription;
Net.serverInfo.maxPlayers = curServerMaxPlayers;
Net.serverInfo.password = curServerPassword;
MasterServerClient.instance.sendServerInfo(Net.serverInfo); // Update data on master server
NetCommands.sendServerSettings(Settings.serverSettings.name, Settings.serverSettings.description, Settings.serverSettings.quickRespawn,
Settings.serverSettings.forceSpectators, Settings.serverSettings.competitiveMode, Settings.serverSettings.oldSpawns);
}
Settings.save();
MarbleGame.canvas.popDialog(this);
}
var serverSettingsContainer = new GuiControl();
serverSettingsContainer.vertSizing = Height;
serverSettingsContainer.horizSizing = Left;
serverSettingsContainer.position = new Vector(16, 65);
serverSettingsContainer.extent = new Vector(390, 346);
this.addChild(serverSettingsContainer);
var serverName = new GuiText(markerFelt18);
serverName.text.text = "Server Name:";
serverName.text.textColor = 0xFFFFFF;
serverName.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
serverName.position = new Vector(0, 0);
serverName.extent = new Vector(206, 14);
serverSettingsContainer.addChild(serverName);
var serverNameEditBg = new GuiImage(ResourceLoader.getResource("data/ui/mp/settings/inputbg.png", ResourceLoader.getImage, this.imageResources)
.toTile());
serverNameEditBg.position = new Vector(93, 0);
serverNameEditBg.extent = new Vector(297, 35);
serverSettingsContainer.addChild(serverNameEditBg);
var serverNameEdit = new GuiTextInput(markerFelt18);
serverNameEdit.position = new Vector(3, 3);
serverNameEdit.extent = new Vector(291, 29);
serverNameEdit.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
serverNameEdit.horizSizing = Left;
serverNameEdit.text.textColor = 0;
serverNameEdit.text.text = curServerName;
serverNameEdit.onTextChange = (t) -> {
curServerName = t;
}
serverNameEditBg.addChild(serverNameEdit);
var password = new GuiText(markerFelt18);
password.text.text = "Password:";
password.text.textColor = 0xFFFFFF;
password.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
password.position = new Vector(0, 39);
password.extent = new Vector(206, 14);
serverSettingsContainer.addChild(password);
var passwordEditBg = new GuiImage(ResourceLoader.getResource("data/ui/mp/settings/inputbg.png", ResourceLoader.getImage, this.imageResources)
.toTile());
passwordEditBg.position = new Vector(93, 6 + 29);
passwordEditBg.extent = new Vector(297, 35);
serverSettingsContainer.addChild(passwordEditBg);
var passwordEdit = new GuiTextInput(markerFelt18);
passwordEdit.position = new Vector(3, 3);
passwordEdit.extent = new Vector(291, 29);
passwordEdit.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
passwordEdit.horizSizing = Left;
passwordEdit.text.textColor = 0;
passwordEdit.text.text = curServerPassword;
passwordEdit.onTextChange = (t) -> {
curServerPassword = t;
}
passwordEditBg.addChild(passwordEdit);
var serverDescTitle = new GuiText(markerFelt18);
serverDescTitle.text.text = "Server Info:";
serverDescTitle.text.textColor = 0xFFFFFF;
serverDescTitle.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
serverDescTitle.position = new Vector(0, 39 * 2);
serverDescTitle.extent = new Vector(206, 14);
serverSettingsContainer.addChild(serverDescTitle);
var serverDescEditBg = new GuiImage(ResourceLoader.getResource("data/ui/mp/settings/inputbg.png", ResourceLoader.getImage, this.imageResources)
.toTile());
serverDescEditBg.position = new Vector(0, 39 * 3);
serverDescEditBg.extent = new Vector(297 + 93, 35);
serverSettingsContainer.addChild(serverDescEditBg);
var serverDescEdit = new GuiTextInput(markerFelt18);
serverDescEdit.position = new Vector(3, 3);
serverDescEdit.extent = new Vector(291 + 93, 29);
serverDescEdit.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
serverDescEdit.horizSizing = Left;
serverDescEdit.text.textColor = 0;
serverDescEdit.text.text = curServerDescription;
serverDescEdit.onTextChange = (t) -> {
curServerDescription = t;
}
serverDescEditBg.addChild(serverDescEdit);
var maxPlayers = new GuiText(markerFelt18);
maxPlayers.text.text = "Max Players: " + curServerMaxPlayers;
maxPlayers.text.textColor = 0xFFFFFF;
maxPlayers.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
maxPlayers.position = new Vector(0, 39 * 4);
maxPlayers.extent = new Vector(206, 14);
serverSettingsContainer.addChild(maxPlayers);
var playerMinus = new GuiButton(loadButtonImages("data/ui/mp/settings/minus"));
playerMinus.position = new Vector(331, 9 + 29 * 5);
playerMinus.extent = new Vector(31, 31);
playerMinus.pressedAction = (sender) -> {
curServerMaxPlayers = Std.int(Math.max(1, curServerMaxPlayers - 1));
maxPlayers.text.text = "Max Players: " + curServerMaxPlayers;
};
serverSettingsContainer.addChild(playerMinus);
var playerPlus = new GuiButton(loadButtonImages("data/ui/mp/settings/plus"));
playerPlus.position = new Vector(359, 9 + 29 * 5);
playerPlus.extent = new Vector(31, 31);
playerPlus.pressedAction = (sender) -> {
curServerMaxPlayers = Std.int(Math.min(8, curServerMaxPlayers + 1));
maxPlayers.text.text = "Max Players: " + curServerMaxPlayers;
};
serverSettingsContainer.addChild(playerPlus);
var forceSpectators = new GuiText(markerFelt18);
forceSpectators.text.text = "Force Spectators:";
forceSpectators.text.textColor = 0xFFFFFF;
forceSpectators.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
forceSpectators.position = new Vector(0, 39 * 5);
forceSpectators.extent = new Vector(206, 14);
serverSettingsContainer.addChild(forceSpectators);
var forceSpectatorsChk = new GuiButton(loadButtonImages("data/ui/mp/lb_chkbx"));
forceSpectatorsChk.position = new Vector(359, 9 * 2 + 29 * 6 + 2);
forceSpectatorsChk.extent = new Vector(31, 31);
forceSpectatorsChk.buttonType = Toggle;
forceSpectatorsChk.pressed = curServerForceSpectators;
forceSpectatorsChk.pressedAction = (sender) -> {
curServerForceSpectators = !curServerForceSpectators;
};
serverSettingsContainer.addChild(forceSpectatorsChk);
var quickRespawn = new GuiText(markerFelt18);
quickRespawn.text.text = "Allow Quick Respawn:";
quickRespawn.text.textColor = 0xFFFFFF;
quickRespawn.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
quickRespawn.position = new Vector(0, 39 * 6);
quickRespawn.extent = new Vector(206, 14);
serverSettingsContainer.addChild(quickRespawn);
var quickRespawnChk = new GuiButton(loadButtonImages("data/ui/mp/lb_chkbx"));
quickRespawnChk.position = new Vector(359, 9 * 3 + 29 * 7 + 4);
quickRespawnChk.extent = new Vector(31, 31);
quickRespawnChk.buttonType = Toggle;
quickRespawnChk.pressed = curServerQuickRespawn;
quickRespawnChk.pressedAction = (sender) -> {
curServerQuickRespawn = !curServerQuickRespawn;
};
serverSettingsContainer.addChild(quickRespawnChk);
var competitive = new GuiText(markerFelt18);
competitive.text.text = "Competitive Mode:";
competitive.text.textColor = 0xFFFFFF;
competitive.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
competitive.position = new Vector(0, 39 * 7);
competitive.extent = new Vector(206, 14);
serverSettingsContainer.addChild(competitive);
var competitiveChk = new GuiButton(loadButtonImages("data/ui/mp/lb_chkbx"));
competitiveChk.position = new Vector(359, 9 * 4 + 29 * 8 + 4);
competitiveChk.extent = new Vector(31, 31);
competitiveChk.buttonType = Toggle;
competitiveChk.pressed = curServerCompetitive;
competitiveChk.pressedAction = (sender) -> {
curServerCompetitive = !curServerCompetitive;
};
serverSettingsContainer.addChild(competitiveChk);
var oldSpawns = new GuiText(markerFelt18);
oldSpawns.text.text = "Old Spawns:";
oldSpawns.text.textColor = 0xFFFFFF;
oldSpawns.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
oldSpawns.position = new Vector(0, 39 * 8);
oldSpawns.extent = new Vector(206, 14);
serverSettingsContainer.addChild(oldSpawns);
var oldSpawnsChk = new GuiButton(loadButtonImages("data/ui/mp/lb_chkbx"));
oldSpawnsChk.position = new Vector(359, 9 * 5 + 29 * 9 + 4);
oldSpawnsChk.extent = new Vector(31, 31);
oldSpawnsChk.buttonType = Toggle;
oldSpawnsChk.pressed = curServerOldSpawns;
oldSpawnsChk.pressedAction = (sender) -> {
curServerOldSpawns = !curServerOldSpawns;
};
serverSettingsContainer.addChild(oldSpawnsChk);
}
}

View file

@ -1,44 +1,42 @@
package gui;
import h2d.filter.DropShadow;
import src.MarbleGame;
import gui.GuiControl.MouseState;
import hxd.res.BitmapFont;
import h3d.Vector;
import src.ResourceLoader;
import src.Settings;
import src.Util;
import src.Replay;
import src.Marbleland;
import src.MissionList;
class MainMenuGui extends GuiImage {
public function new() {
function chooseBg() {
var rand = Math.random();
if (rand >= 0 && rand <= 0.244)
return ResourceLoader.getImage('data/ui/backgrounds/gold/${cast (Math.floor(Util.lerp(1, 12, Math.random())), Int)}.jpg');
if (rand > 0.244 && rand <= 0.816)
return ResourceLoader.getImage('data/ui/backgrounds/platinum/${cast (Math.floor(Util.lerp(1, 28, Math.random())), Int)}.jpg');
return ResourceLoader.getImage('data/ui/backgrounds/ultra/${cast (Math.floor(Util.lerp(1, 9, Math.random())), Int)}.jpg');
}
var img = chooseBg();
var img = ResourceLoader.getImage("data/ui/background.jpg");
super(img.resource.toTile());
var domcasual32fontdata = ResourceLoader.getFileEntry("data/font/DomCasualD.fnt");
var domcasual32b = new BitmapFont(domcasual32fontdata.entry);
@:privateAccess domcasual32b.loader = ResourceLoader.loader;
var domcasual32 = domcasual32b.toSdfFont(cast 42 * Settings.uiScale, MultiChannel);
var domcasual32 = domcasual32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
this.horizSizing = Width;
this.vertSizing = Height;
this.position = new Vector();
this.extent = new Vector(640, 480);
var mainMenuContent = new GuiControl();
mainMenuContent.horizSizing = Center;
mainMenuContent.vertSizing = Center;
mainMenuContent.position = new Vector(-130, -110);
mainMenuContent.extent = new Vector(900, 700);
var versionText = new GuiText(domcasual32);
versionText.horizSizing = Center;
versionText.vertSizing = Top;
versionText.position = new Vector(289, 450);
versionText.extent = new Vector(62, 18);
versionText.text.text = "1.1.12";
versionText.text.textColor = 0;
this.addChild(versionText);
var homebase = new GuiImage(ResourceLoader.getResource("data/ui/home/homegui.png", ResourceLoader.getImage, this.imageResources).toTile());
homebase.horizSizing = Center;
homebase.vertSizing = Center;
homebase.extent = new Vector(349, 477);
homebase.position = new Vector(145, 1);
this.addChild(homebase);
function loadButtonImages(path:String) {
var normal = ResourceLoader.getResource('${path}_n.png', ResourceLoader.getImage, this.imageResources).toTile();
@ -47,167 +45,40 @@ class MainMenuGui extends GuiImage {
return [normal, hover, pressed];
}
function loadStaticButtonImages(path:String) {
var normal = ResourceLoader.getResource('${path}.png', ResourceLoader.getImage, this.imageResources).toTile();
var hover = ResourceLoader.getResource('${path}.png', ResourceLoader.getImage, this.imageResources).toTile();
var pressed = ResourceLoader.getResource('${path}.png', ResourceLoader.getImage, this.imageResources).toTile();
return [normal, hover, pressed];
}
var siteButton = new GuiButton(loadButtonImages('data/ui/menu/site'));
siteButton.horizSizing = Right;
siteButton.vertSizing = Top;
siteButton.position = new Vector(363, 664);
siteButton.extent = new Vector(400, 30);
siteButton.pressedAction = (sender) -> {
#if sys
hxd.System.openURL("https://marbleblast.com");
#end
#if js
js.Browser.window.open("https://marbleblast.com");
#end
}
mainMenuContent.addChild(siteButton);
var motdButton = new GuiButton(loadButtonImages('data/ui/menu/changelog'));
motdButton.horizSizing = Left;
motdButton.vertSizing = Top;
motdButton.position = new Vector(706, 536);
motdButton.extent = new Vector(191, 141);
motdButton.pressedAction = (sender) -> {
MarbleGame.canvas.pushDialog(new VersionGui());
}
mainMenuContent.addChild(motdButton);
var playButton = new GuiButton(loadButtonImages("data/ui/menu/play"));
playButton.position = new Vector(-5, -2);
playButton.extent = new Vector(247, 164);
var playButton = new GuiButton(loadButtonImages("data/ui/home/play"));
playButton.position = new Vector(50, 113);
playButton.extent = new Vector(270, 95);
playButton.gamepadAccelerator = ["A"];
playButton.pressedAction = (sender) -> {
cast(this.parent, Canvas).setContent(new PlayMissionGui());
}
mainMenuContent.addChild(playButton);
homebase.addChild(playButton);
var lbButton = new GuiButton(loadButtonImages("data/ui/menu/online"));
lbButton.position = new Vector(-5, 128);
lbButton.extent = new Vector(247, 164);
lbButton.pressedAction = (sender) -> {
MarbleGame.canvas.setContent(new JoinServerGui());
var helpButton = new GuiButton(loadButtonImages("data/ui/home/help"));
helpButton.position = new Vector(59, 200);
helpButton.extent = new Vector(242, 84);
helpButton.pressedAction = (sender) -> {
MarbleGame.canvas.setContent(new HelpCreditsGui());
}
mainMenuContent.addChild(lbButton);
homebase.addChild(helpButton);
var optionsButton = new GuiButton(loadButtonImages("data/ui/menu/options"));
optionsButton.position = new Vector(-5, 258);
optionsButton.extent = new Vector(247, 164);
var optionsButton = new GuiButton(loadButtonImages("data/ui/home/options"));
optionsButton.position = new Vector(55, 279);
optionsButton.extent = new Vector(253, 83);
optionsButton.pressedAction = (sender) -> {
cast(this.parent, Canvas).setContent(new OptionsDlg());
}
mainMenuContent.addChild(optionsButton);
homebase.addChild(optionsButton);
#if hl
var exitButton = new GuiButton(loadButtonImages("data/ui/menu/quit"));
exitButton.position = new Vector(-5, 388);
exitButton.extent = new Vector(247, 164);
var exitButton = new GuiButton(loadButtonImages("data/ui/home/exit"));
exitButton.position = new Vector(82, 358);
exitButton.extent = new Vector(203, 88);
exitButton.pressedAction = (sender) -> {
#if hl
Sys.exit(0);
#end
};
mainMenuContent.addChild(exitButton);
#end
#if js
var exitButton = new GuiButton(loadButtonImages("data/ui/menu/download"));
exitButton.position = new Vector(-5, 388);
exitButton.extent = new Vector(247, 164);
exitButton.pressedAction = (sender) -> {
js.Browser.window.open("https://github.com/RandomityGuy/MBHaxe");
};
mainMenuContent.addChild(exitButton);
#end
var replButton = new GuiButton(loadButtonImages("data/ui/menu/replay"));
replButton.horizSizing = Left;
replButton.vertSizing = Top;
replButton.position = new Vector(552, 536);
replButton.extent = new Vector(191, 141);
replButton.pressedAction = (sender) -> {
#if hl
MarbleGame.canvas.setContent(new ReplayCenterGui());
#end
#if js
hxd.File.browse((replayToLoad) -> {
replayToLoad.load((replayData) -> {
var replay = new Replay("");
if (!replay.read(replayData)) {
cast(this.parent, Canvas).pushDialog(new MessageBoxOkDlg("Cannot load replay."));
// Idk do something to notify the user here
} else {
var repmis = replay.mission;
#if js
repmis = StringTools.replace(repmis, "data/", "");
#end
if (MissionList.missions == null)
MissionList.buildMissionList();
var mi = replay.customId == 0 ? MissionList.missions.get(repmis) : Marbleland.missions.get(replay.customId);
if (mi.isClaMission) {
mi.download(() -> {
MarbleGame.instance.watchMissionReplay(mi, replay, MainMenuGui);
});
} else {
if (mi != null) {
cast(this.parent, Canvas).marbleGame.watchMissionReplay(mi, replay, MainMenuGui);
} else {
cast(this.parent, Canvas).pushDialog(new MessageBoxOkDlg("Cannot load replay."));
}
}
}
});
}, {
title: "Select replay file",
fileTypes: [
{
name: "Replay (*.mbr)",
extensions: ["mbr"]
}
],
});
#end
};
mainMenuContent.addChild(replButton);
var helpButton = new GuiButton(loadButtonImages("data/ui/menu/help"));
helpButton.horizSizing = Left;
helpButton.vertSizing = Top;
helpButton.position = new Vector(398, 536);
helpButton.extent = new Vector(191, 141);
helpButton.pressedAction = (sender) -> {
MarbleGame.canvas.setContent(new HelpCreditsGui());
}
mainMenuContent.addChild(helpButton);
this.addChild(mainMenuContent);
var mbp = new GuiImage(ResourceLoader.getResource("data/ui/menu/mbp.png", ResourceLoader.getImage, this.imageResources).toTile());
mbp.horizSizing = Left;
mbp.vertSizing = Bottom;
mbp.position = new Vector(476, 12);
mbp.extent = new Vector(153, 150);
this.addChild(mbp);
var versionText = new GuiMLText(domcasual32, null);
versionText.horizSizing = Left;
versionText.vertSizing = Bottom;
versionText.position = new Vector(502, 61);
versionText.extent = new Vector(97, 72);
versionText.text.text = '<p align=\"center\">${MarbleGame.currentVersion}</p>';
versionText.text.dropShadow = {
dx: 1 * Settings.uiScale,
dy: 1 * Settings.uiScale,
alpha: 0.5,
color: 0
};
this.addChild(versionText);
homebase.addChild(exitButton);
var kofi = new GuiButton(loadButtonImages("data/ui/kofi1"));
kofi.horizSizing = Left;
@ -238,44 +109,5 @@ class MainMenuGui extends GuiImage {
#end
}
this.addChild(github);
#if js
var mbg = new GuiButton(loadStaticButtonImages("data/ui/icon_mbg"));
mbg.horizSizing = Right;
mbg.vertSizing = Top;
mbg.position = new Vector(0, 380);
mbg.extent = new Vector(76, 76);
mbg.pressedAction = (sender) -> {
js.Browser.window.open("https://marbleblastgold.randomityguy.me");
}
this.addChild(mbg);
var mbu = new GuiButton(loadStaticButtonImages("data/ui/icon_mbu"));
mbu.horizSizing = Right;
mbu.vertSizing = Top;
mbu.position = new Vector(76, 380);
mbu.extent = new Vector(76, 76);
mbu.pressedAction = (sender) -> {
js.Browser.window.open("https://marbleblastultra.randomityguy.me");
}
this.addChild(mbu);
#end
#if js
var urlParams = new js.html.URLSearchParams(js.Browser.window.location.search);
var playParam = urlParams.get("app");
if (playParam == "1" || playParam == "true") {
// Get people to download the native app instead! Bruh
if (!Util.isIOS()) {
// If we aren't on iOS, then only we force them to download the native app, since thats the only valid use of PWA in this case
haxe.Timer.delay(() -> {
MarbleGame.canvas.pushDialog(new MessageBoxOkDlg("Please download the native app for a better experience! The game will run better and smoother that way!",
() -> {
js.Browser.window.open("https://github.com/RandomityGuy/MBHaxe/blob/master/README.md");
}));
}, 100);
}
}
#end
}
}

View file

@ -44,7 +44,7 @@ class MessageBoxOkDlg extends GuiControl {
var okButton = new GuiButton(loadButtonImages("data/ui/common/ok"));
okButton.position = new Vector(117, 85);
okButton.extent = new Vector(88, 41);
okButton.extent = new Vector(78, 59);
okButton.vertSizing = Top;
okButton.accelerator = hxd.Key.ENTER;
okButton.gamepadAccelerator = ["A"];

View file

@ -44,7 +44,7 @@ class MessageBoxYesNoDlg extends GuiControl {
var yesButton = new GuiButton(loadButtonImages("data/ui/common/yes"));
yesButton.position = new Vector(44, 94);
yesButton.extent = new Vector(82, 35);
yesButton.extent = new Vector(82, 47);
yesButton.vertSizing = Top;
yesButton.accelerator = hxd.Key.ENTER;
yesButton.gamepadAccelerator = ["A"];
@ -56,7 +56,7 @@ class MessageBoxYesNoDlg extends GuiControl {
var noButton = new GuiButton(loadButtonImages("data/ui/common/no"));
noButton.position = new Vector(151, 94);
noButton.extent = new Vector(75, 35);
noButton.extent = new Vector(75, 47);
noButton.vertSizing = Top;
noButton.accelerator = hxd.Key.ESCAPE;
noButton.gamepadAccelerator = ["B"];

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -8,19 +8,10 @@ import h3d.Vector;
import src.ResourceLoader;
import src.MarbleGame;
import src.Settings;
import src.Util;
class TouchCtrlsEditGui extends GuiImage {
public function new() {
function chooseBg() {
var rand = Math.random();
if (rand >= 0 && rand <= 0.244)
return ResourceLoader.getImage('data/ui/backgrounds/gold/${cast (Math.floor(Util.lerp(1, 12, Math.random())), Int)}.jpg');
if (rand > 0.244 && rand <= 0.816)
return ResourceLoader.getImage('data/ui/backgrounds/platinum/${cast (Math.floor(Util.lerp(1, 28, Math.random())), Int)}.jpg');
return ResourceLoader.getImage('data/ui/backgrounds/ultra/${cast (Math.floor(Util.lerp(1, 9, Math.random())), Int)}.jpg');
}
var img = chooseBg();
var img = ResourceLoader.getImage("data/ui/background.jpg");
super(img.resource.toTile());
this.horizSizing = Width;
this.vertSizing = Height;
@ -39,11 +30,11 @@ class TouchCtrlsEditGui extends GuiImage {
@:privateAccess domcasual32b.loader = ResourceLoader.loader;
var domcasual32 = domcasual32b.toSdfFont(cast 26 * Settings.uiScale, MultiChannel);
var mainMenuButton = new GuiButton(loadButtonImages("data/ui/menu/options"));
mainMenuButton.position = new Vector(380, 15);
mainMenuButton.extent = new Vector(247, 164);
var mainMenuButton = new GuiButton(loadButtonImages("data/ui/options/mainm"));
mainMenuButton.position = new Vector(500, 400);
mainMenuButton.extent = new Vector(121, 53);
mainMenuButton.horizSizing = Left;
mainMenuButton.vertSizing = Bottom;
mainMenuButton.vertSizing = Top;
mainMenuButton.pressedAction = (sender) -> {
MarbleGame.canvas.setContent(new OptionsDlg());
}
@ -64,9 +55,6 @@ class TouchCtrlsEditGui extends GuiImage {
var powerupBtn = new TouchEditButton(ResourceLoader.getImage("data/ui/touch/energy.png").resource,
new Vector(Settings.touchSettings.powerupButtonPos[0], Settings.touchSettings.powerupButtonPos[1]), Settings.touchSettings.powerupButtonSize);
var blastBtn = new TouchEditButton(ResourceLoader.getImage("data/ui/touch/explosion.png").resource,
new Vector(Settings.touchSettings.blastButtonPos[0], Settings.touchSettings.blastButtonPos[1]), Settings.touchSettings.blastButtonSize);
var rewindBtn = new TouchEditButton(ResourceLoader.getImage("data/ui/touch/rewind.png").resource,
new Vector(Settings.touchSettings.rewindButtonPos[0], Settings.touchSettings.rewindButtonPos[1]), Settings.touchSettings.rewindButtonSize);
@ -74,7 +62,6 @@ class TouchCtrlsEditGui extends GuiImage {
sender.setSelected(true);
powerupBtn.setSelected(false);
joystick.setSelected(false);
blastBtn.setSelected(false);
rewindBtn.setSelected(false);
}
@ -87,7 +74,6 @@ class TouchCtrlsEditGui extends GuiImage {
sender.setSelected(true);
jumpBtn.setSelected(false);
joystick.setSelected(false);
blastBtn.setSelected(false);
rewindBtn.setSelected(false);
}
@ -96,37 +82,10 @@ class TouchCtrlsEditGui extends GuiImage {
Settings.touchSettings.powerupButtonSize = rvalue;
}
blastBtn.onClick = (sender, mousePos) -> {
sender.setSelected(true);
jumpBtn.setSelected(false);
powerupBtn.setSelected(false);
joystick.setSelected(false);
rewindBtn.setSelected(false);
}
blastBtn.onChangeCb = (sender, value, rvalue) -> {
Settings.touchSettings.blastButtonPos = [value.x, value.y];
Settings.touchSettings.blastButtonSize = rvalue;
}
rewindBtn.onClick = (sender, mousePos) -> {
sender.setSelected(true);
jumpBtn.setSelected(false);
powerupBtn.setSelected(false);
joystick.setSelected(false);
blastBtn.setSelected(false);
}
rewindBtn.onChangeCb = (sender, value, rvalue) -> {
Settings.touchSettings.rewindButtonPos = [value.x, value.y];
Settings.touchSettings.rewindButtonSize = rvalue;
}
joystick.onClick = (mousePos) -> {
joystick.setSelected(true);
jumpBtn.setSelected(false);
powerupBtn.setSelected(false);
blastBtn.setSelected(false);
rewindBtn.setSelected(false);
}
@ -140,7 +99,6 @@ class TouchCtrlsEditGui extends GuiImage {
this.addChild(joystick);
this.addChild(jumpBtn);
this.addChild(powerupBtn);
this.addChild(blastBtn);
this.addChild(rewindBtn);
}
}

View file

@ -35,11 +35,6 @@ interface GameMode {
class GameModeFactory {
public static function getGameMode(level:MarbleWorld, mode:String):GameMode {
if (mode != null) {
if (mode.toLowerCase() == "hunt") {
return new HuntMode(level);
}
}
return new NullMode(level);
}
}

View file

@ -1,857 +0,0 @@
package modes;
import gui.MPEndGameGui;
import net.NetCommands;
import net.BitStream.OutputBitStream;
import net.NetPacket.GemPickupPacket;
import net.NetPacket.GemSpawnPacket;
import octree.IOctreeObject;
import octree.IOctreeObject.RayIntersectionData;
import h3d.col.Bounds;
import octree.IOctreeElement;
import shapes.GemBeam;
import h3d.Quat;
import h3d.Vector;
import shapes.Gem;
import mis.MisParser;
import mis.MissionElement.MissionElementSimGroup;
import octree.Octree;
import mis.MissionElement.MissionElementTrigger;
import mis.MissionElement.MissionElementType;
import src.Mission;
import src.Marble;
import src.AudioManager;
import src.ResourceLoader;
import net.Net;
import src.MarbleGame;
import src.Util;
import src.Settings;
@:structInit
@:publicFields
class GemSpawnPoint implements IOctreeObject {
var gem:Gem;
var gemBeam:GemBeam;
var weight:Float;
var boundingBox:Bounds;
var netIndex:Int;
var priority:Int;
public function new(vec:Vector, spawn:Gem, netIndex:Int) {
boundingBox = new Bounds();
boundingBox.addPoint(vec.add(new Vector(-0.5, -0.5, -0.5)).toPoint());
boundingBox.addPoint(vec.add(new Vector(0.5, 0.5, 0.5)).toPoint());
this.gem = spawn;
this.netIndex = netIndex;
this.gem.netIndex = netIndex;
this.weight = 0.0;
}
public function getElementType() {
return 2;
}
public function setPriority(priority:Int) {
this.priority = priority;
}
public function rayCast(rayOrigin:Vector, rayDirection:Vector, resultSet:Array<RayIntersectionData>, bestT:Float):Float {
throw new haxe.exceptions.NotImplementedException(); // Not applicable
}
}
class HuntMode extends NullMode {
var playerSpawnPoints:Array<MissionElementTrigger> = [];
var spawnPointTaken = [];
var gemOctree:Octree;
var gemGroupRadius:Float;
var maxGemsPerGroup:Int;
var rng:RandomLCG = new RandomLCG(100);
var rng2:RandomLCG = new RandomLCG(100);
var gemSpawnPoints:Array<GemSpawnPoint>;
var lastSpawn:GemSpawnPoint;
var activeGemSpawnGroup:Array<Int>;
var gemBeams:Array<GemBeam> = [];
var gemToBeamMap:Map<Gem, GemBeam> = [];
var gemToBlackBeamMap:Map<Gem, GemBeam> = [];
var activeGems:Array<Gem> = [];
var points:Int = 0;
var gemsCentroid:Vector;
var idealSpawnIndex:Int;
var expiredGems:Map<Gem, Bool> = [];
var competitiveTimerStartTicks:Int;
override function missionScan(mission:Mission) {
function scanMission(simGroup:MissionElementSimGroup) {
var elToRemove = [];
for (element in simGroup.elements) {
if ([MissionElementType.Trigger].contains(element._type)) {
var spawnSphere:MissionElementTrigger = cast element;
var dbname = spawnSphere.datablock.toLowerCase();
if (dbname == "spawntrigger") {
playerSpawnPoints.push(spawnSphere);
spawnPointTaken.push(false);
}
} else if (element._type == MissionElementType.SimGroup) {
var scanPls = true;
if (Net.connectedServerInfo.oldSpawns) {
if (element._name.toLowerCase() == "newversion") {
// Remove this
elToRemove.push(element);
scanPls = false;
}
} else {
if (element._name.toLowerCase() == "oldversion") {
// Remove this
elToRemove.push(element);
scanPls = false;
}
}
if (scanPls)
scanMission(cast element);
}
}
while (elToRemove.length > 0) {
simGroup.elements.remove(elToRemove.pop());
}
}
scanMission(mission.root);
};
override function getSpawnTransform() {
var idx = Net.connectedServerInfo.competitiveMode ? idealSpawnIndex : Math.floor(rng2.randRange(0, playerSpawnPoints.length - 1));
if (!Net.connectedServerInfo.competitiveMode) {
var allTaken = true;
for (spw in spawnPointTaken) {
if (!spw) {
allTaken = false;
break;
}
}
if (!allTaken) {
while (spawnPointTaken[idx]) {
idx = Math.floor(rng2.randRange(0, playerSpawnPoints.length - 1));
}
spawnPointTaken[idx] = true;
}
}
var randomSpawn = playerSpawnPoints[idx];
var spawnPos = MisParser.parseVector3(randomSpawn.position);
spawnPos.x *= -1;
var spawnRot = MisParser.parseRotation(randomSpawn.rotation);
spawnRot.x *= -1;
spawnRot.w *= -1;
var spawnMat = spawnRot.toMatrix();
var up = spawnMat.up();
if (MisParser.parseBoolean(randomSpawn.g))
up.load(up.multiply(-1));
spawnPos = spawnPos.add(up); // 1.5 -> 0.5
return {
position: spawnPos,
orientation: spawnRot,
up: up
}
}
public function freeSpawns() {
for (i in 0...playerSpawnPoints.length) {
spawnPointTaken[i] = false;
}
}
override function getRespawnTransform(marble:Marble) {
var lastContactPos = marble.lastContactPosition;
if (lastContactPos == null) {
var idx = Math.floor(rng2.randRange(0, playerSpawnPoints.length - 1));
var randomSpawn = playerSpawnPoints[idx];
var spawnPos = MisParser.parseVector3(randomSpawn.position);
spawnPos.x *= -1;
var spawnRot = MisParser.parseRotation(randomSpawn.rotation);
spawnRot.x *= -1;
spawnRot.w *= -1;
var spawnMat = spawnRot.toMatrix();
var up = spawnMat.up();
if (MisParser.parseBoolean(randomSpawn.g))
up.load(up.multiply(-1));
spawnPos = spawnPos.add(up); // 1.5 -> 0.5
return {
position: spawnPos,
orientation: spawnRot,
up: up
}
}
// Pick closest spawn point
var closestSpawn:MissionElementTrigger = null;
var closestDistance = 1e10;
for (spawn in playerSpawnPoints) {
var pos = MisParser.parseVector3(spawn.position);
pos.x *= -1;
var dist = pos.distance(lastContactPos);
if (dist < closestDistance) {
closestDistance = dist;
closestSpawn = spawn;
}
}
if (closestSpawn != null) {
var spawnPos = MisParser.parseVector3(closestSpawn.position);
spawnPos.x *= -1;
var spawnRot = MisParser.parseRotation(closestSpawn.rotation);
spawnRot.x *= -1;
spawnRot.w *= -1;
var spawnMat = spawnRot.toMatrix();
var up = spawnMat.up();
if (MisParser.parseBoolean(closestSpawn.g))
up.load(up.multiply(-1));
spawnPos = spawnPos.add(up); // 1.5 -> 0.5
return {
position: spawnPos,
orientation: spawnRot,
up: up
}
}
return null;
}
function prepareGems() {
if (this.gemSpawnPoints == null) {
this.gemOctree = new Octree();
this.gemSpawnPoints = [];
this.gemsCentroid = new Vector();
for (gem in this.level.gems) {
var spawn:GemSpawnPoint = new GemSpawnPoint(gem.getAbsPos().getPosition(), gem, gemSpawnPoints.length);
gem.setHide(true);
gem.pickedUp = true;
this.gemSpawnPoints.push(spawn);
this.gemOctree.insert(spawn);
gem.setHide(true);
this.level.collisionWorld.removeEntity(gem.boundingCollider); // remove from octree to make it easy
if (level.isMultiplayer) {
@:privateAccess level.gemPredictions.alloc();
}
gemsCentroid.load(gemsCentroid.add(gem.getAbsPos().getPosition()));
}
if (gemSpawnPoints.length > 0)
gemsCentroid.load(gemsCentroid.multiply(1.0 / gemSpawnPoints.length));
var closestSpawnIndex = 0;
var closestSpawnDistance = 1e8;
for (i in 0...playerSpawnPoints.length) {
var spawn = playerSpawnPoints[i];
var spawnPos = MisParser.parseVector3(spawn.position);
spawnPos.x *= -1;
if (spawnPos.distance(gemsCentroid) < closestSpawnDistance) {
closestSpawnDistance = spawnPos.distance(gemsCentroid);
closestSpawnIndex = i;
}
}
idealSpawnIndex = closestSpawnIndex;
}
for (i in 0...spawnPointTaken.length) {
spawnPointTaken[i] = false;
}
}
override function getPreloadFiles() {
return [
'data/sound/opponentdiamond.wav',
'data/sound/firewrks.wav',
'data/shapes/items/blue.gem.png',
'data/shapes/items/red.gem.png',
'data/shapes/items/yellow.gem.png',
'data/shapes/items/platinum.gem.png'
];
}
function setupGems() {
hideExisting();
this.activeGems = [];
this.activeGemSpawnGroup = [];
this.rng.setSeed(cast Math.random() * 10000);
this.rng2.setSeed(cast Math.random() * 10000);
prepareGems();
spawnHuntGems();
}
function spawnHuntGems(force:Bool = false) {
if (activeGems.length != 0 && !force)
return;
var gemGroupRadius = 15.0;
var maxGemsPerSpawn = 7;
if (level.mission.missionInfo.maxgemsperspawn != null && level.mission.missionInfo.maxgemsperspawn != "")
maxGemsPerSpawn = Std.parseInt(level.mission.missionInfo.maxgemsperspawn);
if (level.mission.missionInfo.radiusfromgem != null && level.mission.missionInfo.radiusfromgem != "")
gemGroupRadius = Std.parseFloat(level.mission.missionInfo.radiusfromgem);
var spawnBlock = gemGroupRadius * 2;
if (level.mission.missionInfo.spawnblock != null && level.mission.missionInfo.spawnblock != "")
spawnBlock = Std.parseFloat(level.mission.missionInfo.spawnblock);
var minPointsPerSpawn = 5;
var minGemsPerSpawn = 3;
var maxSpawnSearchLoops = 15;
var lastPos = null;
if (lastSpawn != null)
lastPos = lastSpawn.gem.getAbsPos().getPosition();
// On MP, instead of blocking around the last gem, block around the player
// currently in the lead. This should create closer games and discourage
// camping for gems.
if (@:privateAccess level.playGui.playerList.length > 1) {
var leadName = @:privateAccess level.playGui.playerList[0].name;
var leadMarble = null;
if (Settings.highscoreName == leadName) {
leadMarble = level.marble;
} else {
for (marble in level.marbles) {
if (@:privateAccess marble.connection != null && @:privateAccess marble.connection.name == leadName) {
leadMarble = marble;
break;
}
}
}
if (leadMarble != null)
lastPos = leadMarble.getAbsPos().getPosition();
var blockFactor = Util.clamp((((@:privateAccess level.playGui.playerList[0].score / Math.max(@:privateAccess
level.playGui.playerList[@:privateAccess level.playGui.playerList.length - 1].score, 1.0)) - 1) * 2), 0, 3);
spawnBlock *= blockFactor;
}
var furthestDist = 0.0;
var furthest = null;
var validGem = null;
for (i in 0...10) {
var gem = gemSpawnPoints[Std.int(rng.randRange(0, gemSpawnPoints.length - 1))];
if (lastPos != null) {
var dist = gem.gem.getAbsPos().getPosition().distance(lastPos) + gem.weight;
if (dist < spawnBlock) {
if (dist > furthestDist) {
furthestDist = dist;
furthest = gem;
}
continue;
} else {
validGem = gem;
break;
}
} else {
validGem = gem;
break;
}
}
if (validGem == null && furthest != null) {
validGem = furthest;
}
if (validGem == null) {
validGem = gemSpawnPoints[Std.int(rng.randRange(0, gemSpawnPoints.length - 1))];
}
var pos = validGem.gem.getAbsPos().getPosition();
var results = [];
var spawned = 1;
var points = 1 + getGemWeight(validGem.gem);
var loops = 0;
var searchRadius = gemGroupRadius;
while ((results.length == 0 || points < minPointsPerSpawn) && loops < 2) {
var search = gemOctree.radiusSearch(pos, searchRadius);
for (elem in search) {
var gemElem:GemSpawnPoint = cast elem;
var gemPos = gemElem.gem.getAbsPos().getPosition();
if (level.mission.missionInfo.game == "PlatinumQuest") {
if (Net.connectedServerInfo.oldSpawns) {
// Spawn chances!
var chance = switch (gemElem.gem.gemColor.toLowerCase()) {
case "red.gem":
level.mission.missionInfo.spawnchancered != null ? Std.parseFloat(level.mission.missionInfo.spawnchancered) : 0.9;
case "yellow.gem":
level.mission.missionInfo.spawnchanceyellow != null ? Std.parseFloat(level.mission.missionInfo.spawnchanceyellow) : 0.65;
case "blue.gem":
level.mission.missionInfo.spawnchanceblue != null ? Std.parseFloat(level.mission.missionInfo.spawnchanceblue) : 0.35;
case "platinum.gem":
level.mission.missionInfo.spawnchanceplatinum != null ? Std.parseFloat(level.mission.missionInfo.spawnchanceplatinum) : 0.18;
default:
1.0;
};
var choice = Math.random();
if (choice > chance)
continue; // Don't spawn!
} else {
// Spawn chances!
var chance = switch (gemElem.gem.gemColor.toLowerCase()) {
case "red.gem":
level.mission.missionInfo.redspawnchance != null ? Std.parseFloat(level.mission.missionInfo.redspawnchance) : 0.9;
case "yellow.gem":
level.mission.missionInfo.yellowspawnchance != null ? Std.parseFloat(level.mission.missionInfo.yellowspawnchance) : 0.65;
case "blue.gem":
level.mission.missionInfo.bluespawnchance != null ? Std.parseFloat(level.mission.missionInfo.bluespawnchance) : 0.35;
case "platinum.gem":
level.mission.missionInfo.platinumspawnchance != null ? Std.parseFloat(level.mission.missionInfo.platinumspawnchance) : 0.18;
default:
1.0;
};
var choice = Math.random();
if (choice > chance)
continue; // Don't spawn!
}
}
results.push({
gem: gemElem.netIndex,
weight: searchRadius - gemPos.distance(pos) + rng.randRange(0, getGemWeight(gemElem.gem) + 3)
});
points += getGemWeight(gemElem.gem) + 1;
}
loops++;
searchRadius *= 2;
}
results.sort((a, b) -> {
if (a.weight > b.weight)
return -1;
if (a.weight < b.weight)
return 1;
return 0;
});
var spawnSet = results.slice(0, maxGemsPerSpawn).map(x -> x.gem);
// Get the furthest gem
var maxDist = 0.0;
for (gem in spawnSet) {
var dist = gemSpawnPoints[gem].gem.getAbsPos().getPosition().distance(pos);
if (dist > maxDist)
maxDist = dist;
}
// Apply spawn weights
for (gem in spawnSet) {
var dist = gemSpawnPoints[gem].gem.getAbsPos().getPosition().distance(pos);
dist /= maxDist;
dist = Math.floor((1 - dist) * 10);
gemSpawnPoints[gem].weight += dist;
}
// Fix spawn weights so we don't get gems with 10000 spawn weight
var min = 9999.0;
for (gem in gemSpawnPoints) {
if (gem.weight < min) {
min = gem.weight;
}
}
for (gem in gemSpawnPoints) {
gem.weight -= min;
}
if (force) {
for (activeGem in activeGemSpawnGroup)
spawnSet.remove(activeGem);
}
for (gem in spawnSet) {
spawnGem(gem);
}
if (!force)
activeGemSpawnGroup = spawnSet;
else {
var uncollectedGems = [];
for (g in activeGemSpawnGroup) {
if (!gemSpawnPoints[g].gem.pickedUp)
uncollectedGems.push(g);
}
activeGemSpawnGroup = uncollectedGems.concat(spawnSet);
}
if (level.isMultiplayer && Net.isHost) {
var bs = new OutputBitStream();
bs.writeByte(GemSpawn);
var packet = new GemSpawnPacket();
packet.gemIds = activeGemSpawnGroup;
packet.expireds = [];
for (i in 0...packet.gemIds.length) {
if (expiredGems.exists(gemSpawnPoints[packet.gemIds[i]].gem)) {
packet.expireds.push(true);
} else {
packet.expireds.push(false);
}
}
packet.serialize(bs);
Net.sendPacketToIngame(bs);
}
lastSpawn = furthest;
}
function spawnGem(spawn:Int, expired:Bool = false) {
var gem = gemSpawnPoints[spawn];
gem.gem.setHide(false);
gem.gem.pickedUp = false;
this.level.collisionWorld.addEntity(gem.gem.boundingCollider);
activeGems.push(gem.gem);
if (!expired) {
if (gem.gemBeam == null) {
gem.gemBeam = new GemBeam(StringTools.replace(gem.gem.gemColor, '.gem', ''));
var gemPos = gem.gem.getAbsPos().getPosition();
gem.gemBeam.setPosition(gemPos.x, gemPos.y, gemPos.z);
gem.gemBeam.setRotationQuat(gem.gem.getRotationQuat().clone());
// gem.gemBeam.setOpacity(0.99);
this.gemBeams.push(gem.gemBeam);
this.gemToBeamMap.set(gem.gem, gem.gemBeam);
level.addDtsObject(gem.gemBeam, () -> {
// Please be fast lol
});
} else {
gem.gemBeam.setHide(false);
}
} else {
if (gemToBlackBeamMap.exists(gem.gem)) {
gemToBlackBeamMap.get(gem.gem).setHide(false);
} else {
var blackBeam = new GemBeam("black");
var pos = gem.gem.getAbsPos().getPosition();
blackBeam.setPosition(gem.gem.x, gem.gem.y, gem.gem.z);
blackBeam.setRotationQuat(gem.gem.getRotationQuat().clone());
blackBeam.setHide(false);
level.addDtsObject(blackBeam, () -> {});
gemToBlackBeamMap.set(gem.gem, blackBeam);
}
}
}
public inline function setGemHiddenStatus(gemId:Int, status:Bool) {
var gemSpawn = gemSpawnPoints[gemId];
if (gemSpawn.gem != null) {
gemSpawn.gem.pickedUp = status;
gemSpawn.gem.setHide(status);
if (expiredGems.exists(gemSpawn.gem)) {
var blackBeam = gemToBlackBeamMap.get(gemSpawn.gem);
blackBeam.setHide(status);
gemSpawn.gemBeam.setHide(true);
} else {
gemSpawn.gemBeam.setHide(status);
}
if (status)
this.activeGems.push(gemSpawn.gem);
else
this.activeGems.remove(gemSpawn.gem);
} else {
throw new haxe.Exception("Setting gem status for non existent gem!");
}
}
public function setActiveSpawnSphere(gems:Array<Int>, expireds:Array<Bool>) {
hideExisting();
expiredGems = [];
for (i in 0...gems.length) {
var gem = gems[i];
spawnGem(gem, expireds[i]);
if (expireds[i]) {
expiredGems.set(gemSpawnPoints[gem].gem, true);
}
}
activeGemSpawnGroup = gems;
}
function getGemWeight(gem:Gem) {
var col = gem.gemColor.toLowerCase();
if (col == "red.gem")
return 0;
if (col == "yellow.gem")
return 1;
if (col == "blue.gem")
return 4;
if (col == "platinum.gem")
return 9;
return 0;
}
function hideExisting() {
lastSpawn = null;
if (gemSpawnPoints != null) {
for (gs in gemSpawnPoints) {
gs.gem.setHide(true);
gs.gem.pickedUp = true;
if (gs.gemBeam != null) {
gs.gemBeam.setHide(true);
}
if (gemToBlackBeamMap.exists(gs.gem)) {
gemToBlackBeamMap.get(gs.gem).setHide(true);
}
}
}
}
override public function getStartTime() {
return level.mission.qualifyTime;
}
override function onRespawn(marble:Marble) {
if (marble.controllable && activeGemSpawnGroup.length != 0) {
var gemAvg = new Vector();
for (gi in activeGemSpawnGroup) {
var g = gemSpawnPoints[gi];
gemAvg = gemAvg.add(g.boundingBox.getCenter().toVector());
}
gemAvg.scale(1 / activeGemSpawnGroup.length);
var delta = gemAvg.sub(marble.getAbsPos().getPosition());
var gravFrame = level.getOrientationQuat(0).toMatrix();
var v1 = gravFrame.front();
var v2 = gravFrame.right();
var deltaRot = new Vector(delta.dot(v2), delta.dot(v1));
if (deltaRot.length() >= 0.001) {
var ang = Math.atan2(deltaRot.x, deltaRot.y);
marble.camera.CameraYaw = ang;
marble.camera.nextCameraYaw = ang;
}
}
}
override function onRestart() {
setupGems();
points = 0;
competitiveTimerStartTicks = 0;
@:privateAccess level.playGui.formatGemHuntCounter(points);
if (gemSpawnPoints != null)
for (gem in gemSpawnPoints) {
gem.weight = 0.0;
}
}
override function onMissionLoad() {
prepareGems();
competitiveTimerStartTicks = 0;
}
override function onClientRestart() {
prepareGems();
competitiveTimerStartTicks = 0;
}
override function onTimeExpire() {
if (level.finishTime != null)
return;
AudioManager.playSound(ResourceLoader.getResource("data/sound/firewrks.wav", ResourceLoader.getAudio, @:privateAccess level.soundResources));
// AudioManager.playSound(ResourceLoader.getResource('data/sound/finish.wav', ResourceLoader.getAudio, @:privateAccess level.soundResources));
level.finishTime = level.timeState.clone();
level.marble.setMode(Finish);
level.marble.camera.finish = true;
level.finishYaw = level.marble.camera.CameraYaw;
level.finishPitch = level.marble.camera.CameraPitch;
// if (level.isMultiplayer) {
// @:privateAccess level.playGui.doMPEndGameMessage();
// } else {
// level.displayAlert("Congratulations! You've finished!");
// }
level.cancel(@:privateAccess level.oobSchedule);
level.cancel(@:privateAccess level.marble.oobSchedule);
for (marble in level.marbles) {
marble.setMode(Finish);
level.cancel(@:privateAccess marble.oobSchedule);
}
if (Net.isHost)
NetCommands.timerRanOut();
// Stop the ongoing sounds
if (@:privateAccess level.timeTravelSound != null) {
@:privateAccess level.timeTravelSound.stop();
@:privateAccess level.timeTravelSound = null;
}
if (@:privateAccess level.alarmSound != null) {
@:privateAccess level.alarmSound.stop();
@:privateAccess level.alarmSound = null;
}
level.schedule(level.timeState.currentAttemptTime + 2, () -> {
if (Util.isTouchDevice()) {
MarbleGame.instance.touchInput.setControlsEnabled(false);
}
#if js
var pointercontainer = js.Browser.document.querySelector("#pointercontainer");
pointercontainer.hidden = false;
#end
MarbleGame.canvas.pushDialog(new MPEndGameGui());
level.setCursorLock(false);
return 0;
});
}
override function onGemPickup(marble:Marble, gem:Gem) {
if ((@:privateAccess !marble.isNetUpdate && Net.isHost) || !Net.isMP) {
if (marble == level.marble)
AudioManager.playSound(ResourceLoader.getResource('data/sound/gotgem.wav', ResourceLoader.getAudio, @:privateAccess this.level.soundResources));
else
AudioManager.playSound(ResourceLoader.getResource('data/sound/opponentdiamond.wav', ResourceLoader.getAudio,
@:privateAccess this.level.soundResources));
}
activeGems.remove(gem);
var wasExpiredGem = false;
if (expiredGems.exists(gem)) {
wasExpiredGem = true;
}
if (gemToBlackBeamMap.exists(gem)) {
gemToBlackBeamMap.get(gem).setHide(true);
}
var beam = gemToBeamMap.get(gem);
beam.setHide(true);
var incr = 0;
switch (gem.gemColor.toLowerCase()) {
case "red.gem":
incr = 1;
case "yellow.gem":
incr = 2;
case "blue.gem":
incr = 5;
case "platinum.gem":
incr = 10;
}
if (@:privateAccess !marble.isNetUpdate) {
if (marble == level.marble) {
switch (gem.gemColor.toLowerCase()) {
case "red.gem":
points += 1;
@:privateAccess level.playGui.addMiddleMessage('+1', 0xFF6666);
case "yellow.gem":
points += 2;
@:privateAccess level.playGui.addMiddleMessage('+2', 0xFFFF66);
case "blue.gem":
points += 5;
@:privateAccess level.playGui.addMiddleMessage('+5', 0x6666FF);
case "platinum.gem":
points += 10;
@:privateAccess level.playGui.addMiddleMessage('+10', 0xdddddd);
}
if (Net.isHost)
@:privateAccess level.playGui.formatGemHuntCounter(points);
}
}
if (this.level.isMultiplayer && Net.isHost) {
if (Net.connectedServerInfo.competitiveMode && !wasExpiredGem) {
if (competitiveTimerStartTicks == 0) {
NetCommands.setCompetitiveTimerStartTicks(this.level.timeState.ticks);
}
var remaining = 0;
for (g in activeGems)
if (!expiredGems.exists(g))
remaining++;
if (remaining == 3) {
var currentTime = level.timeState.ticks;
var endTime = competitiveTimerStartTicks + (20000 >> 5);
var remainingTicks = (endTime - currentTime);
if (remainingTicks > (15000 >> 5)) {
NetCommands.setCompetitiveTimerStartTicks(currentTime - (5000 >> 5));
}
}
if (remaining == 2) {
var currentTime = level.timeState.ticks;
var endTime = competitiveTimerStartTicks + (20000 >> 5);
var remainingTicks = (endTime - currentTime);
if (remainingTicks > (10000 >> 5)) {
NetCommands.setCompetitiveTimerStartTicks(currentTime - (10000 >> 5));
}
}
if (remaining == 1) {
var currentTime = level.timeState.ticks;
var endTime = competitiveTimerStartTicks + (20000 >> 5);
var remainingTicks = (endTime - currentTime);
if (remainingTicks > (5000 >> 5)) {
NetCommands.setCompetitiveTimerStartTicks(currentTime - (15000 >> 5));
}
}
if (remaining == 0) {
NetCommands.setCompetitiveTimerStartTicks(0);
spawnNextGemCluster();
}
}
var packet = new GemPickupPacket();
packet.clientId = @:privateAccess marble.connection == null ? 0 : @:privateAccess marble.connection.id;
packet.gemId = gem.netIndex;
packet.serverTicks = level.timeState.ticks;
packet.scoreIncr = incr;
var os = new OutputBitStream();
os.writeByte(GemPickup);
packet.serialize(os);
Net.sendPacketToIngame(os);
// Settings.playStatistics.totalMPScore += incr;
@:privateAccess level.playGui.incrementPlayerScore(packet.clientId, packet.scoreIncr);
}
if (wasExpiredGem)
expiredGems.remove(gem);
if (this.level.isMultiplayer && Net.isClient) {
gem.pickUpClient = @:privateAccess marble.connection == null ? Net.clientId : @:privateAccess marble.connection.id;
}
if (!this.level.isMultiplayer || Net.isHost) {
spawnHuntGems();
}
}
public function setCompetitiveTimerStartTicks(ticks:Int) {
competitiveTimerStartTicks = ticks;
}
function spawnNextGemCluster() {
// Expire all existing
for (g in activeGems) {
expiredGems.set(g, true);
var gemBeam = gemToBeamMap.get(g);
gemBeam.setHide(true);
if (gemToBlackBeamMap.exists(g)) {
gemToBlackBeamMap.get(g).setHide(false);
} else {
var blackBeam = new GemBeam("black");
var pos = g.getAbsPos().getPosition();
blackBeam.setPosition(g.x, g.y, g.z);
blackBeam.setRotationQuat(g.getRotationQuat().clone());
blackBeam.setHide(false);
level.addDtsObject(blackBeam, () -> {});
gemToBlackBeamMap.set(g, blackBeam);
}
}
spawnHuntGems(true);
}
override function update(t:src.TimeState) {
if (Net.connectedServerInfo.competitiveMode) {
if (competitiveTimerStartTicks != 0) {
var currentTime = Net.isHost ? t.ticks : @:privateAccess level.marble.serverTicks;
var endTime = competitiveTimerStartTicks + (20000 >> 5);
@:privateAccess level.playGui.formatCountdownTimer(Math.max(0, (endTime - currentTime) * 0.032), 0);
if (Net.isHost && endTime < currentTime) {
spawnNextGemCluster();
NetCommands.setCompetitiveTimerStartTicks(0);
}
} else {
@:privateAccess level.playGui.formatCountdownTimer(0, 0);
}
}
}
override public function timeMultiplier() {
return -1;
}
}

View file

@ -1,324 +0,0 @@
package net;
import gui.MPMessageGui;
import gui.JoinServerGui;
import gui.MessageBoxOkDlg;
import src.MarbleGame;
import haxe.Json;
import net.Net.ServerInfo;
import haxe.net.WebSocket;
import src.Console;
typedef RemoteServerInfo = {
id:String,
name:String,
host:String,
description:String,
players:Int,
maxPlayers:Int,
platform:Int,
version:String,
passworded:Bool
}
class MasterServerClient {
#if js
static var serverIp = "wss://mbpmaster.randomityguy.me:8443";
#else
static var serverIp = "ws://51.75.65.148:8084";
#end
public static var instance:MasterServerClient;
var ws:WebSocket;
var serverListCb:Array<RemoteServerInfo>->Void;
var open = false;
static var wsToken:Int = 0;
#if hl
var wsThread:sys.thread.Thread;
static var responses:sys.thread.Deque<() -> Void> = new sys.thread.Deque<() -> Void>();
var toSend:sys.thread.Deque<String> = new sys.thread.Deque<String>();
var stopping:Bool = false;
var stopMutex:sys.thread.Mutex = new sys.thread.Mutex();
#end
public function new(onOpenFunc:() -> Void, onErrorFunc:() -> Void) {
#if hl
wsThread = sys.thread.Thread.create(() -> {
hl.Gc.enable(false);
hl.Gc.blocking(true); // Wtf is this shit
#end
wsToken++;
var myToken = wsToken;
ws = WebSocket.create(serverIp);
#if hl
hl.Gc.enable(true);
hl.Gc.blocking(false);
#end
ws.onopen = () -> {
open = true;
#if hl
responses.add(() -> onOpenFunc());
#end
#if js
onOpenFunc();
#end
}
ws.onmessageString = (m) -> {
#if hl
responses.add(() -> handleMessage(m));
#end
#if js
handleMessage(m);
#end
}
ws.onerror = (m) -> {
#if hl
responses.add(() -> {
MarbleGame.canvas.pushDialog(new MessageBoxOkDlg("Failed to connect to master server: " + m));
});
if (onErrorFunc != null)
responses.add(() -> {
onErrorFunc();
});
#end
#if js
MarbleGame.canvas.pushDialog(new MessageBoxOkDlg("Failed to connect to master server: " + m));
if (onErrorFunc != null)
onErrorFunc();
#end
#if hl
stopMutex.acquire();
#end
if (myToken == wsToken) {
open = false;
ws = null;
instance = null;
}
#if hl
stopping = true;
stopMutex.release();
if (myToken == wsToken) {
wsThread = null;
}
#end
}
ws.onclose = (?e) -> {
#if hl
stopMutex.acquire();
#end
if (myToken == wsToken) {
open = false;
ws = null;
instance = null;
}
#if hl
stopping = true;
stopMutex.release();
if (myToken == wsToken) {
wsThread = null;
}
#end
}
#if hl
while (true) {
stopMutex.acquire();
if (stopping)
break;
while (true) {
var s = toSend.pop(false);
if (s == null)
break;
#if hl
hl.Gc.blocking(true);
#end
ws.sendString(s);
#if hl
hl.Gc.blocking(false);
#end
}
#if hl
hl.Gc.blocking(true);
#end
ws.process();
#if hl
hl.Gc.blocking(false);
#end
stopMutex.release();
Sys.sleep(0.1);
}
#end
#if hl
});
#end
}
public static function process() {
#if sys
var resp = responses.pop(false);
if (resp != null) {
resp();
}
#end
}
public static function connectToMasterServer(onConnect:() -> Void, onError:() -> Void = null) {
if (instance == null)
instance = new MasterServerClient(onConnect, onError);
else {
if (instance.open)
onConnect();
else {
if (instance != null && instance.ws != null)
instance.ws.close();
instance = new MasterServerClient(onConnect, onError);
}
}
}
public static function disconnectFromMasterServer() {
if (instance != null && instance.ws != null) {
instance.ws.close();
if (instance != null) {
instance.open = false;
instance.ws = null;
instance = null;
}
}
}
public static function requestTurnCredentials() {
if (instance != null && instance.open) {
instance.queueMessage(Json.stringify({
type: "turn_credentials"
}));
}
}
function queueMessage(m:String) {
#if hl
toSend.add(m);
#end
#if js
ws.sendString(m);
#end
}
public function heartBeat() {
queueMessage(Json.stringify({
type: "heartbeat"
}));
}
public function sendServerInfo(serverInfo:ServerInfo) {
queueMessage(Json.stringify({
type: "serverInfo",
id: serverInfo.id,
name: serverInfo.name,
host: serverInfo.hostname,
description: serverInfo.description,
players: serverInfo.players,
maxPlayers: serverInfo.maxPlayers,
password: serverInfo.password,
state: serverInfo.state,
platform: serverInfo.platform,
version: MarbleGame.currentVersion
}));
}
public function sendConnectToServer(serverId:String, sdp:String, password:String) {
queueMessage(Json.stringify({
type: "connect",
id: serverId,
sdp: sdp,
password: password
}));
}
public function getServerList(serverListCb:Array<RemoteServerInfo>->Void) {
this.serverListCb = serverListCb;
queueMessage(Json.stringify({
type: "serverList"
}));
}
function handleMessage(message:String) {
var conts = Json.parse(message);
Console.log('Received ${conts.type}');
if (conts.type == "serverList") {
if (serverListCb != null) {
serverListCb(conts.servers);
}
}
if (conts.type == "connect") {
if (!Net.isHost) {
queueMessage(Json.stringify({
type: "connectFailed",
success: false,
reason: "The server has shut down"
}));
return;
}
var joiningPrivate = conts.isPrivate;
if (Net.serverInfo.players >= Net.serverInfo.maxPlayers) {
queueMessage(Json.stringify({
type: "connectFailed",
success: false,
reason: "The server is full"
}));
return;
}
var pubCount = 1; // Self
for (cid => cc in Net.clientIdMap) {
pubCount++;
}
if (!joiningPrivate && pubCount >= Net.serverInfo.maxPlayers) {
queueMessage(Json.stringify({
type: "connectFailed",
success: false,
reason: "The server is full"
}));
return;
}
Net.addClientFromSdp(conts.sdp, (sdpReply) -> {
queueMessage(Json.stringify({
success: true,
type: "connectResponse",
sdp: sdpReply,
clientId: conts.clientId
}));
});
}
if (conts.type == "connectResponse") {
Console.log("Remote Description Received!");
var sdpObj = Json.parse(conts.sdp);
if (@:privateAccess Net.client != null)
@:privateAccess Net.client.setRemoteDescription(sdpObj.sdp, sdpObj.type);
}
if (conts.type == "connectFailed") {
if (MarbleGame.canvas.content is MPMessageGui) {
var loadGui:MPMessageGui = cast MarbleGame.canvas.content;
if (loadGui != null) {
loadGui.setTexts("Error", conts.reason);
}
}
}
if (conts.type == "turn_credentials") {
Net.turnServers = conts.turn_servers;
if (@:privateAccess Net.onTurnServersReceived != null) {
@:privateAccess Net.onTurnServersReceived();
}
}
}
}

View file

@ -76,7 +76,7 @@ class MoveManager {
if (!MarbleGame.instance.paused) {
move.d.x = Gamepad.getAxis(Settings.gamepadSettings.moveYAxis);
move.d.y = -Gamepad.getAxis(Settings.gamepadSettings.moveXAxis);
if (@:privateAccess !MarbleGame.instance.world.playGui.isChatFocused()) {
if (true) {
if (Key.isDown(Settings.controlsSettings.forward)) {
move.d.x -= 1;
}
@ -100,11 +100,6 @@ class MoveManager {
move.powerup = true;
}
if (Key.isDown(Settings.controlsSettings.blast)
|| (MarbleGame.instance.touchInput.blastbutton.pressed)
|| Gamepad.isDown(Settings.gamepadSettings.blast))
move.blast = true;
if (Key.isDown(Settings.controlsSettings.respawn) || Gamepad.isDown(Settings.gamepadSettings.respawn)) {
move.respawn = true;
@:privateAccess Key.keyPressed[Settings.controlsSettings.respawn] = 0;

View file

@ -1,14 +1,9 @@
package net;
import net.NetPacket.ExplodableUpdatePacket;
import gui.MPMessageGui;
import gui.MessageBoxOkDlg;
import gui.JoinServerGui;
import gui.MPPreGameDlg;
import net.NetPacket.ScoreboardPacket;
import gui.MPPlayMissionGui;
import gui.Canvas;
import net.MasterServerClient.RemoteServerInfo;
import src.ResourceLoader;
import src.AudioManager;
import net.NetPacket.GemPickupPacket;
@ -101,7 +96,6 @@ class Net {
public static var clientIdMap:Map<Int, GameConnection> = [];
public static var clientConnection:ClientConnection;
public static var serverInfo:ServerInfo;
public static var remoteServerInfo:RemoteServerInfo;
public static var connectedServerInfo:ConnectedServerInfo;
static var stunServers = ["stun:stun.l.google.com:19302"];
@ -112,38 +106,9 @@ class Net {
public static function hostServer(name:String, description:String, maxPlayers:Int, password:String, onHosted:() -> Void) {
serverInfo = new ServerInfo(name, Settings.highscoreName, description, 1, maxPlayers, password, "LOBBY", getPlatform());
MasterServerClient.connectToMasterServer(() -> {
isHost = true;
isClient = false;
clientId = 0;
isMP = true;
MasterServerClient.instance.sendServerInfo(serverInfo);
Net.connectedServerInfo = {
name: name,
description: description,
competitiveMode: Settings.serverSettings.competitiveMode,
quickRespawn: Settings.serverSettings.quickRespawn,
forceSpectator: Settings.serverSettings.forceSpectators,
oldSpawns: Settings.serverSettings.oldSpawns
};
onHosted();
});
}
public static function addClientFromSdp(sdpString:String, onFinishSdp:String->Void, turnTried:Bool = false) {
if (Net.turnServers.length == 0 && !turnTried) {
MasterServerClient.requestTurnCredentials();
Net.onTurnServersReceived = () -> {
Net.onTurnServersReceived = null;
addClientFromSdp(sdpString, onFinishSdp, true);
};
return;
}
var peer = new RTCPeerConnection(stunServers.concat(Net.turnServers), "0.0.0.0");
var sdpObj = Json.parse(sdpString);
peer.setRemoteDescription(sdpObj.sdp, sdpObj.type);
addClient(peer, onFinishSdp);
}
public static function addClientFromSdp(sdpString:String, onFinishSdp:String->Void, turnTried:Bool = false) {}
static function addClient(peer:RTCPeerConnection, onFinishSdp:String->Void) {
var candidates = [];
@ -222,170 +187,7 @@ class Net {
clientIdMap[id] = ghost;
}
public static function joinServer(serverName:String, password:String, connectedCb:() -> Void, turnTried:Bool = false) {
MasterServerClient.connectToMasterServer(() -> {
if (Net.turnServers.length == 0 && !turnTried) {
MasterServerClient.requestTurnCredentials();
Net.onTurnServersReceived = () -> {
Net.onTurnServersReceived = null;
joinServer(serverName, password, connectedCb, true);
};
return;
}
client = new RTCPeerConnection(stunServers.concat(Net.turnServers), "0.0.0.0");
var candidates = [];
var closing = false;
isMP = true;
isHost = false;
isClient = true;
var closeFunc = (msg:String, forceShow:Bool) -> {
if (closing)
return;
closing = true;
var weLeftOurselves = !Net.isClient; // If we left ourselves, this would be set to false due to order of ops, disconnect being called first, and then the datachannel closing
disconnect();
if (MarbleGame.instance.world != null) {
MarbleGame.instance.quitMission();
}
if (!weLeftOurselves || forceShow) {
if (MarbleGame.canvas.content is MPMessageGui) {
var loadGui:MPMessageGui = cast MarbleGame.canvas.content;
if (loadGui != null) {
loadGui.setTexts("Error", msg);
}
} else {
MarbleGame.canvas.setContent(new MPMessageGui("Error", msg));
}
}
}
client.onLocalCandidate = (c) -> {
Console.log('Local candidate: ' + c);
if (c != "")
candidates.push('a=${c}');
}
client.onStateChange = (s) -> {
switch (s) {
case RTC_CLOSED:
Console.log("RTC State change: Connection closed!");
closeFunc("Connection closed", false);
case RTC_CONNECTED:
Console.log("RTC State change: Connected!");
case RTC_CONNECTING:
Console.log("RTC State change: Connecting...");
case RTC_DISCONNECTED:
Console.log("RTC State change: Disconnected!");
case RTC_FAILED:
Console.log("RTC State change: Failed!");
case RTC_NEW:
Console.log("RTC State change: New...");
}
}
var sdpFinished = false;
var finishSdp = () -> {
if (sdpFinished)
return;
sdpFinished = true;
if (client == null)
return;
Console.log("Local Description Set!");
var sdpObj = StringTools.trim(client.localDescription);
sdpObj = sdpObj + '\r\n' + candidates.join('\r\n') + '\r\n';
MasterServerClient.instance.sendConnectToServer(serverName, Json.stringify({
sdp: sdpObj,
type: "offer"
}), password);
}
client.onGatheringStateChange = (s) -> {
switch (s) {
case RTC_GATHERING_COMPLETE:
Console.log("Gathering complete!");
case RTC_GATHERING_INPROGRESS:
Console.log("Gathering in progress...");
case RTC_GATHERING_NEW:
Console.log("Gathering new...");
}
if (s == RTC_GATHERING_COMPLETE) {
finishSdp();
}
}
// haxe.Timer.delay(() -> {
// finishSdp();
// }, 5000);
clientDatachannel = client.createDatachannel("mp");
clientDatachannelUnreliable = client.createDatachannelWithOptions("unreliable", true, null, 600);
var openFlags = 0;
var onDatachannelOpen = (idx:Int) -> {
if (!Net.isMP) {
// Close
client.close();
return;
}
openFlags |= idx;
if (openFlags == 3) {
if (MarbleGame.canvas.content is MPMessageGui) {
var loadGui:MPMessageGui = cast MarbleGame.canvas.content;
if (loadGui != null) {
loadGui.setTexts("Please Wait", "Handshaking");
}
}
Console.log("Successfully connected!");
clients.set(client, new ClientConnection(0, client, clientDatachannel, clientDatachannelUnreliable)); // host is always 0
clientIdMap[0] = clients[client];
clientConnection = cast clients[client];
onConnectedToServer();
haxe.Timer.delay(() -> connectedCb(), 1500); // 1.5 second delay to do the RTT calculation
}
}
var onDatachannelMessage = (dc:RTCDataChannel, b:haxe.io.Bytes) -> {
onPacketReceived(clientConnection, client, clientDatachannel, new InputBitStream(b));
}
var onDatachannelClose = (dc:RTCDataChannel) -> {
closeFunc("Disconnected", false);
}
var onDatachannelError = (msg:String) -> {
Console.log('Errored out due to ${msg}');
closeFunc("Connection error", false);
}
clientDatachannel.onOpen = (n) -> {
onDatachannelOpen(1);
}
clientDatachannel.onMessage = (b) -> {
onDatachannelMessage(clientDatachannel, b);
}
clientDatachannel.onClosed = () -> {
onDatachannelClose(clientDatachannel);
}
clientDatachannel.onError = (msg) -> {
onDatachannelError(msg);
}
clientDatachannelUnreliable.onOpen = (n) -> {
onDatachannelOpen(2);
}
clientDatachannelUnreliable.onMessage = (b) -> {
onDatachannelMessage(clientDatachannelUnreliable, b);
}
clientDatachannelUnreliable.onClosed = () -> {
onDatachannelClose(clientDatachannelUnreliable);
}
clientDatachannelUnreliable.onError = (msg) -> {
onDatachannelError(msg);
}
});
}
public static function joinServer(serverName:String, password:String, connectedCb:() -> Void, turnTried:Bool = false) {}
public static function disconnect() {
if (Net.isClient) {
@ -403,14 +205,12 @@ class Net {
Net.clientIdMap.clear();
Net.clientConnection = null;
Net.serverInfo = null;
Net.remoteServerInfo = null;
Net.connectedServerInfo = null;
Net.lobbyHostReady = false;
Net.lobbyClientReady = false;
Net.hostReady = false;
Net.hostSpectate = false;
Net.clientSpectate = false;
MPPlayMissionGui.allChats = [];
// MultiplayerLevelSelectGui.custSelected = false;
}
if (Net.isHost) {
@ -425,16 +225,13 @@ class Net {
Net.clientIdAllocs = 1;
Net.clients.clear();
Net.clientIdMap.clear();
MasterServerClient.disconnectFromMasterServer();
Net.serverInfo = null;
Net.remoteServerInfo = null;
Net.connectedServerInfo = null;
Net.lobbyHostReady = false;
Net.lobbyClientReady = false;
Net.hostReady = false;
Net.hostSpectate = false;
Net.clientSpectate = false;
MPPlayMissionGui.allChats = [];
// MultiplayerLevelSelectGui.custSelected = false;
}
}
@ -474,34 +271,11 @@ class Net {
if (MarbleGame.instance.world != null) {
MarbleGame.instance.quitMission();
}
if (!(MarbleGame.canvas.content is MPMessageGui)) {
var loadGui = new MPMessageGui("Error", "Timed out");
MarbleGame.canvas.setContent(loadGui);
}
}
}
}
}
}
if (wsAccum >= 15.0) {
wsAccum = 0;
if (Net.isHost) {
if (MasterServerClient.instance != null)
MasterServerClient.instance.sendServerInfo(serverInfo); // Heartbeat
else
MasterServerClient.connectToMasterServer(() -> {
MasterServerClient.instance.sendServerInfo(serverInfo); // Heartbeat
});
}
if (Net.isClient) {
if (MasterServerClient.instance != null)
MasterServerClient.instance.heartBeat();
else
MasterServerClient.connectToMasterServer(() -> {
MasterServerClient.instance.heartBeat();
});
}
}
}
static function onClientConnect(c:RTCPeerConnection, dc:RTCDataChannel, dcu:RTCDataChannel) {
@ -580,16 +354,6 @@ class Net {
for (k => v in clients) { // Recount
serverInfo.players++;
}
MasterServerClient.instance.sendServerInfo(serverInfo); // notify the server of the new player
if (MarbleGame.canvas.content is MPPlayMissionGui) {
cast(MarbleGame.canvas.content, MPPlayMissionGui).updateLobbyNames();
}
if (MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1] is MPPreGameDlg) {
cast(MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1], MPPreGameDlg).updatePlayerList();
}
}
static function onConnectedToServer() {
@ -617,17 +381,7 @@ class Net {
serverInfo.players++;
}
MasterServerClient.instance.sendServerInfo(serverInfo); // notify the server of the player leave
// AudioManager.playSound(ResourceLoader.getAudio("data/sound/infotutorial.wav").resource);
if (MarbleGame.canvas.content is MPPlayMissionGui) {
cast(MarbleGame.canvas.content, MPPlayMissionGui).updateLobbyNames();
}
if (MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1] is MPPreGameDlg) {
cast(MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1], MPPreGameDlg).updatePlayerList();
}
}
static function onClientHandshakeComplete(conn:ClientConnection) {
@ -637,14 +391,12 @@ class Net {
// } else {
NetCommands.sendServerSettingsClient(conn, Settings.serverSettings.name, Settings.serverSettings.description, Settings.serverSettings.quickRespawn,
Settings.serverSettings.forceSpectators, Settings.serverSettings.competitiveMode, Settings.serverSettings.oldSpawns);
NetCommands.setLobbyLevelIndexClient(conn, MPPlayMissionGui.currentCategoryStatic, MPPlayMissionGui.currentSelectionStatic);
// }
if (serverInfo.state == "PLAYING") { // We initiated the game, directly add in the marble
// if (MultiplayerLevelSelectGui.custSelected) {
// NetCommands.playCustomLevelMidJoinClient(conn, MultiplayerLevelSelectGui.custPath);
// } else
NetCommands.playLevelMidJoinClient(conn, MPPlayMissionGui.currentCategoryStatic, MPPlayMissionGui.currentSelectionStatic);
MarbleGame.instance.world.addJoiningClient(conn, () -> {});
var playerInfoBytes = sendPlayerInfosBytes();
for (dc => cc in clients) {
@ -791,7 +543,6 @@ class Net {
var gemPickupPacket = new GemPickupPacket();
gemPickupPacket.deserialize(input);
if (MarbleGame.instance.world != null && !MarbleGame.instance.world._disposed) {
@:privateAccess MarbleGame.instance.world.playGui.incrementPlayerScore(gemPickupPacket.clientId, gemPickupPacket.scoreIncr);
@:privateAccess MarbleGame.instance.world.gemPredictions.acknowledgeGemPickup(gemPickupPacket);
}
@ -827,19 +578,10 @@ class Net {
Net.clientSpectate = cspectator;
}
}
if (MarbleGame.canvas.content is MPPlayMissionGui) {
cast(MarbleGame.canvas.content, MPPlayMissionGui).updateLobbyNames();
}
if (MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1] is MPPreGameDlg) {
cast(MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1], MPPreGameDlg).updatePlayerList();
}
case ScoreBoardInfo:
var scoreboardPacket = new ScoreboardPacket();
scoreboardPacket.deserialize(input);
if (MarbleGame.instance.world != null && !MarbleGame.instance.world._disposed) {
@:privateAccess MarbleGame.instance.world.playGui.updatePlayerScores(scoreboardPacket);
}
case ExplodableUpdate:
var explodableUpdatePacket = new ExplodableUpdatePacket();

View file

@ -1,19 +1,11 @@
package net;
import gui.MPMessageGui;
import gui.MessageBoxOkDlg;
import gui.JoinServerGui;
import gui.MPExitGameDlg;
import gui.MPEndGameGui;
import gui.MPPreGameDlg;
import gui.MPPlayMissionGui;
import net.ClientConnection.NetPlatform;
import gui.EndGameGui;
import modes.HuntMode;
import net.ClientConnection.GameplayState;
import net.Net.NetPacketType;
import src.MarbleGame;
import src.MissionList;
import src.Console;
import src.Marbleland;
import src.Settings;
@ -23,16 +15,7 @@ import src.ResourceLoader;
@:build(net.RPCMacro.build())
class NetCommands {
@:rpc(server) public static function setLobbyLevelIndex(category:String, i:Int) {
if (MPPlayMissionGui.setLevelFn == null) {
MPPlayMissionGui.currentCategoryStatic = category;
MPPlayMissionGui.currentSelectionStatic = i;
} else {
MPPlayMissionGui.currentCategoryStatic = category;
MPPlayMissionGui.currentSelectionStatic = i;
MPPlayMissionGui.setLevelFn(category, i);
}
}
@:rpc(server) public static function setLobbyLevelIndex(category:String, i:Int) {}
// @:rpc(server) public static function setLobbyCustLevelName(str:String) {
// if (MPPlayMissionGui.setLevelFn != null) {
@ -43,13 +26,7 @@ class NetCommands {
// }
// }
@:rpc(server) public static function playLevel(category:String, levelIndex:Int) {
MPPlayMissionGui.playSelectedLevel(category, levelIndex);
if (Net.isHost) {
Net.serverInfo.state = "WAITING";
MasterServerClient.instance.sendServerInfo(Net.serverInfo); // notify the server of the wait state
}
}
@:rpc(server) public static function playLevel(category:String, levelIndex:Int) {}
// @:rpc(server) public static function playCustomLevel(levelPath:String) {
// var levelEntry = MPCustoms.missionList.filter(x -> x.path == levelPath)[0];
@ -65,18 +42,7 @@ class NetCommands {
// }
@:rpc(server) public static function playLevelMidJoin(category:String, levelIndex:Int) {
if (Net.isClient) {
MissionList.buildMissionList();
if (category == "custom") {
var curMission = Marbleland.multiplayerMissions[levelIndex];
MarbleGame.instance.playMission(curMission, true);
} else {
var difficultyMissions = MissionList.missionList['multiplayer'][category];
var curMission = difficultyMissions[levelIndex];
MarbleGame.instance.playMission(curMission, true);
}
@:privateAccess MarbleGame.instance.world._skipPreGame = true;
}
if (Net.isClient) {}
}
// @:rpc(server) public static function playCustomLevelMidJoin(path:String) {
@ -86,76 +52,22 @@ class NetCommands {
// }
@:rpc(server) public static function enterLobby() {
if (Net.isClient) {
MarbleGame.canvas.setContent(new MPPlayMissionGui(false));
}
if (Net.isClient) {}
}
@:rpc(server) public static function setNetworkRNG(rng:Float) {
Net.networkRNG = rng;
if (MarbleGame.instance.world != null) {
var gameMode = MarbleGame.instance.world.gameMode;
if (gameMode is modes.HuntMode) {
var hunt:modes.HuntMode = cast gameMode;
@:privateAccess hunt.rng.setSeed(cast rng);
@:privateAccess hunt.rng2.setSeed(cast rng);
}
}
}
@:rpc(client) public static function toggleReadiness(clientId:Int) {
if (Net.isHost) {
if (clientId == 0)
Net.lobbyHostReady = !Net.lobbyHostReady;
else
Net.clientIdMap[clientId].toggleLobbyReady();
var allReady = true;
for (id => client in Net.clientIdMap) {
if (!client.lobbyReady) {
allReady = false;
break;
}
}
if (MarbleGame.canvas.content is MPPlayMissionGui) {
cast(MarbleGame.canvas.content, MPPlayMissionGui).updateLobbyNames();
}
if (MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1] is MPPreGameDlg) {
cast(MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1], MPPreGameDlg).updatePlayerList();
}
var b = Net.sendPlayerInfosBytes();
for (cc in Net.clients) {
cc.sendBytes(b);
}
if (allReady && Net.lobbyHostReady) {
// if (MultiplayerLevelSelectGui.custSelected) {
// NetCommands.playCustomLevel(MultiplayerLevelSelectGui.custPath);
// } else
if (MarbleGame.instance.world == null) {
NetCommands.playLevel(MPPlayMissionGui.currentCategoryStatic, MPPlayMissionGui.currentSelectionStatic);
} else {}
}
}
if (Net.isHost) {}
}
@:rpc(client) public static function toggleSpectate(clientId:Int) {
if (Net.isHost) {
if (clientId == 0)
Net.hostSpectate = !Net.hostSpectate;
else
Net.clientIdMap[clientId].toggleSpectate();
if (MarbleGame.canvas.content is MPPlayMissionGui) {
cast(MarbleGame.canvas.content, MPPlayMissionGui).updateLobbyNames();
}
if (MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1] is MPPreGameDlg) {
cast(MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1], MPPreGameDlg).updatePlayerList();
}
var b = Net.sendPlayerInfosBytes();
for (cc in Net.clients) {
cc.sendBytes(b);
}
}
if (Net.isHost) {}
}
@:rpc(client) public static function clientIsReady(clientId:Int) {
@ -170,12 +82,6 @@ class NetCommands {
Console.log("Mid game join for client " + clientId);
// Send em our present world state
if (MarbleGame.instance.world != null) {
var packets = MarbleGame.instance.world.getWorldStateForClientJoin();
var c = Net.clientIdMap[clientId];
for (packet in packets) {
c.sendBytes(packet);
}
Net.clientIdMap[clientId].ready();
if (Settings.serverSettings.forceSpectators) {
@ -199,9 +105,6 @@ class NetCommands {
MarbleGame.instance.world.allClientsReady();
}
}
} else {
// Send the start ticks
NetCommands.setStartTicksMidJoinClient(c, MarbleGame.instance.world.serverStartTicks, MarbleGame.instance.world.timeState.ticks);
}
}
}
@ -222,23 +125,6 @@ class NetCommands {
@:privateAccess MarbleGame.instance.world.marble.serverTicks = ticks;
}
MarbleGame.instance.world.startTime = MarbleGame.instance.world.timeState.timeSinceLoad + 3.5 + 0.032; // 1 extra tick
if (MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1] is MPPreGameDlg) {
MarbleGame.canvas.popDialog(MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1]);
MarbleGame.instance.world.setCursorLock(true);
if (Util.isTouchDevice()) {
MarbleGame.canvas.render(MarbleGame.canvas.scene2d);
MarbleGame.instance.touchInput.setControlsEnabled(true);
}
MarbleGame.instance.world.marble.camera.stopOverview();
AudioManager.playSound(ResourceLoader.getAudio('data/sound/spawn.wav').resource);
}
if (Net.clientSpectate || Net.hostSpectate) {
MarbleGame.instance.world.marble.camera.enableSpectate();
} else {
MarbleGame.instance.world.marble.camera.stopSpectate();
}
}
}
@ -250,137 +136,27 @@ class NetCommands {
}
}
@:rpc(server) public static function timerRanOut() {
if (Net.isClient && MarbleGame.instance.world != null) {
if (MarbleGame.instance.paused) {
MarbleGame.instance.handlePauseGame(); // Unpause
}
var huntMode:HuntMode = cast MarbleGame.instance.world.gameMode;
huntMode.onTimeExpire();
}
if (Net.isHost) {
Net.serverInfo.state = "WAITING";
MasterServerClient.instance.sendServerInfo(Net.serverInfo); // notify the server of the playing state
}
}
@:rpc(server) public static function timerRanOut() {}
@:rpc(server) public static function clientDisconnected(clientId:Int) {
var conn = Net.clientIdMap.get(clientId);
if (MarbleGame.instance.world != null) {
MarbleGame.instance.world.removePlayer(conn);
}
Net.clientIdMap.remove(clientId);
if (MarbleGame.canvas.content is MPPlayMissionGui) {
cast(MarbleGame.canvas.content, MPPlayMissionGui).updateLobbyNames();
}
if (MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1] is MPPreGameDlg) {
cast(MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1], MPPreGameDlg).updatePlayerList();
}
}
@:rpc(server) public static function clientDisconnected(clientId:Int) {}
@:rpc(server) public static function clientJoin(clientId:Int) {}
@:rpc(client) public static function clientLeave(clientId:Int) {
if (Net.isHost) {
@:privateAccess Net.onClientLeave(cast Net.clientIdMap[clientId]);
}
}
@:rpc(client) public static function clientLeave(clientId:Int) {}
@:rpc(server) public static function serverClosed() {
if (Net.isClient) {
if (MarbleGame.instance.world != null) {
MarbleGame.instance.quitMission();
}
MarbleGame.canvas.setContent(new MPMessageGui("Info", "Server closed"));
}
}
@:rpc(server) public static function serverClosed() {}
@:rpc(server) public static function getKicked() {
if (Net.isClient) {
Net.disconnect();
MarbleGame.canvas.setContent(new MPMessageGui("Info", "You have been kicked from the server"));
}
}
@:rpc(server) public static function getKicked() {}
@:rpc(client) public static function setPlayerData(clientId:Int, name:String, marble:Int, marbleCat:Int, needRetransmit:Bool) {
if (Net.isHost) {
Net.clientIdMap[clientId].setName(name);
Net.clientIdMap[clientId].setMarbleId(marble, marbleCat);
if (MarbleGame.canvas.content is MPPlayMissionGui) {
cast(MarbleGame.canvas.content, MPPlayMissionGui).updateLobbyNames();
}
if (needRetransmit) {
var b = Net.sendPlayerInfosBytes();
for (cc in Net.clients) {
cc.sendBytes(b);
}
}
}
}
@:rpc(client) public static function setPlayerData(clientId:Int, name:String, marble:Int, marbleCat:Int, needRetransmit:Bool) {}
@:rpc(client) public static function transmitPlatform(clientId:Int, platform:Int) {
if (Net.isHost) {
Net.clientIdMap[clientId].platform = platform;
if (MarbleGame.canvas.content is MPPlayMissionGui) {
cast(MarbleGame.canvas.content, MPPlayMissionGui).updateLobbyNames();
}
}
}
@:rpc(client) public static function transmitPlatform(clientId:Int, platform:Int) {}
@:rpc(server) public static function endGame() {
for (c => v in Net.clientIdMap) {
v.state = LOBBY;
v.lobbyReady = false;
}
if (Net.isClient) {
if (MarbleGame.instance.world != null) {
MarbleGame.instance.quitMission();
}
}
if (Net.isHost) {
Net.lobbyHostReady = false;
Net.hostReady = false;
@:rpc(server) public static function endGame() {}
Net.serverInfo.state = "LOBBY";
MasterServerClient.instance.sendServerInfo(Net.serverInfo); // notify the server of the playing state
var b = Net.sendPlayerInfosBytes();
for (cc in Net.clients) {
cc.sendBytes(b);
}
}
}
@:rpc(server) public static function completeRestartGame() {}
@:rpc(server) public static function completeRestartGame() {
if (Net.isClient) {
var gui = MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1];
if (gui is MPEndGameGui || gui is MPExitGameDlg) {
MarbleGame.instance.paused = false;
MarbleGame.canvas.popDialog(gui);
// egg.retryFunc(null);
}
}
var world = MarbleGame.instance.world;
world.completeRestart();
if (Net.isClient) {
world.restartMultiplayerState();
}
}
@:rpc(server) public static function partialRestartGame() {
if (Net.isClient) {
var gui = MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1];
if (gui is MPEndGameGui || gui is MPExitGameDlg) {
MarbleGame.instance.paused = false;
MarbleGame.canvas.popDialog(gui);
// egg.retryFunc(null);
}
}
var world = MarbleGame.instance.world;
world.partialRestart();
if (Net.isClient) {
world.restartMultiplayerState();
}
}
@:rpc(server) public static function partialRestartGame() {}
@:rpc(server) public static function ping(sendTime:Float) {
if (Net.isClient) {
@ -419,20 +195,16 @@ class NetCommands {
@:rpc(server) public static function sendServerChatMessage(msg:String) {
if (MarbleGame.instance.world != null) {
if (MarbleGame.instance.world._ready) {
@:privateAccess MarbleGame.instance.world.playGui.addChatMessage(msg);
// @:privateAccess MarbleGame.instance.world.playGui.addChatMessage(msg);
}
} else {
// if (MarbleGame.canvas.content is MultiplayerLevelSelectGui) {
// cast(MarbleGame.canvas.content, MultiplayerLevelSelectGui).addChatMessage(msg);
// }
}
MPPlayMissionGui.addChatMessage(msg);
}
@:rpc(server) public static function setCompetitiveTimerStartTicks(ticks:Int) {
if (MarbleGame.instance.world != null) {
var huntMode = cast(MarbleGame.instance.world.gameMode, HuntMode);
huntMode.setCompetitiveTimerStartTicks(ticks);
}
if (MarbleGame.instance.world != null) {}
}
}

View file

@ -1,23 +0,0 @@
package touch;
import src.MarbleGame;
import touch.TouchInput.Touch;
import h3d.Vector;
import hxd.Window;
import src.ResourceLoader;
import src.Settings;
class BlastButton extends TouchButton {
public var didPressIt:Bool = true;
public function new() {
var mode = MarbleGame.instance.world != null ? @:privateAccess MarbleGame.instance.world.marble.camera.spectate : false;
super(ResourceLoader.getImage(mode ? "data/ui/touch/video-camera.png" : "data/ui/touch/explosion.png").resource,
new Vector(Settings.touchSettings.blastButtonPos[0], Settings.touchSettings.blastButtonPos[1]), Settings.touchSettings.blastButtonSize);
this.setEnabled(false);
this.onClick = () -> {
this.pressed = true;
didPressIt = true;
}
}
}

View file

@ -1,25 +0,0 @@
package touch;
import src.MarbleGame;
import touch.TouchInput.Touch;
import h3d.Vector;
import hxd.Window;
import src.ResourceLoader;
import src.Settings;
class SpectatorChangeTargetButton extends TouchButton {
public var didPressIt:Bool = true;
public function new(rightFacing:Bool) {
super(ResourceLoader.getImage(rightFacing ? "data/ui/touch/right.png" : "data/ui/touch/left.png").resource, new Vector(rightFacing ? 560 : 70, 120),
60);
if (!rightFacing) {
this.guiElement.horizSizing = Right;
}
this.setEnabled(false);
this.onClick = () -> {
this.pressed = true;
didPressIt = true;
}
}
}

View file

@ -42,12 +42,9 @@ class TouchInput {
public var jumpButton:JumpButton;
public var powerupButton:PowerupButton;
public var blastbutton:BlastButton;
public var pauseButton:PauseButton;
public var rewindButton:RewindButton;
public var restartButton:RestartButton;
public var leftButton:SpectatorChangeTargetButton;
public var rightButton:SpectatorChangeTargetButton;
public var currentTouchState:TouchEventState;
@ -60,7 +57,6 @@ class TouchInput {
this.movementInput = new MovementInput();
this.jumpButton = new JumpButton();
this.powerupButton = new PowerupButton();
this.blastbutton = new BlastButton();
this.pauseButton = new PauseButton();
this.rewindButton = new RewindButton();
this.restartButton = new RestartButton();
@ -112,8 +108,6 @@ class TouchInput {
public function showControls(parentGui:GuiControl, ultra:Bool) {
jumpButton.dispose();
powerupButton.dispose();
if (ultra)
blastbutton.dispose();
movementInput.dispose();
pauseButton.dispose();
restartButton.dispose();
@ -124,8 +118,6 @@ class TouchInput {
this.powerupButton = new PowerupButton();
if (Settings.optionsSettings.rewindEnabled && !MarbleGame.instance.world.isMultiplayer)
this.rewindButton = new RewindButton();
if (ultra)
this.blastbutton = new BlastButton();
this.pauseButton = new PauseButton();
if (!MarbleGame.instance.world.isMultiplayer)
this.restartButton = new RestartButton();
@ -136,8 +128,6 @@ class TouchInput {
powerupButton.add(parentGui);
if (Settings.optionsSettings.rewindEnabled && !MarbleGame.instance.world.isMultiplayer)
rewindButton.add(parentGui);
if (ultra)
blastbutton.add(parentGui);
movementInput.add(parentGui);
cameraInput.add(parentGui);
cameraInput.enabled = true;
@ -145,26 +135,18 @@ class TouchInput {
if (Settings.touchSettings.hideControls) {
this.jumpButton.setVisible(false);
this.powerupButton.setVisible(false);
if (this.blastbutton != null)
this.blastbutton.setVisible(false);
this.movementInput.setVisible(false);
this.pauseButton.setVisible(false);
if (this.restartButton != null)
this.restartButton.setVisible(false);
if (this.rewindButton != null)
this.rewindButton.setVisible(false);
if (this.leftButton != null)
this.leftButton.setVisible(false);
if (this.rightButton != null)
this.rightButton.setVisible(false);
}
}
public function setControlsEnabled(enabled:Bool) {
this.jumpButton.setVisible(enabled);
this.powerupButton.setVisible(enabled);
if (this.blastbutton != null)
this.blastbutton.setVisible(enabled);
this.movementInput.setVisible(enabled);
this.pauseButton.setVisible(enabled);
if (this.restartButton != null)
@ -172,31 +154,19 @@ class TouchInput {
if (this.rewindButton != null)
this.rewindButton.setVisible(enabled);
this.cameraInput.enabled = enabled;
if (this.leftButton != null)
this.leftButton.setVisible(enabled);
if (this.rightButton != null)
this.rightButton.setVisible(enabled);
if (Settings.touchSettings.hideControls) {
this.jumpButton.setVisible(false);
this.powerupButton.setVisible(false);
if (this.blastbutton != null)
this.blastbutton.setVisible(false);
this.movementInput.setVisible(false);
if (this.rewindButton != null)
this.rewindButton.setVisible(false);
if (this.leftButton != null)
this.leftButton.setVisible(false);
if (this.rightButton != null)
this.rightButton.setVisible(false);
}
}
public function hideControls(parentGui:GuiControl) {
jumpButton.remove(parentGui);
powerupButton.remove(parentGui);
if (this.blastbutton != null)
blastbutton.remove(parentGui);
movementInput.remove(parentGui);
pauseButton.remove(parentGui);
if (this.restartButton != null)
@ -204,14 +174,6 @@ class TouchInput {
cameraInput.remove(parentGui);
if (this.rewindButton != null)
rewindButton.remove(parentGui);
if (this.leftButton != null) {
leftButton.remove(parentGui);
leftButton.dispose();
}
if (this.rightButton != null) {
rightButton.remove(parentGui);
rightButton.dispose();
}
jumpButton.dispose();
powerupButton.dispose();
movementInput.dispose();
@ -221,41 +183,4 @@ class TouchInput {
if (this.rewindButton != null)
rewindButton.dispose();
}
public function setSpectatorControls(enabled:Bool) {
var tile = ResourceLoader.getImage(enabled ? "data/ui/touch/video-camera.png" : "data/ui/touch/explosion.png").resource;
@:privateAccess this.blastbutton.guiElement.graphics.content.state.tail.texture = tile.toTexture();
if (enabled) {
jumpButton.setVisible(false);
if (this.leftButton == null) { // both are added at same time so it doesnt matter
var par = jumpButton.guiElement.parent;
this.leftButton = new SpectatorChangeTargetButton(false);
this.rightButton = new SpectatorChangeTargetButton(true);
this.leftButton.add(par);
this.rightButton.add(par);
this.leftButton.guiElement.render(MarbleGame.canvas.scene2d, @:privateAccess par._flow);
this.rightButton.guiElement.render(MarbleGame.canvas.scene2d, @:privateAccess par._flow);
}
} else {
jumpButton.setVisible(true);
if (this.leftButton != null) {
this.leftButton.remove(this.leftButton.guiElement.parent);
this.leftButton.dispose();
this.leftButton = null;
}
if (this.rightButton != null) {
this.rightButton.remove(this.rightButton.guiElement.parent);
this.rightButton.dispose();
this.rightButton = null;
}
}
}
public function setSpectatorControlsVisibility(enabled:Bool) {
if (this.leftButton != null) {
this.leftButton.setVisible(enabled);
this.rightButton.setVisible(enabled);
this.movementInput.setVisible(!enabled);
}
}
}