From 2e94b434f891b7d6992cf0a3ea591fb9ef8160eb Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Sun, 23 Jun 2024 23:24:06 +0530 Subject: [PATCH] mp rework bit --- src/InteriorObject.hx | 4 ++ src/MarbleWorld.hx | 2 +- src/Marbleland.hx | 22 +++++++- src/PathedInterior.hx | 35 ++++++++++-- src/gui/MPPlayMissionGui.hx | 15 ++++- src/net/NetCommands.hx | 12 +++- src/rewind/RewindFrame.hx | 109 ++++++++++++++++++++++-------------- src/rewind/RewindManager.hx | 38 ++++++++----- 8 files changed, 164 insertions(+), 73 deletions(-) diff --git a/src/InteriorObject.hx b/src/InteriorObject.hx index 9aeaf8f2..10279429 100644 --- a/src/InteriorObject.hx +++ b/src/InteriorObject.hx @@ -1,5 +1,6 @@ package src; +import collision.CollisionWorld; import src.MarbleWorld; import src.DifBuilder; import h3d.Matrix; @@ -12,6 +13,7 @@ class InteriorObject extends GameObject { public var interiorFile:String; public var useInstancing = true; public var level:MarbleWorld; + public var collisionWorld:CollisionWorld; public function new() { super(); @@ -21,6 +23,8 @@ class InteriorObject extends GameObject { public function init(level:MarbleWorld, onFinish:Void->Void) { this.identifier = this.interiorFile; this.level = level; + if (this.level != null) + this.collisionWorld = this.level.collisionWorld; DifBuilder.loadDif(this.interiorFile, cast this, onFinish); } diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index d4faf939..77c8e904 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -263,7 +263,6 @@ class MarbleWorld extends Scheduler { this.scene2d = scene2d; this.mission = mission; this.game = mission.game.toLowerCase(); - this.gameMode = GameModeFactory.getGameMode(cast this, mission.gameMode); this.replay = new Replay(mission.path, mission.isClaMission ? mission.id : 0); this.isRecording = record; this.rewindManager = new RewindManager(cast this); @@ -324,6 +323,7 @@ class MarbleWorld extends Scheduler { } }; this.mission.load(); + this.gameMode = GameModeFactory.getGameMode(cast this, mission.gameMode); scanMission(this.mission.root); this.gameMode.missionScan(this.mission); this.resourceLoadFuncs.push(fwd -> this.initScene(fwd)); diff --git a/src/Marbleland.hx b/src/Marbleland.hx index 8d5f9bb2..afb806eb 100644 --- a/src/Marbleland.hx +++ b/src/Marbleland.hx @@ -13,6 +13,7 @@ class Marbleland { public static var goldMissions = []; public static var ultraMissions = []; public static var platinumMissions = []; + public static var multiplayerMissions = []; public static var missions:Map = []; public static function init() { @@ -21,6 +22,7 @@ class Marbleland { Console.log('Loaded gold customs: ${goldMissions.length}'); Console.log('Loaded ultra customs: ${ultraMissions.length}'); Console.log('Loaded platinum customs: ${platinumMissions.length}'); + Console.log('Loaded multiplayer customs: ${multiplayerMissions.length}'); }, (e) -> { Console.log('Error getting custom list from marbleland.'); }); @@ -36,9 +38,11 @@ class Marbleland { continue; if (!['gold', 'platinum', 'ultra', 'platinumquest'].contains(missionData.modification)) continue; - if (missionData.gameMode != null && missionData.gameMode != 'null') + if (missionData.gameMode != null && !(missionData.gameMode == 'null' || missionData.gameMode.toLowerCase() == 'hunt')) continue; - if (missionData.gameType != 'single') + + var isMultiplayer = missionData.gameType == 'multi'; + if (isMultiplayer && (missionData.gameMode == null || missionData.gameMode.toLowerCase() != 'hunt')) continue; var mission = new Mission(); @@ -62,8 +66,12 @@ class Marbleland { mission.hasEgg = missionData.hasEgg; mission.isClaMission = true; mission.addedAt = missionData.addedAt; + mission.gameMode = missionData.gameMode; var game = missionData.modification; + if (isMultiplayer) { + game = 'multiplayer'; + } if (game == 'platinum') { if (platDupes.exists(mission.title + mission.description)) @@ -79,6 +87,8 @@ class Marbleland { ultraMissions.push(mission); case 'platinum': platinumMissions.push(mission); + case 'multiplayer': + multiplayerMissions.push(mission); } missions.set(mission.id, mission); @@ -106,6 +116,14 @@ class Marbleland { } @:privateAccess ultraMissions[ultraMissions.length - 1].next = ultraMissions[0]; ultraMissions[ultraMissions.length - 1].index = ultraMissions.length - 1; + + multiplayerMissions.sort((x, y) -> x.title > y.title ? 1 : (x.title < y.title ? -1 : 0)); + for (i in 0...multiplayerMissions.length - 1) { + @:privateAccess multiplayerMissions[i].next = multiplayerMissions[i + 1]; + multiplayerMissions[i].index = i; + } + @:privateAccess multiplayerMissions[multiplayerMissions.length - 1].next = multiplayerMissions[0]; + multiplayerMissions[multiplayerMissions.length - 1].index = multiplayerMissions.length - 1; } public static function getMissionImage(id:Int, cb:Image->Void) { diff --git a/src/PathedInterior.hx b/src/PathedInterior.hx index 9111ce75..8dc68c16 100644 --- a/src/PathedInterior.hx +++ b/src/PathedInterior.hx @@ -44,9 +44,13 @@ class PathedInterior extends InteriorObject { var baseOrientation:Quat; var baseScale:Vector; + var prevPosition:Vector; + var position:Vector; + public var velocity:Vector; var stopped:Bool = false; + var stoppedPosition:Vector; var soundChannel:Channel; @@ -57,6 +61,7 @@ class PathedInterior extends InteriorObject { onFinish(null); var pathedInterior = new PathedInterior(); pathedInterior.level = level; + pathedInterior.collisionWorld = level.collisionWorld; DifBuilder.loadDif(difFile, pathedInterior, () -> { pathedInterior.identifier = difFile + interiorElement.interiorindex; @@ -158,10 +163,10 @@ class PathedInterior extends InteriorObject { currentTime += delta; } - var curTform = this.getAbsPos(); + var curTform = this.position; var tForm = getTransformAtTime(currentTime); - var displaceDelta = tForm.getPosition().sub(curTform.getPosition()); + var displaceDelta = tForm.getPosition().sub(curTform); velocity.set(displaceDelta.x / timeDelta, displaceDelta.y / timeDelta, displaceDelta.z / timeDelta); this.collider.velocity = velocity.clone(); } @@ -172,9 +177,15 @@ class PathedInterior extends InteriorObject { return; if (this.velocity.length() == 0) return; - var newp = this.getAbsPos().getPosition().add(velocity.multiply(timeDelta)); - this.setPosition(newp.x, newp.y, newp.z); - this.setTransform(this.getTransform()); + var newp = position.add(velocity.multiply(timeDelta)); + var tform = this.getAbsPos().clone(); + tform.setPosition(newp); + + if (this.isCollideable) { + collider.setTransform(tform); + collisionWorld.updateTransform(this.collider); + } + this.position.load(newp); if (this.soundChannel != null) { var spat = this.soundChannel.getEffect(Spatialization); @@ -182,12 +193,22 @@ class PathedInterior extends InteriorObject { } } - public function update(timeState:TimeState) {} + public function update(timeState:TimeState) { + if (!stopped) + this.setPosition(prevPosition.x + + velocity.x * timeState.dt, prevPosition.y + + velocity.y * timeState.dt, + prevPosition.z + + velocity.z * timeState.dt); + else + this.setPosition(stoppedPosition.x, stoppedPosition.y, stoppedPosition.z); + } public function setStopped(stopped:Bool = true) { // if (!this.stopped) // this.stopTime = currentTime; this.stopped = stopped; + this.stoppedPosition = this.position.clone(); } function computeDuration() { @@ -205,6 +226,8 @@ class PathedInterior extends InteriorObject { function updatePosition() { var newp = this.getAbsPos().getPosition(); + this.position = newp; + this.prevPosition = newp; this.setPosition(newp.x, newp.y, newp.z); this.collider.setTransform(this.getTransform()); this.collider.velocity = this.velocity; diff --git a/src/gui/MPPlayMissionGui.hx b/src/gui/MPPlayMissionGui.hx index 04202d46..dbe9090a 100644 --- a/src/gui/MPPlayMissionGui.hx +++ b/src/gui/MPPlayMissionGui.hx @@ -1,5 +1,6 @@ package gui; +import src.Marbleland; import h2d.Scene; import hxd.Key; import gui.GuiControl.MouseState; @@ -391,7 +392,10 @@ class MPPlayMissionGui extends GuiImage { } setCategoryFunc = function(category:String, ?sort:String = null, ?doRender:Bool = true) { - currentList = MissionList.missionList["multiplayer"][category]; + if (category == "custom") { + currentList = Marbleland.multiplayerMissions; + } else + currentList = MissionList.missionList["multiplayer"][category]; @:privateAccess difficultySelector.anim.frames = loadButtonImages('data/ui/mp/play/difficulty_${category}'); @@ -542,8 +546,13 @@ class MPPlayMissionGui extends GuiImage { // if (custSelected) { // NetCommands.playCustomLevel(MPCustoms.missionList[custSelectedIdx].path); // } else { - var curMission = MissionList.missionList["multiplayer"][cat][index]; // mission[index]; - MarbleGame.instance.playMission(curMission, true); + 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); + } // } } diff --git a/src/net/NetCommands.hx b/src/net/NetCommands.hx index b7d4a332..28410e5e 100644 --- a/src/net/NetCommands.hx +++ b/src/net/NetCommands.hx @@ -15,6 +15,7 @@ import net.Net.NetPacketType; import src.MarbleGame; import src.MissionList; import src.Console; +import src.Marbleland; @:build(net.RPCMacro.build()) class NetCommands { @@ -60,9 +61,14 @@ class NetCommands { @:rpc(server) public static function playLevelMidJoin(category:String, levelIndex:Int) { if (Net.isClient) { MissionList.buildMissionList(); - var difficultyMissions = MissionList.missionList['multiplayer'][category]; - var curMission = difficultyMissions[levelIndex]; - MarbleGame.instance.playMission(curMission, true); + 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; } } diff --git a/src/rewind/RewindFrame.hx b/src/rewind/RewindFrame.hx index 3ff793ec..a120c5f9 100644 --- a/src/rewind/RewindFrame.hx +++ b/src/rewind/RewindFrame.hx @@ -14,6 +14,29 @@ import src.TimeState; import src.DtsObject; import shapes.Gem; +@:publicFields +class RewindMPState { + var currentTime:Float; + var targetTime:Float; + var stoppedPosition:Vector; + var prevPosition:Vector; + var position:Vector; + var velocity:Vector; + + public function new() {} + + public function clone() { + var c = new RewindMPState(); + c.currentTime = currentTime; + c.targetTime = targetTime; + c.stoppedPosition = stoppedPosition != null ? stoppedPosition.clone() : null; + c.prevPosition = prevPosition.clone(); + c.position = position.clone(); + c.velocity = velocity.clone(); + return c; + } +} + @:publicFields class RewindFrame { var timeState:TimeState; @@ -23,11 +46,7 @@ class RewindFrame { var marbleAngularVelocity:Vector; var marblePowerup:PowerUp; var bonusTime:Float; - var mpStates:Array<{ - curState:PIState, - stopped:Bool, - position:Vector - }>; + var mpStates:Array; var gemCount:Int; var gemStates:Array; var powerupStates:Array; @@ -69,18 +88,7 @@ class RewindFrame { c.activePowerupStates = activePowerupStates.copy(); c.currentUp = currentUp.clone(); c.lastContactNormal = lastContactNormal.clone(); - c.mpStates = []; - for (s in mpStates) { - c.mpStates.push({ - curState: { - currentTime: s.curState.currentTime, - targetTime: s.curState.targetTime, - velocity: s.curState.velocity.clone(), - }, - stopped: s.stopped, - position: s.position.clone(), - }); - } + c.mpStates = mpStates.copy(); c.trapdoorStates = []; for (s in trapdoorStates) { c.trapdoorStates.push({ @@ -127,11 +135,14 @@ class RewindFrame { framesize += 24; // lastContactNormal framesize += 2; // mpStates.length for (s in mpStates) { - framesize += 8; // s.curState.currentTime - framesize += 8; // s.curState.targetTime - framesize += 24; // s.curState.velocity - framesize += 1; // s.stopped + framesize += 8; // s.currentTime + framesize += 8; // s.targetTime + framesize += 1; // Null + if (s.stoppedPosition != null) + framesize += 24; // s.stoppedPosition + framesize += 24; // s.prevPosition framesize += 24; // s.position + framesize += 24; // s.velocity } framesize += 2; // trapdoorStates.length for (s in trapdoorStates) { @@ -204,15 +215,23 @@ class RewindFrame { bb.writeDouble(lastContactNormal.z); bb.writeInt16(mpStates.length); for (s in mpStates) { - bb.writeDouble(s.curState.currentTime); - bb.writeDouble(s.curState.targetTime); - bb.writeDouble(s.curState.velocity.x); - bb.writeDouble(s.curState.velocity.y); - bb.writeDouble(s.curState.velocity.z); - bb.writeByte(s.stopped ? 1 : 0); + bb.writeDouble(s.currentTime); + bb.writeDouble(s.targetTime); + bb.writeByte(s.stoppedPosition == null ? 0 : 1); + if (s.stoppedPosition != null) { + bb.writeDouble(s.stoppedPosition.x); + bb.writeDouble(s.stoppedPosition.y); + bb.writeDouble(s.stoppedPosition.z); + } + bb.writeDouble(s.prevPosition.x); + bb.writeDouble(s.prevPosition.y); + bb.writeDouble(s.prevPosition.z); bb.writeDouble(s.position.x); bb.writeDouble(s.position.y); bb.writeDouble(s.position.z); + bb.writeDouble(s.velocity.x); + bb.writeDouble(s.velocity.y); + bb.writeDouble(s.velocity.z); } bb.writeInt16(trapdoorStates.length); for (s in trapdoorStates) { @@ -307,28 +326,32 @@ class RewindFrame { currentUp.z = br.readDouble(); lastContactNormal.x = br.readDouble(); lastContactNormal.y = br.readDouble(); - lastContactNormal.z = br.readDouble(); mpStates = []; var mpStates_len = br.readInt16(); for (i in 0...mpStates_len) { - var mpStates_item = { - curState: { - currentTime: 0.0, - targetTime: 0.0, - velocity: new Vector(), - }, - stopped: false, - position: new Vector() - }; - mpStates_item.curState.currentTime = br.readDouble(); - mpStates_item.curState.targetTime = br.readDouble(); - mpStates_item.curState.velocity.x = br.readDouble(); - mpStates_item.curState.velocity.y = br.readDouble(); - mpStates_item.curState.velocity.z = br.readDouble(); - mpStates_item.stopped = br.readByte() != 0; + var mpStates_item = new RewindMPState(); + mpStates_item.currentTime = br.readDouble(); + mpStates_item.targetTime = br.readDouble(); + mpStates_item.stoppedPosition = new Vector(); + mpStates_item.prevPosition = new Vector(); + mpStates_item.position = new Vector(); + mpStates_item.velocity = new Vector(); + if (br.readByte() != 0) { + mpStates_item.stoppedPosition.x = br.readDouble(); + mpStates_item.stoppedPosition.y = br.readDouble(); + mpStates_item.stoppedPosition.z = br.readDouble(); + } else { + mpStates_item.stoppedPosition = null; + } + mpStates_item.prevPosition.x = br.readDouble(); + mpStates_item.prevPosition.y = br.readDouble(); + mpStates_item.prevPosition.z = br.readDouble(); mpStates_item.position.x = br.readDouble(); mpStates_item.position.y = br.readDouble(); mpStates_item.position.z = br.readDouble(); + mpStates_item.velocity.x = br.readDouble(); + mpStates_item.velocity.y = br.readDouble(); + mpStates_item.velocity.z = br.readDouble(); mpStates.push(mpStates_item); } trapdoorStates = []; diff --git a/src/rewind/RewindManager.hx b/src/rewind/RewindManager.hx index 000b61da..30d9cc2f 100644 --- a/src/rewind/RewindManager.hx +++ b/src/rewind/RewindManager.hx @@ -1,5 +1,6 @@ package rewind; +import rewind.RewindFrame.RewindMPState; import haxe.io.BytesInput; import haxe.io.BytesBuffer; import mis.MissionElement.MissionElementBase; @@ -53,15 +54,14 @@ class RewindManager { rf.currentUp = level.marble.currentUp.clone(); rf.lastContactNormal = level.marble.lastContactNormal.clone(); rf.mpStates = level.pathedInteriors.map(x -> { - return { - curState: { - currentTime: x.currentTime, - targetTime: x.targetTime, - velocity: x.velocity.clone(), - }, - stopped: @:privateAccess x.stopped, - position: x.getAbsPos().getPosition().clone(), - } + var mpstate = new RewindMPState(); + mpstate.currentTime = x.currentTime; + mpstate.targetTime = x.targetTime; + mpstate.velocity = x.velocity.clone(); + mpstate.stoppedPosition = @:privateAccess x.stopped ? @:privateAccess x.stoppedPosition.clone() : null; + mpstate.position = @:privateAccess x.position.clone(); + mpstate.prevPosition = @:privateAccess x.prevPosition.clone(); + return mpstate; }); rf.powerupStates = []; rf.landMineStates = []; @@ -167,12 +167,20 @@ class RewindManager { level.marble.currentUp.set(rf.currentUp.x, rf.currentUp.y, rf.currentUp.z); level.marble.lastContactNormal.set(rf.lastContactNormal.x, rf.lastContactNormal.y, rf.lastContactNormal.z); for (i in 0...rf.mpStates.length) { - level.pathedInteriors[i].currentTime = rf.mpStates[i].curState.currentTime; - level.pathedInteriors[i].targetTime = rf.mpStates[i].curState.targetTime; - level.pathedInteriors[i].velocity.set(rf.mpStates[i].curState.velocity.x, rf.mpStates[i].curState.velocity.y, rf.mpStates[i].curState.velocity.z); - @:privateAccess level.pathedInteriors[i].stopped = rf.mpStates[i].stopped; - level.pathedInteriors[i].setPosition(rf.mpStates[i].position.x, rf.mpStates[i].position.y, rf.mpStates[i].position.z); - level.pathedInteriors[i].setTransform(level.pathedInteriors[i].getTransform()); + level.pathedInteriors[i].currentTime = rf.mpStates[i].currentTime; + level.pathedInteriors[i].targetTime = rf.mpStates[i].targetTime; + level.pathedInteriors[i].velocity.load(rf.mpStates[i].velocity); + @:privateAccess level.pathedInteriors[i].stopped = rf.mpStates[i].stoppedPosition != null; + @:privateAccess level.pathedInteriors[i].position.load(rf.mpStates[i].position); + @:privateAccess level.pathedInteriors[i].prevPosition.load(rf.mpStates[i].prevPosition); + @:privateAccess level.pathedInteriors[i].stoppedPosition = rf.mpStates[i].stoppedPosition; + if (level.pathedInteriors[i].isCollideable) { + var tform = level.pathedInteriors[i].getAbsPos().clone(); + tform.setPosition(rf.mpStates[i].position); + @:privateAccess level.pathedInteriors[i].collider.setTransform(tform); + level.collisionWorld.updateTransform(@:privateAccess level.pathedInteriors[i].collider); + } + // level.pathedInteriors[i].setTransform(level.pathedInteriors[i].getTransform()); } var pstates = rf.powerupStates.copy(); var lmstates = rf.landMineStates.copy();