mp rework bit

This commit is contained in:
RandomityGuy 2024-06-23 23:24:06 +05:30
parent 3e6958b150
commit 2e94b434f8
8 changed files with 164 additions and 73 deletions

View file

@ -1,5 +1,6 @@
package src; package src;
import collision.CollisionWorld;
import src.MarbleWorld; import src.MarbleWorld;
import src.DifBuilder; import src.DifBuilder;
import h3d.Matrix; import h3d.Matrix;
@ -12,6 +13,7 @@ class InteriorObject extends GameObject {
public var interiorFile:String; public var interiorFile:String;
public var useInstancing = true; public var useInstancing = true;
public var level:MarbleWorld; public var level:MarbleWorld;
public var collisionWorld:CollisionWorld;
public function new() { public function new() {
super(); super();
@ -21,6 +23,8 @@ class InteriorObject extends GameObject {
public function init(level:MarbleWorld, onFinish:Void->Void) { public function init(level:MarbleWorld, onFinish:Void->Void) {
this.identifier = this.interiorFile; this.identifier = this.interiorFile;
this.level = level; this.level = level;
if (this.level != null)
this.collisionWorld = this.level.collisionWorld;
DifBuilder.loadDif(this.interiorFile, cast this, onFinish); DifBuilder.loadDif(this.interiorFile, cast this, onFinish);
} }

View file

@ -263,7 +263,6 @@ class MarbleWorld extends Scheduler {
this.scene2d = scene2d; this.scene2d = scene2d;
this.mission = mission; this.mission = mission;
this.game = mission.game.toLowerCase(); 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.replay = new Replay(mission.path, mission.isClaMission ? mission.id : 0);
this.isRecording = record; this.isRecording = record;
this.rewindManager = new RewindManager(cast this); this.rewindManager = new RewindManager(cast this);
@ -324,6 +323,7 @@ class MarbleWorld extends Scheduler {
} }
}; };
this.mission.load(); this.mission.load();
this.gameMode = GameModeFactory.getGameMode(cast this, mission.gameMode);
scanMission(this.mission.root); scanMission(this.mission.root);
this.gameMode.missionScan(this.mission); this.gameMode.missionScan(this.mission);
this.resourceLoadFuncs.push(fwd -> this.initScene(fwd)); this.resourceLoadFuncs.push(fwd -> this.initScene(fwd));

View file

@ -13,6 +13,7 @@ class Marbleland {
public static var goldMissions = []; public static var goldMissions = [];
public static var ultraMissions = []; public static var ultraMissions = [];
public static var platinumMissions = []; public static var platinumMissions = [];
public static var multiplayerMissions = [];
public static var missions:Map<Int, Mission> = []; public static var missions:Map<Int, Mission> = [];
public static function init() { public static function init() {
@ -21,6 +22,7 @@ class Marbleland {
Console.log('Loaded gold customs: ${goldMissions.length}'); Console.log('Loaded gold customs: ${goldMissions.length}');
Console.log('Loaded ultra customs: ${ultraMissions.length}'); Console.log('Loaded ultra customs: ${ultraMissions.length}');
Console.log('Loaded platinum customs: ${platinumMissions.length}'); Console.log('Loaded platinum customs: ${platinumMissions.length}');
Console.log('Loaded multiplayer customs: ${multiplayerMissions.length}');
}, (e) -> { }, (e) -> {
Console.log('Error getting custom list from marbleland.'); Console.log('Error getting custom list from marbleland.');
}); });
@ -36,9 +38,11 @@ class Marbleland {
continue; continue;
if (!['gold', 'platinum', 'ultra', 'platinumquest'].contains(missionData.modification)) if (!['gold', 'platinum', 'ultra', 'platinumquest'].contains(missionData.modification))
continue; continue;
if (missionData.gameMode != null && missionData.gameMode != 'null') if (missionData.gameMode != null && !(missionData.gameMode == 'null' || missionData.gameMode.toLowerCase() == 'hunt'))
continue; continue;
if (missionData.gameType != 'single')
var isMultiplayer = missionData.gameType == 'multi';
if (isMultiplayer && (missionData.gameMode == null || missionData.gameMode.toLowerCase() != 'hunt'))
continue; continue;
var mission = new Mission(); var mission = new Mission();
@ -62,8 +66,12 @@ class Marbleland {
mission.hasEgg = missionData.hasEgg; mission.hasEgg = missionData.hasEgg;
mission.isClaMission = true; mission.isClaMission = true;
mission.addedAt = missionData.addedAt; mission.addedAt = missionData.addedAt;
mission.gameMode = missionData.gameMode;
var game = missionData.modification; var game = missionData.modification;
if (isMultiplayer) {
game = 'multiplayer';
}
if (game == 'platinum') { if (game == 'platinum') {
if (platDupes.exists(mission.title + mission.description)) if (platDupes.exists(mission.title + mission.description))
@ -79,6 +87,8 @@ class Marbleland {
ultraMissions.push(mission); ultraMissions.push(mission);
case 'platinum': case 'platinum':
platinumMissions.push(mission); platinumMissions.push(mission);
case 'multiplayer':
multiplayerMissions.push(mission);
} }
missions.set(mission.id, mission); missions.set(mission.id, mission);
@ -106,6 +116,14 @@ class Marbleland {
} }
@:privateAccess ultraMissions[ultraMissions.length - 1].next = ultraMissions[0]; @:privateAccess ultraMissions[ultraMissions.length - 1].next = ultraMissions[0];
ultraMissions[ultraMissions.length - 1].index = ultraMissions.length - 1; 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) { public static function getMissionImage(id:Int, cb:Image->Void) {

View file

@ -44,9 +44,13 @@ class PathedInterior extends InteriorObject {
var baseOrientation:Quat; var baseOrientation:Quat;
var baseScale:Vector; var baseScale:Vector;
var prevPosition:Vector;
var position:Vector;
public var velocity:Vector; public var velocity:Vector;
var stopped:Bool = false; var stopped:Bool = false;
var stoppedPosition:Vector;
var soundChannel:Channel; var soundChannel:Channel;
@ -57,6 +61,7 @@ class PathedInterior extends InteriorObject {
onFinish(null); onFinish(null);
var pathedInterior = new PathedInterior(); var pathedInterior = new PathedInterior();
pathedInterior.level = level; pathedInterior.level = level;
pathedInterior.collisionWorld = level.collisionWorld;
DifBuilder.loadDif(difFile, pathedInterior, () -> { DifBuilder.loadDif(difFile, pathedInterior, () -> {
pathedInterior.identifier = difFile + interiorElement.interiorindex; pathedInterior.identifier = difFile + interiorElement.interiorindex;
@ -158,10 +163,10 @@ class PathedInterior extends InteriorObject {
currentTime += delta; currentTime += delta;
} }
var curTform = this.getAbsPos(); var curTform = this.position;
var tForm = getTransformAtTime(currentTime); 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); velocity.set(displaceDelta.x / timeDelta, displaceDelta.y / timeDelta, displaceDelta.z / timeDelta);
this.collider.velocity = velocity.clone(); this.collider.velocity = velocity.clone();
} }
@ -172,9 +177,15 @@ class PathedInterior extends InteriorObject {
return; return;
if (this.velocity.length() == 0) if (this.velocity.length() == 0)
return; return;
var newp = this.getAbsPos().getPosition().add(velocity.multiply(timeDelta)); var newp = position.add(velocity.multiply(timeDelta));
this.setPosition(newp.x, newp.y, newp.z); var tform = this.getAbsPos().clone();
this.setTransform(this.getTransform()); tform.setPosition(newp);
if (this.isCollideable) {
collider.setTransform(tform);
collisionWorld.updateTransform(this.collider);
}
this.position.load(newp);
if (this.soundChannel != null) { if (this.soundChannel != null) {
var spat = this.soundChannel.getEffect(Spatialization); 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) { public function setStopped(stopped:Bool = true) {
// if (!this.stopped) // if (!this.stopped)
// this.stopTime = currentTime; // this.stopTime = currentTime;
this.stopped = stopped; this.stopped = stopped;
this.stoppedPosition = this.position.clone();
} }
function computeDuration() { function computeDuration() {
@ -205,6 +226,8 @@ class PathedInterior extends InteriorObject {
function updatePosition() { function updatePosition() {
var newp = this.getAbsPos().getPosition(); var newp = this.getAbsPos().getPosition();
this.position = newp;
this.prevPosition = newp;
this.setPosition(newp.x, newp.y, newp.z); this.setPosition(newp.x, newp.y, newp.z);
this.collider.setTransform(this.getTransform()); this.collider.setTransform(this.getTransform());
this.collider.velocity = this.velocity; this.collider.velocity = this.velocity;

View file

@ -1,5 +1,6 @@
package gui; package gui;
import src.Marbleland;
import h2d.Scene; import h2d.Scene;
import hxd.Key; import hxd.Key;
import gui.GuiControl.MouseState; import gui.GuiControl.MouseState;
@ -391,7 +392,10 @@ class MPPlayMissionGui extends GuiImage {
} }
setCategoryFunc = function(category:String, ?sort:String = null, ?doRender:Bool = true) { 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}'); @:privateAccess difficultySelector.anim.frames = loadButtonImages('data/ui/mp/play/difficulty_${category}');
@ -542,8 +546,13 @@ class MPPlayMissionGui extends GuiImage {
// if (custSelected) { // if (custSelected) {
// NetCommands.playCustomLevel(MPCustoms.missionList[custSelectedIdx].path); // NetCommands.playCustomLevel(MPCustoms.missionList[custSelectedIdx].path);
// } else { // } else {
var curMission = MissionList.missionList["multiplayer"][cat][index]; // mission[index]; if (cat == "custom") {
MarbleGame.instance.playMission(curMission, true); 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);
}
// } // }
} }

View file

@ -15,6 +15,7 @@ import net.Net.NetPacketType;
import src.MarbleGame; import src.MarbleGame;
import src.MissionList; import src.MissionList;
import src.Console; import src.Console;
import src.Marbleland;
@:build(net.RPCMacro.build()) @:build(net.RPCMacro.build())
class NetCommands { class NetCommands {
@ -60,9 +61,14 @@ class NetCommands {
@:rpc(server) public static function playLevelMidJoin(category:String, levelIndex:Int) { @:rpc(server) public static function playLevelMidJoin(category:String, levelIndex:Int) {
if (Net.isClient) { if (Net.isClient) {
MissionList.buildMissionList(); MissionList.buildMissionList();
var difficultyMissions = MissionList.missionList['multiplayer'][category]; if (category == "custom") {
var curMission = difficultyMissions[levelIndex]; var curMission = Marbleland.multiplayerMissions[levelIndex];
MarbleGame.instance.playMission(curMission, true); 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; @:privateAccess MarbleGame.instance.world._skipPreGame = true;
} }
} }

View file

@ -14,6 +14,29 @@ import src.TimeState;
import src.DtsObject; import src.DtsObject;
import shapes.Gem; 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 @:publicFields
class RewindFrame { class RewindFrame {
var timeState:TimeState; var timeState:TimeState;
@ -23,11 +46,7 @@ class RewindFrame {
var marbleAngularVelocity:Vector; var marbleAngularVelocity:Vector;
var marblePowerup:PowerUp; var marblePowerup:PowerUp;
var bonusTime:Float; var bonusTime:Float;
var mpStates:Array<{ var mpStates:Array<RewindMPState>;
curState:PIState,
stopped:Bool,
position:Vector
}>;
var gemCount:Int; var gemCount:Int;
var gemStates:Array<Bool>; var gemStates:Array<Bool>;
var powerupStates:Array<Float>; var powerupStates:Array<Float>;
@ -69,18 +88,7 @@ class RewindFrame {
c.activePowerupStates = activePowerupStates.copy(); c.activePowerupStates = activePowerupStates.copy();
c.currentUp = currentUp.clone(); c.currentUp = currentUp.clone();
c.lastContactNormal = lastContactNormal.clone(); c.lastContactNormal = lastContactNormal.clone();
c.mpStates = []; c.mpStates = mpStates.copy();
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.trapdoorStates = []; c.trapdoorStates = [];
for (s in trapdoorStates) { for (s in trapdoorStates) {
c.trapdoorStates.push({ c.trapdoorStates.push({
@ -127,11 +135,14 @@ class RewindFrame {
framesize += 24; // lastContactNormal framesize += 24; // lastContactNormal
framesize += 2; // mpStates.length framesize += 2; // mpStates.length
for (s in mpStates) { for (s in mpStates) {
framesize += 8; // s.curState.currentTime framesize += 8; // s.currentTime
framesize += 8; // s.curState.targetTime framesize += 8; // s.targetTime
framesize += 24; // s.curState.velocity framesize += 1; // Null<s.stoppedPosition>
framesize += 1; // s.stopped if (s.stoppedPosition != null)
framesize += 24; // s.stoppedPosition
framesize += 24; // s.prevPosition
framesize += 24; // s.position framesize += 24; // s.position
framesize += 24; // s.velocity
} }
framesize += 2; // trapdoorStates.length framesize += 2; // trapdoorStates.length
for (s in trapdoorStates) { for (s in trapdoorStates) {
@ -204,15 +215,23 @@ class RewindFrame {
bb.writeDouble(lastContactNormal.z); bb.writeDouble(lastContactNormal.z);
bb.writeInt16(mpStates.length); bb.writeInt16(mpStates.length);
for (s in mpStates) { for (s in mpStates) {
bb.writeDouble(s.curState.currentTime); bb.writeDouble(s.currentTime);
bb.writeDouble(s.curState.targetTime); bb.writeDouble(s.targetTime);
bb.writeDouble(s.curState.velocity.x); bb.writeByte(s.stoppedPosition == null ? 0 : 1);
bb.writeDouble(s.curState.velocity.y); if (s.stoppedPosition != null) {
bb.writeDouble(s.curState.velocity.z); bb.writeDouble(s.stoppedPosition.x);
bb.writeByte(s.stopped ? 1 : 0); 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.x);
bb.writeDouble(s.position.y); bb.writeDouble(s.position.y);
bb.writeDouble(s.position.z); bb.writeDouble(s.position.z);
bb.writeDouble(s.velocity.x);
bb.writeDouble(s.velocity.y);
bb.writeDouble(s.velocity.z);
} }
bb.writeInt16(trapdoorStates.length); bb.writeInt16(trapdoorStates.length);
for (s in trapdoorStates) { for (s in trapdoorStates) {
@ -307,28 +326,32 @@ class RewindFrame {
currentUp.z = br.readDouble(); currentUp.z = br.readDouble();
lastContactNormal.x = br.readDouble(); lastContactNormal.x = br.readDouble();
lastContactNormal.y = br.readDouble(); lastContactNormal.y = br.readDouble();
lastContactNormal.z = br.readDouble();
mpStates = []; mpStates = [];
var mpStates_len = br.readInt16(); var mpStates_len = br.readInt16();
for (i in 0...mpStates_len) { for (i in 0...mpStates_len) {
var mpStates_item = { var mpStates_item = new RewindMPState();
curState: { mpStates_item.currentTime = br.readDouble();
currentTime: 0.0, mpStates_item.targetTime = br.readDouble();
targetTime: 0.0, mpStates_item.stoppedPosition = new Vector();
velocity: new Vector(), mpStates_item.prevPosition = new Vector();
}, mpStates_item.position = new Vector();
stopped: false, mpStates_item.velocity = new Vector();
position: new Vector() if (br.readByte() != 0) {
}; mpStates_item.stoppedPosition.x = br.readDouble();
mpStates_item.curState.currentTime = br.readDouble(); mpStates_item.stoppedPosition.y = br.readDouble();
mpStates_item.curState.targetTime = br.readDouble(); mpStates_item.stoppedPosition.z = br.readDouble();
mpStates_item.curState.velocity.x = br.readDouble(); } else {
mpStates_item.curState.velocity.y = br.readDouble(); mpStates_item.stoppedPosition = null;
mpStates_item.curState.velocity.z = br.readDouble(); }
mpStates_item.stopped = br.readByte() != 0; 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.x = br.readDouble();
mpStates_item.position.y = br.readDouble(); mpStates_item.position.y = br.readDouble();
mpStates_item.position.z = 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); mpStates.push(mpStates_item);
} }
trapdoorStates = []; trapdoorStates = [];

View file

@ -1,5 +1,6 @@
package rewind; package rewind;
import rewind.RewindFrame.RewindMPState;
import haxe.io.BytesInput; import haxe.io.BytesInput;
import haxe.io.BytesBuffer; import haxe.io.BytesBuffer;
import mis.MissionElement.MissionElementBase; import mis.MissionElement.MissionElementBase;
@ -53,15 +54,14 @@ class RewindManager {
rf.currentUp = level.marble.currentUp.clone(); rf.currentUp = level.marble.currentUp.clone();
rf.lastContactNormal = level.marble.lastContactNormal.clone(); rf.lastContactNormal = level.marble.lastContactNormal.clone();
rf.mpStates = level.pathedInteriors.map(x -> { rf.mpStates = level.pathedInteriors.map(x -> {
return { var mpstate = new RewindMPState();
curState: { mpstate.currentTime = x.currentTime;
currentTime: x.currentTime, mpstate.targetTime = x.targetTime;
targetTime: x.targetTime, mpstate.velocity = x.velocity.clone();
velocity: x.velocity.clone(), mpstate.stoppedPosition = @:privateAccess x.stopped ? @:privateAccess x.stoppedPosition.clone() : null;
}, mpstate.position = @:privateAccess x.position.clone();
stopped: @:privateAccess x.stopped, mpstate.prevPosition = @:privateAccess x.prevPosition.clone();
position: x.getAbsPos().getPosition().clone(), return mpstate;
}
}); });
rf.powerupStates = []; rf.powerupStates = [];
rf.landMineStates = []; rf.landMineStates = [];
@ -167,12 +167,20 @@ class RewindManager {
level.marble.currentUp.set(rf.currentUp.x, rf.currentUp.y, rf.currentUp.z); 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); level.marble.lastContactNormal.set(rf.lastContactNormal.x, rf.lastContactNormal.y, rf.lastContactNormal.z);
for (i in 0...rf.mpStates.length) { for (i in 0...rf.mpStates.length) {
level.pathedInteriors[i].currentTime = rf.mpStates[i].curState.currentTime; level.pathedInteriors[i].currentTime = rf.mpStates[i].currentTime;
level.pathedInteriors[i].targetTime = rf.mpStates[i].curState.targetTime; level.pathedInteriors[i].targetTime = rf.mpStates[i].targetTime;
level.pathedInteriors[i].velocity.set(rf.mpStates[i].curState.velocity.x, rf.mpStates[i].curState.velocity.y, rf.mpStates[i].curState.velocity.z); level.pathedInteriors[i].velocity.load(rf.mpStates[i].velocity);
@:privateAccess level.pathedInteriors[i].stopped = rf.mpStates[i].stopped; @:privateAccess level.pathedInteriors[i].stopped = rf.mpStates[i].stoppedPosition != null;
level.pathedInteriors[i].setPosition(rf.mpStates[i].position.x, rf.mpStates[i].position.y, rf.mpStates[i].position.z); @:privateAccess level.pathedInteriors[i].position.load(rf.mpStates[i].position);
level.pathedInteriors[i].setTransform(level.pathedInteriors[i].getTransform()); @: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 pstates = rf.powerupStates.copy();
var lmstates = rf.landMineStates.copy(); var lmstates = rf.landMineStates.copy();