From 9fe3cbcd2207f93c2809e54e3e0e6315ac3a965b Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Thu, 10 Jun 2021 17:45:54 +0530 Subject: [PATCH] landmine and few other items --- src/DtsObject.hx | 15 ++- src/GameObject.hx | 1 + src/InteriorObject.hx | 1 + src/Main.hx | 5 + src/collision/CollisionWorld.hx | 6 +- src/shapes/EndPad.hx | 13 +++ src/shapes/Gem.hx | 46 +++++++++ src/shapes/LandMine.hx | 162 ++++++++++++++++++++++++++++++++ src/shapes/TimeTravel.hx | 2 + 9 files changed, 248 insertions(+), 3 deletions(-) create mode 100644 src/shapes/EndPad.hx create mode 100644 src/shapes/Gem.hx create mode 100644 src/shapes/LandMine.hx diff --git a/src/DtsObject.hx b/src/DtsObject.hx index 66262d1e..582edf29 100644 --- a/src/DtsObject.hx +++ b/src/DtsObject.hx @@ -85,7 +85,6 @@ class DtsObject extends GameObject { var useInstancing:Bool = true; var isTSStatic:Bool; - var isCollideable:Bool; var showSequences:Bool = true; var hasNonVisualSequences:Bool = true; var isInstanced:Bool = false; @@ -811,4 +810,18 @@ class DtsObject extends GameObject { } } } + + public function setHide(hide:Bool) { + if (hide) { + this.setCollisionEnabled(false); + this.setOpacity(0); + } else { + this.setCollisionEnabled(true); + this.setOpacity(1); + } + } + + public function setCollisionEnabled(flag:Bool) { + this.isCollideable = flag; + } } diff --git a/src/GameObject.hx b/src/GameObject.hx index e18a4c20..3acf15e5 100644 --- a/src/GameObject.hx +++ b/src/GameObject.hx @@ -6,6 +6,7 @@ import h3d.scene.Object; class GameObject extends Object { public var identifier:String; public var currentOpacity:Float = 1; + public var isCollideable:Bool = false; public function onMarbleContact(time:Float, ?contact:CollisionInfo) {} diff --git a/src/InteriorObject.hx b/src/InteriorObject.hx index 3618df10..b7326143 100644 --- a/src/InteriorObject.hx +++ b/src/InteriorObject.hx @@ -14,6 +14,7 @@ class InteriorObject extends GameObject { public function new() { super(); + this.isCollideable = true; } public function init(level:MarbleWorld) { diff --git a/src/Main.hx b/src/Main.hx index 458438c4..59c3fdcc 100644 --- a/src/Main.hx +++ b/src/Main.hx @@ -1,5 +1,6 @@ package; +import shapes.LandMine; import shapes.StartPad; import shapes.TriangleBumper; import shapes.RoundBumper; @@ -146,6 +147,10 @@ class Main extends hxd.App { tb.y = 3; world.addDtsObject(spad); + var lm = new LandMine(); + lm.x = 7; + world.addDtsObject(lm); + // var le:ParticleEmitterOptions = { // ejectionPeriod: 0.01, diff --git a/src/collision/CollisionWorld.hx b/src/collision/CollisionWorld.hx index da2e28ad..cd18baf2 100644 --- a/src/collision/CollisionWorld.hx +++ b/src/collision/CollisionWorld.hx @@ -34,12 +34,14 @@ class CollisionWorld { for (obj in intersections) { var entity:CollisionEntity = cast obj; - contacts = contacts.concat(entity.sphereIntersection(spherecollision, dt)); + if (entity.go.isCollideable) { + contacts = contacts.concat(entity.sphereIntersection(spherecollision, dt)); + } } for (obj in dynamicEntities) { if (obj != spherecollision) { - if (obj.boundingBox.collide(box)) + if (obj.boundingBox.collide(box) && obj.go.isCollideable) contacts = contacts.concat(obj.sphereIntersection(spherecollision, dt)); } } diff --git a/src/shapes/EndPad.hx b/src/shapes/EndPad.hx new file mode 100644 index 00000000..f55b560f --- /dev/null +++ b/src/shapes/EndPad.hx @@ -0,0 +1,13 @@ +package shapes; + +import src.DtsObject; + +class EndPad extends DtsObject { + public function new() { + super(); + this.dtsPath = "data/shapes/pads/endarea.dts"; + this.useInstancing = false; + this.isCollideable = true; + this.identifier = "EndPad"; + } +} diff --git a/src/shapes/Gem.hx b/src/shapes/Gem.hx new file mode 100644 index 00000000..d1d0b65f --- /dev/null +++ b/src/shapes/Gem.hx @@ -0,0 +1,46 @@ +package shapes; + +import src.DtsObject; + +class Gem extends DtsObject { + public var pickedUp:Bool; + + public function new() { + super(); + dtsPath = "data/shapes/items/gem.dts"; + ambientRotate = true; + isCollideable = false; + pickedUp = false; + showSequences = false; // Gems actually have an animation for the little shiny thing, but the actual game ignores that. I get it, it was annoying as hell. + + var GEM_COLORS = ["blue", "red", "yellow", "purple", "green", "turquoise", "orange", "black"]; + var color = GEM_COLORS[Math.floor(Math.random() * GEM_COLORS.length)]; + this.identifier = "Gem" + color; + this.matNameOverride.set('base.gem', color + ".gem"); + } + + public function setHide(hide:Bool) { + if (hide) { + this.pickedUp = true; + this.setOpacity(0); + } else { + this.pickedUp = false; + this.setOpacity(1); + } + } + + override function onMarbleInside(time:Float) { + super.onMarbleInside(time); + if (this.pickedUp) + return; + this.pickedUp = true; + this.setOpacity(0); // Hide the gem + // this.level.pickUpGem(this); + // this.level.replay.recordMarbleInside(this); + } + + override function reset() { + this.pickedUp = false; + this.setOpacity(1); + } +} diff --git a/src/shapes/LandMine.hx b/src/shapes/LandMine.hx new file mode 100644 index 00000000..ebe706e8 --- /dev/null +++ b/src/shapes/LandMine.hx @@ -0,0 +1,162 @@ +package shapes; + +import collision.CollisionInfo; +import src.DtsObject; +import src.Util; +import src.ParticleSystem.ParticleEmitterOptions; +import src.ParticleSystem.ParticleData; +import h3d.Vector; +import src.ResourceLoader; + +final landMineParticle:ParticleEmitterOptions = { + ejectionPeriod: 0.2, + ambientVelocity: new Vector(0, 0, 0), + ejectionVelocity: 2, + velocityVariance: 1, + emitterLifetime: 50, + inheritedVelFactor: 0.2, + particleOptions: { + texture: 'particles/smoke.png', + blending: Add, + spinSpeed: 40, + spinRandomMin: -90, + spinRandomMax: 90, + lifetime: 1000, + lifetimeVariance: 150, + 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] + } +}; + +final landMineSmokeParticle:ParticleEmitterOptions = { + ejectionPeriod: 0.5, + ambientVelocity: new Vector(0, 0, 0), + ejectionVelocity: 0.8, + velocityVariance: 0.4, + emitterLifetime: 50, + inheritedVelFactor: 0.25, + particleOptions: { + texture: 'particles/smoke.png', + blending: Alpha, + spinSpeed: 40, + spinRandomMin: -90, + spinRandomMax: 90, + lifetime: 1200, + lifetimeVariance: 300, + dragCoefficient: 0.85, + acceleration: -8, + colors: [ + new Vector(0.56, 0.36, 0.26, 1), + new Vector(0.2, 0.2, 0.2, 1), + new Vector(0, 0, 0, 0) + ], + sizes: [1, 1.5, 2], + times: [0, 0.5, 1] + } +}; + +final landMineSparksParticle:ParticleEmitterOptions = { + ejectionPeriod: 0.4, + ambientVelocity: new Vector(0, 0, 0), + ejectionVelocity: 13 / 4, + velocityVariance: 6.75 / 4, + emitterLifetime: 100, + inheritedVelFactor: 0.2, + particleOptions: { + texture: 'particles/spark.png', + blending: Add, + spinSpeed: 40, + spinRandomMin: -90, + spinRandomMax: 90, + lifetime: 500, + lifetimeVariance: 350, + dragCoefficient: 0.75, + acceleration: -8, + colors: [ + new Vector(0.6, 0.4, 0.3, 1), + new Vector(0.6, 0.4, 0.3, 1), + new Vector(1, 0.4, 0.3, 0) + ], + sizes: [0.5, 0.25, 0.25], + times: [0, 0.5, 1] + } +}; + +class LandMine extends DtsObject { + var disappearTime = -1e8; + + var landMineParticleData:ParticleData; + var landMineSmokeParticleData:ParticleData; + var landMineSparkParticleData:ParticleData; + + public function new() { + super(); + dtsPath = "data/shapes/hazards/landmine.dts"; + this.identifier = "LandMine"; + this.isCollideable = true; + + landMineParticleData = new ParticleData(); + landMineParticleData.identifier = "landMineParticle"; + landMineParticleData.texture = ResourceLoader.getTexture("data/particles/smoke.png"); + + landMineSmokeParticleData = new ParticleData(); + landMineSmokeParticleData.identifier = "landMineSmokeParticle"; + landMineSmokeParticleData.texture = ResourceLoader.getTexture("data/particles/smoke.png"); + + landMineSparkParticleData = new ParticleData(); + landMineSparkParticleData.identifier = "landMineSparkParticle"; + landMineSparkParticleData.texture = ResourceLoader.getTexture("data/particles/spark.png"); + } + + function computeExplosionStrength(r:Float) { + // Figured out through testing by RandomityGuy + if (r >= 10.25) + return 0.0; + if (r >= 10) + return Util.lerp(30.0087, 30.7555, r - 10); + + // The explosion first becomes stronger the further you are away from it, then becomes weaker again (parabolic). + var a = 0.071436222; + var v = (Math.pow((r - 5), 2)) / (-4 * a) + 87.5; + + return v; + } + + override function onMarbleContact(time:Float, ?contact:CollisionInfo) { + var marble = this.level.marble; + var minePos = this.getAbsPos().getPosition(); + var off = marble.getAbsPos().getPosition().sub(minePos); + var vec = off.normalized(); // Use the last pos so that it's a little less RNG + + // Add velocity to the marble + var explosionStrength = this.computeExplosionStrength(off.length()); + marble.velocity = marble.velocity.add(vec.multiply(explosionStrength)); + this.disappearTime = level.currentTime; + this.isCollideable = false; + // this.setCollisionEnabled(false); + + // if (!this.level.rewinding) + // AudioManager.play(this.sounds[0]); + this.level.particleManager.createEmitter(landMineParticle, landMineParticleData, this.getAbsPos().getPosition()); + this.level.particleManager.createEmitter(landMineSmokeParticle, landMineSmokeParticleData, this.getAbsPos().getPosition()); + this.level.particleManager.createEmitter(landMineSparksParticle, landMineSparkParticleData, this.getAbsPos().getPosition()); + // Normally, we would add a light here, but that's too expensive for THREE, apparently. + + // this.level.replay.recordMarbleContact(this); + } + + override function update(currentTime:Float, dt:Float) { + super.update(currentTime, dt); + if (currentTime >= this.disappearTime + 5 || currentTime < this.disappearTime) { + this.setHide(false); + } else { + this.setHide(true); + } + + var opacity = Util.clamp((currentTime - (this.disappearTime + 5)), 0, 1); + this.setOpacity(opacity); + } +} diff --git a/src/shapes/TimeTravel.hx b/src/shapes/TimeTravel.hx index 3a1101e3..c7266f10 100644 --- a/src/shapes/TimeTravel.hx +++ b/src/shapes/TimeTravel.hx @@ -1,3 +1,5 @@ +package shapes; + class TimeTravel extends PowerUp { var timeBonus:Float = 5;