random pup and cleanup marbleworld

This commit is contained in:
RandomityGuy 2023-02-14 18:58:05 +05:30
parent 4bfd6dd6be
commit 07bd6a15c8
5 changed files with 235 additions and 251 deletions

View file

@ -46,3 +46,127 @@ class MisParserMacros {
}
}
}
class MarbleWorldMacros {
public static macro function addStaticShapeOrItem() {
// Rip intellisense
return macro {
var shape:DtsObject = null;
// Add the correct shape based on type
var dataBlockLowerCase = element.datablock.toLowerCase();
if (dataBlockLowerCase == "") {} // Make sure we don't do anything if there's no data block
else if (dataBlockLowerCase == "startpad")
shape = new StartPad();
else if (dataBlockLowerCase == "endpad") {
shape = new EndPad();
if (element is MissionElementStaticShape && cast(element, MissionElementStaticShape) == endPadElement)
endPad = cast shape;
} else if (dataBlockLowerCase == "signfinish")
shape = new SignFinish();
else if (StringTools.startsWith(dataBlockLowerCase, "gemitem")) {
shape = new Gem(cast element);
this.totalGems++;
this.gems.push(cast shape);
} else if (dataBlockLowerCase == "superjumpitem")
shape = new SuperJump(cast element);
else if (dataBlockLowerCase == "superbounceitem")
shape = new SuperBounce(cast element);
else if (dataBlockLowerCase == "roundbumper")
shape = new RoundBumper();
else if (dataBlockLowerCase == "trianglebumper")
shape = new TriangleBumper();
else if (dataBlockLowerCase == "helicopteritem")
shape = new Helicopter(cast element);
else if (dataBlockLowerCase == "easteregg")
shape = new EasterEgg(cast element);
else if (dataBlockLowerCase == "checkpoint")
shape = new Checkpoint(cast element);
else if (dataBlockLowerCase == "ductfan")
shape = new DuctFan();
else if (dataBlockLowerCase == "smallductfan")
shape = new SmallDuctFan();
else if (dataBlockLowerCase == "magnet")
shape = new Magnet();
else if (dataBlockLowerCase == "antigravityitem")
shape = new AntiGravity(cast element);
else if (dataBlockLowerCase == "norespawnantigravityitem")
shape = new AntiGravity(cast element, true);
else if (dataBlockLowerCase == "landmine")
shape = new LandMine();
else if (dataBlockLowerCase == "nuke")
shape = new Nuke();
else if (dataBlockLowerCase == "shockabsorberitem")
shape = new ShockAbsorber(cast element);
else if (dataBlockLowerCase == "superspeeditem")
shape = new SuperSpeed(cast element);
else if (dataBlockLowerCase == "timetravelitem" || dataBlockLowerCase == "timepenaltyitem")
shape = new TimeTravel(cast element);
else if (dataBlockLowerCase == "randompowerupitem")
shape = new RandomPowerup(cast element);
else if (dataBlockLowerCase == "blastitem")
shape = new Blast(cast element);
else if (dataBlockLowerCase == "megamarbleitem")
shape = new MegaMarble(cast element);
else if (dataBlockLowerCase == "tornado")
shape = new Tornado();
else if (dataBlockLowerCase == "trapdoor")
shape = new Trapdoor();
else if (dataBlockLowerCase == "pushbutton")
shape = new PushButton();
else if (dataBlockLowerCase == "oilslick")
shape = new Oilslick();
else if (dataBlockLowerCase == "arrow" || StringTools.startsWith(dataBlockLowerCase, "sign"))
shape = new Sign(cast element);
else if ([
"glass_3shape",
"glass_6shape",
"glass_9shape",
"glass_12shape",
"glass_15shape",
"glass_18shape"
].contains(dataBlockLowerCase))
shape = new Glass(cast element);
else if (["clear", "cloudy", "dusk", "wintry"].contains(dataBlockLowerCase))
shape = new shapes.Sky(dataBlockLowerCase);
else {
Console.error("Unknown item: " + element.datablock);
onFinish();
return;
}
if (element._name != null && element._name != "") {
this.namedObjects.set(element._name, {
obj: shape,
elem: element
});
}
var shapePosition = MisParser.parseVector3(element.position);
shapePosition.x = -shapePosition.x;
var shapeRotation = MisParser.parseRotation(element.rotation);
shapeRotation.x = -shapeRotation.x;
shapeRotation.w = -shapeRotation.w;
var shapeScale = MisParser.parseVector3(element.scale);
// Apparently we still do collide with zero-volume shapes
if (shapeScale.x == 0)
shapeScale.x = 0.0001;
if (shapeScale.y == 0)
shapeScale.y = 0.0001;
if (shapeScale.z == 0)
shapeScale.z = 0.0001;
var mat = Matrix.S(shapeScale.x, shapeScale.y, shapeScale.z);
var tmp = new Matrix();
shapeRotation.toMatrix(tmp);
mat.multiply3x4(mat, tmp);
mat.setPosition(shapePosition);
this.addDtsObject(shape, () -> {
shape.setTransform(mat);
onFinish();
});
}
}
}

