pre-game stuff

This commit is contained in:
RandomityGuy 2024-06-20 22:12:22 +05:30
parent cc57591342
commit a1c4691466
9 changed files with 233 additions and 120 deletions

View file

@ -1,5 +1,6 @@
package src;
import gui.MPPreGameDlg;
import gui.MPExitGameDlg;
import gui.GuiControl;
import gui.MPPlayMissionGui;
@ -204,6 +205,9 @@ 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) {
return; // don't pause
}
paused = !paused;
handlePauseGame();
}

View file

@ -531,10 +531,10 @@ class MarbleWorld extends Scheduler {
interior.onLevelStart();
for (shape in this.dtsObjects)
shape.onLevelStart();
if (this.isMultiplayer && Net.isClient)
NetCommands.clientIsReady(Net.clientId);
// if (this.isMultiplayer && Net.isClient)
// NetCommands.clientIsReady(Net.clientId);
if (this.isMultiplayer && Net.isHost) {
NetCommands.clientIsReady(-1);
// NetCommands.clientIsReady(-1);
// Sort all the marbles so that they are updated in a deterministic order
this.marbles.sort((a, b) -> @:privateAccess {
@ -1719,50 +1719,53 @@ class MarbleWorld extends Scheduler {
var otherMoves = [];
var myMove = null;
for (marble in marbles) {
var move = marble.updateServer(fixedDt, collisionWorld, pathedInteriors);
if (marble == this.marble)
myMove = move;
else
otherMoves.push(move);
}
if (serverStartTicks != 0) {
for (marble in marbles) {
var move = marble.updateServer(fixedDt, collisionWorld, pathedInteriors);
if (marble == this.marble)
myMove = move;
else
otherMoves.push(move);
}
if (myMove != null && Net.isClient) {
this.predictions.storeState(marble, myMove.timeState.ticks);
for (client => marble in clientMarbles) {
if (myMove != null && Net.isClient) {
this.predictions.storeState(marble, myMove.timeState.ticks);
}
}
if (Net.isHost) {
packets.push(marble.packUpdate(myMove, fixedDt));
for (othermarble in marbles) {
if (othermarble != this.marble) {
var mv = otherMoves.shift();
packets.push(othermarble.packUpdate(mv, fixedDt));
for (client => marble in clientMarbles) {
this.predictions.storeState(marble, myMove.timeState.ticks);
}
}
// for (client => othermarble in clientMarbles) { // Oh no!
// var mv = otherMoves.shift();
// packets.push(marble.packUpdate(myMove, fixedDt));
// packets.push(othermarble.packUpdate(mv, fixedDt));
// }
var allRecv = true;
for (client => marble in clientMarbles) { // Oh no!
// var pktClone = packets.copy();
// pktClone.sort((a, b) -> {
// return (a.c == client.id) ? 1 : (b.c == client.id) ? -1 : 0;
// });
if (client.state != GAME) {
allRecv = false;
continue; // Only send if in game
if (Net.isHost) {
packets.push(marble.packUpdate(myMove, fixedDt));
for (othermarble in marbles) {
if (othermarble != this.marble) {
var mv = otherMoves.shift();
packets.push(othermarble.packUpdate(mv, fixedDt));
}
}
marble.clearNetFlags();
for (packet in packets) {
client.sendBytes(packet);
// for (client => othermarble in clientMarbles) { // Oh no!
// var mv = otherMoves.shift();
// packets.push(marble.packUpdate(myMove, fixedDt));
// packets.push(othermarble.packUpdate(mv, fixedDt));
// }
var allRecv = true;
for (client => marble in clientMarbles) { // Oh no!
// var pktClone = packets.copy();
// pktClone.sort((a, b) -> {
// return (a.c == client.id) ? 1 : (b.c == client.id) ? -1 : 0;
// });
if (client.state != GAME) {
allRecv = false;
continue; // Only send if in game
}
marble.clearNetFlags();
for (packet in packets) {
client.sendBytes(packet);
}
}
if (allRecv)
this.marble.clearNetFlags();
}
if (allRecv)
this.marble.clearNetFlags();
}
timeState.ticks++;
}

View file

@ -34,18 +34,28 @@ class GuiMLTextListCtrl extends GuiControl {
public var scrollable:Bool = false;
var filter:Filter = null;
var dropShadow:{
dx:Float,
dy:Float,
color:Int,
alpha:Float
};
var flow:Flow;
var _imageLoader:String->Tile;
public function new(font:Font, texts:Array<String>, imageLoader:String->Tile, ?filter:Filter = null) {
public function new(font:Font, texts:Array<String>, imageLoader:String->Tile, ?filter:{
dx:Float,
dy:Float,
color:Int,
alpha:Float
} = null) {
super();
this.font = font;
this.texts = texts;
this._manualScroll = true;
this.textObjs = [];
this.filter = filter;
this.dropShadow = filter;
this._imageLoader = imageLoader;
for (text in texts) {
var tobj = new HtmlText(font);
@ -54,7 +64,7 @@ class GuiMLTextListCtrl extends GuiControl {
tobj.text = text;
tobj.textColor = 0;
if (filter != null)
tobj.filter = filter;
tobj.dropShadow = filter;
textObjs.push(tobj);
}
this.g = new Graphics();
@ -72,8 +82,8 @@ class GuiMLTextListCtrl extends GuiControl {
tobj.lineHeightMode = TextOnly;
tobj.text = text;
tobj.textColor = 0;
if (filter != null)
tobj.filter = filter;
if (dropShadow != null)
tobj.dropShadow = dropShadow;
textObjs.push(tobj);
if (this.scrollable) {

View file

@ -25,6 +25,7 @@ class GuiTextListCtrl extends GuiControl {
public var selectedColor:Int = 0x206464;
public var selectedFillColor:Int = 0xC8C8C8;
public var selectedFillColorAlpha:Float = 1.0;
public var textColor:Int = 0;
public var textYOffset:Int = 0;
@ -33,19 +34,33 @@ class GuiTextListCtrl extends GuiControl {
public var scrollable:Bool = false;
var dropShadow:{
dx:Float,
dy:Float,
color:Int,
alpha:Float
};
var flow:Flow;
public function new(font:Font, texts:Array<String>, textColor:Int = 0) {
public function new(font:Font, texts:Array<String>, textColor:Int = 0, ?filter:{
dx:Float,
dy:Float,
color:Int,
alpha:Float
} = null) {
super();
this.font = font;
this.texts = texts;
this._manualScroll = true;
this.textObjs = [];
this.textColor = textColor;
this.dropShadow = filter;
for (text in texts) {
var tobj = new Text(font);
tobj.text = text;
tobj.textColor = textColor;
tobj.dropShadow = this.dropShadow;
textObjs.push(tobj);
}
this.g = new Graphics();
@ -61,6 +76,7 @@ class GuiTextListCtrl extends GuiControl {
var tobj = new Text(font);
tobj.text = text;
tobj.textColor = textColor;
tobj.dropShadow = this.dropShadow;
textObjs.push(tobj);
if (this.scrollable && this.flow != null) {
@ -188,7 +204,7 @@ class GuiTextListCtrl extends GuiControl {
var renderRect = this.getRenderRectangle();
var yStart = renderRect.position.y;
var dy = mousePos.y - yStart;
var hoverIndex = Math.floor(dy / (font.size + 4 * Settings.uiScale));
var hoverIndex = Math.floor((dy + this.scroll) / (font.size + 4 * Settings.uiScale));
if (hoverIndex >= this.texts.length) {
hoverIndex = -1;
}
@ -238,7 +254,7 @@ class GuiTextListCtrl extends GuiControl {
function redrawSelectionRect(renderRect:Rect) {
if (_prevSelected != -1) {
g.clear();
g.beginFill(selectedFillColor);
g.beginFill(selectedFillColor, selectedFillColorAlpha);
var off = this.getOffsetFromParent();
// Check if we are between the top and bottom, render normally in that case

View file

@ -45,7 +45,6 @@ class MPPlayMissionGui extends GuiImage {
#end
var playerListCtrl:GuiTextListCtrl;
var playerListCtrlDs:GuiTextListCtrl;
public function new(isHost:Bool = true) {
MissionList.buildMissionList();
@ -336,13 +335,6 @@ class MPPlayMissionGui extends GuiImage {
playersBox.extent = new Vector(305, 229);
window.addChild(playersBox);
playerListCtrlDs = new GuiTextListCtrl(markerFelt18, [], 0x000000);
playerListCtrlDs.position = new Vector(-1, 25);
playerListCtrlDs.extent = new Vector(305, 203);
playerListCtrlDs.scrollable = true;
playerListCtrlDs.textYOffset = -6;
playersBox.addChild(playerListCtrlDs);
playerListCtrl = new GuiTextListCtrl(markerFelt18, [], 0xFFFFFF);
playerListCtrl.position = new Vector(0, 26);
playerListCtrl.extent = new Vector(305, 203);
@ -616,7 +608,6 @@ class MPPlayMissionGui extends GuiImage {
}
var playerListCompiled = playerListArr.map(player -> player.name);
playerListCtrlDs.setTexts(playerListCompiled);
playerListCtrl.setTexts(playerListCompiled);
// if (!showingCustoms)

View file

@ -1,5 +1,6 @@
package gui;
import net.NetCommands;
import h2d.filter.DropShadow;
import net.Net;
import src.MarbleGame;
@ -7,6 +8,8 @@ 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() {
@ -53,15 +56,32 @@ class MPPreGameDlg extends GuiControl {
leaveBtn.vertSizing = Top;
leaveBtn.position = new Vector(499, 388);
leaveBtn.extent = new Vector(94, 45);
leaveBtn.pressedAction = (e) -> {
MarbleGame.instance.quitMission(true);
}
dialogImg.addChild(leaveBtn);
var playBtn = new GuiButton(loadButtonImages("/data/ui/mp/pre/play"));
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;
dialogImg.addChild(playBtn);
playBtn.disabled = true;
playBtn.pressedAction = (e) -> {
for (id => client in Net.clientIdMap) {
client.state = GAME;
}
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;
@ -144,7 +164,7 @@ class MPPreGameDlg extends GuiControl {
playerTitle.text.textColor = 0xDDDDEE;
playerTitle.position = new Vector(60, 263);
playerTitle.extent = new Vector(525, 14);
playerTitle.text.text = "Player Status";
playerTitle.text.text = "Player Status";
playerTitle.text.dropShadow = {
dx: 1,
dy: 1,
@ -161,40 +181,101 @@ class MPPreGameDlg extends GuiControl {
// playerList.maxScrollY = 394 * Settings.uiScale;
dialogImg.addChild(playerListContainer);
var playerListLeftShadow = new GuiTextListCtrl(markerFelt18, [
Settings.highscoreName,
Settings.highscoreName,
Settings.highscoreName,
Settings.highscoreName,
Settings.highscoreName,
Settings.highscoreName,
Settings.highscoreName,
Settings.highscoreName
], 0);
playerListLeftShadow.horizSizing = Width;
playerListLeftShadow.position = new Vector(0, 0);
playerListLeftShadow.extent = new Vector(525, 99);
playerListLeftShadow.scrollable = true;
playerListLeftShadow.textYOffset = -6;
playerListContainer.addChild(playerListLeftShadow);
var playerListLeft = new GuiTextListCtrl(markerFelt18, [
Settings.highscoreName,
Settings.highscoreName,
Settings.highscoreName,
Settings.highscoreName,
Settings.highscoreName,
Settings.highscoreName,
Settings.highscoreName,
Settings.highscoreName
], 0xFFFFFF);
var playerListLeft = new GuiTextListCtrl(markerFelt18, [], 0xFFFFFF, {
dx: 1,
dy: 1,
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, 99);
playerListLeft.extent = new Vector(525, 2880);
playerListLeft.scrollable = true;
playerListLeft.textYOffset = -6;
playerListContainer.addChild(playerListLeft);
var playerListRight = new GuiTextListCtrl(markerFelt18, [], 0xFFFFFF, {
dx: 1,
dy: 1,
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
});
}
if (Net.isClient) {
playerListArr.push({
name: Settings.highscoreName,
ready: Net.lobbyClientReady
});
}
if (Net.clientIdMap != null) {
for (c => v in Net.clientIdMap) {
playerListArr.push({
name: v.name,
ready: v.lobbyReady
});
}
}
for (p in playerListArr) {
if (!p.ready) {
allReady = false;
break;
}
}
playBtn.disabled = !allReady;
var playerListCompiled = playerListArr.map(player -> player.name);
var playerListStateCompiled = playerListArr.map(player -> player.ready ? "[Ready]" : "[Waiting]");
playerListLeft.setTexts(playerListCompiled);
playerListRight.setTexts(playerListStateCompiled);
// 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;
}
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

@ -86,8 +86,6 @@ class PlayGui {
var playerListContainer:GuiControl;
var playerListCtrl:GuiMLTextListCtrl;
var playerListScoresCtrl:GuiMLTextListCtrl;
var playerListShadowCtrl:GuiMLTextListCtrl;
var playerListScoresShadowCtrl:GuiMLTextListCtrl;
var playerList:Array<PlayerInfo> = [];
var imageResources:Array<Resource<Image>> = [];
@ -113,12 +111,8 @@ class PlayGui {
playerListContainer = null;
playerListCtrl.dispose();
playerListCtrl = null;
playerListShadowCtrl.dispose();
playerListShadowCtrl = null;
playerListScoresCtrl.dispose();
playerListScoresCtrl = null;
playerListScoresShadowCtrl.dispose();
playerListScoresShadowCtrl = null;
}
gemImageScene.dispose();
@ -550,23 +544,12 @@ class PlayGui {
return null;
}
playerListShadowCtrl = new GuiMLTextListCtrl(bfont, [], imgLoader);
playerListShadowCtrl.position = new Vector(34, 4);
playerListShadowCtrl.extent = new Vector(210, 271);
playerListShadowCtrl.scrollable = true;
playerListShadowCtrl.onSelectedFunc = (sel) -> {}
playerListContainer.addChild(playerListShadowCtrl);
playerListScoresShadowCtrl = new GuiMLTextListCtrl(bfont, [], imgLoader);
playerListScoresShadowCtrl.position = new Vector(234, 4);
playerListScoresShadowCtrl.extent = new Vector(210, 271);
playerListScoresShadowCtrl.scrollable = true;
playerListScoresShadowCtrl.onSelectedFunc = (sel) -> {}
playerListContainer.addChild(playerListScoresShadowCtrl);
playerListCtrl = new GuiMLTextListCtrl(bfont, [], imgLoader);
playerListCtrl = new GuiMLTextListCtrl(bfont, [], imgLoader, {
dx: 1,
dy: 1,
color: 0,
alpha: 1
});
playerListCtrl.position = new Vector(33, 3);
playerListCtrl.extent = new Vector(210, 271);
@ -574,7 +557,12 @@ class PlayGui {
playerListCtrl.onSelectedFunc = (sel) -> {}
playerListContainer.addChild(playerListCtrl);
playerListScoresCtrl = new GuiMLTextListCtrl(bfont, [], imgLoader);
playerListScoresCtrl = new GuiMLTextListCtrl(bfont, [], imgLoader, {
dx: 1,
dy: 1,
color: 0,
alpha: 1
});
playerListScoresCtrl.position = new Vector(233, 3);
playerListScoresCtrl.extent = new Vector(210, 271);
@ -586,8 +574,6 @@ class PlayGui {
public function redrawPlayerList() {
var pl = [];
var plScores = [];
var plShadow = [];
var plShadowScores = [];
var col0 = "#CFB52B";
var col1 = "#CDCDCD";
var col2 = "#D19275";
@ -607,13 +593,9 @@ class PlayGui {
};
pl.push('<font color="${color}">${i + 1}. ${Util.rightPad(item.name, 25, 3)}</font>');
plScores.push('<font color="${color}">${item.score}</font>');
plShadow.push('<font color="#000000">${i + 1}. ${Util.rightPad(item.name, 25, 3)}</font>');
plShadowScores.push('<font color="#000000">${item.score}</font>');
}
playerListCtrl.setTexts(pl);
playerListScoresCtrl.setTexts(plScores);
playerListShadowCtrl.setTexts(plShadow);
playerListScoresShadowCtrl.setTexts(plShadowScores);
}
public function addPlayer(id:Int, name:String, us:Bool) {

View file

@ -1,5 +1,6 @@
package net;
import gui.MPPreGameDlg;
import net.NetPacket.ScoreboardPacket;
import gui.MPPlayMissionGui;
import gui.Canvas;
@ -537,6 +538,10 @@ class Net {
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() {
@ -571,6 +576,10 @@ class Net {
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) {
@ -758,6 +767,9 @@ class Net {
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();

View file

@ -1,5 +1,6 @@
package net;
import gui.MPPreGameDlg;
import gui.MPPlayMissionGui;
import net.ClientConnection.NetPlatform;
import gui.EndGameGui;
@ -99,6 +100,9 @@ class NetCommands {
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);
@ -108,7 +112,9 @@ class NetCommands {
// if (MultiplayerLevelSelectGui.custSelected) {
// NetCommands.playCustomLevel(MultiplayerLevelSelectGui.custPath);
// } else
NetCommands.playLevel(MPPlayMissionGui.currentCategoryStatic, MPPlayMissionGui.currentSelectionStatic);
if (MarbleGame.instance.world == null) {
NetCommands.playLevel(MPPlayMissionGui.currentCategoryStatic, MPPlayMissionGui.currentSelectionStatic);
} else {}
}
}
}
@ -185,6 +191,11 @@ 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);
}
}
}
@ -230,6 +241,9 @@ class NetCommands {
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 clientJoin(clientId:Int) {}