From 8702305e7973b028406be821a0777388b5bc1089 Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Mon, 14 Jun 2021 13:41:42 +0530 Subject: [PATCH] pathedinterior fix parsing --- src/InstanceManager.hx | 7 + src/Main.hx | 178 +------------------ src/Marble.hx | 8 +- src/MarbleWorld.hx | 361 +++++++++++++++++++++++++++++++++++++- src/Mission.hx | 7 +- src/PathedInterior.hx | 31 ++-- src/gui/PlayGui.hx | 13 ++ src/mis/MisParser.hx | 10 +- src/shapes/Gem.hx | 14 +- src/shapes/SignCaution.hx | 1 + src/shapes/SignPlain.hx | 4 +- src/triggers/Trigger.hx | 2 +- 12 files changed, 436 insertions(+), 200 deletions(-) diff --git a/src/InstanceManager.hx b/src/InstanceManager.hx index 461ee896..08311ac9 100644 --- a/src/InstanceManager.hx +++ b/src/InstanceManager.hx @@ -1,5 +1,6 @@ package src; +import h3d.shader.pbr.PropsValues; import shaders.Billboard; import shaders.DtsTexture; import h3d.mat.Pass; @@ -100,6 +101,12 @@ class InstanceManager { minfo.transparencymeshbatch = new MeshBatch(cast(cast(obj, Mesh).primitive), cast(cast(obj, Mesh)).material.clone(), scene); minfo.transparencymeshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); minfo.transparencymeshbatch.material.mainPass.addShader(dtsshader); + + var pbrshader = mat.mainPass.getShader(PropsValues); + if (pbrshader != null) { + minfo.meshbatch.material.mainPass.addShader(pbrshader); + minfo.transparencymeshbatch.material.mainPass.addShader(pbrshader); + } } minfos.push(minfo); } diff --git a/src/Main.hx b/src/Main.hx index 654123bf..a51e3781 100644 --- a/src/Main.hx +++ b/src/Main.hx @@ -1,5 +1,6 @@ package; +import src.Mission; import mis.MisParser; import sys.io.File; import shapes.EndPad; @@ -47,188 +48,21 @@ class Main extends hxd.App { override function init() { super.init(); - dtsObj = new SuperSpeed(); - dtsObj.x = -3; - - world = new MarbleWorld(s3d, s2d); - - var db = new InteriorObject(); - db.interiorFile = "data/interiors/beginner/beginner_finish.dif"; - world.addInterior(db); - var tform = db.getTransform(); - tform.setPosition(new Vector(0, 0, 0)); - db.setTransform(tform); - var ltr = File.getContent("data/missions/beginner/finale.mis"); var mfp = new MisParser(ltr); var mis = mfp.parse(); - // var pi = new PathedInterior(); - // DifBuilder.loadDif("data/interiors/addon/smallplatform.dif", loader, pi); - // var pim = pi.getTransform(); - // pim.setPosition(new Vector(5, 0, 0)); - // pi.setTransform(pim); + var mission = new Mission(); + mission.root = mis.root; - // var cube = new Polygon([new h3d.col.Point(0, 0, 0), new h3d.col.Point(0, 0, 1), new h3d.col.Point(0, 1, 0)]); - // cube.addNormals(); - // cube.addUVs(); - // var tex = ResourceLoader.loader.load("data/interiors/arrow_cool1.jpg").toTexture(); - // var mat = Material.create(tex); - // var mesh = new Mesh(cube, mat); - // var go = new GameObject(); - // go.identifier = "lol"; - // go.addChild(mesh); - // world.instanceManager.addObject(go); - - // var m1 = new PathedInteriorMarker(); - // m1.msToNext = 5; - // m1.position = new Vector(0, 0, 0); - // m1.smoothingType = ""; - // m1.rotation = new Quat(); - - // var m2 = new PathedInteriorMarker(); - // m2.msToNext = 3; - // m2.position = new Vector(0, 0, 5); - // m2.smoothingType = ""; - // m2.rotation = new Quat(); - - // var m3 = new PathedInteriorMarker(); - // m3.msToNext = 5; - // m3.position = new Vector(0, 0, 0); - // m3.smoothingType = ""; - // m3.rotation = new Quat(); - - // pi.markerData = [m1, m2, m3]; - - // world.addPathedInterior(pi); - - world.addDtsObject(dtsObj); - - var sj = new SuperJump(); - sj.x = 3; - world.addDtsObject(sj); - - var sj2 = new SuperJump(); - sj2.x = 3; - sj2.z = 2; - world.addDtsObject(sj2); - - var sb = new SuperBounce(); - sb.y = 3; - world.addDtsObject(sb); - - var sh = new ShockAbsorber(); - sh.y = -3; - world.addDtsObject(sh); - - var he = new Helicopter(); - world.addDtsObject(he); - sj.setTransform(sj.getTransform()); - - var ag = new AntiGravity(); - ag.y = 6; - world.addDtsObject(ag); - - var os = new Oilslick(); - os.x = 5; - os.z = 0.1; - world.addDtsObject(os); - - var tdoor = new Trapdoor(); - tdoor.x = -5; - tdoor.z = 1; - world.addDtsObject(tdoor); - - var rb = new RoundBumper(); - rb.x = -5; - rb.y = 2; - world.addDtsObject(rb); - - var tb = new TriangleBumper(); - tb.x = -5; - tb.y = 4; - world.addDtsObject(tb); - - var spad = new StartPad(); - spad.x = 5; - spad.y = 3; - world.addDtsObject(spad); - - var lm = new LandMine(); - lm.x = 7; - world.addDtsObject(lm); - - var epad = new EndPad(); - epad.x = 5; - epad.x = -3; - world.addDtsObject(epad); - - // var le:ParticleEmitterOptions = { - - // ejectionPeriod: 0.01, - // ambientVelocity: new Vector(0, 0, 0), - // ejectionVelocity: 0.5, - // velocityVariance: 0.25, - // emitterLifetime: 1e8, - // inheritedVelFactor: 0.2, - // particleOptions: { - // texture: 'particles/smoke.png', - // blending: Add, - // spinSpeed: 40, - // spinRandomMin: -90, - // spinRandomMax: 90, - // lifetime: 1, - // lifetimeVariance: 0.15, - // dragCoefficient: 0.8, - // acceleration: 0, - // colors: [new Vector(0.56, 0.36, 0.26, 1), new Vector(0.56, 0.36, 0.26, 0)], - // sizes: [0.5, 1], - // times: [0, 1] - // } - // }; - - // var p1 = new ParticleData(); - // p1.identifier = "testparticle"; - // p1.texture = ResourceLoader.getTexture("data/particles/smoke.png"); - - // // var emitter = new ParticleEmitter(le, p1, world.particleManager); // var p = new Particle(); - // world.particleManager.createEmitter(le, p1, new Vector()); - - // p.position = new Vector(); - // p.color = new Vector(255, 255, 255); - // p.rotation = Math.PI; - // p.scale = 5; - - // world.particleManager.addParticle(p1, p); - - // for (i in 0...10) { - - // for (j in 0...10) { - // var trapdoor = new Tornado(); - // trapdoor.x = i * 2; - // trapdoor.y = j * 2; - // world.addDtsObject(trapdoor); - // } - // } - - // for (surf in db.collider.surfaces) { - // var surfmin = new CustomObject(cube, mat, s3d); - // var bound = surf.boundingBox; - // surfmin.setPosition(bound.xMin, bound.yMin, bound.zMin); - - // var surfmax = new CustomObject(cube, mat, s3d); - // surfmax.setPosition(bound.xMax, bound.yMax, bound.zMax); - // } - - // var mat = Material.create(); - // var so = new CustomObject(cube, mat); - // so.setPosition(0, 0, 0); - // s3d.addChild(so); + world = new MarbleWorld(s3d, s2d, mission); var dirlight = new DirLight(new Vector(0.5, 0.5, -0.5), s3d); dirlight.enableSpecular = true; s3d.lightSystem.ambientLight.set(0.3, 0.3, 0.3); + world.init(); + // s3d.camera. var marble = new Marble(); diff --git a/src/Marble.hx b/src/Marble.hx index 8fcfb7d1..f4cbce2d 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -599,7 +599,8 @@ class Marble extends GameObject { var tform = obj.transform.clone(); var velDir = obj.velocity.normalized(); // tform.setPosition(tform.getPosition().add(velDir.multiply(_radius))); - tform.setPosition(tform.getPosition().add(obj.velocity.multiply(dt)).sub(velDir.multiply(_radius))); + // tform.setPosition(tform.getPosition().add(obj.velocity.multiply(dt)).sub(velDir.multiply(_radius))); + tform.setPosition(tform.getPosition().add(obj.velocity.multiply(dt))); var contacts = []; @@ -693,20 +694,19 @@ class Marble extends GameObject { var intersectT = this.getIntersectionTime(timeStep, velocity); if (intersectT < timeStep) { - intersectT *= 0.8; // We uh tick the shit to not actually at the contact time cause bruh + // intersectT *= 0.8; // We uh tick the shit to not actually at the contact time cause bruh // intersectT /= 2; var diff = timeStep - intersectT; this.velocity = this.velocity.sub(A.multiply(diff)); this.omega = this.omega.sub(a.multiply(diff)); timeStep = intersectT; - trace("CCD"); } piTime += timeStep; if (this.controllable) { for (interior in pathedInteriors) { // interior.popTickState(); - // interior.setStopped(stoppedPaths); + interior.setStopped(stoppedPaths); var piDT = timeState.clone(); piDT.currentAttemptTime = piTime; piDT.dt = timeStep; diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index 71c82f36..9af98a79 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -1,5 +1,33 @@ package src; +import triggers.HelpTrigger; +import triggers.InBoundsTrigger; +import triggers.OutOfBoundsTrigger; +import shapes.Trapdoor; +import shapes.Oilslick; +import shapes.Tornado; +import shapes.TimeTravel; +import shapes.SuperSpeed; +import shapes.ShockAbsorber; +import shapes.LandMine; +import shapes.AntiGravity; +import shapes.SmallDuctFan; +import shapes.DuctFan; +import shapes.Helicopter; +import shapes.TriangleBumper; +import shapes.RoundBumper; +import shapes.SuperBounce; +import shapes.SignCaution; +import shapes.SuperJump; +import shapes.Gem; +import shapes.SignPlain; +import shapes.SignFinish; +import shapes.EndPad; +import shapes.StartPad; +import h3d.Matrix; +import mis.MisParser; +import src.DifBuilder; +import mis.MissionElement; import src.GameObject; import triggers.Trigger; import src.Mission; @@ -35,6 +63,7 @@ class MarbleWorld extends Scheduler { public var pathedInteriors:Array = []; public var marbles:Array = []; public var dtsObjects:Array = []; + public var triggers:Array = []; var shapeImmunity:Array = []; var shapeOrTriggerInside:Array = []; @@ -43,7 +72,10 @@ class MarbleWorld extends Scheduler { public var bonusTime:Float = 0; public var sky:Sky; + var endPadElement:MissionElementStaticShape; + public var scene:Scene; + public var scene2d:h2d.Scene; public var mission:Mission; public var marble:Marble; @@ -52,6 +84,8 @@ class MarbleWorld extends Scheduler { public var outOfBounds:Bool = false; public var outOfBoundsTime:TimeState; public var finishTime:TimeState; + public var totalGems:Int = 0; + public var gemCount:Int = 0; var helpTextTimeState:Float = -1e8; var alertTextTimeState:Float = -1e8; @@ -62,9 +96,38 @@ class MarbleWorld extends Scheduler { /** The new target camera orientation quat */ public var newOrientationQuat = new Quat(); - public function new(scene:Scene, scene2d:h2d.Scene) { - this.collisionWorld = new CollisionWorld(); + public function new(scene:Scene, scene2d:h2d.Scene, mission:Mission) { this.scene = scene; + this.scene2d = scene2d; + this.mission = mission; + } + + public function init() { + function scanMission(simGroup:MissionElementSimGroup) { + for (element in simGroup.elements) { + if ([ + MissionElementType.InteriorInstance, + MissionElementType.Item, + MissionElementType.PathedInterior, + MissionElementType.StaticShape, + MissionElementType.TSStatic + ].contains(element._type)) { + // this.loadingState.total++; + + // Override the end pad element. We do this because only the last finish pad element will actually do anything. + if (element._type == MissionElementType.StaticShape) { + var so:MissionElementStaticShape = cast element; + if (so.datablock.toLowerCase() == 'endpad') + this.endPadElement = so; + } + } else if (element._type == MissionElementType.SimGroup) { + scanMission(cast element); + } + } + }; + scanMission(this.mission.root); + + this.collisionWorld = new CollisionWorld(); this.playGui = new PlayGui(); this.instanceManager = new InstanceManager(scene); this.particleManager = new ParticleManager(cast this); @@ -73,6 +136,9 @@ class MarbleWorld extends Scheduler { sky.init(cast this); playGui.init(scene2d); scene.addChild(sky); + + this.addSimGroup(this.mission.root); + this.playGui.formatGemCounter(this.gemCount, this.totalGems); } public function start() { @@ -102,6 +168,8 @@ class MarbleWorld extends Scheduler { this.deselectPowerUp(); this.clearSchedule(); + + return 0; } public function updateGameState() { @@ -125,6 +193,261 @@ class MarbleWorld extends Scheduler { } } + public function addSimGroup(simGroup:MissionElementSimGroup) { + if (simGroup.elements.filter((element) -> element._type == MissionElementType.PathedInterior).length != 0) { + // Create the pathed interior + var pathedInterior = src.PathedInterior.createFromSimGroup(simGroup, cast this); + this.addPathedInterior(pathedInterior); + if (pathedInterior == null) + return; + + // if (pathedInterior.hasCollision) + // this.physics.addInterior(pathedInterior); + for (trigger in pathedInterior.triggers) + this.triggers.push(trigger); + + return; + } + + for (element in simGroup.elements) { + switch (element._type) { + case MissionElementType.SimGroup: + this.addSimGroup(cast element); + case MissionElementType.InteriorInstance: + this.addInteriorFromMis(cast element); + case MissionElementType.StaticShape: + this.addStaticShape(cast element); + case MissionElementType.Item: + this.addItem(cast element); + case MissionElementType.Trigger: + this.addTrigger(cast element); + case MissionElementType.TSStatic: + this.addTSStatic(cast element); + case MissionElementType.ParticleEmitterNode: + this.addParticleEmitterNode(cast element); + default: + } + } + } + + public function addInteriorFromMis(element:MissionElementInteriorInstance) { + var difPath = this.mission.getDifPath(element.interiorfile); + if (difPath == "") + return; + + var interior = new InteriorObject(); + interior.interiorFile = difPath; + // DifBuilder.loadDif(difPath, interior); + // this.interiors.push(interior); + this.addInterior(interior); + + var interiorPosition = MisParser.parseVector3(element.position); + interiorPosition.x = -interiorPosition.x; + var interiorRotation = MisParser.parseRotation(element.rotation); + interiorRotation.x = -interiorRotation.x; + interiorRotation.w = -interiorRotation.w; + var interiorScale = MisParser.parseVector3(element.scale); + // var hasCollision = interiorScale.x != = 0 && interiorScale.y != = 0 && interiorScale.z != = 0; // Don't want to add buggy geometry + + // Fix zero-volume interiors so they receive correct lighting + if (interiorScale.x == 0) + interiorScale.x = 0.0001; + if (interiorScale.y == 0) + interiorScale.y = 0.0001; + if (interiorScale.z == 0) + interiorScale.z = 0.0001; + + var mat = new Matrix(); + interiorRotation.toMatrix(mat); + mat.scale(interiorScale.x, interiorScale.y, interiorScale.z); + mat.setPosition(interiorPosition); + + interior.setTransform(mat); + + // interior.setTransform(interiorPosition, interiorRotation, interiorScale); + + // this.scene.add(interior.group); + // if (hasCollision) + // this.physics.addInterior(interior); + } + + public function addStaticShape(element:MissionElementStaticShape) { + var shape:DtsObject = null; + + // Add the correct shape based on type + var dataBlockLowerCase = element.datablock.toLowerCase(); + if (dataBlockLowerCase == "") {} // Make sure we don't do anything if there's no data block + else if (dataBlockLowerCase == "startpad") + shape = new StartPad(); + else if (dataBlockLowerCase == "endpad") + shape = new EndPad(); + else if (dataBlockLowerCase == "signfinish") + shape = new SignFinish(); + else if (StringTools.startsWith(dataBlockLowerCase, "signplain")) + shape = new SignPlain(element); + else if (StringTools.startsWith(dataBlockLowerCase, "gemitem")) { + shape = new Gem(cast element); + this.totalGems++; + } else if (dataBlockLowerCase == "superjumpitem") + shape = new SuperJump(); + else if (StringTools.startsWith(dataBlockLowerCase, "signcaution")) + shape = new SignCaution(element); + else if (dataBlockLowerCase == "superbounceitem") + shape = new SuperBounce(); + else if (dataBlockLowerCase == "roundbumper") + shape = new RoundBumper(); + else if (dataBlockLowerCase == "trianglebumper") + shape = new TriangleBumper(); + else if (dataBlockLowerCase == "helicopteritem") + shape = new Helicopter(); + else if (dataBlockLowerCase == "ductfan") + shape = new DuctFan(); + else if (dataBlockLowerCase == "smallductfan") + shape = new SmallDuctFan(); + else if (dataBlockLowerCase == "antigravityitem") + shape = new AntiGravity(); + else if (dataBlockLowerCase == "landmine") + shape = new LandMine(); + else if (dataBlockLowerCase == "shockabsorberitem") + shape = new ShockAbsorber(); + else if (dataBlockLowerCase == "superspeeditem") + shape = new SuperSpeed(); + else if (dataBlockLowerCase == "timetravelitem") + shape = new TimeTravel(cast element); + else if (dataBlockLowerCase == "tornado") + shape = new Tornado(); + else if (dataBlockLowerCase == "trapdoor") + shape = new Trapdoor(); + else if (dataBlockLowerCase == "oilslick") + shape = new Oilslick(); + else { + return; + } + + var shapePosition = MisParser.parseVector3(element.position); + shapePosition.x = -shapePosition.x; + var shapeRotation = MisParser.parseRotation(element.rotation); + shapeRotation.x = -shapeRotation.x; + shapeRotation.w = -shapeRotation.w; + var shapeScale = MisParser.parseVector3(element.scale); + + // Apparently we still do collide with zero-volume shapes + if (shapeScale.x == 0) + shapeScale.x = 0.0001; + if (shapeScale.y == 0) + shapeScale.y = 0.0001; + if (shapeScale.z == 0) + shapeScale.z = 0.0001; + + var mat = shapeRotation.toMatrix(); + mat.scale(shapeScale.x, shapeScale.y, shapeScale.z); + mat.setPosition(shapePosition); + + this.addDtsObject(shape); + + shape.setTransform(mat); + + // else if (dataBlockLowerCase == "pushbutton") + // shape = new PushButton(); + } + + public function addItem(element:MissionElementItem) { + var shape:DtsObject = null; + + // Add the correct shape based on type + var dataBlockLowerCase = element.datablock.toLowerCase(); + if (dataBlockLowerCase == "") {} // Make sure we don't do anything if there's no data block + else if (dataBlockLowerCase == "startpad") + shape = new StartPad(); + else if (dataBlockLowerCase == "endpad") + shape = new EndPad(); + else if (dataBlockLowerCase == "signfinish") + shape = new SignFinish(); + else if (StringTools.startsWith(dataBlockLowerCase, "gemitem")) { + shape = new Gem(cast element); + this.totalGems++; + } else if (dataBlockLowerCase == "superjumpitem") + shape = new SuperJump(); + else if (dataBlockLowerCase == "superbounceitem") + shape = new SuperBounce(); + else if (dataBlockLowerCase == "roundbumper") + shape = new RoundBumper(); + else if (dataBlockLowerCase == "trianglebumper") + shape = new TriangleBumper(); + else if (dataBlockLowerCase == "helicopteritem") + shape = new Helicopter(); + else if (dataBlockLowerCase == "ductfan") + shape = new DuctFan(); + else if (dataBlockLowerCase == "smallductfan") + shape = new SmallDuctFan(); + else if (dataBlockLowerCase == "antigravityitem") + shape = new AntiGravity(); + else if (dataBlockLowerCase == "landmine") + shape = new LandMine(); + else if (dataBlockLowerCase == "shockabsorberitem") + shape = new ShockAbsorber(); + else if (dataBlockLowerCase == "superspeeditem") + shape = new SuperSpeed(); + else if (dataBlockLowerCase == "timetravelitem") + shape = new TimeTravel(cast element); + else if (dataBlockLowerCase == "tornado") + shape = new Tornado(); + else if (dataBlockLowerCase == "trapdoor") + shape = new Trapdoor(); + else if (dataBlockLowerCase == "oilslick") + shape = new Oilslick(); + else { + return; + } + + var shapePosition = MisParser.parseVector3(element.position); + shapePosition.x = -shapePosition.x; + var shapeRotation = MisParser.parseRotation(element.rotation); + shapeRotation.x = -shapeRotation.x; + shapeRotation.w = -shapeRotation.w; + var shapeScale = MisParser.parseVector3(element.scale); + + // Apparently we still do collide with zero-volume shapes + if (shapeScale.x == 0) + shapeScale.x = 0.0001; + if (shapeScale.y == 0) + shapeScale.y = 0.0001; + if (shapeScale.z == 0) + shapeScale.z = 0.0001; + + var mat = shapeRotation.toMatrix(); + mat.scale(shapeScale.x, shapeScale.y, shapeScale.z); + mat.setPosition(shapePosition); + + this.addDtsObject(shape); + + shape.setTransform(mat); + } + + public function addTrigger(element:MissionElementTrigger) { + var trigger:Trigger = null; + + return; + + // Create a trigger based on type + if (element.datablock == "OutOfBoundsTrigger") { + trigger = new OutOfBoundsTrigger(element, cast this); + } else if (element.datablock == "InBoundsTrigger") { + trigger = new InBoundsTrigger(element, cast this); + } else if (element.datablock == "HelpTrigger") { + trigger = new HelpTrigger(element, cast this); + } else { + return; + } + + this.triggers.push(trigger); + this.collisionWorld.addEntity(trigger.collider); + } + + public function addTSStatic(element:MissionElementTSStatic) {} + + public function addParticleEmitterNode(element:MissionElementParticleEmitterNode) {} + public function addInterior(obj:InteriorObject) { this.interiors.push(obj); obj.init(cast this); @@ -235,6 +558,40 @@ class MarbleWorld extends Scheduler { // TODO FIX } + public function pickUpGem(gem:Gem) { + this.gemCount++; + var string:String; + + // Show a notification (and play a sound) based on the gems remaining + if (this.gemCount == this.totalGems) { + string = "You have all the gems, head for the finish!"; + // if (!this.rewinding) + // AudioManager.play('gotallgems.wav'); + + // Some levels with this package end immediately upon collection of all gems + // if (this.mission.misFile.activatedPackages.includes('endWithTheGems')) { + // let + // completionOfImpact = this.physics.computeCompletionOfImpactWithBody(gem.bodies[0], 2); // Get the exact point of impact + // this.touchFinish(completionOfImpact); + // } + } else { + string = "You picked up a gem. "; + + var remaining = this.totalGems - this.gemCount; + if (remaining == 1) { + string += "Only one gem to go!"; + } else { + string += '${remaining} gems to go!'; + } + + // if (!this.rewinding) + // AudioManager.play('gotgem.wav'); + } + + displayAlert(string); + this.playGui.formatGemCounter(this.gemCount, this.totalGems); + } + function callCollisionHandlers(marble:Marble) { var contacts = this.collisionWorld.radiusSearch(marble.getAbsPos().getPosition(), marble._radius); var newImmunity = []; diff --git a/src/Mission.hx b/src/Mission.hx index b4ec5de6..53205d76 100644 --- a/src/Mission.hx +++ b/src/Mission.hx @@ -1,11 +1,16 @@ package src; +import mis.MissionElement.MissionElementSimGroup; import src.ResourceLoader; class Mission { + public var root:MissionElementSimGroup; + + public function new() {} + public function getDifPath(rawElementPath:String) { rawElementPath = rawElementPath.toLowerCase(); - var path = rawElementPath; + var path = StringTools.replace(rawElementPath.substring(rawElementPath.indexOf('data/')), "\"", ""); if (StringTools.contains(path, 'interiors_mbg/')) path = StringTools.replace(path, 'interiors_mbg/', 'interiors/'); return path; diff --git a/src/PathedInterior.hx b/src/PathedInterior.hx index d77eddfb..e9f2c033 100644 --- a/src/PathedInterior.hx +++ b/src/PathedInterior.hx @@ -29,7 +29,8 @@ class PathedInterior extends InteriorObject { var path:MissionElementPath; var simGroup:MissionElementSimGroup; var element:MissionElementPathedInterior; - var triggers:Array = []; + + public var triggers:Array = []; public var markerData:Array = []; @@ -64,6 +65,8 @@ class PathedInterior extends InteriorObject { DifBuilder.loadDif(difFile, pathedInterior, cast MisParser.parseNumber(interiorElement.interiorindex)); // (difFile, path, level, ); + pathedInterior.identifier = difFile + interiorElement.interiorindex; + pathedInterior.simGroup = simGroup; pathedInterior.element = interiorElement; level.interiors.push(pathedInterior); @@ -80,7 +83,10 @@ class PathedInterior extends InteriorObject { public override function init(level:MarbleWorld) { this.basePosition = MisParser.parseVector3(this.element.baseposition); + this.basePosition.x = -this.basePosition.x; this.baseOrientation = MisParser.parseRotation(this.element.baserotation); + this.baseOrientation.x = -this.baseOrientation.x; + this.baseOrientation.w = -this.baseOrientation.w; this.baseScale = MisParser.parseVector3(this.element.basescale); // this.hasCollision = this.baseScale.x != 0 // && this.baseScale.y != = 0 && this.baseScale.z != = 0; // Don't want to add buggy geometry @@ -133,9 +139,7 @@ class PathedInterior extends InteriorObject { popTickState(); } - var transform = this.getTransformAtTime(this.getInternalTime(currentTime)); - - this.updatePosition(); + var transform = this.getTransformAtTime(this.getInternalTime(timeState.currentAttemptTime)); var position = transform.getPosition(); this.prevPosition = this.currentPosition; @@ -145,9 +149,11 @@ class PathedInterior extends InteriorObject { pushTickState(); } // if (!stopped) - // this.currentTime = currentTime; + // this.currentTime = timeState.currentAttemptTime; velocity = position.sub(this.prevPosition).multiply(1 / timeState.dt); + + this.updatePosition(); } public function setStopped(stopped:Bool = true) { @@ -191,11 +197,11 @@ class PathedInterior extends InteriorObject { this.duration = total; } - public function setTargetTime(now:Float, target:Float) { - var currentInternalTime = this.getInternalTime(now); + public function setTargetTime(now:TimeState, target:Float) { + var currentInternalTime = this.getInternalTime(now.currentAttemptTime); this.currentTime = currentInternalTime; // Start where the interior currently is this.targetTime = target; - this.changeTime = now; + this.changeTime = now.currentAttemptTime; } public function getInternalTime(externalTime:Float) { @@ -224,8 +230,8 @@ class PathedInterior extends InteriorObject { // Incase there are no markers at all var mat = new Matrix(); this.baseOrientation.toMatrix(mat); - mat.setPosition(this.basePosition); mat.scale(this.baseScale.x, this.baseScale.y, this.baseScale.z); + mat.setPosition(this.basePosition); return mat; } else { m1 = this.markerData[0]; @@ -274,13 +280,14 @@ class PathedInterior extends InteriorObject { } // Offset by the position of the first marker var firstPosition = this.markerData[0].position; - position.sub(firstPosition); - position.add(basePosition); // Add the base position + position = position.sub(firstPosition); + position = position.add(basePosition); // Add the base position var mat = new Matrix(); this.baseOrientation.toMatrix(mat); - mat.setPosition(position); + mat.scale(this.baseScale.x, this.baseScale.y, this.baseScale.z); + mat.setPosition(position); return mat; } diff --git a/src/gui/PlayGui.hx b/src/gui/PlayGui.hx index 1fc845bb..55aecb00 100644 --- a/src/gui/PlayGui.hx +++ b/src/gui/PlayGui.hx @@ -277,6 +277,19 @@ class PlayGui { } } + public function formatGemCounter(collected:Int, total:Int) { + var totalTenths = Math.floor(total / 10); + var totalOnes = total % 10; + + var collectedTenths = Math.floor(collected / 10); + var collectedOnes = collected % 10; + + gemCountNumbers[0].currentFrame = collectedTenths; + gemCountNumbers[1].currentFrame = collectedOnes; + gemCountNumbers[2].currentFrame = totalTenths; + gemCountNumbers[3].currentFrame = totalOnes; + } + public function formatTimer(time:Float) { var et = time * 1000; var thousandth = et % 10; diff --git a/src/mis/MisParser.hx b/src/mis/MisParser.hx index e5fcaeb6..e48fd0cd 100644 --- a/src/mis/MisParser.hx +++ b/src/mis/MisParser.hx @@ -181,9 +181,9 @@ class MisParser { } function hasNextElement() { - if (!elementHeadRegEx.match(this.text.substring(this.index))) + if (!elementHeadRegEx.matchSub(this.text, this.index)) return false; - if (Util.indexOfIgnoreStringLiterals(this.text.substring(this.index, this.index + elementHeadRegEx.matchedPos().pos), '}') != -1) + if (Util.indexOfIgnoreStringLiterals(this.text.substring(this.index, elementHeadRegEx.matchedPos().pos), '}') != -1) return false; return true; } @@ -197,6 +197,7 @@ class MisParser { continue; elements.push(element); } + var endingBraceIndex = Util.indexOfIgnoreStringLiterals(this.text, '};', this.index); if (endingBraceIndex == -1) endingBraceIndex = this.text.length; @@ -346,7 +347,6 @@ class MisParser { obj._name = name; obj.markers = sg.elements.map(x -> cast x); obj.markers.sort((a, b) -> cast MisParser.parseNumber(a.seqnum) - MisParser.parseNumber(b.seqnum)); - copyFields(obj); return obj; } @@ -428,8 +428,8 @@ class MisParser { if (StringTools.startsWith(x, '$ ') && this.variables[x] != null) { // Replace the variable with its value x = this.resolveExpression(this.variables[x]); - } else if (StringTools.startsWith(x, ' "') && StringTools.endsWith(x, '" ')) { - x = Util.unescape(x.substring(1, x.length - 2)); // It' s a string literal, so remove " " + } else if (StringTools.startsWith(x, '"') && StringTools.endsWith(x, '"')) { + x = Util.unescape(x.substring(1, x.length - 1)); // It' s a string literal, so remove " " } return x; }); diff --git a/src/shapes/Gem.hx b/src/shapes/Gem.hx index 23a652d7..35975b73 100644 --- a/src/shapes/Gem.hx +++ b/src/shapes/Gem.hx @@ -1,5 +1,7 @@ package shapes; +import h3d.shader.pbr.PropsValues; +import src.MarbleWorld; import mis.MissionElement.MissionElementItem; import src.TimeState; import src.DtsObject; @@ -18,11 +20,19 @@ class Gem extends DtsObject { var GEM_COLORS = ["blue", "red", "yellow", "purple", "green", "turquoise", "orange", "black"]; var color = element.datablock.substring("GemItem".length); if (color.length == 0) - GEM_COLORS[Math.floor(Math.random() * GEM_COLORS.length)]; + color = GEM_COLORS[Math.floor(Math.random() * GEM_COLORS.length)]; this.identifier = "Gem" + color; this.matNameOverride.set('base.gem', color + ".gem"); } + public override function init(level:MarbleWorld) { + super.init(level); + + for (material in this.materials) { + material.mainPass.addShader(new PropsValues(1, 0, 0, 1)); + } + } + public override function setHide(hide:Bool) { if (hide) { this.pickedUp = true; @@ -39,7 +49,7 @@ class Gem extends DtsObject { return; this.pickedUp = true; this.setOpacity(0); // Hide the gem - // this.level.pickUpGem(this); + this.level.pickUpGem(this); // this.level.replay.recordMarbleInside(this); } diff --git a/src/shapes/SignCaution.hx b/src/shapes/SignCaution.hx index e9e26945..cb83c9c1 100644 --- a/src/shapes/SignCaution.hx +++ b/src/shapes/SignCaution.hx @@ -16,5 +16,6 @@ class SignCaution extends DtsObject { case "Danger": this.matNameOverride.set("base.cautionsign", "danger.cautionsign"); } + this.identifier = "CautionSign" + type; } } diff --git a/src/shapes/SignPlain.hx b/src/shapes/SignPlain.hx index 045dff63..22204a4b 100644 --- a/src/shapes/SignPlain.hx +++ b/src/shapes/SignPlain.hx @@ -18,9 +18,11 @@ class SignPlain extends DtsObject { case "Left": this.matNameOverride.set("base.plainsign", "left.plainsign"); case "Up": - this.matNameOverride.set("base.plainsign", "uo.plainsign"); + this.matNameOverride.set("base.plainsign", "up.plainsign"); case "Down": this.matNameOverride.set("base.plainsign", "down.plainsign"); } + + this.identifier = "SignPlain" + direction; } } diff --git a/src/triggers/Trigger.hx b/src/triggers/Trigger.hx index ea85db61..f2e5fe3d 100644 --- a/src/triggers/Trigger.hx +++ b/src/triggers/Trigger.hx @@ -41,9 +41,9 @@ class Trigger extends GameObject { var mat = new Matrix(); var quat = MisParser.parseRotation(element.rotation); quat.toMatrix(mat); - mat.setPosition(MisParser.parseVector3(element.position)); var scale = MisParser.parseVector3(element.scale); mat.scale(scale.x, scale.y, scale.z); + mat.setPosition(MisParser.parseVector3(element.position)); var vertices = [p1, p2, p3, p4, p5, p6, p7, p8].map((vert) -> vert.transformed(mat));