View file

@ -1,5 +1,6 @@
package src;
import Macros.MarbleWorldMacros;
import shapes.PushButton;
#if js
import gui.MainMenuGui;
@ -57,6 +58,7 @@ import shapes.Helicopter;
import shapes.TriangleBumper;
import shapes.RoundBumper;
import shapes.SuperBounce;
import shapes.RandomPowerup;
import shapes.SignCaution;
import shapes.SuperJump;
import shapes.Gem;
@ -712,242 +714,12 @@ class MarbleWorld extends Scheduler {
public function addStaticShape(element:MissionElementStaticShape, onFinish:Void->Void) {
var shape:DtsObject = null;
// Add the correct shape based on type
var dataBlockLowerCase = element.datablock.toLowerCase();
if (dataBlockLowerCase == "") {} // Make sure we don't do anything if there's no data block
else if (dataBlockLowerCase == "startpad")
shape = new StartPad();
else if (dataBlockLowerCase == "endpad") {
shape = new EndPad();
if (element == endPadElement)
endPad = cast shape;
} else if (dataBlockLowerCase == "signfinish")
shape = new SignFinish();
else if (StringTools.startsWith(dataBlockLowerCase, "signplain"))
shape = new SignPlain(element);
else if (StringTools.startsWith(dataBlockLowerCase, "gemitem")) {
shape = new Gem(cast element);
this.totalGems++;
this.gems.push(cast shape);
} else if (dataBlockLowerCase == "superjumpitem")
shape = new SuperJump(cast element);
else if (StringTools.startsWith(dataBlockLowerCase, "signcaution"))
shape = new SignCaution(element);
else if (dataBlockLowerCase == "superbounceitem")
shape = new SuperBounce(cast element);
else if (dataBlockLowerCase == "roundbumper")
shape = new RoundBumper();
else if (dataBlockLowerCase == "trianglebumper")
shape = new TriangleBumper();
else if (dataBlockLowerCase == "helicopteritem")
shape = new Helicopter(cast element);
else if (dataBlockLowerCase == "easteregg")
shape = new EasterEgg(cast element);
else if (dataBlockLowerCase == "checkpoint")
shape = new Checkpoint(cast element);
else if (dataBlockLowerCase == "ductfan")
shape = new DuctFan();
else if (dataBlockLowerCase == "smallductfan")
shape = new SmallDuctFan();
else if (dataBlockLowerCase == "magnet")
shape = new Magnet();
else if (dataBlockLowerCase == "antigravityitem")
shape = new AntiGravity(cast element);
else if (dataBlockLowerCase == "norespawnantigravityitem")
shape = new AntiGravity(cast element, true);
else if (dataBlockLowerCase == "landmine")
shape = new LandMine();
else if (dataBlockLowerCase == "nuke")
shape = new Nuke();
else if (dataBlockLowerCase == "shockabsorberitem")
shape = new ShockAbsorber(cast element);
else if (dataBlockLowerCase == "superspeeditem")
shape = new SuperSpeed(cast element);
else if (dataBlockLowerCase == "timetravelitem" || dataBlockLowerCase == "timepenaltyitem")
shape = new TimeTravel(cast element);
else if (dataBlockLowerCase == "blast")
shape = new Blast(cast element);
else if (dataBlockLowerCase == "megamarble")
shape = new MegaMarble(cast element);
else if (dataBlockLowerCase == "tornado")
shape = new Tornado();
else if (dataBlockLowerCase == "trapdoor")
shape = new Trapdoor();
else if (dataBlockLowerCase == "pushbutton")
shape = new PushButton();
else if (dataBlockLowerCase == "oilslick")
shape = new Oilslick();
else if (dataBlockLowerCase == "arrow" || StringTools.startsWith(dataBlockLowerCase, "sign"))
shape = new Sign(cast element);
else if ([
"glass_3shape",
"glass_6shape",
"glass_9shape",
"glass_12shape",
"glass_15shape",
"glass_18shape"
].contains(dataBlockLowerCase))
shape = new Glass(cast element);
else if (["clear", "cloudy", "dusk", "wintry"].contains(dataBlockLowerCase))
shape = new shapes.Sky(dataBlockLowerCase);
else {
Console.error("Unable to create static shape with data block '" + element.datablock + "'");
onFinish();
return;
}
if (element._name != null && element._name != "") {
this.namedObjects.set(element._name, {
obj: shape,
elem: element
});
}
var shapePosition = MisParser.parseVector3(element.position);
shapePosition.x = -shapePosition.x;
var shapeRotation = MisParser.parseRotation(element.rotation);
shapeRotation.x = -shapeRotation.x;
shapeRotation.w = -shapeRotation.w;
var shapeScale = MisParser.parseVector3(element.scale);
// Apparently we still do collide with zero-volume shapes
if (shapeScale.x == 0)
shapeScale.x = 0.0001;
if (shapeScale.y == 0)
shapeScale.y = 0.0001;
if (shapeScale.z == 0)
shapeScale.z = 0.0001;
var mat = Matrix.S(shapeScale.x, shapeScale.y, shapeScale.z);
var tmp = new Matrix();
shapeRotation.toMatrix(tmp);
mat.multiply3x4(mat, tmp);
var tmat = Matrix.T(shapePosition.x, shapePosition.y, shapePosition.z);
mat.multiply(mat, tmat);
this.addDtsObject(shape, () -> {
shape.setTransform(mat);
onFinish();
});
// else if (dataBlockLowerCase == "pushbutton")
// shape = new PushButton();
MarbleWorldMacros.addStaticShapeOrItem();
}
public function addItem(element:MissionElementItem, onFinish:Void->Void) {
var shape:DtsObject = null;
// Add the correct shape based on type
var dataBlockLowerCase = element.datablock.toLowerCase();
if (dataBlockLowerCase == "") {} // Make sure we don't do anything if there's no data block
else if (dataBlockLowerCase == "startpad")
shape = new StartPad();
else if (dataBlockLowerCase == "endpad")
shape = new EndPad();
else if (dataBlockLowerCase == "signfinish")
shape = new SignFinish();
else if (StringTools.startsWith(dataBlockLowerCase, "gemitem")) {
shape = new Gem(cast element);
this.totalGems++;
this.gems.push(cast shape);
} else if (dataBlockLowerCase == "superjumpitem")
shape = new SuperJump(cast element);
else if (dataBlockLowerCase == "superbounceitem")
shape = new SuperBounce(cast element);
else if (dataBlockLowerCase == "roundbumper")
shape = new RoundBumper();
else if (dataBlockLowerCase == "trianglebumper")
shape = new TriangleBumper();
else if (dataBlockLowerCase == "helicopteritem")
shape = new Helicopter(cast element);
else if (dataBlockLowerCase == "easteregg")
shape = new EasterEgg(cast element);
else if (dataBlockLowerCase == "checkpoint")
shape = new Checkpoint(cast element);
else if (dataBlockLowerCase == "ductfan")
shape = new DuctFan();
else if (dataBlockLowerCase == "smallductfan")
shape = new SmallDuctFan();
else if (dataBlockLowerCase == "magnet")
shape = new Magnet();
else if (dataBlockLowerCase == "antigravityitem")
shape = new AntiGravity(cast element);
else if (dataBlockLowerCase == "norespawnantigravityitem")
shape = new AntiGravity(cast element, true);
else if (dataBlockLowerCase == "landmine")
shape = new LandMine();
else if (dataBlockLowerCase == "nuke")
shape = new Nuke();
else if (dataBlockLowerCase == "shockabsorberitem")
shape = new ShockAbsorber(cast element);
else if (dataBlockLowerCase == "superspeeditem")
shape = new SuperSpeed(cast element);
else if (dataBlockLowerCase == "timetravelitem" || dataBlockLowerCase == "timepenaltyitem")
shape = new TimeTravel(cast element);
else if (dataBlockLowerCase == "blastitem")
shape = new Blast(cast element);
else if (dataBlockLowerCase == "megamarbleitem")
shape = new MegaMarble(cast element);
else if (dataBlockLowerCase == "tornado")
shape = new Tornado();
else if (dataBlockLowerCase == "trapdoor")
shape = new Trapdoor();
else if (dataBlockLowerCase == "pushbutton")
shape = new PushButton();
else if (dataBlockLowerCase == "oilslick")
shape = new Oilslick();
else if (dataBlockLowerCase == "arrow" || StringTools.startsWith(dataBlockLowerCase, "sign"))
shape = new Sign(cast element);
else if ([
"glass_3shape",
"glass_6shape",
"glass_9shape",
"glass_12shape",
"glass_15shape",
"glass_18shape"
].contains(dataBlockLowerCase))
shape = new Glass(cast element);
else if (["clear", "cloudy", "dusk", "wintry"].contains(dataBlockLowerCase))
shape = new shapes.Sky(dataBlockLowerCase);
else {
Console.error("Unknown item: " + element.datablock);
onFinish();
return;
}
if (element._name != null && element._name != "") {
this.namedObjects.set(element._name, {
obj: shape,
elem: element
});
}
var shapePosition = MisParser.parseVector3(element.position);
shapePosition.x = -shapePosition.x;
var shapeRotation = MisParser.parseRotation(element.rotation);
shapeRotation.x = -shapeRotation.x;
shapeRotation.w = -shapeRotation.w;
var shapeScale = MisParser.parseVector3(element.scale);
// Apparently we still do collide with zero-volume shapes
if (shapeScale.x == 0)
shapeScale.x = 0.0001;
if (shapeScale.y == 0)
shapeScale.y = 0.0001;
if (shapeScale.z == 0)
shapeScale.z = 0.0001;
var mat = Matrix.S(shapeScale.x, shapeScale.y, shapeScale.z);
var tmp = new Matrix();
shapeRotation.toMatrix(tmp);
mat.multiply3x4(mat, tmp);
mat.setPosition(shapePosition);
this.addDtsObject(shape, () -> {
shape.setTransform(mat);
onFinish();
});
MarbleWorldMacros.addStaticShapeOrItem();
}
public function addTrigger(element:MissionElementTrigger, onFinish:Void->Void) {

View file

@ -202,6 +202,7 @@ class ReplayInitialState {
var trapdoorLastCompletions:Array<Float> = [];
var landMineDisappearTimes:Array<Float> = [];
var pushButtonContactTimes:Array<Float> = [];
var randomGens:Array<Int> = [];
public function new() {}
@ -224,6 +225,10 @@ class ReplayInitialState {
for (time in this.pushButtonContactTimes) {
bw.writeFloat(time);
}
bw.writeInt16(this.randomGens.length);
for (ri in this.randomGens) {
bw.writeByte(ri);
}
}
public function read(br:BytesReader) {
@ -245,6 +250,10 @@ class ReplayInitialState {
for (i in 0...pushButtonCount) {
this.pushButtonContactTimes.push(br.readFloat());
}
var rcount = br.readInt16();
for (i in 0...rcount) {
this.randomGens.push(br.readByte());
}
}
}
@ -341,6 +350,14 @@ class Replay {
initialState.pushButtonContactTimes.push(lastContactTime);
}
public function recordRandomGenState(ri:Int) {
initialState.randomGens.push(ri);
}
public function getRandomGenState() {
return initialState.randomGens.shift();
}
public function getTrapdoorState(idx:Int) {
return {
lastContactTime: initialState.trapdoorLastContactTimes[idx],
@ -359,6 +376,7 @@ class Replay {
public function clear() {
this.frames = [];
this.initialState.randomGens = [];
currentRecordFrame = null;
}

View file

@ -8,29 +8,10 @@ import src.Util;
import h3d.Vector;
import src.DtsObject;
class PowerupParams {
public var duration:Float = 5;
public var airAccel = 1.0;
public var activateTime:Float = 0;
public var bounce = -1.0;
public var sizeScale = 1.0;
public var massScale = 1.0;
public var gravityMod = 1.0;
public var repulseDist = 0.0;
public var repulseMax = 0.0;
public var boostDir = new Vector();
public var timeFreeze:Float = 0;
public var boostAmount = 0.0;
public var boostMassless = 0.0;
public function new() {};
}
abstract class PowerUp extends DtsObject {
public var lastPickUpTime:Float = -1;
public var cooldownDuration:Float = 7;
public var autoUse:Bool = false;
public var powerupParams:PowerupParams = new PowerupParams();
public var pickUpName:String;
public var element:MissionElementItem;
public var pickupSound:Sound;

View file

@ -0,0 +1,89 @@
package shapes;
import src.ResourceLoaderWorker;
import src.ResourceLoader;
import mis.MissionElement.MissionElementItem;
import src.TimeState;
import mis.MisParser;
import src.MarbleWorld;
class RandomPowerup extends PowerUp {
var wasTimeTravel:Bool;
public function new(element:MissionElementItem) {
super(element);
this.dtsPath = "data/shapes/items/random.dts";
this.isCollideable = false;
this.isTSStatic = false;
this.identifier = "RandomPowerup";
this.useInstancing = true;
this.autoUse = true;
this.wasTimeTravel = false;
}
public override function init(level:MarbleWorld, onFinish:Void->Void) {
super.init(level, () -> {
var sounds = [
"sound/pugyrocoptervoice.wav",
"sound/pushockabsorbervoice.wav",
"sound/pusuperbouncevoice.wav",
"sound/pusuperjumpvoice.wav",
"sound/pusuperspeedvoice.wav",
"sound/dosuperspeed.wav",
"sound/dosuperjump.wav",
"sound/putimetravelvoice.wav",
"sound/timetravelactive.wav"
];
var rlw = new ResourceLoaderWorker(onFinish);
for (sound in sounds) {
rlw.loadFile(sound);
}
rlw.run();
});
}
public function pickUp():Bool {
while (true) {
var r = Std.random(6);
if (this.level.isWatching)
r = this.level.replay.getRandomGenState();
var pow:PowerUp = null;
switch (r) {
case 0:
pow = new TimeTravel(this.element);
this.pickupSound = ResourceLoader.getResource("data/sound/putimetravelvoice.wav", ResourceLoader.getAudio, this.soundResources);
wasTimeTravel = true;
case 1:
pow = new SuperJump(this.element);
this.pickupSound = ResourceLoader.getResource("data/sound/pusuperjumpvoice.wav", ResourceLoader.getAudio, this.soundResources);
case 2:
pow = new SuperSpeed(this.element);
this.pickupSound = ResourceLoader.getResource("data/sound/pusuperspeedvoice.wav", ResourceLoader.getAudio, this.soundResources);
case 3:
pow = new ShockAbsorber(this.element);
this.pickupSound = ResourceLoader.getResource("data/sound/pushockabsorbervoice.wav", ResourceLoader.getAudio, this.soundResources);
case 4:
pow = new SuperBounce(this.element);
this.pickupSound = ResourceLoader.getResource("data/sound/pusuperbouncevoice.wav", ResourceLoader.getAudio, this.soundResources);
case 5:
pow = new Helicopter(this.element);
this.pickupSound = ResourceLoader.getResource("data/sound/pugyrocoptervoice.wav", ResourceLoader.getAudio, this.soundResources);
}
pow.level = this.level;
if (pow.pickUp()) {
this.cooldownDuration = pow.cooldownDuration;
this.pickUpName = pow.pickUpName;
if (this.level.isRecording)
this.level.replay.recordRandomGenState(r);
return true;
}
}
return true;
}
public function use(time:TimeState) {
if (this.wasTimeTravel)
this.level.addBonusTime(5);
}
}