Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 22 additions & 18 deletions src/MarbleWorld.hx
Original file line number Diff line number Diff line change
Expand Up @@ -956,29 +956,28 @@ class MarbleWorld extends Scheduler {
}

public function addSimGroup(simGroup:MissionElementSimGroup) {
if (simGroup.elements.filter((element) -> element._type == MissionElementType.PathedInterior).length != 0) {
var pathedInteriorElements:Array<MissionElementPathedInterior> = cast simGroup.elements.filter((element) -> element._type == MissionElementType.PathedInterior);
if (pathedInteriorElements.length != 0) {
// Create the pathed interior
resourceLoadFuncs.push(fwd -> {
src.PathedInterior.createFromSimGroup(simGroup, cast this, pathedInterior -> {
this.addPathedInterior(pathedInterior, () -> {
if (pathedInterior == null) {
fwd();
Console.error("Unable to load pathed interior");
return;
}

// if (pathedInterior.hasCollision)
// this.physics.addInterior(pathedInterior);
for (trigger in pathedInterior.triggers) {
this.triggers.push(trigger);
this.collisionWorld.addEntity(trigger.collider);
}
src.PathedInterior.createFromSimGroup(simGroup, cast this, pathedInteriors -> {
if (pathedInteriors == null || pathedInteriors.length == 0) {
fwd();
});
Console.error("Unable to load pathed interior");
return;
}

var count = pathedInteriors.length;
for (pathedInterior in pathedInteriors) {
this.addPathedInterior(pathedInterior, () -> {
count--;
if (count == 0) {
fwd();
}
});
}
});
});

return;
}

for (element in simGroup.elements) {
Expand All @@ -992,6 +991,9 @@ class MarbleWorld extends Scheduler {
case MissionElementType.Item:
resourceLoadFuncs.push(fwd -> this.addItem(cast element, fwd));
case MissionElementType.Trigger:
var te:MissionElementTrigger = cast element;
if (pathedInteriorElements.length != 0 && te.targettime != null)
continue;
resourceLoadFuncs.push(fwd -> this.addTrigger(cast element, fwd));
case MissionElementType.TSStatic:
resourceLoadFuncs.push(fwd -> this.addTSStatic(cast element, fwd));
Expand All @@ -1000,6 +1002,8 @@ class MarbleWorld extends Scheduler {
this.addParticleEmitterNode(cast element);
fwd();
});
case MissionElementType.Path, MissionElementType.PathedInterior:
// Handled by createFromSimGroup
default:
}
}
Expand Down
134 changes: 87 additions & 47 deletions src/PathedInterior.hx
Original file line number Diff line number Diff line change
Expand Up @@ -64,25 +64,61 @@ class PathedInterior extends InteriorObject {

var soundChannel:Channel;

public static function createFromSimGroup(simGroup:MissionElementSimGroup, level:MarbleWorld, onFinish:PathedInterior->Void) {
var interiorElement:MissionElementPathedInterior = cast simGroup.elements.filter((element) -> element._type == MissionElementType.PathedInterior)[0];
var difFile = level.mission.getDifPath(interiorElement.interiorresource);
if (difFile == null)
onFinish(null);
var pathedInterior = new PathedInterior();
pathedInterior.level = level;
pathedInterior.collisionWorld = level.collisionWorld;

DifBuilder.loadDif(difFile, pathedInterior, () -> {
pathedInterior.identifier = difFile + interiorElement.interiorindex;

pathedInterior.simGroup = simGroup;
pathedInterior.element = interiorElement;
level.interiors.push(pathedInterior);
pathedInterior.init(level, () -> {
onFinish(pathedInterior);
});
}, cast MisParser.parseNumber(interiorElement.interiorindex));
public static function createFromSimGroup(simGroup:MissionElementSimGroup, level:MarbleWorld, onFinish:Array<PathedInterior>->Void) {
var interiorElements:Array<MissionElementPathedInterior> = cast simGroup.elements.filter((element) -> element._type == MissionElementType.PathedInterior);
if (interiorElements.length == 0) {
onFinish([]);
return;
}

var createdInteriors:Array<PathedInterior> = [];
var total = interiorElements.length;
var completed = 0;

var triggers = simGroup.elements.filter((element) -> element._type == MissionElementType.Trigger);
var mustChangeTriggers:Array<MustChangeTrigger> = [];
for (triggerElement in triggers) {
var te:MissionElementTrigger = cast triggerElement;
if (te.targettime == null)
continue; // Not a pathed interior trigger
var trigger = new MustChangeTrigger(te, level);
mustChangeTriggers.push(trigger);
level.triggers.push(trigger);
level.collisionWorld.addEntity(trigger.collider);
}

for (interiorElement in interiorElements) {
var difFile = level.mission.getDifPath(interiorElement.interiorresource);
if (difFile == null) {
completed++;
if (completed == total) {
onFinish(createdInteriors);
}
continue;
}
var pathedInterior = new PathedInterior();
pathedInterior.level = level;
pathedInterior.collisionWorld = level.collisionWorld;

DifBuilder.loadDif(difFile, pathedInterior, () -> {
pathedInterior.identifier = difFile + interiorElement.interiorindex;

pathedInterior.simGroup = simGroup;
pathedInterior.element = interiorElement;
for (mct in mustChangeTriggers) {
mct.addInterior(pathedInterior);
pathedInterior.triggers.push(mct);
}
level.interiors.push(pathedInterior);
pathedInterior.init(level, () -> {
createdInteriors.push(pathedInterior);
completed++;
if (completed == total) {
onFinish(createdInteriors);
}
});
}, cast MisParser.parseNumber(interiorElement.interiorindex));
}
}

public function new() {
Expand Down Expand Up @@ -113,34 +149,38 @@ class PathedInterior extends InteriorObject {

this.path = cast this.simGroup.elements.filter((element) -> element._type == MissionElementType.Path)[0];

this.markerData = this.path.markers.map(x -> {
var marker = new PathedInteriorMarker();
marker.msToNext = MisParser.parseNumber(x.mstonext) / 1000;
marker.smoothingType = switch (x.smoothingtype) {
case "Accelerate":
PathedInteriorMarker.SMOOTHING_ACCELERATE;
case "Spline":
PathedInteriorMarker.SMOOTHING_SPLINE;
default:
PathedInteriorMarker.SMOOTHING_LINEAR;
};
marker.position = MisParser.parseVector3(x.position);
marker.position.x = -marker.position.x;
marker.rotation = MisParser.parseRotation(x.rotation);
marker.rotation.x = -marker.rotation.x;
marker.rotation.w = -marker.rotation.w;
return marker;
});

this.computeDuration();

var triggers = this.simGroup.elements.filter((element) -> element._type == MissionElementType.Trigger);
for (triggerElement in triggers) {
var te:MissionElementTrigger = cast triggerElement;
if (te.targettime == null)
continue; // Not a pathed interior trigger
var trigger = new MustChangeTrigger(te, cast this);
this.triggers.push(trigger);
if (this.path != null) {
this.markerData = this.path.markers.map(x -> {
var marker = new PathedInteriorMarker();
marker.msToNext = MisParser.parseNumber(x.mstonext) / 1000;
marker.smoothingType = switch (x.smoothingtype) {
case "Accelerate":
PathedInteriorMarker.SMOOTHING_ACCELERATE;
case "Spline":
PathedInteriorMarker.SMOOTHING_SPLINE;
default:
PathedInteriorMarker.SMOOTHING_LINEAR;
};
marker.position = MisParser.parseVector3(x.position);
marker.position.x = -marker.position.x;
marker.rotation = MisParser.parseRotation(x.rotation);
marker.rotation.x = -marker.rotation.x;
marker.rotation.w = -marker.rotation.w;
return marker;
});

this.computeDuration();
}

if (this.triggers.length == 0) {
var triggers = this.simGroup.elements.filter((element) -> element._type == MissionElementType.Trigger);
for (triggerElement in triggers) {
var te:MissionElementTrigger = cast triggerElement;
if (te.targettime == null)
continue; // Not a pathed interior trigger
var trigger = new MustChangeTrigger(te, cast this);
this.triggers.push(trigger);
}
}

if (this.element.datablock.toLowerCase() == "pathedmovingblock") {
Expand Down
36 changes: 26 additions & 10 deletions src/triggers/MustChangeTrigger.hx
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,39 @@ import src.TimeState;
import mis.MisParser;

class MustChangeTrigger extends Trigger {
var interior:PathedInterior;
public var interiors:Array<PathedInterior> = [];

public function new(element:MissionElementTrigger, interior:PathedInterior) {
super(element, interior.level);
this.interior = interior;
public function new(element:MissionElementTrigger, levelOrInterior:Dynamic, ?interior:PathedInterior) {
if (Std.isOfType(levelOrInterior, PathedInterior)) {
var pi:PathedInterior = cast levelOrInterior;
super(element, pi.level);
this.interiors.push(pi);
} else {
super(element, cast levelOrInterior);
}
if (interior != null && !this.interiors.contains(interior)) {
this.interiors.push(interior);
}
}

public function addInterior(interior:PathedInterior) {
if (interior != null && !this.interiors.contains(interior)) {
this.interiors.push(interior);
}
}

public override function onMarbleEnter(marble:src.Marble, time:TimeState) {
var ttime = MisParser.parseNumber(this.element.targettime);
if (ttime > 0)
ttime /= 1000;
this.interior.setTargetTime(time, ttime);
if (this.element.instant == "1") {
if (this.element.icontinuetottime != null && this.element.icontinuetottime != "0") {
// Absolutely strange, and not sure if it's even a thing in MBG, but is implement nonetheless.
this.interior.currentTime = this.interior.targetTime;
this.interior.targetTime = MisParser.parseNumber(this.element.icontinuetottime) / 1000;
for (interior in this.interiors) {
interior.setTargetTime(time, ttime);
if (this.element.instant == "1") {
if (this.element.icontinuetottime != null && this.element.icontinuetottime != "0") {
// Absolutely strange, and not sure if it's even a thing in MBG, but is implement nonetheless.
interior.currentTime = interior.targetTime;
interior.targetTime = MisParser.parseNumber(this.element.icontinuetottime) / 1000;
}
}
}
// this.level.replay.recordMarbleEnter(this);
Expand Down