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;
|
package src;
|
||||||
|
|
||||||
|
import shapes.Explodable;
|
||||||
|
import net.ExplodablePredictionStore;
|
||||||
import gui.MPPreGameDlg;
|
import gui.MPPreGameDlg;
|
||||||
import src.Radar;
|
import src.Radar;
|
||||||
import rewind.InputRecorder;
|
import rewind.InputRecorder;
|
||||||
|
|
@ -145,6 +147,7 @@ class MarbleWorld extends Scheduler {
|
||||||
public var dtsObjects:Array<DtsObject> = [];
|
public var dtsObjects:Array<DtsObject> = [];
|
||||||
public var powerUps:Array<PowerUp> = [];
|
public var powerUps:Array<PowerUp> = [];
|
||||||
public var forceObjects:Array<ForceObject> = [];
|
public var forceObjects:Array<ForceObject> = [];
|
||||||
|
public var explodables:Array<Explodable> = [];
|
||||||
public var triggers:Array<Trigger> = [];
|
public var triggers:Array<Trigger> = [];
|
||||||
public var gems:Array<Gem> = [];
|
public var gems:Array<Gem> = [];
|
||||||
public var namedObjects:Map<String, {obj:DtsObject, elem:MissionElementBase}> = [];
|
public var namedObjects:Map<String, {obj:DtsObject, elem:MissionElementBase}> = [];
|
||||||
|
|
@ -230,6 +233,7 @@ class MarbleWorld extends Scheduler {
|
||||||
var predictions:MarblePredictionStore;
|
var predictions:MarblePredictionStore;
|
||||||
var powerupPredictions:PowerupPredictionStore;
|
var powerupPredictions:PowerupPredictionStore;
|
||||||
var gemPredictions:GemPredictionStore;
|
var gemPredictions:GemPredictionStore;
|
||||||
|
var explodablePredictions:ExplodablePredictionStore;
|
||||||
|
|
||||||
public var lastMoves:MarbleUpdateQueue;
|
public var lastMoves:MarbleUpdateQueue;
|
||||||
|
|
||||||
|
|
@ -274,6 +278,7 @@ class MarbleWorld extends Scheduler {
|
||||||
predictions = new MarblePredictionStore();
|
predictions = new MarblePredictionStore();
|
||||||
powerupPredictions = new PowerupPredictionStore();
|
powerupPredictions = new PowerupPredictionStore();
|
||||||
gemPredictions = new GemPredictionStore();
|
gemPredictions = new GemPredictionStore();
|
||||||
|
explodablePredictions = new ExplodablePredictionStore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -613,6 +618,7 @@ class MarbleWorld extends Scheduler {
|
||||||
predictions = new MarblePredictionStore();
|
predictions = new MarblePredictionStore();
|
||||||
powerupPredictions = new PowerupPredictionStore();
|
powerupPredictions = new PowerupPredictionStore();
|
||||||
gemPredictions = new GemPredictionStore();
|
gemPredictions = new GemPredictionStore();
|
||||||
|
explodablePredictions = new ExplodablePredictionStore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1171,6 +1177,13 @@ class MarbleWorld extends Scheduler {
|
||||||
if (obj is ForceObject) {
|
if (obj is ForceObject) {
|
||||||
this.forceObjects.push(cast obj);
|
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.isTSStatic = isTsStatic;
|
||||||
obj.init(cast this, () -> {
|
obj.init(cast this, () -> {
|
||||||
obj.update(this.timeState);
|
obj.update(this.timeState);
|
||||||
|
|
@ -1485,7 +1498,7 @@ class MarbleWorld extends Scheduler {
|
||||||
// if (marbleNeedsPrediction & (1 << Net.clientId) > 0) { // Only for our clients pls
|
// if (marbleNeedsPrediction & (1 << Net.clientId) > 0) { // Only for our clients pls
|
||||||
// if (qm != null) {
|
// if (qm != null) {
|
||||||
// var mvs = qm.powerupStates.copy();
|
// var mvs = qm.powerupStates.copy();
|
||||||
for (pw in marble.level.powerUps) {
|
for (pw in powerUps) {
|
||||||
// var val = mvs.shift();
|
// var val = mvs.shift();
|
||||||
// if (pw.lastPickUpTime != val)
|
// if (pw.lastPickUpTime != val)
|
||||||
// Console.log('Revert powerup pickup: ${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)
|
if (pw.pickupClient != -1 && marbleNeedsPrediction & (1 << pw.pickupClient) > 0)
|
||||||
pw.lastPickUpTime = powerupPredictions.getState(pw.netIndex);
|
pw.lastPickUpTime = powerupPredictions.getState(pw.netIndex);
|
||||||
}
|
}
|
||||||
|
for (exp in explodables) {
|
||||||
|
exp.revertContactTicks(explodablePredictions.getState(exp.netId));
|
||||||
|
}
|
||||||
var huntMode:HuntMode = cast this.gameMode;
|
var huntMode:HuntMode = cast this.gameMode;
|
||||||
if (@:privateAccess huntMode.activeGemSpawnGroup != null) {
|
if (@:privateAccess huntMode.activeGemSpawnGroup != null) {
|
||||||
for (activeGem in @:privateAccess huntMode.activeGemSpawnGroup) {
|
for (activeGem in @:privateAccess huntMode.activeGemSpawnGroup) {
|
||||||
|
|
@ -2807,7 +2823,8 @@ class MarbleWorld extends Scheduler {
|
||||||
dtsObject.dispose();
|
dtsObject.dispose();
|
||||||
}
|
}
|
||||||
dtsObjects = null;
|
dtsObjects = null;
|
||||||
powerUps = [];
|
powerUps = null;
|
||||||
|
explodables = null;
|
||||||
for (trigger in this.triggers) {
|
for (trigger in this.triggers) {
|
||||||
trigger.dispose();
|
trigger.dispose();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,9 +65,9 @@ class Particle {
|
||||||
public function update(time:Float, dt:Float) {
|
public function update(time:Float, dt:Float) {
|
||||||
var t = dt;
|
var t = dt;
|
||||||
var a = this.acc;
|
var a = this.acc;
|
||||||
a.load(a.sub(this.vel.multiply(this.o.dragCoefficient)));
|
a = a.sub(this.vel.multiply(this.o.dragCoefficient));
|
||||||
this.vel.load(this.vel.add(a.multiply(dt)));
|
this.vel = this.vel.add(a.multiply(dt));
|
||||||
this.position.load(this.position.add(this.vel.multiply(dt)));
|
this.position = this.position.add(this.vel.multiply(dt));
|
||||||
|
|
||||||
this.currentAge += dt;
|
this.currentAge += dt;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -429,7 +429,7 @@ class Util {
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
public static inline inline function isIOS() {
|
public static inline function isIOS() {
|
||||||
#if js
|
#if js
|
||||||
var reg = ~/iPad|iPhone|iPod/;
|
var reg = ~/iPad|iPhone|iPod/;
|
||||||
return reg.match(js.Browser.navigator.userAgent);
|
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;
|
package net;
|
||||||
|
|
||||||
|
import net.NetPacket.ExplodableUpdatePacket;
|
||||||
import gui.MPMessageGui;
|
import gui.MPMessageGui;
|
||||||
import gui.MessageBoxOkDlg;
|
import gui.MessageBoxOkDlg;
|
||||||
import gui.JoinServerGui;
|
import gui.JoinServerGui;
|
||||||
|
|
@ -37,6 +38,7 @@ enum abstract NetPacketType(Int) from Int to Int {
|
||||||
var PowerupPickup;
|
var PowerupPickup;
|
||||||
var GemSpawn;
|
var GemSpawn;
|
||||||
var GemPickup;
|
var GemPickup;
|
||||||
|
var ExplodableUpdate;
|
||||||
var PlayerInfo;
|
var PlayerInfo;
|
||||||
var ScoreBoardInfo;
|
var ScoreBoardInfo;
|
||||||
}
|
}
|
||||||
|
|
@ -784,6 +786,13 @@ class Net {
|
||||||
@:privateAccess MarbleGame.instance.world.playGui.updatePlayerScores(scoreboardPacket);
|
@: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 _:
|
case _:
|
||||||
Console.log("unknown command: " + packetType);
|
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
|
@:publicFields
|
||||||
class GemSpawnPacket implements NetPacket {
|
class GemSpawnPacket implements NetPacket {
|
||||||
var gemIds:Array<Int>;
|
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;
|
package shapes;
|
||||||
|
|
||||||
|
import net.BitStream.OutputBitStream;
|
||||||
|
import net.NetPacket.ExplodableUpdatePacket;
|
||||||
|
import net.Net;
|
||||||
import src.AudioManager;
|
import src.AudioManager;
|
||||||
import src.TimeState;
|
import src.TimeState;
|
||||||
import collision.CollisionHull;
|
import collision.CollisionHull;
|
||||||
|
|
@ -90,13 +93,7 @@ final landMineSparksParticle:ParticleEmitterOptions = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class LandMine extends DtsObject {
|
class LandMine extends Explodable {
|
||||||
var disappearTime = -1e8;
|
|
||||||
|
|
||||||
var landMineParticleData:ParticleData;
|
|
||||||
var landMineSmokeParticleData:ParticleData;
|
|
||||||
var landMineSparkParticleData:ParticleData;
|
|
||||||
|
|
||||||
var light:h3d.scene.fwd.PointLight;
|
var light:h3d.scene.fwd.PointLight;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
|
|
@ -105,57 +102,21 @@ class LandMine extends DtsObject {
|
||||||
this.identifier = "LandMine";
|
this.identifier = "LandMine";
|
||||||
this.isCollideable = true;
|
this.isCollideable = true;
|
||||||
|
|
||||||
landMineParticleData = new ParticleData();
|
particleData = new ParticleData();
|
||||||
landMineParticleData.identifier = "landMineParticle";
|
particleData.identifier = "landMineParticle";
|
||||||
landMineParticleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
particleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
||||||
|
|
||||||
landMineSmokeParticleData = new ParticleData();
|
smokeParticleData = new ParticleData();
|
||||||
landMineSmokeParticleData.identifier = "landMineSmokeParticle";
|
smokeParticleData.identifier = "landMineSmokeParticle";
|
||||||
landMineSmokeParticleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
smokeParticleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
||||||
|
|
||||||
landMineSparkParticleData = new ParticleData();
|
sparkParticleData = new ParticleData();
|
||||||
landMineSparkParticleData.identifier = "landMineSparkParticle";
|
sparkParticleData.identifier = "landMineSparkParticle";
|
||||||
landMineSparkParticleData.texture = ResourceLoader.getResource("data/particles/spark.png", ResourceLoader.getTexture, this.textureResources);
|
sparkParticleData.texture = ResourceLoader.getResource("data/particles/spark.png", ResourceLoader.getTexture, this.textureResources);
|
||||||
}
|
|
||||||
|
|
||||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
this.smokeParticle = landMineSmokeParticle;
|
||||||
super.init(level, () -> {
|
this.sparksParticle = landMineSparksParticle;
|
||||||
ResourceLoader.load("sound/explode1.wav").entry.load(onFinish);
|
this.particle = landMineParticle;
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeExplosionStrength(r:Float) {
|
function computeExplosionStrength(r:Float) {
|
||||||
|
|
@ -172,28 +133,13 @@ class LandMine extends DtsObject {
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
override function update(timeState:TimeState) {
|
public function applyImpulse(marble:src.Marble) {
|
||||||
super.update(timeState);
|
var minePos = this.getAbsPos().getPosition();
|
||||||
if (timeState.timeSinceLoad >= this.disappearTime + 5 || timeState.timeSinceLoad < this.disappearTime) {
|
var off = marble.getAbsPos().getPosition().sub(minePos);
|
||||||
this.setHide(false);
|
|
||||||
} else {
|
|
||||||
this.setHide(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (light != null) {
|
var strength = computeExplosionStrength(off.length());
|
||||||
// var t = Util.clamp((timeState.timeSinceLoad - this.disappearTime) / 1.2, 0, 1);
|
|
||||||
|
|
||||||
// light.color = Util.lerpThreeVectors(new Vector(0.5, 0.5, 0), new Vector(0, 0, 0), t);
|
var impulse = off.normalized().multiply(strength);
|
||||||
// var radius = Util.lerp(6, 3, t);
|
marble.applyImpulse(impulse);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package shapes;
|
package shapes;
|
||||||
|
|
||||||
|
import net.BitStream.OutputBitStream;
|
||||||
|
import net.NetPacket.ExplodableUpdatePacket;
|
||||||
import src.AudioManager;
|
import src.AudioManager;
|
||||||
import src.TimeState;
|
import src.TimeState;
|
||||||
import collision.CollisionHull;
|
import collision.CollisionHull;
|
||||||
|
|
@ -11,6 +13,7 @@ import src.ParticleSystem.ParticleData;
|
||||||
import h3d.Vector;
|
import h3d.Vector;
|
||||||
import src.ResourceLoader;
|
import src.ResourceLoader;
|
||||||
import src.MarbleWorld;
|
import src.MarbleWorld;
|
||||||
|
import net.Net;
|
||||||
|
|
||||||
final nukeParticle:ParticleEmitterOptions = {
|
final nukeParticle:ParticleEmitterOptions = {
|
||||||
ejectionPeriod: 0.2,
|
ejectionPeriod: 0.2,
|
||||||
|
|
@ -89,71 +92,31 @@ final nukeSparksParticle:ParticleEmitterOptions = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Nuke extends DtsObject {
|
class Nuke extends Explodable {
|
||||||
var disappearTime = -1e8;
|
|
||||||
|
|
||||||
var nukeParticleData:ParticleData;
|
|
||||||
var nukeSmokeParticleData:ParticleData;
|
|
||||||
var nukeSparkParticleData:ParticleData;
|
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
dtsPath = "data/shapes/hazards/nuke/nuke.dts";
|
dtsPath = "data/shapes/hazards/nuke/nuke.dts";
|
||||||
this.identifier = "Nuke";
|
this.identifier = "Nuke";
|
||||||
this.isCollideable = true;
|
this.isCollideable = true;
|
||||||
|
|
||||||
nukeParticleData = new ParticleData();
|
particleData = new ParticleData();
|
||||||
nukeParticleData.identifier = "nukeParticle";
|
particleData.identifier = "nukeParticle";
|
||||||
nukeParticleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
particleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
||||||
|
|
||||||
nukeSmokeParticleData = new ParticleData();
|
smokeParticleData = new ParticleData();
|
||||||
nukeSmokeParticleData.identifier = "nukeSmokeParticle";
|
smokeParticleData.identifier = "nukeSmokeParticle";
|
||||||
nukeSmokeParticleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
smokeParticleData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
|
||||||
|
|
||||||
nukeSparkParticleData = new ParticleData();
|
sparkParticleData = new ParticleData();
|
||||||
nukeSparkParticleData.identifier = "nukeSparkParticle";
|
sparkParticleData.identifier = "nukeSparkParticle";
|
||||||
nukeSparkParticleData.texture = ResourceLoader.getResource("data/particles/spark.png", ResourceLoader.getTexture, this.textureResources);
|
sparkParticleData.texture = ResourceLoader.getResource("data/particles/spark.png", ResourceLoader.getTexture, this.textureResources);
|
||||||
}
|
|
||||||
|
|
||||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
particle = nukeParticle;
|
||||||
super.init(level, () -> {
|
smokeParticle = nukeSmokeParticle;
|
||||||
ResourceLoader.load("sound/nukeexplode.wav").entry.load(onFinish);
|
sparksParticle = nukeSparksParticle;
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
override function onMarbleContact(marble:src.Marble, timeState:TimeState, ?contact:CollisionInfo) {
|
renewTime = 15000;
|
||||||
if (this.isCollideable && !this.level.rewinding) {
|
explodeSoundFile = "data/sound/nukeexplode.wav";
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeExplosionForce(distVec:Vector) {
|
function computeExplosionForce(distVec:Vector) {
|
||||||
|
|
@ -169,15 +132,12 @@ class Nuke extends DtsObject {
|
||||||
return distVec;
|
return distVec;
|
||||||
}
|
}
|
||||||
|
|
||||||
override function update(timeState:TimeState) {
|
public function applyImpulse(marble:src.Marble) {
|
||||||
super.update(timeState);
|
var minePos = this.getAbsPos().getPosition();
|
||||||
if (timeState.timeSinceLoad >= this.disappearTime + 15 || timeState.timeSinceLoad < this.disappearTime) {
|
var dtsCenter = this.dts.bounds.center();
|
||||||
this.setHide(false);
|
var off = marble.getAbsPos().getPosition().sub(minePos);
|
||||||
} else {
|
|
||||||
this.setHide(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
var opacity = Util.clamp((timeState.timeSinceLoad - (this.disappearTime + 15)), 0, 1);
|
var force = computeExplosionForce(off);
|
||||||
this.setOpacity(opacity);
|
marble.applyImpulse(force, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue