mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
make nukes network successfully
This commit is contained in:
parent
a33fb533df
commit
a8d316d4fd
9 changed files with 275 additions and 146 deletions
|
|
@ -1,5 +1,7 @@
|
|||
package src;
|
||||
|
||||
import shapes.Explodable;
|
||||
import net.ExplodablePredictionStore;
|
||||
import gui.MPPreGameDlg;
|
||||
import src.Radar;
|
||||
import rewind.InputRecorder;
|
||||
|
|
@ -145,6 +147,7 @@ class MarbleWorld extends Scheduler {
|
|||
public var dtsObjects:Array<DtsObject> = [];
|
||||
public var powerUps:Array<PowerUp> = [];
|
||||
public var forceObjects:Array<ForceObject> = [];
|
||||
public var explodables:Array<Explodable> = [];
|
||||
public var triggers:Array<Trigger> = [];
|
||||
public var gems:Array<Gem> = [];
|
||||
public var namedObjects:Map<String, {obj:DtsObject, elem:MissionElementBase}> = [];
|
||||
|
|
@ -230,6 +233,7 @@ class MarbleWorld extends Scheduler {
|
|||
var predictions:MarblePredictionStore;
|
||||
var powerupPredictions:PowerupPredictionStore;
|
||||
var gemPredictions:GemPredictionStore;
|
||||
var explodablePredictions:ExplodablePredictionStore;
|
||||
|
||||
public var lastMoves:MarbleUpdateQueue;
|
||||
|
||||
|
|
@ -274,6 +278,7 @@ class MarbleWorld extends Scheduler {
|
|||
predictions = new MarblePredictionStore();
|
||||
powerupPredictions = new PowerupPredictionStore();
|
||||
gemPredictions = new GemPredictionStore();
|
||||
explodablePredictions = new ExplodablePredictionStore();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -613,6 +618,7 @@ class MarbleWorld extends Scheduler {
|
|||
predictions = new MarblePredictionStore();
|
||||
powerupPredictions = new PowerupPredictionStore();
|
||||
gemPredictions = new GemPredictionStore();
|
||||
explodablePredictions = new ExplodablePredictionStore();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1171,6 +1177,13 @@ class MarbleWorld extends Scheduler {
|
|||
if (obj is ForceObject) {
|
||||
this.forceObjects.push(cast obj);
|
||||
}
|
||||
if (obj is Explodable) {
|
||||
var exp:Explodable = cast obj;
|
||||
exp.netId = this.explodables.length;
|
||||
this.explodables.push(exp);
|
||||
if (Net.isClient)
|
||||
explodablePredictions.alloc();
|
||||
}
|
||||
obj.isTSStatic = isTsStatic;
|
||||
obj.init(cast this, () -> {
|
||||
obj.update(this.timeState);
|
||||
|
|
@ -1485,7 +1498,7 @@ class MarbleWorld extends Scheduler {
|
|||
// if (marbleNeedsPrediction & (1 << Net.clientId) > 0) { // Only for our clients pls
|
||||
// if (qm != null) {
|
||||
// var mvs = qm.powerupStates.copy();
|
||||
for (pw in marble.level.powerUps) {
|
||||
for (pw in powerUps) {
|
||||
// var val = mvs.shift();
|
||||
// if (pw.lastPickUpTime != val)
|
||||
// Console.log('Revert powerup pickup: ${pw.lastPickUpTime} -> ${val}');
|
||||
|
|
@ -1493,6 +1506,9 @@ class MarbleWorld extends Scheduler {
|
|||
if (pw.pickupClient != -1 && marbleNeedsPrediction & (1 << pw.pickupClient) > 0)
|
||||
pw.lastPickUpTime = powerupPredictions.getState(pw.netIndex);
|
||||
}
|
||||
for (exp in explodables) {
|
||||
exp.revertContactTicks(explodablePredictions.getState(exp.netId));
|
||||
}
|
||||
var huntMode:HuntMode = cast this.gameMode;
|
||||
if (@:privateAccess huntMode.activeGemSpawnGroup != null) {
|
||||
for (activeGem in @:privateAccess huntMode.activeGemSpawnGroup) {
|
||||
|
|
@ -2807,7 +2823,8 @@ class MarbleWorld extends Scheduler {
|
|||
dtsObject.dispose();
|
||||
}
|
||||
dtsObjects = null;
|
||||
powerUps = [];
|
||||
powerUps = null;
|
||||
explodables = null;
|
||||
for (trigger in this.triggers) {
|
||||
trigger.dispose();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,9 +65,9 @@ class Particle {
|
|||
public function update(time:Float, dt:Float) {
|
||||
var t = dt;
|
||||
var a = this.acc;
|
||||
a.load(a.sub(this.vel.multiply(this.o.dragCoefficient)));
|
||||
this.vel.load(this.vel.add(a.multiply(dt)));
|
||||
this.position.load(this.position.add(this.vel.multiply(dt)));
|
||||
a = a.sub(this.vel.multiply(this.o.dragCoefficient));
|
||||
this.vel = this.vel.add(a.multiply(dt));
|
||||
this.position = this.position.add(this.vel.multiply(dt));
|
||||
|
||||
this.currentAge += dt;
|
||||
|
||||
|
|
|
|||
|
|
@ -429,7 +429,7 @@ class Util {
|
|||
#end
|
||||
}
|
||||
|
||||
public static inline inline function isIOS() {
|
||||
public static inline function isIOS() {
|
||||
#if js
|
||||
var reg = ~/iPad|iPhone|iPod/;
|
||||
return reg.match(js.Browser.navigator.userAgent);
|
||||
|
|
|
|||
25
src/net/ExplodablePredictionStore.hx
Normal file
25
src/net/ExplodablePredictionStore.hx
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package net;
|
||||
|
||||
import net.NetPacket.ExplodableUpdatePacket;
|
||||
import src.TimeState;
|
||||
import net.NetPacket.PowerupPickupPacket;
|
||||
|
||||
class ExplodablePredictionStore {
|
||||
var predictions:Array<Int>;
|
||||
|
||||
public inline function new() {
|
||||
predictions = [];
|
||||
}
|
||||
|
||||
public inline function alloc() {
|
||||
predictions.push(-100000);
|
||||
}
|
||||
|
||||
public inline function getState(netIndex:Int) {
|
||||
return predictions[netIndex];
|
||||
}
|
||||
|
||||
public inline function acknowledgeExplodableUpdate(packet:ExplodableUpdatePacket) {
|
||||
predictions[packet.explodableId] = packet.serverTicks;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package net;
|
||||
|
||||
import net.NetPacket.ExplodableUpdatePacket;
|
||||
import gui.MPMessageGui;
|
||||
import gui.MessageBoxOkDlg;
|
||||
import gui.JoinServerGui;
|
||||
|
|
@ -37,6 +38,7 @@ enum abstract NetPacketType(Int) from Int to Int {
|
|||
var PowerupPickup;
|
||||
var GemSpawn;
|
||||
var GemPickup;
|
||||
var ExplodableUpdate;
|
||||
var PlayerInfo;
|
||||
var ScoreBoardInfo;
|
||||
}
|
||||
|
|
@ -784,6 +786,13 @@ class Net {
|
|||
@:privateAccess MarbleGame.instance.world.playGui.updatePlayerScores(scoreboardPacket);
|
||||
}
|
||||
|
||||
case ExplodableUpdate:
|
||||
var explodableUpdatePacket = new ExplodableUpdatePacket();
|
||||
explodableUpdatePacket.deserialize(input);
|
||||
if (MarbleGame.instance.world != null && !MarbleGame.instance.world._disposed) {
|
||||
@:privateAccess MarbleGame.instance.world.explodablePredictions.acknowledgeExplodableUpdate(explodableUpdatePacket);
|
||||
}
|
||||
|
||||
case _:
|
||||
Console.log("unknown command: " + packetType);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,6 +208,24 @@ class PowerupPickupPacket implements NetPacket {
|
|||
}
|
||||
}
|
||||
|
||||
@:publicFields
|
||||
class ExplodableUpdatePacket implements NetPacket {
|
||||
var serverTicks:Int;
|
||||
var explodableId:Int;
|
||||
|
||||
public function new() {}
|
||||
|
||||
public inline function deserialize(b:InputBitStream) {
|
||||
serverTicks = b.readUInt16();
|
||||
explodableId = b.readInt(11);
|
||||
}
|
||||
|
||||
public inline function serialize(b:OutputBitStream) {
|
||||
b.writeUInt16(serverTicks);
|
||||
b.writeInt(explodableId, 11);
|
||||
}
|
||||
}
|
||||
|
||||
@:publicFields
|
||||
class GemSpawnPacket implements NetPacket {
|
||||
var gemIds:Array<Int>;
|
||||
|
|
|
|||
154
src/shapes/Explodable.hx
Normal file
154
src/shapes/Explodable.hx
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
package shapes;
|
||||
|
||||
import src.ParticleSystem.ParticleEmitter;
|
||||
import src.Marble;
|
||||
import h3d.Vector;
|
||||
import src.ParticleSystem.ParticleEmitterOptions;
|
||||
import net.BitStream.OutputBitStream;
|
||||
import net.NetPacket.ExplodableUpdatePacket;
|
||||
import collision.CollisionInfo;
|
||||
import src.ParticleSystem.ParticleData;
|
||||
import src.DtsObject;
|
||||
import src.TimeState;
|
||||
import src.Util;
|
||||
import net.Net;
|
||||
import src.MarbleWorld;
|
||||
import src.ResourceLoader;
|
||||
import src.AudioManager;
|
||||
|
||||
abstract class Explodable extends DtsObject {
|
||||
var particle:ParticleEmitterOptions;
|
||||
var smokeParticle:ParticleEmitterOptions;
|
||||
var sparksParticle:ParticleEmitterOptions;
|
||||
|
||||
var particleData:ParticleData;
|
||||
var smokeParticleData:ParticleData;
|
||||
var sparkParticleData:ParticleData;
|
||||
|
||||
var disappearTime = -1e8;
|
||||
var lastContactTick:Int = -100000;
|
||||
|
||||
var renewTime = 5000;
|
||||
|
||||
var explodeSoundFile:String = "data/sound/explode1.wav";
|
||||
|
||||
var emitter1:ParticleEmitter;
|
||||
var emitter2:ParticleEmitter;
|
||||
var emitter3:ParticleEmitter;
|
||||
|
||||
public var netId:Int;
|
||||
|
||||
override function update(timeState:TimeState) {
|
||||
super.update(timeState);
|
||||
|
||||
if (Net.isMP) {
|
||||
if (Net.isHost) {
|
||||
if (timeState.ticks >= this.lastContactTick + (renewTime >> 5) || timeState.ticks < this.lastContactTick) {
|
||||
this.setHide(false);
|
||||
} else {
|
||||
this.setHide(true);
|
||||
}
|
||||
|
||||
var opacity = Util.clamp((timeState.ticks - (this.lastContactTick + (renewTime >> 5))), 0, 1);
|
||||
this.setOpacity(opacity);
|
||||
} else {
|
||||
if (@:privateAccess level.marble.serverTicks >= this.lastContactTick + (renewTime >> 5) || @:privateAccess level.marble.serverTicks < this.lastContactTick) {
|
||||
this.setHide(false);
|
||||
} else {
|
||||
this.setHide(true);
|
||||
}
|
||||
|
||||
var opacity = Util.clamp((@:privateAccess level.marble.serverTicks - (this.lastContactTick + (renewTime >> 5))), 0, 1);
|
||||
this.setOpacity(opacity);
|
||||
}
|
||||
} else {
|
||||
if (timeState.timeSinceLoad >= this.disappearTime + (renewTime / 1000) || timeState.timeSinceLoad < this.disappearTime) {
|
||||
this.setHide(false);
|
||||
} else {
|
||||
this.setHide(true);
|
||||
}
|
||||
|
||||
var opacity = Util.clamp((timeState.timeSinceLoad - (this.disappearTime + (renewTime / 1000))), 0, 1);
|
||||
this.setOpacity(opacity);
|
||||
}
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.load(explodeSoundFile).entry.load(onFinish);
|
||||
});
|
||||
}
|
||||
|
||||
override function onMarbleContact(marble:src.Marble, timeState:TimeState, ?contact:CollisionInfo) {
|
||||
if (this.isCollideable && !this.level.rewinding) {
|
||||
// marble.velocity = marble.velocity.add(vec);
|
||||
this.disappearTime = timeState.timeSinceLoad;
|
||||
if (Net.isClient) {
|
||||
this.lastContactTick = @:privateAccess marble.serverTicks;
|
||||
} else {
|
||||
this.lastContactTick = timeState.ticks;
|
||||
}
|
||||
this.setCollisionEnabled(false);
|
||||
|
||||
if (!this.level.rewinding && @:privateAccess !marble.isNetUpdate)
|
||||
AudioManager.playSound(ResourceLoader.getResource(explodeSoundFile, ResourceLoader.getAudio, this.soundResources));
|
||||
if (@:privateAccess !marble.isNetUpdate) {
|
||||
emitter1 = this.level.particleManager.createEmitter(particle, particleData, this.getAbsPos().getPosition());
|
||||
emitter2 = this.level.particleManager.createEmitter(smokeParticle, smokeParticleData, this.getAbsPos().getPosition());
|
||||
emitter3 = this.level.particleManager.createEmitter(sparksParticle, sparkParticleData, this.getAbsPos().getPosition());
|
||||
}
|
||||
|
||||
// var minePos = this.getAbsPos().getPosition();
|
||||
// var off = marble.getAbsPos().getPosition().sub(minePos);
|
||||
|
||||
// var strength = computeExplosionStrength(off.length());
|
||||
|
||||
// var impulse = off.normalized().multiply(strength);
|
||||
applyImpulse(marble);
|
||||
|
||||
if (Net.isHost) {
|
||||
var packet = new ExplodableUpdatePacket();
|
||||
packet.explodableId = netId;
|
||||
packet.serverTicks = timeState.ticks;
|
||||
var os = new OutputBitStream();
|
||||
os.writeByte(ExplodableUpdate);
|
||||
packet.serialize(os);
|
||||
Net.sendPacketToIngame(os);
|
||||
}
|
||||
|
||||
// light = new h3d.scene.fwd.PointLight(MarbleGame.instance.scene);
|
||||
// light.setPosition(minePos.x, minePos.y, minePos.z);
|
||||
// light.enableSpecular = false;
|
||||
|
||||
// for (collider in this.colliders) {
|
||||
// var hull:CollisionHull = cast collider;
|
||||
// hull.force = strength;
|
||||
// }
|
||||
}
|
||||
// Normally, we would add a light here, but that's too expensive for THREE, apparently.
|
||||
|
||||
// this.level.replay.recordMarbleContact(this);
|
||||
}
|
||||
|
||||
public function revertContactTicks(ticks:Int) {
|
||||
this.lastContactTick = ticks;
|
||||
if (level.timeState.ticks >= this.lastContactTick + (renewTime >> 5) || level.timeState.ticks < this.lastContactTick) {
|
||||
if (emitter1 != null) {
|
||||
this.level.particleManager.removeEmitter(emitter1);
|
||||
emitter1 = null;
|
||||
}
|
||||
|
||||
if (emitter2 != null) {
|
||||
this.level.particleManager.removeEmitter(emitter2);
|
||||
emitter2 = null;
|
||||
}
|
||||
|
||||
if (emitter3 != null) {
|
||||
this.level.particleManager.removeEmitter(emitter3);
|
||||
emitter3 = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract function applyImpulse(marble:Marble):Void;
|
||||
}
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
package shapes;
|
||||
|
||||
import net.BitStream.OutputBitStream;
|
||||
import net.NetPacket.ExplodableUpdatePacket;
|
||||
import net.Net;
|
||||
import src.AudioManager;
|
||||
import src.TimeState;
|
||||
import collision.CollisionHull;
|
||||
|
|
@ -90,13 +93,7 @@ final landMineSparksParticle:ParticleEmitterOptions = {
|
|||
}
|
||||
};
|
||||
|
||||
class LandMine extends DtsObject {
|
||||
var disappearTime = -1e8;
|
||||
|
||||
var landMineParticleData:ParticleData;
|
||||
var landMineSmokeParticleData:ParticleData;
|
||||
var landMineSparkParticleData:ParticleData;
|
||||
|
||||
class LandMine extends Explodable {
|
||||
var light:h3d.scene.fwd.PointLight;
|
||||
|
||||
public function new() {
|
||||
|
|
@ -105,57 +102,21 @@ class LandMine extends DtsObject {
|
|||
this.identifier = "LandMine";
|
||||
this.isCollideable = true;
|
||||
|
||||
landMineParticleData = new ParticleData();
|
||||
landMineParticleData.identifier = "landMineParticle";
|
||||
landMineParticleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
||||
particleData = new ParticleData();
|
||||
particleData.identifier = "landMineParticle";
|
||||
particleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
||||
|
||||
landMineSmokeParticleData = new ParticleData();
|
||||
landMineSmokeParticleData.identifier = "landMineSmokeParticle";
|
||||
landMineSmokeParticleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
||||
smokeParticleData = new ParticleData();
|
||||
smokeParticleData.identifier = "landMineSmokeParticle";
|
||||
smokeParticleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
||||
|
||||
landMineSparkParticleData = new ParticleData();
|
||||
landMineSparkParticleData.identifier = "landMineSparkParticle";
|
||||
landMineSparkParticleData.texture = ResourceLoader.getResource("data/particles/spark.png", ResourceLoader.getTexture, this.textureResources);
|
||||
}
|
||||
sparkParticleData = new ParticleData();
|
||||
sparkParticleData.identifier = "landMineSparkParticle";
|
||||
sparkParticleData.texture = ResourceLoader.getResource("data/particles/spark.png", ResourceLoader.getTexture, this.textureResources);
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.load("sound/explode1.wav").entry.load(onFinish);
|
||||
});
|
||||
}
|
||||
|
||||
override function onMarbleContact(marble:src.Marble, timeState:TimeState, ?contact:CollisionInfo) {
|
||||
if (this.isCollideable && !this.level.rewinding) {
|
||||
// marble.velocity = marble.velocity.add(vec);
|
||||
this.disappearTime = timeState.timeSinceLoad;
|
||||
this.setCollisionEnabled(false);
|
||||
|
||||
if (!this.level.rewinding)
|
||||
AudioManager.playSound(ResourceLoader.getResource("data/sound/explode1.wav", ResourceLoader.getAudio, this.soundResources));
|
||||
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());
|
||||
|
||||
var minePos = this.getAbsPos().getPosition();
|
||||
var off = marble.getAbsPos().getPosition().sub(minePos);
|
||||
|
||||
var strength = computeExplosionStrength(off.length());
|
||||
|
||||
var impulse = off.normalized().multiply(strength);
|
||||
marble.applyImpulse(impulse);
|
||||
|
||||
// light = new h3d.scene.fwd.PointLight(MarbleGame.instance.scene);
|
||||
// light.setPosition(minePos.x, minePos.y, minePos.z);
|
||||
// light.enableSpecular = false;
|
||||
|
||||
// for (collider in this.colliders) {
|
||||
// var hull:CollisionHull = cast collider;
|
||||
// hull.force = strength;
|
||||
// }
|
||||
}
|
||||
// Normally, we would add a light here, but that's too expensive for THREE, apparently.
|
||||
|
||||
// this.level.replay.recordMarbleContact(this);
|
||||
this.smokeParticle = landMineSmokeParticle;
|
||||
this.sparksParticle = landMineSparksParticle;
|
||||
this.particle = landMineParticle;
|
||||
}
|
||||
|
||||
function computeExplosionStrength(r:Float) {
|
||||
|
|
@ -172,28 +133,13 @@ class LandMine extends DtsObject {
|
|||
return v;
|
||||
}
|
||||
|
||||
override function update(timeState:TimeState) {
|
||||
super.update(timeState);
|
||||
if (timeState.timeSinceLoad >= this.disappearTime + 5 || timeState.timeSinceLoad < this.disappearTime) {
|
||||
this.setHide(false);
|
||||
} else {
|
||||
this.setHide(true);
|
||||
}
|
||||
public function applyImpulse(marble:src.Marble) {
|
||||
var minePos = this.getAbsPos().getPosition();
|
||||
var off = marble.getAbsPos().getPosition().sub(minePos);
|
||||
|
||||
// if (light != null) {
|
||||
// var t = Util.clamp((timeState.timeSinceLoad - this.disappearTime) / 1.2, 0, 1);
|
||||
var strength = computeExplosionStrength(off.length());
|
||||
|
||||
// light.color = Util.lerpThreeVectors(new Vector(0.5, 0.5, 0), new Vector(0, 0, 0), t);
|
||||
// var radius = Util.lerp(6, 3, t);
|
||||
// light.params = new Vector(0, 1 / radius, 0);
|
||||
|
||||
// if (t >= 1) {
|
||||
// light.remove();
|
||||
// light = null;
|
||||
// }
|
||||
// }
|
||||
|
||||
var opacity = Util.clamp((timeState.timeSinceLoad - (this.disappearTime + 5)), 0, 1);
|
||||
this.setOpacity(opacity);
|
||||
var impulse = off.normalized().multiply(strength);
|
||||
marble.applyImpulse(impulse);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package shapes;
|
||||
|
||||
import net.BitStream.OutputBitStream;
|
||||
import net.NetPacket.ExplodableUpdatePacket;
|
||||
import src.AudioManager;
|
||||
import src.TimeState;
|
||||
import collision.CollisionHull;
|
||||
|
|
@ -11,6 +13,7 @@ import src.ParticleSystem.ParticleData;
|
|||
import h3d.Vector;
|
||||
import src.ResourceLoader;
|
||||
import src.MarbleWorld;
|
||||
import net.Net;
|
||||
|
||||
final nukeParticle:ParticleEmitterOptions = {
|
||||
ejectionPeriod: 0.2,
|
||||
|
|
@ -89,71 +92,31 @@ final nukeSparksParticle:ParticleEmitterOptions = {
|
|||
}
|
||||
};
|
||||
|
||||
class Nuke extends DtsObject {
|
||||
var disappearTime = -1e8;
|
||||
|
||||
var nukeParticleData:ParticleData;
|
||||
var nukeSmokeParticleData:ParticleData;
|
||||
var nukeSparkParticleData:ParticleData;
|
||||
|
||||
class Nuke extends Explodable {
|
||||
public function new() {
|
||||
super();
|
||||
dtsPath = "data/shapes/hazards/nuke/nuke.dts";
|
||||
this.identifier = "Nuke";
|
||||
this.isCollideable = true;
|
||||
|
||||
nukeParticleData = new ParticleData();
|
||||
nukeParticleData.identifier = "nukeParticle";
|
||||
nukeParticleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
||||
particleData = new ParticleData();
|
||||
particleData.identifier = "nukeParticle";
|
||||
particleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
||||
|
||||
nukeSmokeParticleData = new ParticleData();
|
||||
nukeSmokeParticleData.identifier = "nukeSmokeParticle";
|
||||
nukeSmokeParticleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
||||
smokeParticleData = new ParticleData();
|
||||
smokeParticleData.identifier = "nukeSmokeParticle";
|
||||
smokeParticleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
||||
|
||||
nukeSparkParticleData = new ParticleData();
|
||||
nukeSparkParticleData.identifier = "nukeSparkParticle";
|
||||
nukeSparkParticleData.texture = ResourceLoader.getResource("data/particles/spark.png", ResourceLoader.getTexture, this.textureResources);
|
||||
}
|
||||
sparkParticleData = new ParticleData();
|
||||
sparkParticleData.identifier = "nukeSparkParticle";
|
||||
sparkParticleData.texture = ResourceLoader.getResource("data/particles/spark.png", ResourceLoader.getTexture, this.textureResources);
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.load("sound/nukeexplode.wav").entry.load(onFinish);
|
||||
});
|
||||
}
|
||||
particle = nukeParticle;
|
||||
smokeParticle = nukeSmokeParticle;
|
||||
sparksParticle = nukeSparksParticle;
|
||||
|
||||
override function onMarbleContact(marble:src.Marble, timeState:TimeState, ?contact:CollisionInfo) {
|
||||
if (this.isCollideable && !this.level.rewinding) {
|
||||
// marble.velocity = marble.velocity.add(vec);
|
||||
this.disappearTime = timeState.timeSinceLoad;
|
||||
this.setCollisionEnabled(false);
|
||||
|
||||
// if (!this.level.rewinding)
|
||||
if (@:privateAccess !marble.isNetUpdate) {
|
||||
AudioManager.playSound(ResourceLoader.getResource("data/sound/nukeexplode.wav", ResourceLoader.getAudio, this.soundResources));
|
||||
this.level.particleManager.createEmitter(nukeParticle, nukeParticleData, this.getAbsPos().getPosition());
|
||||
this.level.particleManager.createEmitter(nukeSmokeParticle, nukeSmokeParticleData, this.getAbsPos().getPosition());
|
||||
this.level.particleManager.createEmitter(nukeSparksParticle, nukeSparkParticleData, this.getAbsPos().getPosition());
|
||||
}
|
||||
|
||||
var minePos = this.getAbsPos().getPosition();
|
||||
var dtsCenter = this.dts.bounds.center();
|
||||
// dtsCenter.x = -dtsCenter.x;
|
||||
// minePos.x += dtsCenter.x;
|
||||
// minePos.y += dtsCenter.y;
|
||||
// minePos.z += dtsCenter.z;
|
||||
var off = marble.getAbsPos().getPosition().sub(minePos);
|
||||
|
||||
var force = computeExplosionForce(off);
|
||||
marble.applyImpulse(force, true);
|
||||
|
||||
// for (collider in this.colliders) {
|
||||
// var hull:CollisionHull = cast collider;
|
||||
// hull.force = strength;
|
||||
// }
|
||||
}
|
||||
// Normally, we would add a light here, but that's too expensive for THREE, apparently.
|
||||
|
||||
// this.level.replay.recordMarbleContact(this);
|
||||
renewTime = 15000;
|
||||
explodeSoundFile = "data/sound/nukeexplode.wav";
|
||||
}
|
||||
|
||||
function computeExplosionForce(distVec:Vector) {
|
||||
|
|
@ -169,15 +132,12 @@ class Nuke extends DtsObject {
|
|||
return distVec;
|
||||
}
|
||||
|
||||
override function update(timeState:TimeState) {
|
||||
super.update(timeState);
|
||||
if (timeState.timeSinceLoad >= this.disappearTime + 15 || timeState.timeSinceLoad < this.disappearTime) {
|
||||
this.setHide(false);
|
||||
} else {
|
||||
this.setHide(true);
|
||||
}
|
||||
public function applyImpulse(marble:src.Marble) {
|
||||
var minePos = this.getAbsPos().getPosition();
|
||||
var dtsCenter = this.dts.bounds.center();
|
||||
var off = marble.getAbsPos().getPosition().sub(minePos);
|
||||
|
||||
var opacity = Util.clamp((timeState.timeSinceLoad - (this.disappearTime + 15)), 0, 1);
|
||||
this.setOpacity(opacity);
|
||||
var force = computeExplosionForce(off);
|
||||
marble.applyImpulse(force, true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue