mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
deterministic gem hunt spawn
This commit is contained in:
parent
5cc595bbe7
commit
9a76eecaca
5 changed files with 110 additions and 2 deletions
|
|
@ -580,6 +580,7 @@ class MarbleWorld extends Scheduler {
|
|||
this.playGui.setCenterText('');
|
||||
this.clearSchedule();
|
||||
this.outOfBounds = false;
|
||||
this.gameMode.onRespawn();
|
||||
AudioManager.playSound(ResourceLoader.getResource('data/sound/spawn_alternate.wav', ResourceLoader.getAudio, this.soundResources));
|
||||
}
|
||||
|
||||
|
|
|
|||
53
src/RandomLCG.hx
Normal file
53
src/RandomLCG.hx
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
class RandomLCG {
|
||||
var seed:Int;
|
||||
|
||||
static var msSeed:Int = 1376312589;
|
||||
|
||||
static var quotient = 127773;
|
||||
static var remainder = 2836;
|
||||
|
||||
public function new(seed = -1) {
|
||||
this.seed = (seed == -1) ? generateSeed() : seed;
|
||||
}
|
||||
|
||||
inline function generateSeed() {
|
||||
// A very, VERY crude LCG but good enough to generate
|
||||
// a nice range of seed values
|
||||
msSeed = (msSeed * 0x015a4e35) + 1;
|
||||
msSeed = (msSeed >> 16) & 0x7fff;
|
||||
return (msSeed);
|
||||
}
|
||||
|
||||
public function setSeed(seed:Int) {
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
public function randInt() {
|
||||
if (seed <= quotient)
|
||||
seed = (seed * 16807) % 2147483647;
|
||||
else {
|
||||
var high_part:Int = Std.int(seed / quotient);
|
||||
var low_part = seed % quotient;
|
||||
|
||||
var test:Int = (16807 * low_part) - (remainder * high_part);
|
||||
|
||||
if (test > 0)
|
||||
seed = test;
|
||||
else
|
||||
seed = test + 2147483647;
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
|
||||
public function randFloat() {
|
||||
return randInt() / 2147483647.0;
|
||||
}
|
||||
|
||||
public function randRange(i:Int, n:Int) {
|
||||
return (i + (randInt() % (n - i + 1)));
|
||||
}
|
||||
|
||||
public function randRangeF(i:Float, n:Int) {
|
||||
return (i + (n - i) * randFloat());
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ interface GameMode {
|
|||
public function applyRewindState(state:RewindableState):Void;
|
||||
public function onTimeExpire():Void;
|
||||
public function onRestart():Void;
|
||||
public function onRespawn():Void;
|
||||
public function onGemPickup(gem:Gem):Void;
|
||||
|
||||
public function getPreloadFiles():Array<String>;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package modes;
|
||||
|
||||
import hxd.Rand;
|
||||
import rewind.RewindableState;
|
||||
import gui.AchievementsGui;
|
||||
import modes.GameMode.ScoreType;
|
||||
|
|
@ -81,6 +82,8 @@ class HuntState implements RewindableState {
|
|||
var activeGemSpawnGroup:Array<GemSpawnSphere>;
|
||||
var activeGems:Array<Gem>;
|
||||
var points:Int;
|
||||
var rngState:Int;
|
||||
var rngState2:Int;
|
||||
|
||||
public function new() {}
|
||||
|
||||
|
|
@ -94,6 +97,8 @@ class HuntState implements RewindableState {
|
|||
c.activeGemSpawnGroup = activeGemSpawnGroup.copy();
|
||||
c.points = points;
|
||||
c.activeGems = activeGems.copy();
|
||||
c.rngState = rngState;
|
||||
c.rngState2 = rngState2;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
|
@ -109,6 +114,8 @@ class HuntMode extends NullMode {
|
|||
var activeGems:Array<Gem> = [];
|
||||
var gemBeams:Array<GemBeam> = [];
|
||||
var gemToBeamMap:Map<Gem, GemBeam> = [];
|
||||
var rng:RandomLCG = new RandomLCG(100);
|
||||
var rng2:RandomLCG = new RandomLCG(100);
|
||||
|
||||
var points:Int = 0;
|
||||
|
||||
|
|
@ -131,7 +138,7 @@ class HuntMode extends NullMode {
|
|||
};
|
||||
|
||||
override function getSpawnTransform() {
|
||||
var randomSpawn = playerSpawnPoints[Math.floor(Math.random() * playerSpawnPoints.length)];
|
||||
var randomSpawn = playerSpawnPoints[Math.floor(rng2.randRange(0, playerSpawnPoints.length - 1))];
|
||||
var spawnPos = MisParser.parseVector3(randomSpawn.position);
|
||||
spawnPos.x *= -1;
|
||||
var spawnRot = MisParser.parseRotation(randomSpawn.rotation);
|
||||
|
|
@ -170,6 +177,7 @@ class HuntMode extends NullMode {
|
|||
var spawnMat = spawnRot.toMatrix();
|
||||
var up = spawnMat.up();
|
||||
spawnPos = spawnPos.add(up.multiply(0.727843 / 3)); // 1.5 -> 0.5
|
||||
|
||||
return {
|
||||
position: spawnPos,
|
||||
orientation: spawnRot,
|
||||
|
|
@ -179,6 +187,26 @@ class HuntMode extends NullMode {
|
|||
return null;
|
||||
}
|
||||
|
||||
override function onRespawn() {
|
||||
if (activeGemSpawnGroup.length != 0) {
|
||||
var gemAvg = new Vector();
|
||||
for (g in activeGemSpawnGroup) {
|
||||
gemAvg = gemAvg.add(g.position);
|
||||
}
|
||||
gemAvg.scale(1 / activeGemSpawnGroup.length);
|
||||
var delta = gemAvg.sub(level.marble.getAbsPos().getPosition());
|
||||
var gravFrame = level.getOrientationQuat(0).toMatrix();
|
||||
var v1 = gravFrame.front();
|
||||
var v2 = gravFrame.right();
|
||||
var deltaRot = new Vector(delta.dot(v2), delta.dot(v1));
|
||||
if (deltaRot.length() >= 0.001) {
|
||||
var ang = Math.atan2(deltaRot.x, deltaRot.y);
|
||||
level.marble.camera.CameraYaw = ang;
|
||||
level.marble.camera.nextCameraYaw = ang;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override public function getStartTime() {
|
||||
return level.mission.qualifyTime;
|
||||
}
|
||||
|
|
@ -188,6 +216,8 @@ class HuntMode extends NullMode {
|
|||
}
|
||||
|
||||
override function onRestart() {
|
||||
rng.setSeed(100);
|
||||
rng2.setSeed(100);
|
||||
setupGems();
|
||||
points = 0;
|
||||
@:privateAccess level.playGui.formatGemHuntCounter(points);
|
||||
|
|
@ -242,9 +272,26 @@ class HuntMode extends NullMode {
|
|||
}
|
||||
}
|
||||
}
|
||||
activeGemSpawnGroup = [];
|
||||
|
||||
activeGems = [];
|
||||
refillGemGroups();
|
||||
|
||||
var gemAvg = new Vector();
|
||||
for (g in activeGemSpawnGroup) {
|
||||
gemAvg = gemAvg.add(g.position);
|
||||
}
|
||||
gemAvg.scale(1 / activeGemSpawnGroup.length);
|
||||
var delta = gemAvg.sub(level.marble.getAbsPos().getPosition());
|
||||
var gravFrame = level.getOrientationQuat(0).toMatrix();
|
||||
var v1 = gravFrame.front();
|
||||
var v2 = gravFrame.right();
|
||||
var deltaRot = new Vector(delta.dot(v2), delta.dot(v1));
|
||||
if (deltaRot.length() >= 0.001) {
|
||||
var ang = Math.atan2(deltaRot.x, deltaRot.y);
|
||||
level.marble.camera.CameraYaw = ang;
|
||||
level.marble.camera.nextCameraYaw = ang;
|
||||
}
|
||||
}
|
||||
|
||||
function refillGemGroups() {
|
||||
|
|
@ -320,7 +367,7 @@ class HuntMode extends NullMode {
|
|||
|
||||
function findGemSpawnGroup(outSpawnPoint:Vector) {
|
||||
// Pick random spawn point
|
||||
var rnd:Int = Std.int(Math.random() * gemSpawnPoints.length);
|
||||
var rnd:Int = Std.int(rng.randRange(0, gemSpawnPoints.length - 1));
|
||||
if (level.isRecording)
|
||||
level.replay.recordRandomGenState(rnd);
|
||||
if (level.isWatching)
|
||||
|
|
@ -394,6 +441,8 @@ class HuntMode extends NullMode {
|
|||
s.points = points;
|
||||
s.activeGemSpawnGroup = activeGemSpawnGroup;
|
||||
s.activeGems = activeGems.copy();
|
||||
s.rngState = @:privateAccess rng.seed;
|
||||
s.rngState2 = @:privateAccess rng2.seed;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
@ -415,5 +464,7 @@ class HuntMode extends NullMode {
|
|||
var gemBeam = gemToBeamMap.get(gem);
|
||||
gemBeam.setHide(false);
|
||||
}
|
||||
rng.setSeed(s.rngState);
|
||||
rng2.setSeed(s.rngState2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ class NullMode implements GameMode {
|
|||
|
||||
public function onRestart() {}
|
||||
|
||||
public function onRespawn() {}
|
||||
|
||||
public function onGemPickup(gem:Gem) {
|
||||
this.level.gemCount++;
|
||||
var string:String;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue