make gravity and blast work independently too

This commit is contained in:
RandomityGuy 2024-01-26 22:57:21 +05:30
parent 70698b37bd
commit b7753511b4
10 changed files with 69 additions and 59 deletions

View file

@ -365,7 +365,7 @@ class CameraController extends Object {
camera.target = marblePosition.add(cameraVerticalTranslation);
var closeness = 0.1;
var rayCastOrigin = marblePosition.add(level.currentUp.multiply(marble._radius)).add(cameraVerticalTranslation);
var rayCastOrigin = marblePosition.add(level.marble.currentUp.multiply(marble._radius)).add(cameraVerticalTranslation);
for (pi in level.pathedInteriors) {
pi.pushTickState();

View file

@ -75,6 +75,7 @@ class Move {
public var d:Vector;
public var jump:Bool;
public var powerup:Bool;
public var blast:Bool;
public function new() {}
}
@ -249,6 +250,7 @@ class Marble extends GameObject {
public var heldPowerup:PowerUp;
public var lastContactNormal:Vector;
public var lastContactPosition:Vector;
public var currentUp = new Vector(0, 0, 1);
var helicopter:HelicopterImage;
var blastWave:BlastWave;
@ -256,6 +258,8 @@ class Marble extends GameObject {
var megaMarbleEnableTime:Float = -1e8;
var blastUseTime:Float = -1e8;
public var blastAmount:Float = 0;
var teleportEnableTime:Null<Float> = null;
var teleportDisableTime:Null<Float> = null;
var bounceEmitDelay:Float = 0;
@ -537,7 +541,7 @@ class Marble extends GameObject {
if (this.controllable && !this.isNetUpdate) {
motiondir.transform(Matrix.R(0, 0, camera.CameraYaw));
motiondir.transform(level.newOrientationQuat.toMatrix());
var updir = this.level.currentUp;
var updir = this.currentUp;
var sidedir = motiondir.cross(updir);
sidedir.normalize();
@ -546,7 +550,7 @@ class Marble extends GameObject {
} else {
if (moveMotionDir != null)
motiondir = moveMotionDir;
var updir = this.level.currentUp;
var updir = this.currentUp;
var sidedir = motiondir.cross(updir);
return [sidedir, motiondir, updir];
}
@ -555,7 +559,7 @@ class Marble extends GameObject {
function getExternalForces(currentTime:Float, m:Move, dt:Float) {
if (this.mode == Finish)
return this.velocity.multiply(-16);
var gWorkGravityDir = this.level != null ? this.level.currentUp.multiply(-1) : new Vector(0, 0, -1);
var gWorkGravityDir = this.currentUp.multiply(-1);
var A = new Vector();
A = gWorkGravityDir.multiply(this._gravity);
if (currentTime - this.helicopterEnableTime < 5) {
@ -617,7 +621,7 @@ class Marble extends GameObject {
}
function computeMoveForces(m:Move, aControl:Vector, desiredOmega:Vector) {
var currentGravityDir = this.level != null ? this.level.currentUp.multiply(-1) : new Vector(0, 0, -1);
var currentGravityDir = this.currentUp.multiply(-1);
var R = currentGravityDir.multiply(-this._radius);
var rollVelocity = this.omega.cross(R);
var axes = this.getMarbleAxis();
@ -795,7 +799,7 @@ class Marble extends GameObject {
function applyContactForces(dt:Float, m:Move, isCentered:Bool, aControl:Vector, desiredOmega:Vector, A:Vector) {
var a = new Vector();
this._slipAmount = 0;
var gWorkGravityDir = this.level != null ? this.level.currentUp.multiply(-1) : new Vector(0, 0, -1);
var gWorkGravityDir = this.currentUp.multiply(-1);
var bestSurface = -1;
var bestNormalForce = 0.0;
for (i in 0...contacts.length) {
@ -1467,6 +1471,14 @@ class Marble extends GameObject {
}
}
// Blast
if (m.blast) {
this.useBlast();
if (level.isRecording) {
level.replay.recordMarbleStateFlags(false, false, false, true);
}
}
do {
if (timeRemaining <= 0)
break;
@ -1687,6 +1699,7 @@ class Marble extends GameObject {
}
public function updateClient(timeState:TimeState, pathedInteriors:Array<PathedInterior>) {
this.level.updateBlast(this, timeState);
if (oldPos != null && newPos != null) {
var deltaT = physicsAccumulator / 0.032;
var renderPos = Util.lerpThreeVectors(this.oldPos, this.newPos, deltaT);
@ -1732,7 +1745,7 @@ class Marble extends GameObject {
this._radius = 0.675;
this.collider.radius = 0.675;
this._marbleScale *= 2.25;
var boost = this.level.currentUp.multiply(5);
var boost = this.currentUp.multiply(5);
this.velocity = this.velocity.add(boost);
} else if (timeState.currentAttemptTime - this.megaMarbleEnableTime > 10) {
if (this._radius != this._prevRadius) {
@ -1893,7 +1906,7 @@ class Marble extends GameObject {
this._radius = 0.675;
this.collider.radius = 0.675;
this._marbleScale *= 2.25;
var boost = this.level.currentUp.multiply(5);
var boost = this.currentUp.multiply(5);
this.velocity = this.velocity.add(boost);
} else if (timeState.currentAttemptTime - this.megaMarbleEnableTime > 10) {
if (this._radius != this._prevRadius) {
@ -2032,14 +2045,15 @@ class Marble extends GameObject {
}
public function useBlast() {
if (this.level.blastAmount < 0.25 || this.level.game != "ultra")
if (this.blastAmount < 0.25)
return false;
var impulse = this.level.currentUp.multiply(this.level.blastAmount * 8);
var impulse = this.currentUp.multiply(this.blastAmount * 8);
this.applyImpulse(impulse);
AudioManager.playSound(ResourceLoader.getResource('data/sound/use_blast.wav', ResourceLoader.getAudio, this.soundResources));
if (this.controllable)
AudioManager.playSound(ResourceLoader.getResource('data/sound/use_blast.wav', ResourceLoader.getAudio, this.soundResources));
this.blastWave.doSequenceOnceBeginTime = this.level.timeState.timeSinceLoad;
this.blastUseTime = this.level.timeState.currentAttemptTime;
this.level.blastAmount = 0;
this.blastAmount = 0;
return true;
}

View file

@ -144,8 +144,6 @@ class MarbleWorld extends Scheduler {
public var game:String;
public var marble:Marble;
public var worldOrientation:Quat;
public var currentUp = new Vector(0, 0, 1);
public var outOfBounds:Bool = false;
public var outOfBoundsTime:TimeState;
public var finishTime:TimeState;
@ -153,7 +151,6 @@ class MarbleWorld extends Scheduler {
public var finishYaw:Float;
public var totalGems:Int = 0;
public var gemCount:Int = 0;
public var blastAmount:Float = 0;
public var skipStartBugPauseTime:Float = 0.0;
var renderBlastAmount:Float = 0;
@ -510,7 +507,7 @@ class MarbleWorld extends Scheduler {
this.timeState.gameplayClock = this.gameMode.getStartTime();
this.bonusTime = 0;
this.outOfBounds = false;
this.blastAmount = 0;
this.marble.blastAmount = 0;
this.renderBlastAmount = 0;
this.outOfBoundsTime = null;
this.finishTime = null;
@ -1094,7 +1091,7 @@ class MarbleWorld extends Scheduler {
}
this.updateGameState();
this.updateBlast(timeState);
this.updateBlast(this.marble, timeState);
ProfilerUI.measure("updateDTS");
for (obj in dtsObjects) {
obj.update(timeState);
@ -1224,18 +1221,6 @@ class MarbleWorld extends Scheduler {
this.tickSchedule(timeState.currentAttemptTime);
if (Key.isDown(Settings.controlsSettings.blast)
|| (MarbleGame.instance.touchInput.blastbutton.pressed)
|| Gamepad.isDown(Settings.gamepadSettings.blast)
&& !this.isWatching
&& this.game == "ultra") {
if (this.marble.useBlast()) {
if (this.isRecording) {
this.replay.recordMarbleStateFlags(false, false, false, true);
}
}
}
if (this.isWatching && this.replay.currentPlaybackFrame.marbleStateFlags.has(UsedBlast))
this.marble.useBlast();
@ -1251,7 +1236,8 @@ class MarbleWorld extends Scheduler {
radar.update(dt);
this.updateGameState();
this.updateBlast(timeState);
if (!this.isMultiplayer)
this.updateBlast(this.marble, timeState);
ProfilerUI.measure("updateDTS");
for (obj in dtsObjects) {
obj.update(timeState);
@ -1451,16 +1437,17 @@ class MarbleWorld extends Scheduler {
this.replay.recordTimeState(timeState.currentAttemptTime, timeState.gameplayClock, this.bonusTime);
}
function updateBlast(timestate:TimeState) {
if (this.game == "ultra") {
if (this.blastAmount < 1) {
this.blastAmount = Util.clamp(this.blastAmount + (timeState.dt / 30), 0, 1);
this.renderBlastAmount = this.blastAmount;
} else {
this.renderBlastAmount = Math.min(this.blastAmount, timestate.dt * 0.75 + this.renderBlastAmount);
}
this.playGui.setBlastValue(this.renderBlastAmount);
public function updateBlast(marble:Marble, timestate:TimeState) {
if (marble.blastAmount < 1) {
marble.blastAmount = Util.clamp(marble.blastAmount + (timeState.dt / 30), 0, 1);
if (marble == this.marble)
this.renderBlastAmount = marble.blastAmount;
} else {
if (marble == this.marble)
this.renderBlastAmount = Math.min(marble.blastAmount, timestate.dt * 0.75 + this.renderBlastAmount);
}
if (marble == this.marble)
this.playGui.setBlastValue(this.renderBlastAmount);
}
function updateTexts() {
@ -1829,7 +1816,7 @@ class MarbleWorld extends Scheduler {
}
public function setUp(vec:Vector, timeState:TimeState, instant:Bool = false) {
this.currentUp = vec;
this.marble.currentUp = vec;
var currentQuat = this.getOrientationQuat(timeState.currentAttemptTime);
var oldUp = new Vector(0, 0, 1);
oldUp.transform(currentQuat.toMatrix());
@ -1927,7 +1914,7 @@ class MarbleWorld extends Scheduler {
this.currentCheckpoint = shape;
this.currentCheckpointTrigger = trigger;
this.checkpointCollectedGems.clear();
this.cheeckpointBlast = this.blastAmount;
this.cheeckpointBlast = this.marble.blastAmount;
// Remember all gems that were collected up to this point
for (gem in this.gems) {
if (gem.pickedUp)
@ -1963,7 +1950,7 @@ class MarbleWorld extends Scheduler {
this.marble.camera.oob = false;
@:privateAccess this.marble.helicopterEnableTime = -1e8;
@:privateAccess this.marble.megaMarbleEnableTime = -1e8;
this.blastAmount = this.cheeckpointBlast;
this.marble.blastAmount = this.cheeckpointBlast;
if (this.isRecording) {
this.replay.recordCameraState(this.marble.camera.CameraYaw, this.marble.camera.CameraPitch);
this.replay.recordMarbleInput(0, 0);

View file

@ -73,6 +73,12 @@ class MoveManager {
|| Gamepad.isDown(Settings.gamepadSettings.powerup)) {
move.powerup = true;
}
if (Key.isDown(Settings.controlsSettings.blast)
|| (MarbleGame.instance.touchInput.blastbutton.pressed)
|| Gamepad.isDown(Settings.gamepadSettings.blast))
move.blast = true;
if (MarbleGame.instance.touchInput.movementInput.pressed) {
move.d.y = -MarbleGame.instance.touchInput.movementInput.value.x;
move.d.x = MarbleGame.instance.touchInput.movementInput.value.y;
@ -106,6 +112,8 @@ class MoveManager {
flags |= 1;
if (m.move.powerup)
flags |= 2;
if (m.move.blast)
flags |= 4;
b.writeByte(flags);
b.writeFloat(m.motionDir.x);
b.writeFloat(m.motionDir.y);
@ -122,6 +130,7 @@ class MoveManager {
var flags = b.readByte();
move.jump = (flags & 1) != 0;
move.powerup = (flags & 2) != 0;
move.blast = (flags & 4) != 0;
var motionDir = new Vector();
motionDir.x = b.readFloat();
motionDir.y = b.readFloat();

View file

@ -56,7 +56,7 @@ class RewindManager {
rf.gemCount = level.gemCount;
rf.gemStates = level.gems.map(x -> x.pickedUp);
rf.activePowerupStates = [@:privateAccess level.marble.helicopterEnableTime, @:privateAccess level.marble.megaMarbleEnableTime];
rf.currentUp = level.currentUp.clone();
rf.currentUp = level.marble.currentUp.clone();
rf.lastContactNormal = level.marble.lastContactNormal.clone();
rf.mpStates = level.pathedInteriors.map(x -> {
var mpstate = new RewindMPState();
@ -89,7 +89,7 @@ class RewindManager {
rf.powerupStates.push(ab.lastContactTime);
}
}
rf.blastAmt = level.blastAmount;
rf.blastAmt = level.marble.blastAmount;
rf.oobState = {
oob: level.outOfBounds,
timeState: level.outOfBoundsTime != null ? level.outOfBoundsTime.clone() : null
@ -145,7 +145,9 @@ class RewindManager {
@:privateAccess level.marble.helicopterEnableTime = rf.activePowerupStates[0];
@:privateAccess level.marble.megaMarbleEnableTime = rf.activePowerupStates[1];
if (level.currentUp.x != rf.currentUp.x || level.currentUp.y != rf.currentUp.y || level.currentUp.z != rf.currentUp.z) {
if (level.marble.currentUp.x != rf.currentUp.x
|| level.marble.currentUp.y != rf.currentUp.y
|| level.marble.currentUp.z != rf.currentUp.z) {
level.setUp(rf.currentUp, level.timeState);
// Hacky things
@:privateAccess level.orientationChangeTime = level.timeState.currentAttemptTime - 300;
@ -160,7 +162,7 @@ class RewindManager {
@:privateAccess level.orientationChangeTime = -1e8;
}
level.currentUp.load(rf.currentUp);
level.marble.currentUp.load(rf.currentUp);
level.marble.lastContactNormal.load(rf.lastContactNormal);
for (i in 0...rf.mpStates.length) {
level.pathedInteriors[i].currentTime = rf.mpStates[i].currentTime;
@ -213,7 +215,7 @@ class RewindManager {
@:privateAccess level.playGui.setCenterText('');
level.marble.camera.oob = rf.oobState.oob;
level.outOfBoundsTime = rf.oobState.timeState != null ? rf.oobState.timeState.clone() : null;
level.blastAmount = rf.blastAmt;
level.marble.blastAmount = rf.blastAmt;
@:privateAccess level.checkpointCollectedGems = rf.checkpointState.checkpointCollectedGems;
@:privateAccess level.cheeckpointBlast = rf.checkpointState.checkpointBlast;
@:privateAccess level.checkpointHeldPowerup = rf.checkpointState.checkpointHeldPowerup;

View file

@ -34,9 +34,9 @@ class DirLight extends Light {
}
override function getShadowDirection():h3d.Vector {
if (MarbleGame.instance.world == null)
if (MarbleGame.instance.world == null || MarbleGame.instance.world.marble == null)
return new h3d.Vector(0, 0, -1);
return MarbleGame.instance.world.currentUp.multiply(-1);
return MarbleGame.instance.world.marble.currentUp.multiply(-1);
}
override function emit(ctx) {

View file

@ -30,20 +30,18 @@ class AntiGravity extends PowerUp {
public function pickUp(marble:Marble):Bool {
var direction = new Vector(0, 0, -1);
direction.transform(this.getRotationQuat().toMatrix());
return !direction.equals(this.level.currentUp);
return !direction.equals(this.level.marble.currentUp);
}
public function use(marble:Marble, timeState:TimeState) {
if (!this.level.rewinding) {
var direction = new Vector(0, 0, -1);
direction.transform(this.getRotationQuat().toMatrix());
this.level.setUp(direction, timeState);
if (marble == level.marble)
this.level.setUp(direction, timeState);
else
marble.currentUp.load(direction);
}
// marble.body.addLinearVelocity(this.level.currentUp.scale(20)); // Simply add to vertical velocity
// if (!this.level.rewinding)
// AudioManager.play(this.sounds[1]);
// this.level.particles.createEmitter(superJumpParticleOptions, null, () => Util.vecOimoToThree(marble.body.getPosition()));
// this.level.deselectPowerUp();
}
public override function init(level:MarbleWorld, onFinish:Void->Void) {

View file

@ -33,7 +33,7 @@ class Blast extends PowerUp {
}
public function use(marble:Marble, timeState:TimeState) {
this.level.blastAmount = 1.2;
marble.blastAmount = 1.2;
}
override function getPreloadMaterials(dts:dts.DtsFile) {

View file

@ -69,7 +69,7 @@ class SuperJump extends PowerUp {
public function use(marble:Marble, timeState:TimeState) {
var masslessFactor = marble.getMass() * 0.7 + 1 - 0.7;
var boost = this.level.currentUp.multiply(20 * masslessFactor / marble.getMass());
var boost = marble.currentUp.multiply(20 * masslessFactor / marble.getMass());
marble.velocity = marble.velocity.add(boost);
this.level.particleManager.createEmitter(superJumpParticleOptions, this.sjEmitterParticleData, null, () -> marble.getAbsPos().getPosition());
// marble.body.addLinearVelocity(this.level.currentUp.scale(20)); // Simply add to vertical velocity

View file

@ -78,7 +78,7 @@ class SuperSpeed extends PowerUp {
var quat2 = new Quat();
// Determine the necessary rotation to rotate the up vector to the contact normal.
quat2.initMoveTo(this.level.currentUp, marble.lastContactNormal);
quat2.initMoveTo(marble.currentUp, marble.lastContactNormal);
movementVector.transform(quat2.toMatrix());
var masslessFactor = marble.getMass() * 0.7 + 1 - 0.7;
marble.velocity = marble.velocity.add(movementVector.multiply(-25 * masslessFactor / marble.getMass()));