end game initial

This commit is contained in:
RandomityGuy 2024-06-21 22:42:30 +05:30
parent 651726bb06
commit 7837be38e9
8 changed files with 389 additions and 16 deletions

View file

@ -500,7 +500,7 @@ class MarbleWorld extends Scheduler {
if (client == null) {
marblefiles.push(StringTools.replace(Settings.optionsSettings.marbleModel, "data/", ""));
} else {
var marbleDts = MarbleSelectGui.marbleData[0][client.getMarbleId()].dts; // FIXME
var marbleDts = MarbleSelectGui.marbleData[client.getMarbleCatId()][client.getMarbleId()].dts; // FIXME
marblefiles.push(StringTools.replace(marbleDts, "data/", ""));
}
@ -1581,9 +1581,9 @@ class MarbleWorld extends Scheduler {
return;
}
if (Key.isPressed(Key.T)) {
rollback(0.4);
}
// if (Key.isPressed(Key.T)) {
// rollback(0.4);
// }
var realDt = dt;
@ -2021,10 +2021,9 @@ class MarbleWorld extends Scheduler {
AudioManager.playSound(ResourceLoader.getResource("data/sound/alarm_timeout.wav", ResourceLoader.getAudio, this.soundResources));
}
}
if (finishTime != null)
this.timeState.gameplayClock = finishTime.gameplayClock;
}
if (finishTime != null)
this.timeState.gameplayClock = finishTime.gameplayClock;
playGui.formatTimer(this.timeState.gameplayClock, determineClockColor(this.timeState.gameplayClock));
if (!this.isWatching && this.isRecording)

277
src/gui/MPEndGameGui.hx Normal file
View file

@ -0,0 +1,277 @@
package gui;
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);
if (Net.isClient) {
lobbyBtn.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;
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 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 Marble";
middleCtrl.addChild(headerML);
var scores = @:privateAccess MarbleGame.instance.world.playGui.playerList;
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,
dy: 1,
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);
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, 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 = 0x0000FF;
playerB.text.text = '${b}';
playerB.justify = Center;
playerB.position = new Vector(452, 3);
playerB.extent = new Vector(52, 14);
container.addChild(playerB);
var marble = buildObjectShow(MarbleSelectGui.marbleData[marbleCat][marbleSel].dts, new Vector(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, 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

@ -48,6 +48,9 @@ class PlayerInfo {
var name:String;
var us:Bool;
var score:Int;
var r:Int;
var y:Int;
var b:Int;
}
class PlayGui {
@ -604,7 +607,10 @@ class PlayGui {
id: id,
name: name,
us: us,
score: 0
score: 0,
r: 0,
y: 0,
b: 0
});
redrawPlayerList();
}
@ -621,8 +627,18 @@ class PlayGui {
public function incrementPlayerScore(id:Int, score:Int) {
var f = playerList.filter(x -> x.id == id);
if (f.length != 0)
if (f.length != 0) {
f[0].score += score;
if (score == 1) {
f[0].r += 1;
}
if (score == 2) {
f[0].y += 1;
}
if (score == 5) {
f[0].b += 1;
}
}
if (id == Net.clientId) {
if (Net.isClient)
@ -636,6 +652,9 @@ class PlayGui {
public function updatePlayerScores(scoreboardPacket:ScoreboardPacket) {
for (player in playerList) {
player.score = scoreboardPacket.scoreBoard.exists(player.id) ? scoreboardPacket.scoreBoard.get(player.id) : 0;
player.r = scoreboardPacket.rBoard.exists(player.id) ? scoreboardPacket.rBoard.get(player.id) : 0;
player.y = scoreboardPacket.yBoard.exists(player.id) ? scoreboardPacket.yBoard.get(player.id) : 0;
player.b = scoreboardPacket.bBoard.exists(player.id) ? scoreboardPacket.bBoard.get(player.id) : 0;
}
redrawPlayerList();
}

View file

@ -1,5 +1,7 @@
package modes;
import gui.MPEndGameGui;
import net.NetCommands;
import net.BitStream.OutputBitStream;
import net.NetPacket.GemPickupPacket;
import net.NetPacket.GemSpawnPacket;
@ -21,6 +23,7 @@ import src.Marble;
import src.AudioManager;
import src.ResourceLoader;
import net.Net;
import src.MarbleGame;
@:structInit
@:publicFields
@ -94,6 +97,7 @@ class HuntMode extends NullMode {
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;
@ -113,7 +117,21 @@ class HuntMode extends NullMode {
override function getRespawnTransform(marble:Marble) {
var lastContactPos = marble.lastContactPosition;
if (lastContactPos == null) {
return getSpawnTransform();
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();
spawnPos = spawnPos.add(up); // 1.5 -> 0.5
return {
position: spawnPos,
orientation: spawnRot,
up: up
}
}
// Pick closest spawn point
var closestSpawn:MissionElementTrigger = null;
@ -340,6 +358,43 @@ class HuntMode extends NullMode {
prepareGems();
}
override function onTimeExpire() {
if (level.finishTime != null)
return;
// 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;
}
level.schedule(level.timeState.currentAttemptTime + 2, () -> {
MarbleGame.canvas.setContent(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)

View file

@ -76,6 +76,7 @@ abstract class GameConnection {
var lobbyReady:Bool;
var platform:NetPlatform;
var marbleId:Int;
var marbleCatId:Int;
function new(id:Int) {
this.id = id;
@ -127,11 +128,16 @@ abstract class GameConnection {
name = value;
}
public inline function setMarbleId(value:Int) {
public inline function setMarbleId(value:Int, category:Int) {
marbleId = value;
marbleCatId = category;
}
public inline function getMarbleId() {
return marbleId;
}
public inline function getMarbleCatId() {
return marbleCatId;
}
}

View file

@ -624,6 +624,7 @@ class Net {
b.writeByte(v.lobbyReady ? 1 : 0);
b.writeByte(v.platform);
b.writeByte(v.marbleId);
b.writeByte(v.marbleCatId);
var name = v.getName();
b.writeByte(name.length);
for (i in 0...name.length) {
@ -635,6 +636,7 @@ class Net {
b.writeByte(Net.lobbyHostReady ? 1 : 0);
b.writeByte(getPlatform());
b.writeByte(Settings.optionsSettings.marbleIndex);
b.writeByte(Settings.optionsSettings.marbleCategoryIndex);
var name = Settings.highscoreName;
b.writeByte(name.length);
for (i in 0...name.length) {
@ -657,7 +659,8 @@ class Net {
case ClientIdAssign:
clientId = input.readByte(); // 8 bit client id, hopefully we don't exceed this
Console.log('Client ID set to ${clientId}');
NetCommands.setPlayerData(clientId, Settings.highscoreName, Settings.optionsSettings.marbleIndex); // Send our player name to the server
NetCommands.setPlayerData(clientId, Settings.highscoreName, Settings.optionsSettings.marbleIndex,
Settings.optionsSettings.marbleCategoryIndex); // Send our player name to the server
NetCommands.transmitPlatform(clientId, getPlatform()); // send our platform too
case Ping:
@ -744,6 +747,7 @@ class Net {
var cready = input.readByte() == 1;
var platform = input.readByte();
var marble = input.readByte();
var marbleCat = input.readByte();
if (id != 0 && id != Net.clientId && !clientIdMap.exists(id)) {
Console.log('Adding ghost connection ${id}');
addGhost(id);
@ -756,7 +760,7 @@ class Net {
}
if (clientIdMap.exists(id)) {
clientIdMap[id].setName(name);
clientIdMap[id].setMarbleId(marble);
clientIdMap[id].setMarbleId(marble, marbleCat);
clientIdMap[id].lobbyReady = cready;
clientIdMap[id].platform = platform;
}

View file

@ -266,10 +266,10 @@ class NetCommands {
}
}
@:rpc(client) public static function setPlayerData(clientId:Int, name:String, marble:Int) {
@:rpc(client) public static function setPlayerData(clientId:Int, name:String, marble:Int, marbleCat:Int) {
if (Net.isHost) {
Net.clientIdMap[clientId].setName(name);
Net.clientIdMap[clientId].setMarbleId(marble);
Net.clientIdMap[clientId].setMarbleId(marble, marbleCat);
if (MarbleGame.canvas.content is MPPlayMissionGui) {
cast(MarbleGame.canvas.content, MPPlayMissionGui).updateLobbyNames();
}

View file

@ -258,15 +258,25 @@ class GemPickupPacket implements NetPacket {
@:publicFields
class ScoreboardPacket implements NetPacket {
var scoreBoard:Map<Int, Int>;
var rBoard:Map<Int, Int>;
var yBoard:Map<Int, Int>;
var bBoard:Map<Int, Int>;
public function new() {
scoreBoard = new Map();
rBoard = new Map();
yBoard = new Map();
bBoard = new Map();
}
public inline function deserialize(b:InputBitStream) {
var count = b.readInt(4);
for (i in 0...count) {
scoreBoard[b.readInt(6)] = b.readInt(10);
var id = b.readInt(6);
scoreBoard[id] = b.readInt(10);
rBoard[id] = b.readInt(10);
yBoard[id] = b.readInt(10);
bBoard[id] = b.readInt(10);
}
}
@ -278,6 +288,9 @@ class ScoreboardPacket implements NetPacket {
for (key => v in scoreBoard) {
b.writeInt(key, 6);
b.writeInt(v, 10);
b.writeInt(rBoard[key], 10);
b.writeInt(yBoard[key], 10);
b.writeInt(bBoard[key], 10);
}
}
}