2048 lines
90 KiB
JavaScript
2048 lines
90 KiB
JavaScript
export default class ShipManager {
|
|||
|
|
constructor(_scene, _level, _id, _isPlayer = true, _isAI = false, _modelFile = null) {
|
||
|
|
this.scene = _scene;
|
||
|
|
this.level = _level;
|
||
|
|
this.id = _id;
|
||
|
|
this.isPlayer = _isPlayer;
|
||
|
|
this.isAI = _isAI;
|
||
|
|
this.modelFile = _modelFile;
|
||
|
|
this.name = "Player";
|
||
|
|
this.character = null;
|
||
|
|
//
|
||
|
|
this.splineId = 0;
|
||
|
|
this.cameraSplineId = 0;
|
||
|
|
this.targetSplineId = 0;
|
||
|
|
this.referenceSplineId = 0;
|
||
|
|
this.bonusSplineId = 0;
|
||
|
|
this.temp = 0;
|
||
|
|
this.autopilot = false;
|
||
|
|
this.curveAmt = 0;
|
||
|
|
this.speedFactor = 0;
|
||
|
|
this.distToPerfectPitch = 0;
|
||
|
|
this.overSpeed = false;
|
||
|
|
this.scraping = false;
|
||
|
|
this.scrapingTime = 0;
|
||
|
|
this.overTemp = false;
|
||
|
|
this.position = -1;
|
||
|
|
this.raceProgress = 0; // = lap * trackleng + spline ID for position calculation
|
||
|
|
this.ignoreFinish = true;//ignore first finish line crossing and maybe also after the race when autppilot just drives you around
|
||
|
|
this.crossedFinish = true;
|
||
|
|
this.progressFinish = false;//add an offset to raceProgress when on the Start Finish Straight but not crossed the line yet
|
||
|
|
this.ignoreProgress = true;
|
||
|
|
//flightvars
|
||
|
|
this.flightRadius = 112;
|
||
|
|
this.flightRadiusLowerLimit = 32;//-112 + 32;
|
||
|
|
this.flightRadiusUpperLimit = 112;
|
||
|
|
this.speed = 0;
|
||
|
|
this.speedNormalized = 0;
|
||
|
|
this.speedMax = 16;
|
||
|
|
this.speedBonus = 0;
|
||
|
|
this.nearmissBoost = 1.5;
|
||
|
|
this.nearmissBoostCooldown = 0;
|
||
|
|
|
||
|
|
this.slipstreaming = false;
|
||
|
|
this.slipstreamBoost = 1.1;
|
||
|
|
this.slipstreamTarget = null;
|
||
|
|
this.slipstreamLasting = 0;
|
||
|
|
this.slipsteamTime = 0;
|
||
|
|
|
||
|
|
this.jumping = false;
|
||
|
|
this.jumpingLasting = 0;
|
||
|
|
|
||
|
|
this.crashPoints = 0;
|
||
|
|
|
||
|
|
this.wobble = {
|
||
|
|
pos: {
|
||
|
|
x: 0,
|
||
|
|
y: 0,
|
||
|
|
z: 0,
|
||
|
|
},
|
||
|
|
dir: {
|
||
|
|
yaw: 0,
|
||
|
|
pitch: 0,
|
||
|
|
roll: 0
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
this.acceleration = 0.1;
|
||
|
|
this.deceleration = -0.05;
|
||
|
|
this.brakes = -0.2;
|
||
|
|
this.rollSpeed = 0;
|
||
|
|
this.rollSpeedMax = 1;
|
||
|
|
this.rollSpeedMin = -1;
|
||
|
|
this.rollAcceleration = 0.05;
|
||
|
|
this.rollDeceleration = 0.2;
|
||
|
|
this.angleToTrack = 0;
|
||
|
|
this.angleToTrackMod = 1;
|
||
|
|
this.targetModel = null;
|
||
|
|
this.pitch = {
|
||
|
|
current: 0,
|
||
|
|
target: 0,
|
||
|
|
delta: 0,
|
||
|
|
acceleration: 0.1,
|
||
|
|
deceleration: 0.05,
|
||
|
|
min: -1,
|
||
|
|
max: 1
|
||
|
|
}
|
||
|
|
this.last = {
|
||
|
|
speedBonus: 0,
|
||
|
|
curveAmt: 0,
|
||
|
|
input: {
|
||
|
|
spd: 0,
|
||
|
|
roll: 0,
|
||
|
|
pitch: 0
|
||
|
|
},
|
||
|
|
keyInput: {
|
||
|
|
spd: 0,
|
||
|
|
roll: 0,
|
||
|
|
pitch: 0
|
||
|
|
},
|
||
|
|
fastestLap: 0
|
||
|
|
}
|
||
|
|
this.ai = {
|
||
|
|
prefRoll: 1,
|
||
|
|
flippedRoll: 0,
|
||
|
|
lastRollGood: false,
|
||
|
|
lastGoodPrefRoll: 1,
|
||
|
|
waitRoll: 0,
|
||
|
|
curveRec: -9999,
|
||
|
|
curveSample: 0,
|
||
|
|
navStates: {
|
||
|
|
seek: 0,
|
||
|
|
wait: 1,
|
||
|
|
dodge: 2,
|
||
|
|
follow: 3,
|
||
|
|
cooling: 4
|
||
|
|
},
|
||
|
|
navState: 0,
|
||
|
|
aggression: 0,
|
||
|
|
|
||
|
|
}
|
||
|
|
//camera
|
||
|
|
this.cameras = {
|
||
|
|
thirdPersonFollow: 0,
|
||
|
|
firstPersonCockpit: 1,
|
||
|
|
firstPersonBumper: 2,
|
||
|
|
thirdPersonOrbit: 3
|
||
|
|
}
|
||
|
|
this.camera = this.cameras.firstPersonCockpit;
|
||
|
|
this.cameraFovs = [2.5, 3, 3.5, 4.5, 5];
|
||
|
|
this.cameraFovEscalation = 0;
|
||
|
|
this.cameraSplineId = 0;
|
||
|
|
//input
|
||
|
|
this.input = {
|
||
|
|
spd: 0,
|
||
|
|
roll: 0,
|
||
|
|
rollSpd: 0.1,
|
||
|
|
pitch: 0,
|
||
|
|
previous: {
|
||
|
|
spd: 0,
|
||
|
|
roll: 0,
|
||
|
|
pitch: 0
|
||
|
|
}
|
||
|
|
}
|
||
|
|
this.keyInput = {
|
||
|
|
spd: 0,
|
||
|
|
roll: 0,
|
||
|
|
rollSpd: 0.1,
|
||
|
|
pitch: 0,
|
||
|
|
previous: {
|
||
|
|
spd: 0,
|
||
|
|
roll: 0,
|
||
|
|
pitch: 0
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
this.gondula = this.scene.geometryController.loadModel("hoverShip gondula " + String(this.id), "modDebugTile", { x: 0, y: 0, z: 0 }); //modDebugArrow
|
||
|
|
//this.gondula.flags.draw = true;
|
||
|
|
|
||
|
|
this.shipAnchor = this.scene.geometryController.loadModel("hoverShip anchor " + String(this.id), "modDebugTile", { x: 0, y: 96, z: 0 }); //modDebugArrow
|
||
|
|
//this.shipAnchor.flags.draw = true;
|
||
|
|
|
||
|
|
let models = ["modHoverCarWipeOutStyle", "modHoverCarF1", "modHoverCarTinnemann00", "modHoverCarHapton00"];
|
||
|
|
if (this.modelFile !== null) {
|
||
|
|
models = [this.modelFile]
|
||
|
|
}
|
||
|
|
this.ship = this.scene.geometryController.loadModel("hoverShip model " + String(this.id), models[Math.floor(Math.random() * models.length)], { x: 0, y: 96, z: 0 });//modHoverCarF1 modHoverCarWipeOutStyle
|
||
|
|
this.ship.flags.draw = true;
|
||
|
|
this.ship.depthMod = 48;
|
||
|
|
this.addCollisionBox();
|
||
|
|
|
||
|
|
this.shipAnchor.jumpToPosition({
|
||
|
|
x: (this.gondula.pos.x + (this.gondula.transform.up.x * -this.flightRadius)),
|
||
|
|
y: (this.gondula.pos.y + (this.gondula.transform.up.y * -this.flightRadius)),
|
||
|
|
z: (this.gondula.pos.z + (this.gondula.transform.up.z * -this.flightRadius))
|
||
|
|
});
|
||
|
|
|
||
|
|
//thrusters
|
||
|
|
this.thrusters = [];
|
||
|
|
for (let q of this.ship.quadData) {
|
||
|
|
if (q.frame === "texGlowSquareWhite00") {
|
||
|
|
this.thrusters.push(q);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//lensflare
|
||
|
|
this.lensflares = [];
|
||
|
|
this.lensflares.push(this.scene.geometryController.loadModel("hovership lensflare " + String(this.id), "modLensflare", { x: 0, y: 0, z: 0 }));
|
||
|
|
this.lensflares[this.lensflares.length - 1].flags.draw = true;
|
||
|
|
this.lensflares[this.lensflares.length - 1].setDrawMode(DRAWMODE.BILLBOARD3D);
|
||
|
|
this.lensflares[this.lensflares.length - 1].depthMod = 64;
|
||
|
|
this.lensflares[this.lensflares.length - 1].quadData[0].alpha = 0.2;
|
||
|
|
|
||
|
|
//trails
|
||
|
|
this.trails = [];
|
||
|
|
this.swooshOrigins = [];
|
||
|
|
this.shipSwooshOrigins = [];
|
||
|
|
this.trailLength = 10;
|
||
|
|
for (let q of this.ship.quadData) {
|
||
|
|
if (q.frame === "sprDebugTexture") {
|
||
|
|
this.shipSwooshOrigins.push(q);
|
||
|
|
this.swooshOrigins.push(this.scene.geometryController.loadModel("trail " + String(this.id) + " " + this.swooshOrigins.length, "modDebugTile", { x: 0, y: 0, z: 0 }));
|
||
|
|
this.swooshOrigins[this.swooshOrigins.length - 1].flags.draw = true;
|
||
|
|
this.swooshOrigins[this.swooshOrigins.length - 1].depthMod = 128;//todo: this causes issues
|
||
|
|
this.trails.push([this.swooshOrigins[this.swooshOrigins.length - 1].quadData[0]]);
|
||
|
|
|
||
|
|
this.trails[this.trails.length - 1][0].setTexture("atlasAll", "flatPal00White");
|
||
|
|
this.trails[this.trails.length - 1][0].alpha = 0.8;
|
||
|
|
//hide debug trail position on ship
|
||
|
|
this.shipSwooshOrigins[this.shipSwooshOrigins.length - 1].alpha = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for (let j = 0; j < this.swooshOrigins.length; j++) {//<- number of swoosh Origins on ship (eg both wing tips)
|
||
|
|
let q = this.trails[j][0];
|
||
|
|
for (let i = 0; i < this.trailLength; i++) {
|
||
|
|
this.swooshOrigins[j].addQuadFromData({
|
||
|
|
type: q.type,
|
||
|
|
texture: q.texture,
|
||
|
|
frame: q.frame,
|
||
|
|
position: {
|
||
|
|
x: q.pos.x - this.swooshOrigins[j].pos.x,
|
||
|
|
y: q.pos.y - this.swooshOrigins[j].pos.y,
|
||
|
|
z: q.pos.z - this.swooshOrigins[j].pos.z,
|
||
|
|
},
|
||
|
|
points: [
|
||
|
|
{
|
||
|
|
x: q.points[0].x,
|
||
|
|
y: q.points[0].y,
|
||
|
|
z: q.points[0].z,
|
||
|
|
}, {
|
||
|
|
x: q.points[1].x,
|
||
|
|
y: q.points[1].y,
|
||
|
|
z: q.points[1].z,
|
||
|
|
}, {
|
||
|
|
x: q.points[2].x,
|
||
|
|
y: q.points[2].y,
|
||
|
|
z: q.points[2].z,
|
||
|
|
}, {
|
||
|
|
x: q.points[3].x,
|
||
|
|
y: q.points[3].y,
|
||
|
|
z: q.points[3].z,
|
||
|
|
}
|
||
|
|
]
|
||
|
|
});
|
||
|
|
this.trails[j].push(this.swooshOrigins[j].quadData[this.swooshOrigins[j].quadData.length - 1]);
|
||
|
|
this.swooshOrigins[j].quadData[this.swooshOrigins[j].quadData.length - 1].alpha = 1 - (i / (this.trailLength + 1));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//init trail history
|
||
|
|
this.shipTrailHistory = [];
|
||
|
|
for (let [j, t] of this.trails.entries()) {
|
||
|
|
this.shipTrailHistory.push([]);
|
||
|
|
for (let q of t) {
|
||
|
|
this.shipTrailHistory[j].push(this.ship.getWorldPositionOfQuad(this.shipSwooshOrigins[j]));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
this.trailTicker = 0;
|
||
|
|
|
||
|
|
|
||
|
|
//times
|
||
|
|
this.startTime = Date.now();
|
||
|
|
this.elapsedTime = Date.now() - this.startTime;
|
||
|
|
this.lapTimes = [];
|
||
|
|
this.fastestLap = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
setShipColor(_color) {
|
||
|
|
for (let q of this.ship.quadData) {
|
||
|
|
if (q.texture === "atlasPlating") {
|
||
|
|
let frame = q.frame;
|
||
|
|
// t e x P l a t i n g R e d 0 0
|
||
|
|
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||
|
|
let prStr = frame.substr(0, 10);
|
||
|
|
let nuStr = frame.substr(13, 2);
|
||
|
|
q.setTexture(q.texture, prStr + _color + nuStr);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
setShipModel(_file, _color = "Red") {
|
||
|
|
this.scene.geometryController.destroyModelById(this.ship.id);
|
||
|
|
this.ship = this.scene.geometryController.loadModel("hoverShip model " + String(this.id), _file, { x: 0, y: 96, z: 0 });
|
||
|
|
this.ship.flags.draw = true;
|
||
|
|
this.ship.depthMod = 48;
|
||
|
|
this.addCollisionBox();
|
||
|
|
|
||
|
|
this.setShipColor(_color);
|
||
|
|
}
|
||
|
|
|
||
|
|
destroy() {
|
||
|
|
this.scene.geometryController.destroyModelById(this.ship.id);
|
||
|
|
}
|
||
|
|
|
||
|
|
addCollisionBox(_type = 0) {
|
||
|
|
switch (_type) {
|
||
|
|
case 0:
|
||
|
|
this.ship.addQuadFromData({
|
||
|
|
type: "collisionQuad",
|
||
|
|
position: {
|
||
|
|
x: 0, y: 0, z: 0
|
||
|
|
}, points: [{
|
||
|
|
x: -24, y: 0 + 0, z: -64
|
||
|
|
}, {
|
||
|
|
x: 24, y: 0 + 0, z: -64
|
||
|
|
}, {
|
||
|
|
x: 24, y: -32 - 0, z: -64
|
||
|
|
}, {
|
||
|
|
x: -24, y: -32 - 0, z: -64
|
||
|
|
}]
|
||
|
|
})
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
update() {
|
||
|
|
this.elapsedTime = Date.now() - this.startTime;
|
||
|
|
|
||
|
|
//normalize transform
|
||
|
|
/*
|
||
|
|
this.gondula.transform.forward = gl_vec3.normalize(this.gondula.transform.forward, this.gondula.transform.forward);
|
||
|
|
this.gondula.transform.right = gl_vec3.normalize(this.gondula.transform.right, this.gondula.transform.right);
|
||
|
|
this.gondula.transform.up = gl_vec3.normalize(this.gondula.transform.up, this.gondula.transform.up);
|
||
|
|
|
||
|
|
this.shipAnchor.transform.forward = gl_vec3.normalize(this.shipAnchor.transform.forward, this.shipAnchor.transform.forward);
|
||
|
|
this.shipAnchor.transform.right = gl_vec3.normalize(this.shipAnchor.transform.right, this.shipAnchor.transform.right);
|
||
|
|
this.shipAnchor.transform.up = gl_vec3.normalize(this.shipAnchor.transform.up, this.shipAnchor.transform.up);
|
||
|
|
|
||
|
|
this.ship.transform.forward = gl_vec3.normalize(this.ship.transform.forward, this.ship.transform.forward);
|
||
|
|
this.ship.transform.right = gl_vec3.normalize(this.ship.transform.right, this.ship.transform.right);
|
||
|
|
this.ship.transform.up = gl_vec3.normalize(this.ship.transform.up, this.ship.transform.up);
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
for(let [i, t] of this.trails.entries()){
|
||
|
|
this.shipTrailHistory.push([]);
|
||
|
|
for(let q of t){
|
||
|
|
this.shipTrailHistory[i].push(this.ship.getWorldPositionOfQuad(q));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
//TODO breaks bc spline id 0-44 is not next lap yyet
|
||
|
|
this.raceProgress = (this.lapTimes.length * this.level.trackBuilder.spline.length) + this.splineId;
|
||
|
|
if (this.progressFinish === true) {
|
||
|
|
this.raceProgress += this.level.trackBuilder.spline.length;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
updateFromHangar() {
|
||
|
|
//if(this.gondula.pos.y > 0){
|
||
|
|
//also change in lvlHangar if speed upwards changes
|
||
|
|
//this.gondula.jumpToPosition({x: this.gondula.pos.x, y: this.gondula.pos.y - (0.5 * this.scene.dt), z: this.gondula.pos.z}, true);
|
||
|
|
|
||
|
|
//this is also in racing
|
||
|
|
this.cameraSplineId = this.splineId - 5;
|
||
|
|
if (this.cameraSplineId < 0) {
|
||
|
|
this.cameraSplineId += this.level.trackBuilder.spline.length;
|
||
|
|
}
|
||
|
|
this.targetSplineId = this.splineId + 1;//INFO looking further down with higher speed?
|
||
|
|
while (this.targetSplineId >= this.level.trackBuilder.spline.length) {
|
||
|
|
this.targetSplineId -= this.level.trackBuilder.spline.length;
|
||
|
|
}
|
||
|
|
let splineRef = this.level.trackBuilder.spline[this.targetSplineId];
|
||
|
|
//until here in racing
|
||
|
|
|
||
|
|
//move gonudla and ship
|
||
|
|
//todo: why do the enemies fly further? is this not fuzzy enough?
|
||
|
|
let d = eud.distance([this.gondula.pos.x, this.gondula.pos.y, this.gondula.pos.z], [this.level.trackBuilder.spline[this.splineId].x, this.level.trackBuilder.spline[this.splineId].y, this.level.trackBuilder.spline[this.splineId].z]);
|
||
|
|
//if(this.isPlayer === true){
|
||
|
|
//console.log(d)
|
||
|
|
//}
|
||
|
|
if (d >= this.scene.dt) {
|
||
|
|
let spd = 0.5 * this.scene.dt;
|
||
|
|
this.gondula.jumpToPosition({ x: this.gondula.pos.x + (this.gondula.transform.up.x * spd), y: this.gondula.pos.y + (this.gondula.transform.up.y * spd), z: this.gondula.pos.z + (this.gondula.transform.up.z * spd) }, true);
|
||
|
|
this.shipAnchor.jumpToPosition({ x: this.gondula.pos.x + (this.gondula.transform.up.x * -96), y: this.gondula.pos.y + (this.gondula.transform.up.y * -96), z: this.gondula.pos.z + (this.gondula.transform.up.z * -96) }, true);
|
||
|
|
this.ship.jumpToPosition({ x: this.gondula.pos.x + (this.gondula.transform.up.x * -96), y: this.gondula.pos.y + (this.gondula.transform.up.y * -96), z: this.gondula.pos.z + (this.gondula.transform.up.z * -96) }, true);
|
||
|
|
}
|
||
|
|
|
||
|
|
//this is also in racing
|
||
|
|
let posFactor = 0.25 * this.scene.dt;// 0.5 //Math.max(0.01, ((this.speed + this.speedBonus) / (this.speedMax + this.speedBonus))) * 0.5;//todo: at max speed it still jitters
|
||
|
|
let rotFactor = 0.05 * this.scene.dt;
|
||
|
|
//rotate ship Anchor to Gondula
|
||
|
|
let targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.shipAnchor.transform.toVectorArray(this.shipAnchor.transform.forward),
|
||
|
|
this.shipAnchor.transform.toVectorArray(splineRef.transform.forward)
|
||
|
|
)
|
||
|
|
let rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.shipAnchor.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.shipAnchor.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.shipAnchor.transform.toVectorArray(this.shipAnchor.transform.right),
|
||
|
|
this.shipAnchor.transform.toVectorArray(this.gondula.transform.right)
|
||
|
|
)
|
||
|
|
rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.shipAnchor.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.shipAnchor.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
//move and rotate ship model to actual ship anchor point
|
||
|
|
this.ship.jumpToPosition({ x: this.shipAnchor.pos.x, y: this.shipAnchor.pos.y, z: this.shipAnchor.pos.z });
|
||
|
|
//rotate ship to Gondula
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.ship.transform.toVectorArray(this.ship.transform.forward),
|
||
|
|
this.ship.transform.toVectorArray(splineRef.transform.forward)
|
||
|
|
)
|
||
|
|
rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.ship.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.ship.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.ship.transform.toVectorArray(this.ship.transform.right),
|
||
|
|
this.ship.transform.toVectorArray(this.gondula.transform.right)
|
||
|
|
)
|
||
|
|
rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.ship.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.ship.rotateByQuaternion(rot);
|
||
|
|
//until here
|
||
|
|
//}
|
||
|
|
}
|
||
|
|
|
||
|
|
updateRacing() {
|
||
|
|
|
||
|
|
let invertedSpeedFactor = 1 - this.speedFactor;//(this.speed / (this.speedMax + this.speedBonus));
|
||
|
|
|
||
|
|
this.cameraSplineId = this.splineId - 5;
|
||
|
|
if (this.cameraSplineId < 0) {
|
||
|
|
this.cameraSplineId += this.level.trackBuilder.spline.length;
|
||
|
|
}
|
||
|
|
this.targetSplineId = this.splineId + 1;//INFO looking further down with higher speed?
|
||
|
|
while (this.targetSplineId >= this.level.trackBuilder.spline.length) {
|
||
|
|
this.targetSplineId -= this.level.trackBuilder.spline.length;
|
||
|
|
}
|
||
|
|
let splineRef = this.level.trackBuilder.spline[this.targetSplineId];
|
||
|
|
|
||
|
|
this.bonusSplineId = this.splineId + 5;
|
||
|
|
while (this.bonusSplineId >= this.level.trackBuilder.spline.length) {
|
||
|
|
this.bonusSplineId -= this.level.trackBuilder.spline.length;
|
||
|
|
}
|
||
|
|
|
||
|
|
let bonusRef = this.level.trackBuilder.spline[this.bonusSplineId];
|
||
|
|
|
||
|
|
this.input.spd = 0;
|
||
|
|
this.input.roll = 0;
|
||
|
|
this.input.pitch = 0;
|
||
|
|
if (this.level.state === this.level.states.race) {
|
||
|
|
if (this.autopilot === false) {
|
||
|
|
this.inputPlayer();
|
||
|
|
} else {
|
||
|
|
this.inputAI(bonusRef);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (this.slipstreamLasting <= 0) {
|
||
|
|
this.slipstreaming = false;
|
||
|
|
} else {
|
||
|
|
this.slipstreamLasting -= this.scene.dt;
|
||
|
|
this.slipsteamTime += this.scene.dt;
|
||
|
|
}
|
||
|
|
this.slipstreamTarget = null;
|
||
|
|
|
||
|
|
if (this.jumpingLasting <= 0) {
|
||
|
|
this.jumping = false;
|
||
|
|
} else {
|
||
|
|
this.jumpingLasting -= this.scene.dt;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (this.nearmissBoostCooldown >= 0) {
|
||
|
|
this.nearmissBoostCooldown -= this.scene.dt;
|
||
|
|
if (this.nearmissBoostCooldown <= 0) {
|
||
|
|
//console.log("COOLDOWNED")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
this.last.speedBonus = this.speedBonus;
|
||
|
|
this.last.input.roll = this.input.roll;
|
||
|
|
this.last.curveAmt = this.curveAmt;
|
||
|
|
|
||
|
|
//check Collisions
|
||
|
|
let collCheckArr = [
|
||
|
|
{//check forward of ship
|
||
|
|
pos: {
|
||
|
|
x: this.ship.pos.x,
|
||
|
|
y: this.ship.pos.y,
|
||
|
|
z: this.ship.pos.z
|
||
|
|
},
|
||
|
|
dir: {
|
||
|
|
x: this.shipAnchor.transform.forward.x,
|
||
|
|
y: this.shipAnchor.transform.forward.y,
|
||
|
|
z: this.shipAnchor.transform.forward.z
|
||
|
|
},
|
||
|
|
hit: []
|
||
|
|
}, {//check forward right of ship for booster
|
||
|
|
pos: {
|
||
|
|
x: this.ship.pos.x + (this.shipAnchor.transform.right.x * 48),
|
||
|
|
y: this.ship.pos.y + (this.shipAnchor.transform.right.y * 48),
|
||
|
|
z: this.ship.pos.z + (this.shipAnchor.transform.right.z * 48)
|
||
|
|
},
|
||
|
|
dir: {
|
||
|
|
x: this.shipAnchor.transform.forward.x,
|
||
|
|
y: this.shipAnchor.transform.forward.y,
|
||
|
|
z: this.shipAnchor.transform.forward.z
|
||
|
|
},
|
||
|
|
hit: []
|
||
|
|
}, {//check forward left of ship for booster
|
||
|
|
pos: {
|
||
|
|
x: this.ship.pos.x + (this.shipAnchor.transform.right.x * -48),
|
||
|
|
y: this.ship.pos.y + (this.shipAnchor.transform.right.y * -48),
|
||
|
|
z: this.ship.pos.z + (this.shipAnchor.transform.right.z * -48)
|
||
|
|
},
|
||
|
|
dir: {
|
||
|
|
x: this.shipAnchor.transform.forward.x,
|
||
|
|
y: this.shipAnchor.transform.forward.y,
|
||
|
|
z: this.shipAnchor.transform.forward.z
|
||
|
|
},
|
||
|
|
hit: []
|
||
|
|
}, {//check slipstream with curve amt
|
||
|
|
pos: {
|
||
|
|
x: this.ship.pos.x,
|
||
|
|
y: this.ship.pos.y,
|
||
|
|
z: this.ship.pos.z
|
||
|
|
},
|
||
|
|
dir: {
|
||
|
|
x: this.shipAnchor.transform.forward.x + (this.shipAnchor.transform.up.x * this.curveAmt),
|
||
|
|
y: this.shipAnchor.transform.forward.y + (this.shipAnchor.transform.up.y * this.curveAmt),
|
||
|
|
z: this.shipAnchor.transform.forward.z + (this.shipAnchor.transform.up.z * this.curveAmt)
|
||
|
|
},
|
||
|
|
hit: []
|
||
|
|
}
|
||
|
|
];
|
||
|
|
//push stuff to collide with
|
||
|
|
let toCollideWith = [];
|
||
|
|
for (let o of this.level.trackBuilder.obstacles) {
|
||
|
|
if (o.data.id + 1 > this.splineId) {
|
||
|
|
toCollideWith.push(o);
|
||
|
|
}
|
||
|
|
//if (o.flags.update === true){
|
||
|
|
//o.update();
|
||
|
|
//}
|
||
|
|
}
|
||
|
|
for (let s of this.level.aiShips) {
|
||
|
|
if (s.id !== this.id) {
|
||
|
|
if (s.splineId > this.splineId) {
|
||
|
|
toCollideWith.push(s.ship);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (this.isPlayer === false) {
|
||
|
|
if (this.level.playerShip.splineId > this.splineId) {
|
||
|
|
toCollideWith.push(this.level.playerShip.ship);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for (let m of toCollideWith) {
|
||
|
|
//if (m.flags.update === true){
|
||
|
|
// m.update();
|
||
|
|
//}
|
||
|
|
for (let q of m.collisionData) {
|
||
|
|
for (let c of collCheckArr) {
|
||
|
|
let hitData = this.scene.geometryController.collide(q, c);
|
||
|
|
if (hitData.pt !== null) {
|
||
|
|
hitData.model = m;
|
||
|
|
c.hit.push(hitData);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
let alreadyColliding = false;
|
||
|
|
let distSpeed = this.speed * 2;
|
||
|
|
/*if (this.isPlayer === true) {
|
||
|
|
console.log(distSpeed)
|
||
|
|
}*/
|
||
|
|
//let avoids = [0, 0, 0];
|
||
|
|
let returnColl = collCheckArr;
|
||
|
|
//resolve collision with forward
|
||
|
|
if (returnColl[0].hit.length > 0) {
|
||
|
|
//filter relevant = nearest hit
|
||
|
|
let dist = 9999;
|
||
|
|
let nearestHit = returnColl[0].hit[0];
|
||
|
|
for (let [i, n] of returnColl[0].hit.entries()) {
|
||
|
|
let d = eud.distance([this.ship.pos.x, this.ship.pos.y, this.ship.pos.z], returnColl[0].hit[i].pt)
|
||
|
|
if (d < dist) {
|
||
|
|
dist = d;
|
||
|
|
nearestHit = returnColl[0].hit[i];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (dist < 2048) {
|
||
|
|
//slipstreaming? //todo: set dist < slipstream wake / distance of that object (maybe additional check within 1024m)
|
||
|
|
if (nearestHit.model.data.slipstreamLength !== undefined) {
|
||
|
|
if (dist < nearestHit.model.data.slipstreamLength) {
|
||
|
|
//console.log(`slipstreaming: ${Math.floor(dist)}`);
|
||
|
|
this.slipstreaming = true;
|
||
|
|
this.slipstreamTarget = nearestHit.model;
|
||
|
|
this.slipstreamLasting = 60 * 3;
|
||
|
|
//TODO let the AI know you are slipstreaming
|
||
|
|
if (this.isPlayer === true) {
|
||
|
|
this.level.situation.actions.slipstream.who = nearestHit.model.data.name;
|
||
|
|
this.level.situation.actions.slipstream.priority += 1;
|
||
|
|
} else {
|
||
|
|
if (this.slipstreamTarget.data.name === "Player") {//"Player" // TODO does not work as of yet
|
||
|
|
this.level.situation.actions.slipstreamed.who = this.ship.data.name;
|
||
|
|
this.level.situation.actions.slipstream.priority += 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (dist < 128 + distSpeed) {
|
||
|
|
alreadyColliding = true;
|
||
|
|
if (nearestHit.model.trigger.isTrigger === false) {
|
||
|
|
//console.log(returnColl[0]);
|
||
|
|
|
||
|
|
if (this.speed > 0 && this.isPlayer) {
|
||
|
|
this.scene.soundManager.playRandomSound(this.scene.soundManager.bumpSound);
|
||
|
|
}
|
||
|
|
|
||
|
|
this.crashPoints += 1;
|
||
|
|
|
||
|
|
this.speed *= 0.75;//= 0;
|
||
|
|
if (this.speed <= 1) {
|
||
|
|
this.speed = 0;
|
||
|
|
}
|
||
|
|
this.input.spd = 0;
|
||
|
|
if (nearestHit.model.data.roll !== undefined && nearestHit.model.data.roll !== 0) {
|
||
|
|
this.input.roll = nearestHit.model.data.roll * 2;
|
||
|
|
}
|
||
|
|
if (this.isPlayer) {
|
||
|
|
//console.log(nearestHit.model.data.name);
|
||
|
|
if (nearestHit.model.data.name !== undefined) {
|
||
|
|
//set ui.racerReaction to hitted pilot
|
||
|
|
this.level.situation.actions.hit.who = nearestHit.model.data.name;
|
||
|
|
this.level.situation.actions.hit.priority += 2;
|
||
|
|
//let character = this.level.aiShips.filter(el => el.name === nearestHit.model.data.name)[0].character;
|
||
|
|
//this.level.ui.addReaction("charSheetExpressions", character.reactions.hit[Math.floor(Math.random() * character.reactions.hit.length)]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
} else {
|
||
|
|
nearestHit.model.trigger.other = this;
|
||
|
|
nearestHit.model.updateTrigger();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//check booster only if collision free in front (0)
|
||
|
|
if (alreadyColliding === false) {
|
||
|
|
//resolve collision with forward right and then left of ship for boost
|
||
|
|
for (let j = 1; j < 3; j++) {
|
||
|
|
if (returnColl[j].hit.length > 0) {
|
||
|
|
//filter relevant = nearest hit
|
||
|
|
let dist = 9999;
|
||
|
|
let nearestHit = returnColl[j].hit[0];
|
||
|
|
for (let [i, n] of returnColl[j].hit.entries()) {
|
||
|
|
let d = eud.distance([returnColl[j].pos.x, returnColl[j].pos.y, returnColl[j].pos.z], returnColl[j].hit[i].pt)
|
||
|
|
if (d < dist) {
|
||
|
|
dist = d;
|
||
|
|
nearestHit = returnColl[j].hit[i];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/*if(dist < 1024){
|
||
|
|
avoids[j] = 1;
|
||
|
|
}*/
|
||
|
|
if (dist < 128) {
|
||
|
|
if (nearestHit.model.trigger.isTrigger === false) {
|
||
|
|
if (this.speed > (this.speedMax * 0.25) && this.input.spd >= 0 && this.nearmissBoostCooldown <= 0) {
|
||
|
|
this.input.spd = 1;
|
||
|
|
this.speed = this.speed * this.nearmissBoost;//this.speedMax * this.nearmissBoost;
|
||
|
|
this.speed = Math.min(this.speed, this.speedMax * this.nearmissBoost);
|
||
|
|
|
||
|
|
this.nearmissBoostCooldown = 60;
|
||
|
|
if (this.isPlayer === true) {
|
||
|
|
if (this.scene.cam.fov < 3.5) {//todo: find a good value for the boost effect
|
||
|
|
this.scene.cam.fov += 1 * this.scene.dt;
|
||
|
|
this.scene.cam.fov = Math.min(this.scene.cam.fov, 3.5);
|
||
|
|
}
|
||
|
|
//sound
|
||
|
|
this.scene.soundManager.playRandomSound(this.scene.soundManager.swooshSound);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
//nearestHit.model.updateTrigger();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//check if slipstreaming with curve calculated
|
||
|
|
//filter relevant = nearest hit
|
||
|
|
let dist = 9999;
|
||
|
|
let nearestHit = returnColl[3].hit[0];
|
||
|
|
for (let [i, n] of returnColl[3].hit.entries()) {
|
||
|
|
let d = eud.distance([this.ship.pos.x, this.ship.pos.y, this.ship.pos.z], returnColl[3].hit[i].pt)
|
||
|
|
if (d < dist) {
|
||
|
|
dist = d;
|
||
|
|
nearestHit = returnColl[3].hit[i];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (dist < 2048) {
|
||
|
|
//slipstreaming? //todo: set dist < slipstream wake / distance of that object (maybe additional check within 1024m)
|
||
|
|
if (nearestHit.model.data.slipstreamLength !== undefined) {
|
||
|
|
if (dist < nearestHit.model.data.slipstreamLength) {
|
||
|
|
//console.log(`slipstreaming: ${Math.floor(dist)}`);
|
||
|
|
this.slipstreaming = true;
|
||
|
|
this.slipstreamTarget = nearestHit.model;
|
||
|
|
this.slipstreamLasting = 60 * 3;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//find pitch to track to set bonus
|
||
|
|
let upVec = [//was gonudla before, but could work well with ship
|
||
|
|
bonusRef.x + (this.ship.transform.forward.x * 10) + (this.ship.transform.up.x * 10),
|
||
|
|
bonusRef.y + (this.ship.transform.forward.y * 10) + (this.ship.transform.up.y * 10),
|
||
|
|
bonusRef.z + (this.ship.transform.forward.z * 10) + (this.ship.transform.up.z * 10)
|
||
|
|
]
|
||
|
|
let doVec = [
|
||
|
|
bonusRef.x + (this.ship.transform.forward.x * 10) + (this.ship.transform.up.x * -10),
|
||
|
|
bonusRef.y + (this.ship.transform.forward.y * 10) + (this.ship.transform.up.y * -10),
|
||
|
|
bonusRef.z + (this.ship.transform.forward.z * 10) + (this.ship.transform.up.z * -10)
|
||
|
|
]
|
||
|
|
let upDist = eud.distance(upVec, [bonusRef.x + (bonusRef.transform.forward.x), bonusRef.y + (bonusRef.transform.forward.y), bonusRef.z + (bonusRef.transform.forward.z)]);
|
||
|
|
let doDist = eud.distance(doVec, [bonusRef.x + (bonusRef.transform.forward.x), bonusRef.y + (bonusRef.transform.forward.y), bonusRef.z + (bonusRef.transform.forward.z)]);
|
||
|
|
let bonusAmt = (doDist - upDist);
|
||
|
|
bonusAmt = Math.max(-1, Math.min(bonusAmt, 1));
|
||
|
|
let flingAmt = (doDist - upDist);
|
||
|
|
flingAmt = Math.max(-1, Math.min(flingAmt, 1));
|
||
|
|
if (this.jumping === true) {
|
||
|
|
flingAmt -= 1 * this.speedFactor;
|
||
|
|
if (this.isPlayer) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//INFO reference : this.ui.pitchLimit.y = 64 - (32 * this.playerShip.curveAmt) - (32 * this.playerShip.pitch.current)
|
||
|
|
//bonusAmt = 64 - (32 * this.playerShip.curveAmt) - (32 * this.playerShip.pitch.current)//<<<<INFO original bonus amt
|
||
|
|
|
||
|
|
//32 is perfect < 0 is crash, > 32 is cooling in theory
|
||
|
|
this.distToPerfectPitch = 64 - (32 * this.curveAmt) - (32 * this.pitch.current) - (this.pitch.current * 32);
|
||
|
|
this.distToPerfectPitch = Math.max(-64, Math.min(this.distToPerfectPitch, 64));
|
||
|
|
//console.log(this.distToPerfectPitch) //todo: this might be stupid ^^^^
|
||
|
|
//this way <0 is heating >0 is cooling ~0 is speed gain zoon?
|
||
|
|
//bonusAmt = ((((this.distToPerfectPitch - 32) / 64) ) * -1);
|
||
|
|
bonusAmt = ((this.distToPerfectPitch / 64) * -1) + 0.5 + this.curveAmt;//INFO bot of these two lines dont quite work as intended - no jumping - too fast, too hot weird
|
||
|
|
|
||
|
|
//scraping?
|
||
|
|
if (this.distToPerfectPitch <= 0) {
|
||
|
|
if (this.speed > 0) {
|
||
|
|
this.scraping = true;
|
||
|
|
this.scrapingTime += this.scene.dt * 0.001;
|
||
|
|
}
|
||
|
|
bonusAmt = Math.max(-8, this.scrapingTime * -1);
|
||
|
|
} else {
|
||
|
|
this.scraping = false;
|
||
|
|
this.scrapingTime = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (this.slipstreaming === true) {
|
||
|
|
bonusAmt += this.slipstreamBoost;
|
||
|
|
}
|
||
|
|
|
||
|
|
//move away from ideal height
|
||
|
|
//this.flightRadius += (bonusAmt * (this.speed * 0.25)) * this.scene.dt;
|
||
|
|
this.flightRadius += (flingAmt * (this.speed * 0.25)) * this.scene.dt;
|
||
|
|
//if(this.temp > 500){
|
||
|
|
// this.flightRadius -= 10;
|
||
|
|
//}
|
||
|
|
let calmer = 1 * this.scene.dt;
|
||
|
|
this.flightRadius = Math.max(this.flightRadiusLowerLimit, Math.min(this.flightRadius + (calmer * Math.max(0.1, this.speedFactor)), this.flightRadiusUpperLimit));
|
||
|
|
if (this.flightRadius >= this.flightRadiusUpperLimit) {
|
||
|
|
this.jumping = false;
|
||
|
|
}
|
||
|
|
this.speedBonus = this.speedMax * bonusAmt;
|
||
|
|
//this.speedBonus += 8;//INFO neutral on a streaight is -8 atm, +8 and making the bonus less aggressive could be helpful in general for a less twitchy feel
|
||
|
|
|
||
|
|
|
||
|
|
//find pitch to track from gondula to set navigation
|
||
|
|
upVec = [
|
||
|
|
bonusRef.x + (this.gondula.transform.forward.x * 1) + (this.gondula.transform.up.x * 1),
|
||
|
|
bonusRef.y + (this.gondula.transform.forward.y * 1) + (this.gondula.transform.up.y * 1),
|
||
|
|
bonusRef.z + (this.gondula.transform.forward.z * 1) + (this.gondula.transform.up.z * 1)
|
||
|
|
]
|
||
|
|
doVec = [
|
||
|
|
bonusRef.x + (this.gondula.transform.forward.x * 1) + (this.gondula.transform.up.x * -1),
|
||
|
|
bonusRef.y + (this.gondula.transform.forward.y * 1) + (this.gondula.transform.up.y * -1),
|
||
|
|
bonusRef.z + (this.gondula.transform.forward.z * 1) + (this.gondula.transform.up.z * -1)
|
||
|
|
]
|
||
|
|
upDist = eud.distance(upVec, [bonusRef.x + (bonusRef.transform.forward.x * 320), bonusRef.y + (bonusRef.transform.forward.y * 320), bonusRef.z + (bonusRef.transform.forward.z * 320)]);
|
||
|
|
doDist = eud.distance(doVec, [bonusRef.x + (bonusRef.transform.forward.x * 320), bonusRef.y + (bonusRef.transform.forward.y * 320), bonusRef.z + (bonusRef.transform.forward.z * 320)]);
|
||
|
|
let curveAmt = (doDist - upDist);
|
||
|
|
//curveAmt = Math.max(-1, Math.min(curveAmt * 0.005, 1));
|
||
|
|
this.curveAmt = curveAmt;
|
||
|
|
|
||
|
|
//apply sppeed and move accordingly
|
||
|
|
if (this.input.spd !== 0) {
|
||
|
|
if (this.speed > this.speedMax + this.speedBonus) {
|
||
|
|
this.input.spd = (this.acceleration * -2);
|
||
|
|
}
|
||
|
|
this.speed += this.input.spd;
|
||
|
|
this.speed = Math.max(0, this.speed);
|
||
|
|
//this.speed = Math.max(0, Math.min(this.speed, this.speedMax + this.speedBonus));
|
||
|
|
|
||
|
|
//console.log(splineRef)
|
||
|
|
//use right axis if you need roll as well, but if using forward, you just follow the track as intended any you can roll on your own later
|
||
|
|
let targetVec = [splineRef.x - this.gondula.pos.x, splineRef.y - this.gondula.pos.y, splineRef.z - this.gondula.pos.z];
|
||
|
|
targetVec = gl_vec3.normalize(targetVec, targetVec);
|
||
|
|
|
||
|
|
let targetRot = [0, 0, 0, 0];
|
||
|
|
//console.log(targetVec)
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.gondula.transform.toVectorArray(this.gondula.transform.forward),
|
||
|
|
//this.gondula.transform.toVectorArray( splineRef.transform.forward)
|
||
|
|
targetVec
|
||
|
|
)
|
||
|
|
let rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.gondula.transform.rotationQuat, targetRot, 0.5);
|
||
|
|
this.gondula.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
//this.gondula.rotateByQuaternion(targetRot);
|
||
|
|
//move gondula forward by spd
|
||
|
|
this.gondula.jumpToPosition({
|
||
|
|
x: this.gondula.pos.x + ((targetVec[0] * this.speed) * this.scene.dt),
|
||
|
|
y: this.gondula.pos.y + ((targetVec[1] * this.speed) * this.scene.dt),
|
||
|
|
z: this.gondula.pos.z + ((targetVec[2] * this.speed) * this.scene.dt)
|
||
|
|
});
|
||
|
|
|
||
|
|
let criticalSpeed = (1 * this.speed) * this.scene.dt;
|
||
|
|
/*if(this.isPlayer === true){
|
||
|
|
if(criticalSpeed >= 64){
|
||
|
|
console.log(criticalSpeed);
|
||
|
|
};
|
||
|
|
}*/
|
||
|
|
|
||
|
|
//check if reached target
|
||
|
|
let d = gl_vec3.distance(this.gondula.transform.toVectorArray(this.gondula.pos), [splineRef.x, splineRef.y, splineRef.z]);
|
||
|
|
//console.log(d)
|
||
|
|
if (d <= 64 /*this.speed * 1*/ /*64*/) {
|
||
|
|
let amt = Math.floor(criticalSpeed / 64) + 1; //jumjp further if speed exceeds the distance between splines
|
||
|
|
this.splineId += amt;
|
||
|
|
if (this.splineId >= this.level.trackBuilder.spline.length) {
|
||
|
|
this.splineId -= this.level.trackBuilder.spline.length;
|
||
|
|
this.crossedFinish = false;
|
||
|
|
}
|
||
|
|
if (this.splineId >= 0 && this.crossedFinish === false) {
|
||
|
|
//add length of track to raceProgress to prevent false positions
|
||
|
|
this.progressFinish = true;
|
||
|
|
}
|
||
|
|
if (this.splineId >= 44 && this.crossedFinish === false) {
|
||
|
|
if (this.ignoreFinish === false) {
|
||
|
|
this.crossedFinish = true;
|
||
|
|
this.progressFinish = false;
|
||
|
|
this.startNewLap();
|
||
|
|
} else {
|
||
|
|
this.ignoreFinish = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//console.log("next point: " + String(this.splineId) + " / " + String(this.level.trackBuilder.spline.length))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//INFO original temp calc
|
||
|
|
if (this.speed > this.speedMax && this.slipstreaming === false) {
|
||
|
|
this.temp += 0.5 * this.scene.dt;
|
||
|
|
if (this.speedBonus < 3) {
|
||
|
|
if (this.scraping === false) {
|
||
|
|
this.temp -= 0.75 * this.scene.dt;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
if (this.scraping === false) {
|
||
|
|
this.temp -= 1.1 * this.scene.dt;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (this.scraping === true) {
|
||
|
|
this.temp += (Math.max(0, Math.min(1, this.speed / this.speedMax)) * 1) * this.scene.dt;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
this.temp = Math.max(0, Math.min(this.temp, 999));
|
||
|
|
if (this.temp >= 999) {
|
||
|
|
this.speedBonus = 0;
|
||
|
|
} else {
|
||
|
|
}
|
||
|
|
|
||
|
|
this.speedNormalized = this.speed / this.speedMax;
|
||
|
|
|
||
|
|
|
||
|
|
//roll the ship
|
||
|
|
if (this.input.roll !== 0) {
|
||
|
|
let kir = Math.abs(this.input.roll);
|
||
|
|
if (this.input.roll > 0) {
|
||
|
|
if (this.rollSpeed < this.rollSpeedMax) {
|
||
|
|
this.rollSpeed += this.rollAcceleration * this.scene.dt;
|
||
|
|
this.rollSpeed = Math.min(this.rollSpeed, this.rollSpeedMax * kir);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (this.input.roll < 0) {
|
||
|
|
if (this.rollSpeed > this.rollSpeedMin) {
|
||
|
|
this.rollSpeed -= this.rollAcceleration * this.scene.dt;
|
||
|
|
this.rollSpeed = Math.max(this.rollSpeed, this.rollSpeedMin * kir);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
if (this.rollSpeed < 0) {
|
||
|
|
this.rollSpeed += this.rollDeceleration * this.scene.dt;
|
||
|
|
this.rollSpeed = Math.min(this.rollSpeed, 0);
|
||
|
|
}
|
||
|
|
if (this.rollSpeed > 0) {
|
||
|
|
this.rollSpeed -= this.rollDeceleration * this.scene.dt;
|
||
|
|
this.rollSpeed = Math.max(this.rollSpeed, 0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (this.scene.numkeys.nine.isDown) {
|
||
|
|
if (this.flightRadius > this.flightRadiusLowerLimit) {
|
||
|
|
this.flightRadius -= 1 * this.scene.dt;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (this.scene.numkeys.three.isDown) {
|
||
|
|
//if(this.flightRadius < this.flightRadiusUpperLimit){
|
||
|
|
this.flightRadius += 1 * this.scene.dt;
|
||
|
|
//}
|
||
|
|
}
|
||
|
|
|
||
|
|
this.speedFactor = Math.max(0, Math.min((this.speed + this.speedBonus) / (this.speedMax + this.speedBonus), 1));
|
||
|
|
if (this.speed > this.speedMax) {
|
||
|
|
this.overSpeed = true;
|
||
|
|
} else {
|
||
|
|
this.overSpeed = false;
|
||
|
|
}
|
||
|
|
//visual rotatons based on input
|
||
|
|
//INFO: ALERT //todo: rotateAroundAxis fucks up the heatzone indicator (distToPerfectPitch) and moving the ship (currently out commented and indented) is the crazy crashout
|
||
|
|
//todo: at least with pitchditch it might be broken maybe more
|
||
|
|
//INFO //todo: clamping pitch.current (and the visual heatzone indicator (pitchLimit) prevents hiccups, but might be a pflaster solution)
|
||
|
|
this.gondula.rotateAroundAxis(this.gondula.transform.toVectorArray(this.gondula.transform.forward), (Math.PI * 0.01) * (this.rollSpeed) * this.scene.dt);
|
||
|
|
//let ship look a bit ahead of corner on input
|
||
|
|
this.shipAnchor.rotateAroundAxis(this.gondula.transform.toVectorArray(this.gondula.transform.up), (Math.PI * 0.01) * (this.rollSpeed) * this.scene.dt);
|
||
|
|
this.ship.rotateAroundAxis(this.ship.transform.toVectorArray(this.ship.transform.forward), ((Math.PI * 0.005 * this.speedFactor)) * (this.rollSpeed) * this.scene.dt);
|
||
|
|
this.pitch.target = Math.max(this.pitch.min, Math.min(this.keyInput.pitch, this.pitch.max));
|
||
|
|
this.pitch.delta = this.pitch.target - this.pitch.current;
|
||
|
|
this.pitch.current += this.pitch.delta * this.scene.dt;
|
||
|
|
this.pitch.current = Math.max(-1, Math.min(this.pitch.current, 1));
|
||
|
|
let pitchditch = this.pitch.current * 0.01;
|
||
|
|
this.ship.rotateAroundAxis(this.ship.transform.toVectorArray(this.ship.transform.right), pitchditch);
|
||
|
|
//roll ship for cool drifting effect
|
||
|
|
this.ship.rotateAroundAxis(this.shipAnchor.transform.toVectorArray(this.shipAnchor.transform.forward), (Math.PI * -0.0075) * (this.rollSpeed) * this.scene.dt);
|
||
|
|
//experimentalthis.ship.rotateAroundAxis(this.shipAnchor.transform.toVectorArray(this.shipAnchor.transform.up), (Math.PI * 0.025) * (this.rollSpeed) * this.scene.dt);
|
||
|
|
|
||
|
|
|
||
|
|
//move Ship to gondula
|
||
|
|
let posFactor = 0.25 * this.scene.dt; // 0.5 //Math.max(0.01, ((this.speed + this.speedBonus) / (this.speedMax + this.speedBonus))) * 0.5;//todo: at max speed it still jitters
|
||
|
|
let rotFactor = 0.05 * this.scene.dt; //0.1 //Math.max(0.01, ((this.speed + this.speedBonus) / (this.speedMax + this.speedBonus)) * 0.1);
|
||
|
|
|
||
|
|
if (this.speed < 0.01) {
|
||
|
|
//posFactor = 0.5;
|
||
|
|
//rotFactor = 0.1;
|
||
|
|
}
|
||
|
|
let deltaPos = {
|
||
|
|
x: ((this.gondula.pos.x + (this.gondula.transform.up.x * -this.flightRadius))) - this.shipAnchor.pos.x,
|
||
|
|
y: ((this.gondula.pos.y + (this.gondula.transform.up.y * -this.flightRadius))) - this.shipAnchor.pos.y,
|
||
|
|
z: ((this.gondula.pos.z + (this.gondula.transform.up.z * -this.flightRadius))) - this.shipAnchor.pos.z
|
||
|
|
}
|
||
|
|
this.shipAnchor.jumpToPosition({
|
||
|
|
x: this.shipAnchor.pos.x + (deltaPos.x * posFactor),
|
||
|
|
y: this.shipAnchor.pos.y + (deltaPos.y * posFactor),
|
||
|
|
z: this.shipAnchor.pos.z + (deltaPos.z * posFactor)
|
||
|
|
});
|
||
|
|
//rotate ship Anchor to Gondula
|
||
|
|
let targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.shipAnchor.transform.toVectorArray(this.shipAnchor.transform.forward),
|
||
|
|
this.shipAnchor.transform.toVectorArray(splineRef.transform.forward)
|
||
|
|
)
|
||
|
|
let rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.shipAnchor.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.shipAnchor.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.shipAnchor.transform.toVectorArray(this.shipAnchor.transform.right),
|
||
|
|
this.shipAnchor.transform.toVectorArray(this.gondula.transform.right)
|
||
|
|
)
|
||
|
|
rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.shipAnchor.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.shipAnchor.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
//move and rotate ship model to actual ship anchor point
|
||
|
|
let jitterPos = { x: 0, y: 0, z: 0 }
|
||
|
|
if (this.scraping === true) {
|
||
|
|
//todo: play scrape audio of player
|
||
|
|
let jitterMod = (this.speed / this.speedMax);
|
||
|
|
//jitterMod *= jitterMod;
|
||
|
|
if (jitterMod < 0) {
|
||
|
|
jitterMod = 0;
|
||
|
|
}
|
||
|
|
if (jitterMod > 1) {
|
||
|
|
jitterMod = 1;
|
||
|
|
}
|
||
|
|
jitterPos = { x: -(1 + (Math.random() * 2)) * jitterMod, y: -(3 + (Math.random() * 6)) * jitterMod, z: (-1 + (Math.random() * 2)) * jitterMod }
|
||
|
|
//(Math.max(0, Math.min(1, this.speed / this.speedMax)) * 1) * this.scene.dt;
|
||
|
|
}
|
||
|
|
this.ship.jumpToPosition({ x: this.shipAnchor.pos.x + jitterPos.x, y: this.shipAnchor.pos.y + jitterPos.y, z: this.shipAnchor.pos.z + jitterPos.z });
|
||
|
|
//rotate ship to Gondula
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.ship.transform.toVectorArray(this.ship.transform.forward),
|
||
|
|
this.ship.transform.toVectorArray(splineRef.transform.forward)
|
||
|
|
)
|
||
|
|
rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.ship.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.ship.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.ship.transform.toVectorArray(this.ship.transform.right),
|
||
|
|
this.ship.transform.toVectorArray(this.gondula.transform.right)
|
||
|
|
)
|
||
|
|
rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.ship.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.ship.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
//show ship trail
|
||
|
|
/*let tipL = {
|
||
|
|
x: this.ship.quadData[this.ship.quadData.length - 1].points[0].x + ((this.gondula.transform.forward.x * (1 + (-56 * (this.speed / this.speedMax)))) + (this.gondula.transform.right.x * 0) + (this.gondula.transform.up.x * -2)),
|
||
|
|
y: this.ship.quadData[this.ship.quadData.length - 1].points[0].y + ((this.gondula.transform.forward.y * (1 + (-56 * (this.speed / this.speedMax)))) + (this.gondula.transform.right.y * 0) + (this.gondula.transform.up.y * -2)),
|
||
|
|
z: this.ship.quadData[this.ship.quadData.length - 1].points[0].z + ((this.gondula.transform.forward.z * (1 + (-56 * (this.speed / this.speedMax)))) + (this.gondula.transform.right.z * 0) + (this.gondula.transform.up.z * -2))
|
||
|
|
}
|
||
|
|
let tipR = {
|
||
|
|
x: this.ship.quadData[this.ship.quadData.length - 1].points[1].x + ((this.gondula.transform.forward.x * (1 + (-56 * (this.speed / this.speedMax)))) + (this.gondula.transform.right.x * 0) + (this.gondula.transform.up.x * -2)),
|
||
|
|
y: this.ship.quadData[this.ship.quadData.length - 1].points[1].y + ((this.gondula.transform.forward.y * (1 + (-56 * (this.speed / this.speedMax)))) + (this.gondula.transform.right.y * 0) + (this.gondula.transform.up.y * -2)),
|
||
|
|
z: this.ship.quadData[this.ship.quadData.length - 1].points[1].z + ((this.gondula.transform.forward.z * (1 + (-56 * (this.speed / this.speedMax)))) + (this.gondula.transform.right.z * 0) + (this.gondula.transform.up.z * -2))
|
||
|
|
}
|
||
|
|
this.ship.quadData[this.ship.quadData.length - 1].points[3] = tipL;
|
||
|
|
this.ship.quadData[this.ship.quadData.length - 1].points[2] = tipR;
|
||
|
|
this.ship.quadData[this.ship.quadData.length - 2].points[3] = tipL;
|
||
|
|
this.ship.quadData[this.ship.quadData.length - 2].points[2] = tipR;*/
|
||
|
|
for (let t of this.thrusters) {
|
||
|
|
//todo: get the saved original position of the vertex to move and add the move vector to keep the shape of the thruster to keep a cone shape
|
||
|
|
t.points[3].x = t.points[0].x + (this.gondula.transform.forward.x * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
t.points[3].y = t.points[0].y + (this.gondula.transform.forward.y * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
t.points[3].z = t.points[0].z + (this.gondula.transform.forward.z * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
|
||
|
|
t.points[2].x = t.points[1].x + (this.gondula.transform.forward.x * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
t.points[2].y = t.points[1].y + (this.gondula.transform.forward.y * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
t.points[2].z = t.points[1].z + (this.gondula.transform.forward.z * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
}
|
||
|
|
|
||
|
|
this.lensflares[this.lensflares.length - 1].jumpToPosition({
|
||
|
|
x: this.ship.pos.x + (this.ship.transform.forward.x * -66) + (this.ship.transform.up.x * 22),
|
||
|
|
y: this.ship.pos.y + (this.ship.transform.forward.y * -66) + (this.ship.transform.up.y * 22),
|
||
|
|
z: this.ship.pos.z + (this.ship.transform.forward.z * -66) + (this.ship.transform.up.z * 22),
|
||
|
|
}, true);
|
||
|
|
this.lensflares[this.lensflares.length - 1].quadData[0].alpha = 1 * this.speedFactor;//0.2
|
||
|
|
|
||
|
|
//todo: save an array of previous tip positions (part of the model) and let quads dynamically stretch over them to form a growing trail
|
||
|
|
/*for(let t of this.trails){
|
||
|
|
for(let i = t.length -1 ; i >= 0 ; i--){
|
||
|
|
let p = t[i];
|
||
|
|
p.points[3] = p.points[0];
|
||
|
|
p.points[2] = p.points[1];
|
||
|
|
}
|
||
|
|
}*/
|
||
|
|
/*//my origin points
|
||
|
|
this.trails[0][0].points[0]
|
||
|
|
this.trails[0][0].points[1]
|
||
|
|
this.trails[1][0].points[0]
|
||
|
|
this.trails[1][0].points[1]
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
this.trailTicker -= this.scene.dt;
|
||
|
|
for (let [j, t] of this.trails.entries()) {
|
||
|
|
if (this.trailTicker <= 0) {
|
||
|
|
for (let i = t.length - 1; i > 0; i--) {
|
||
|
|
this.shipTrailHistory[j][i] = this.shipTrailHistory[j][i - 1]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
this.shipTrailHistory[j][0] = this.ship.getWorldPositionOfQuad(this.shipSwooshOrigins[j]);
|
||
|
|
for (let p of this.shipTrailHistory[j][0]) {
|
||
|
|
p.x += this.ship.pos.x;
|
||
|
|
p.y += this.ship.pos.y;
|
||
|
|
p.z += this.ship.pos.z;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for (let [j, t] of this.trails.entries()) {//each trail
|
||
|
|
//this.swooshOrigins[j].jumpToPosition(this.ship.pos);
|
||
|
|
if (this.trailTicker <= 0) {
|
||
|
|
for (let i = t.length - 1; i > 0; i--) {//each trail quad / saved position
|
||
|
|
let q = t[i];//each quad
|
||
|
|
//jump end of trailpart to timesaved position
|
||
|
|
q.points[3].x = this.shipTrailHistory[j][i][0].x + this.shipTrailHistory[j][i][4].x;
|
||
|
|
q.points[3].y = this.shipTrailHistory[j][i][0].y + this.shipTrailHistory[j][i][4].y;
|
||
|
|
q.points[3].z = this.shipTrailHistory[j][i][0].z + this.shipTrailHistory[j][i][4].z;
|
||
|
|
q.points[2].x = this.shipTrailHistory[j][i][1].x + this.shipTrailHistory[j][i][4].x;
|
||
|
|
q.points[2].y = this.shipTrailHistory[j][i][1].y + this.shipTrailHistory[j][i][4].y;
|
||
|
|
q.points[2].z = this.shipTrailHistory[j][i][1].z + this.shipTrailHistory[j][i][4].z;
|
||
|
|
|
||
|
|
//jump start of trailpart to timesaved previous position
|
||
|
|
q.points[0].x = this.shipTrailHistory[j][i - 1][0].x + this.shipTrailHistory[j][i - 1][4].x;
|
||
|
|
q.points[0].y = this.shipTrailHistory[j][i - 1][0].y + this.shipTrailHistory[j][i - 1][4].y;
|
||
|
|
q.points[0].z = this.shipTrailHistory[j][i - 1][0].z + this.shipTrailHistory[j][i - 1][4].z;
|
||
|
|
q.points[1].x = this.shipTrailHistory[j][i - 1][1].x + this.shipTrailHistory[j][i - 1][4].x;
|
||
|
|
q.points[1].y = this.shipTrailHistory[j][i - 1][1].y + this.shipTrailHistory[j][i - 1][4].y;
|
||
|
|
q.points[1].z = this.shipTrailHistory[j][i - 1][1].z + this.shipTrailHistory[j][i - 1][4].z;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//correct first trail part that is connected to the ship
|
||
|
|
//jump end of trailpart to timesaved position
|
||
|
|
t[0].points[3].x = this.shipTrailHistory[j][1][0].x + this.shipTrailHistory[j][1][4].x;
|
||
|
|
t[0].points[3].y = this.shipTrailHistory[j][1][0].y + this.shipTrailHistory[j][1][4].y;
|
||
|
|
t[0].points[3].z = this.shipTrailHistory[j][1][0].z + this.shipTrailHistory[j][1][4].z;
|
||
|
|
t[0].points[2].x = this.shipTrailHistory[j][1][1].x + this.shipTrailHistory[j][1][4].x;
|
||
|
|
t[0].points[2].y = this.shipTrailHistory[j][1][1].y + this.shipTrailHistory[j][1][4].y;
|
||
|
|
t[0].points[2].z = this.shipTrailHistory[j][1][1].z + this.shipTrailHistory[j][1][4].z;
|
||
|
|
|
||
|
|
t[0].points[0].x = this.shipTrailHistory[j][0][0].x + this.shipTrailHistory[j][0][4].x;
|
||
|
|
t[0].points[0].y = this.shipTrailHistory[j][0][0].y + this.shipTrailHistory[j][0][4].y;
|
||
|
|
t[0].points[0].z = this.shipTrailHistory[j][0][0].z + this.shipTrailHistory[j][0][4].z;
|
||
|
|
t[0].points[1].x = this.shipTrailHistory[j][0][1].x + this.shipTrailHistory[j][0][4].x;
|
||
|
|
t[0].points[1].y = this.shipTrailHistory[j][0][1].y + this.shipTrailHistory[j][0][4].y;
|
||
|
|
t[0].points[1].z = this.shipTrailHistory[j][0][1].z + this.shipTrailHistory[j][0][4].z;
|
||
|
|
}
|
||
|
|
if (this.trailTicker <= 0) {
|
||
|
|
this.trailTicker = this.speed * 0.25;
|
||
|
|
}
|
||
|
|
|
||
|
|
//after moving setters
|
||
|
|
let ref = this.level.trackBuilder.spline[this.splineId];
|
||
|
|
if (ref.model !== null) {
|
||
|
|
//console.log(ref)
|
||
|
|
this.targetModel = ref.model;
|
||
|
|
//console.log(this.level.trackBuilder.spline[this.splineId]);//model.transfrom .roll .obstacles
|
||
|
|
//console.log(shipRight[0])
|
||
|
|
}
|
||
|
|
if (this.targetModel !== null) {
|
||
|
|
let trackRight = [this.targetModel.transform.right.x, this.targetModel.transform.right.y, this.targetModel.transform.right.z];
|
||
|
|
let shipRight = [this.gondula.transform.right.x, this.gondula.transform.right.y, this.gondula.transform.right.z];
|
||
|
|
this.angleToTrack = gl_vec3.dot(trackRight, shipRight);
|
||
|
|
//console.log(this.angleToTrack) gondula
|
||
|
|
let trackUp = [this.targetModel.transform.up.x, this.targetModel.transform.up.y, this.targetModel.transform.up.z];
|
||
|
|
let shipUp = [this.gondula.transform.up.x, this.gondula.transform.up.y, this.gondula.transform.up.z];
|
||
|
|
this.angleToTrackMod = gl_vec3.dot(trackUp, shipRight);
|
||
|
|
}
|
||
|
|
|
||
|
|
//todo: positional sound here
|
||
|
|
}
|
||
|
|
|
||
|
|
updateDream() {
|
||
|
|
let splineRef = this.level.trackBuilder.spline[0];
|
||
|
|
|
||
|
|
this.gondula.jumpToPosition({
|
||
|
|
x: this.gondula.pos.x,
|
||
|
|
y: this.gondula.pos.y,
|
||
|
|
z: this.gondula.pos.z + ((1 * this.speed) * this.scene.dt)
|
||
|
|
});
|
||
|
|
|
||
|
|
//move Ship to gondula
|
||
|
|
let posFactor = 0.25 * this.scene.dt;// 0.5 //Math.max(0.01, ((this.speed + this.speedBonus) / (this.speedMax + this.speedBonus))) * 0.5;//todo: at max speed it still jitters
|
||
|
|
let rotFactor = 0.05 * this.scene.dt;//0.1 //Math.max(0.01, ((this.speed + this.speedBonus) / (this.speedMax + this.speedBonus)) * 0.1);
|
||
|
|
|
||
|
|
if (this.speed < 0.01) {
|
||
|
|
//posFactor = 0.5;
|
||
|
|
//rotFactor = 0.1;
|
||
|
|
}
|
||
|
|
let deltaPos = {
|
||
|
|
x: ((this.gondula.pos.x + (this.gondula.transform.up.x * -this.flightRadius))) - this.shipAnchor.pos.x,
|
||
|
|
y: ((this.gondula.pos.y + (this.gondula.transform.up.y * -this.flightRadius))) - this.shipAnchor.pos.y,
|
||
|
|
z: ((this.gondula.pos.z + (this.gondula.transform.up.z * -this.flightRadius))) - this.shipAnchor.pos.z
|
||
|
|
}
|
||
|
|
this.shipAnchor.jumpToPosition({
|
||
|
|
x: this.shipAnchor.pos.x + (deltaPos.x * posFactor),
|
||
|
|
y: this.shipAnchor.pos.y + (deltaPos.y * posFactor),
|
||
|
|
z: this.shipAnchor.pos.z + (deltaPos.z * posFactor)
|
||
|
|
});
|
||
|
|
|
||
|
|
//rotate ship Anchor to Gondula
|
||
|
|
let targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.shipAnchor.transform.toVectorArray(this.shipAnchor.transform.forward),
|
||
|
|
this.shipAnchor.transform.toVectorArray(splineRef.transform.forward)
|
||
|
|
)
|
||
|
|
let rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.shipAnchor.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.shipAnchor.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.shipAnchor.transform.toVectorArray(this.shipAnchor.transform.right),
|
||
|
|
this.shipAnchor.transform.toVectorArray(this.gondula.transform.right)
|
||
|
|
)
|
||
|
|
rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.shipAnchor.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.shipAnchor.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
//move and rotate ship model to actual ship anchor point
|
||
|
|
this.ship.jumpToPosition({ x: this.shipAnchor.pos.x, y: this.shipAnchor.pos.y, z: this.shipAnchor.pos.z });
|
||
|
|
//rotate ship to Gondula
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.ship.transform.toVectorArray(this.ship.transform.forward),
|
||
|
|
this.ship.transform.toVectorArray(splineRef.transform.forward)
|
||
|
|
)
|
||
|
|
rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.ship.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.ship.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.ship.transform.toVectorArray(this.ship.transform.right),
|
||
|
|
this.ship.transform.toVectorArray(this.gondula.transform.right)
|
||
|
|
)
|
||
|
|
rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.ship.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.ship.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
for (let t of this.thrusters) {
|
||
|
|
//todo: get the saved original position of the vertex to move and add the move vector to keep the shape of the thruster to keep a cone shape
|
||
|
|
t.points[3].x = t.points[0].x + (this.gondula.transform.forward.x * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
t.points[3].y = t.points[0].y + (this.gondula.transform.forward.y * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
t.points[3].z = t.points[0].z + (this.gondula.transform.forward.z * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
|
||
|
|
t.points[2].x = t.points[1].x + (this.gondula.transform.forward.x * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
t.points[2].y = t.points[1].y + (this.gondula.transform.forward.y * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
t.points[2].z = t.points[1].z + (this.gondula.transform.forward.z * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
}
|
||
|
|
|
||
|
|
this.lensflares[this.lensflares.length - 1].jumpToPosition({
|
||
|
|
x: this.ship.pos.x + (this.ship.transform.forward.x * -66) + (this.ship.transform.up.x * 22),
|
||
|
|
y: this.ship.pos.y + (this.ship.transform.forward.y * -66) + (this.ship.transform.up.y * 22),
|
||
|
|
z: this.ship.pos.z + (this.ship.transform.forward.z * -66) + (this.ship.transform.up.z * 22),
|
||
|
|
}, true);
|
||
|
|
this.lensflares[this.lensflares.length - 1].quadData[0].alpha = 1 * this.speedFactor;//0.2
|
||
|
|
|
||
|
|
this.trailTicker -= this.scene.dt;
|
||
|
|
for (let [j, t] of this.trails.entries()) {
|
||
|
|
if (this.trailTicker <= 0) {
|
||
|
|
for (let i = t.length - 1; i > 0; i--) {
|
||
|
|
this.shipTrailHistory[j][i] = this.shipTrailHistory[j][i - 1]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
this.shipTrailHistory[j][0] = this.ship.getWorldPositionOfQuad(this.shipSwooshOrigins[j]);
|
||
|
|
for (let p of this.shipTrailHistory[j][0]) {
|
||
|
|
p.x += this.ship.pos.x;
|
||
|
|
p.y += this.ship.pos.y;
|
||
|
|
p.z += this.ship.pos.z;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for (let [j, t] of this.trails.entries()) {//each trail
|
||
|
|
//this.swooshOrigins[j].jumpToPosition(this.ship.pos);
|
||
|
|
if (this.trailTicker <= 0) {
|
||
|
|
for (let i = t.length - 1; i > 0; i--) {//each trail quad / saved position
|
||
|
|
let q = t[i];//each quad
|
||
|
|
//jump end of trailpart to timesaved position
|
||
|
|
q.points[3].x = this.shipTrailHistory[j][i][0].x + this.shipTrailHistory[j][i][4].x;
|
||
|
|
q.points[3].y = this.shipTrailHistory[j][i][0].y + this.shipTrailHistory[j][i][4].y;
|
||
|
|
q.points[3].z = this.shipTrailHistory[j][i][0].z + this.shipTrailHistory[j][i][4].z;
|
||
|
|
q.points[2].x = this.shipTrailHistory[j][i][1].x + this.shipTrailHistory[j][i][4].x;
|
||
|
|
q.points[2].y = this.shipTrailHistory[j][i][1].y + this.shipTrailHistory[j][i][4].y;
|
||
|
|
q.points[2].z = this.shipTrailHistory[j][i][1].z + this.shipTrailHistory[j][i][4].z;
|
||
|
|
|
||
|
|
//jump start of trailpart to timesaved previous position
|
||
|
|
q.points[0].x = this.shipTrailHistory[j][i - 1][0].x + this.shipTrailHistory[j][i - 1][4].x;
|
||
|
|
q.points[0].y = this.shipTrailHistory[j][i - 1][0].y + this.shipTrailHistory[j][i - 1][4].y;
|
||
|
|
q.points[0].z = this.shipTrailHistory[j][i - 1][0].z + this.shipTrailHistory[j][i - 1][4].z;
|
||
|
|
q.points[1].x = this.shipTrailHistory[j][i - 1][1].x + this.shipTrailHistory[j][i - 1][4].x;
|
||
|
|
q.points[1].y = this.shipTrailHistory[j][i - 1][1].y + this.shipTrailHistory[j][i - 1][4].y;
|
||
|
|
q.points[1].z = this.shipTrailHistory[j][i - 1][1].z + this.shipTrailHistory[j][i - 1][4].z;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//correct first trail part that is connected to the ship
|
||
|
|
//jump end of trailpart to timesaved position
|
||
|
|
t[0].points[3].x = this.shipTrailHistory[j][1][0].x + this.shipTrailHistory[j][1][4].x;
|
||
|
|
t[0].points[3].y = this.shipTrailHistory[j][1][0].y + this.shipTrailHistory[j][1][4].y;
|
||
|
|
t[0].points[3].z = this.shipTrailHistory[j][1][0].z + this.shipTrailHistory[j][1][4].z;
|
||
|
|
t[0].points[2].x = this.shipTrailHistory[j][1][1].x + this.shipTrailHistory[j][1][4].x;
|
||
|
|
t[0].points[2].y = this.shipTrailHistory[j][1][1].y + this.shipTrailHistory[j][1][4].y;
|
||
|
|
t[0].points[2].z = this.shipTrailHistory[j][1][1].z + this.shipTrailHistory[j][1][4].z;
|
||
|
|
|
||
|
|
t[0].points[0].x = this.shipTrailHistory[j][0][0].x + this.shipTrailHistory[j][0][4].x;
|
||
|
|
t[0].points[0].y = this.shipTrailHistory[j][0][0].y + this.shipTrailHistory[j][0][4].y;
|
||
|
|
t[0].points[0].z = this.shipTrailHistory[j][0][0].z + this.shipTrailHistory[j][0][4].z;
|
||
|
|
t[0].points[1].x = this.shipTrailHistory[j][0][1].x + this.shipTrailHistory[j][0][4].x;
|
||
|
|
t[0].points[1].y = this.shipTrailHistory[j][0][1].y + this.shipTrailHistory[j][0][4].y;
|
||
|
|
t[0].points[1].z = this.shipTrailHistory[j][0][1].z + this.shipTrailHistory[j][0][4].z;
|
||
|
|
}
|
||
|
|
if (this.trailTicker <= 0) {
|
||
|
|
this.trailTicker = this.speed * 0.25;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
updateSelection(_delta, _slerpAmt = -1) {
|
||
|
|
this.targetSplineId = this.splineId + 1;//INFO looking further down with higher speed?
|
||
|
|
while (this.targetSplineId >= this.level.trackBuilder.spline.length) {
|
||
|
|
this.targetSplineId -= this.level.trackBuilder.spline.length;
|
||
|
|
}
|
||
|
|
let splineRef = this.level.trackBuilder.spline[this.targetSplineId];
|
||
|
|
|
||
|
|
let targetVec = [splineRef.x - this.gondula.pos.x, splineRef.y - this.gondula.pos.y, splineRef.z - this.gondula.pos.z];
|
||
|
|
targetVec = gl_vec3.normalize(targetVec, targetVec);
|
||
|
|
|
||
|
|
let targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.gondula.transform.toVectorArray(this.gondula.transform.forward),
|
||
|
|
targetVec
|
||
|
|
)
|
||
|
|
this.gondula.rotateByQuaternion(targetRot);
|
||
|
|
//move gondula forward by spd
|
||
|
|
this.gondula.jumpToPosition({
|
||
|
|
x: this.gondula.pos.x + ((targetVec[0] * this.speed) * this.scene.dt),
|
||
|
|
y: this.gondula.pos.y + ((targetVec[1] * this.speed) * this.scene.dt),
|
||
|
|
z: this.gondula.pos.z + ((targetVec[2] * this.speed) * this.scene.dt)
|
||
|
|
});
|
||
|
|
|
||
|
|
//check if reached target
|
||
|
|
let d = gl_vec3.distance(this.gondula.transform.toVectorArray(this.gondula.pos), [splineRef.x, splineRef.y, splineRef.z]);
|
||
|
|
if (d <= 64) {
|
||
|
|
//let amt = Math.floor(criticalSpeed/64) + 1; //jumjp further if speed exceeds the distance between splines
|
||
|
|
this.splineId += 1//amt;
|
||
|
|
if (this.splineId >= this.level.trackBuilder.spline.length) {
|
||
|
|
this.splineId -= this.level.trackBuilder.spline.length;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//move Ship to gondula
|
||
|
|
let posFactor = 0.25 * this.scene.dt;// 0.5 //Math.max(0.01, ((this.speed + this.speedBonus) / (this.speedMax + this.speedBonus))) * 0.5;//todo: at max speed it still jitters
|
||
|
|
let rotFactor = 0.015 * this.scene.dt;//0.1 //Math.max(0.01, ((this.speed + this.speedBonus) / (this.speedMax + this.speedBonus)) * 0.1);
|
||
|
|
|
||
|
|
if (this.speed < 0.01) {
|
||
|
|
//posFactor = 0.5;
|
||
|
|
//rotFactor = 0.1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (_slerpAmt > 0) {
|
||
|
|
posFactor = 1;
|
||
|
|
rotFactor = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
let deltaPos = {
|
||
|
|
x: ((this.gondula.pos.x + (this.gondula.transform.up.x * -this.flightRadius))) - this.shipAnchor.pos.x,
|
||
|
|
y: ((this.gondula.pos.y + (this.gondula.transform.up.y * -this.flightRadius))) - this.shipAnchor.pos.y,
|
||
|
|
z: ((this.gondula.pos.z + (this.gondula.transform.up.z * -this.flightRadius))) - this.shipAnchor.pos.z
|
||
|
|
}
|
||
|
|
this.shipAnchor.jumpToPosition({
|
||
|
|
x: this.shipAnchor.pos.x + (deltaPos.x * posFactor),
|
||
|
|
y: this.shipAnchor.pos.y + (deltaPos.y * posFactor),
|
||
|
|
z: this.shipAnchor.pos.z + (deltaPos.z * posFactor)
|
||
|
|
});
|
||
|
|
|
||
|
|
//rotate ship Anchor to Gondula
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.shipAnchor.transform.toVectorArray(this.shipAnchor.transform.forward),
|
||
|
|
this.shipAnchor.transform.toVectorArray(splineRef.transform.forward)
|
||
|
|
)
|
||
|
|
let rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.shipAnchor.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.shipAnchor.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.shipAnchor.transform.toVectorArray(this.shipAnchor.transform.right),
|
||
|
|
this.shipAnchor.transform.toVectorArray(this.gondula.transform.right)
|
||
|
|
)
|
||
|
|
rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.shipAnchor.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.shipAnchor.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
//move and rotate ship model to actual ship anchor point
|
||
|
|
this.ship.jumpToPosition({ x: this.shipAnchor.pos.x, y: this.shipAnchor.pos.y, z: this.shipAnchor.pos.z });
|
||
|
|
//rotate ship to Gondula
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.ship.transform.toVectorArray(this.ship.transform.forward),
|
||
|
|
this.ship.transform.toVectorArray(splineRef.transform.forward)
|
||
|
|
)
|
||
|
|
rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.ship.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.ship.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.ship.transform.toVectorArray(this.ship.transform.right),
|
||
|
|
this.ship.transform.toVectorArray(this.gondula.transform.right)
|
||
|
|
)
|
||
|
|
rot = [0, 0, 0, 0];
|
||
|
|
rot = gl_quat.slerp(rot, this.ship.transform.rotationQuat, targetRot, rotFactor);
|
||
|
|
this.ship.rotateByQuaternion(rot);
|
||
|
|
|
||
|
|
for (let t of this.thrusters) {
|
||
|
|
//todo: get the saved original position of the vertex to move and add the move vector to keep the shape of the thruster to keep a cone shape
|
||
|
|
t.points[3].x = t.points[0].x + (this.gondula.transform.forward.x * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
t.points[3].y = t.points[0].y + (this.gondula.transform.forward.y * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
t.points[3].z = t.points[0].z + (this.gondula.transform.forward.z * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
|
||
|
|
t.points[2].x = t.points[1].x + (this.gondula.transform.forward.x * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
t.points[2].y = t.points[1].y + (this.gondula.transform.forward.y * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
t.points[2].z = t.points[1].z + (this.gondula.transform.forward.z * (1 + (-56 * (this.speed / this.speedMax))));
|
||
|
|
}
|
||
|
|
|
||
|
|
this.lensflares[this.lensflares.length - 1].jumpToPosition({
|
||
|
|
x: this.ship.pos.x + (this.ship.transform.forward.x * -66) + (this.ship.transform.up.x * 22),
|
||
|
|
y: this.ship.pos.y + (this.ship.transform.forward.y * -66) + (this.ship.transform.up.y * 22),
|
||
|
|
z: this.ship.pos.z + (this.ship.transform.forward.z * -66) + (this.ship.transform.up.z * 22),
|
||
|
|
}, true);
|
||
|
|
this.lensflares[this.lensflares.length - 1].quadData[0].alpha = 1 * this.speedFactor;//0.2
|
||
|
|
|
||
|
|
this.trailTicker -= this.scene.dt;
|
||
|
|
for (let [j, t] of this.trails.entries()) {
|
||
|
|
if (this.trailTicker <= 0) {
|
||
|
|
for (let i = t.length - 1; i > 0; i--) {
|
||
|
|
this.shipTrailHistory[j][i] = this.shipTrailHistory[j][i - 1]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
this.shipTrailHistory[j][0] = this.ship.getWorldPositionOfQuad(this.shipSwooshOrigins[j]);
|
||
|
|
for (let p of this.shipTrailHistory[j][0]) {
|
||
|
|
p.x += this.ship.pos.x;
|
||
|
|
p.y += this.ship.pos.y;
|
||
|
|
p.z += this.ship.pos.z;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for (let [j, t] of this.trails.entries()) {//each trail
|
||
|
|
//this.swooshOrigins[j].jumpToPosition(this.ship.pos);
|
||
|
|
if (this.trailTicker <= 0) {
|
||
|
|
for (let i = t.length - 1; i > 0; i--) {//each trail quad / saved position
|
||
|
|
let q = t[i];//each quad
|
||
|
|
//jump end of trailpart to timesaved position
|
||
|
|
q.points[3].x = this.shipTrailHistory[j][i][0].x + this.shipTrailHistory[j][i][4].x;
|
||
|
|
q.points[3].y = this.shipTrailHistory[j][i][0].y + this.shipTrailHistory[j][i][4].y;
|
||
|
|
q.points[3].z = this.shipTrailHistory[j][i][0].z + this.shipTrailHistory[j][i][4].z;
|
||
|
|
q.points[2].x = this.shipTrailHistory[j][i][1].x + this.shipTrailHistory[j][i][4].x;
|
||
|
|
q.points[2].y = this.shipTrailHistory[j][i][1].y + this.shipTrailHistory[j][i][4].y;
|
||
|
|
q.points[2].z = this.shipTrailHistory[j][i][1].z + this.shipTrailHistory[j][i][4].z;
|
||
|
|
|
||
|
|
//jump start of trailpart to timesaved previous position
|
||
|
|
q.points[0].x = this.shipTrailHistory[j][i - 1][0].x + this.shipTrailHistory[j][i - 1][4].x;
|
||
|
|
q.points[0].y = this.shipTrailHistory[j][i - 1][0].y + this.shipTrailHistory[j][i - 1][4].y;
|
||
|
|
q.points[0].z = this.shipTrailHistory[j][i - 1][0].z + this.shipTrailHistory[j][i - 1][4].z;
|
||
|
|
q.points[1].x = this.shipTrailHistory[j][i - 1][1].x + this.shipTrailHistory[j][i - 1][4].x;
|
||
|
|
q.points[1].y = this.shipTrailHistory[j][i - 1][1].y + this.shipTrailHistory[j][i - 1][4].y;
|
||
|
|
q.points[1].z = this.shipTrailHistory[j][i - 1][1].z + this.shipTrailHistory[j][i - 1][4].z;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//correct first trail part that is connected to the ship
|
||
|
|
//jump end of trailpart to timesaved position
|
||
|
|
t[0].points[3].x = this.shipTrailHistory[j][1][0].x + this.shipTrailHistory[j][1][4].x;
|
||
|
|
t[0].points[3].y = this.shipTrailHistory[j][1][0].y + this.shipTrailHistory[j][1][4].y;
|
||
|
|
t[0].points[3].z = this.shipTrailHistory[j][1][0].z + this.shipTrailHistory[j][1][4].z;
|
||
|
|
t[0].points[2].x = this.shipTrailHistory[j][1][1].x + this.shipTrailHistory[j][1][4].x;
|
||
|
|
t[0].points[2].y = this.shipTrailHistory[j][1][1].y + this.shipTrailHistory[j][1][4].y;
|
||
|
|
t[0].points[2].z = this.shipTrailHistory[j][1][1].z + this.shipTrailHistory[j][1][4].z;
|
||
|
|
|
||
|
|
t[0].points[0].x = this.shipTrailHistory[j][0][0].x + this.shipTrailHistory[j][0][4].x;
|
||
|
|
t[0].points[0].y = this.shipTrailHistory[j][0][0].y + this.shipTrailHistory[j][0][4].y;
|
||
|
|
t[0].points[0].z = this.shipTrailHistory[j][0][0].z + this.shipTrailHistory[j][0][4].z;
|
||
|
|
t[0].points[1].x = this.shipTrailHistory[j][0][1].x + this.shipTrailHistory[j][0][4].x;
|
||
|
|
t[0].points[1].y = this.shipTrailHistory[j][0][1].y + this.shipTrailHistory[j][0][4].y;
|
||
|
|
t[0].points[1].z = this.shipTrailHistory[j][0][1].z + this.shipTrailHistory[j][0][4].z;
|
||
|
|
}
|
||
|
|
if (this.trailTicker <= 0) {
|
||
|
|
this.trailTicker = this.speed * 0.25;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
setDraw(_bool) {
|
||
|
|
this.ship.flags.draw = _bool
|
||
|
|
for (let l of this.lensflares) {
|
||
|
|
l.flags.draw = _bool;
|
||
|
|
}
|
||
|
|
for (let s of this.swooshOrigins) {
|
||
|
|
s.flags.draw = _bool;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
startNewLap() {
|
||
|
|
//save and show last laptime
|
||
|
|
this.lapTimes.push({
|
||
|
|
time: this.elapsedTime,
|
||
|
|
position: this.position
|
||
|
|
});
|
||
|
|
//this.last.lapTime = this.elapsedTime
|
||
|
|
|
||
|
|
//find fastest laptime
|
||
|
|
this.last.fastestLap = this.fastestLap;
|
||
|
|
let r = (60 * 60) * 1000;
|
||
|
|
for (let [i, l] of this.lapTimes.entries()) {
|
||
|
|
if (l.time < r) {
|
||
|
|
r = l.time;
|
||
|
|
this.fastestLap = i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (this.isPlayer === true) {
|
||
|
|
if (this.level.raceMode === this.level.raceModes.canyon) {
|
||
|
|
this.level.raceModeData.playerIsHunter = !this.level.raceModeData.playerIsHunter;
|
||
|
|
this.level.startNewCanyon();
|
||
|
|
} else {
|
||
|
|
this.level.startNewLap();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//start new lap time
|
||
|
|
this.startTime = Date.now();
|
||
|
|
this.elapsedTime = Date.now() - this.startTime;
|
||
|
|
}
|
||
|
|
|
||
|
|
restartOnFromSplineId(_splineId, _roll = 0) {
|
||
|
|
this.splineId = _splineId;
|
||
|
|
let splg = this.level.trackBuilder.spline[this.splineId];
|
||
|
|
this.gondula.jumpToPosition({ x: splg.x, y: splg.y, z: splg.z });
|
||
|
|
|
||
|
|
let targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.gondula.transform.toVectorArray(this.gondula.transform.forward),
|
||
|
|
[0, 0, 1]
|
||
|
|
)
|
||
|
|
this.gondula.rotateByQuaternion(targetRot);
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.gondula.transform.toVectorArray(this.gondula.transform.right),
|
||
|
|
[1, 0, 0]
|
||
|
|
)
|
||
|
|
this.gondula.rotateByQuaternion(targetRot);
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.gondula.transform.toVectorArray(this.gondula.transform.up),
|
||
|
|
[0, -1, 0]
|
||
|
|
)
|
||
|
|
this.gondula.rotateByQuaternion(targetRot);
|
||
|
|
|
||
|
|
this.gondula.rotateAroundAxis(this.gondula.transform.toVectorArray(this.gondula.transform.forward), _roll);
|
||
|
|
|
||
|
|
this.speed = 0;
|
||
|
|
|
||
|
|
|
||
|
|
//start from hangar?
|
||
|
|
if (this.level.startFromHangar === true) {
|
||
|
|
this.gondula.jumpToPosition({ x: this.gondula.pos.x + (this.gondula.transform.up.x * -244), y: this.gondula.pos.y + (this.gondula.transform.up.y * -244), z: this.gondula.pos.z + (this.gondula.transform.up.z * -244) });//y 468-128-96 init start
|
||
|
|
this.shipAnchor.jumpToPosition({ x: this.gondula.pos.x + (this.gondula.transform.up.x * -96), y: this.gondula.pos.y + (this.gondula.transform.up.y * -96), z: this.gondula.pos.z + (this.gondula.transform.up.z * -96) }, true);
|
||
|
|
this.ship.jumpToPosition({ x: this.gondula.pos.x + (this.gondula.transform.up.x * -96), y: this.gondula.pos.y + (this.gondula.transform.up.y * -96), z: this.gondula.pos.z + (this.gondula.transform.up.z * -96) }, true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
jumpToSplineId(_splineId, _roll = 0) {
|
||
|
|
this.splineId = _splineId;
|
||
|
|
let splg = this.level.trackBuilder.spline[this.splineId];
|
||
|
|
this.gondula.jumpToPosition({ x: splg.x, y: splg.y, z: splg.z });
|
||
|
|
|
||
|
|
let targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.gondula.transform.toVectorArray(this.gondula.transform.forward),
|
||
|
|
[0, 0, 1]
|
||
|
|
)
|
||
|
|
this.gondula.rotateByQuaternion(targetRot);
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.gondula.transform.toVectorArray(this.gondula.transform.right),
|
||
|
|
[1, 0, 0]
|
||
|
|
)
|
||
|
|
this.gondula.rotateByQuaternion(targetRot);
|
||
|
|
targetRot = [0, 0, 0, 0];
|
||
|
|
targetRot = gl_quat.rotationTo(targetRot,
|
||
|
|
this.gondula.transform.toVectorArray(this.gondula.transform.up),
|
||
|
|
[0, -1, 0]
|
||
|
|
)
|
||
|
|
this.gondula.rotateByQuaternion(targetRot);
|
||
|
|
|
||
|
|
this.gondula.rotateAroundAxis(this.gondula.transform.toVectorArray(this.gondula.transform.forward), _roll);
|
||
|
|
|
||
|
|
this.speed = 0;
|
||
|
|
|
||
|
|
|
||
|
|
//start from hangar?
|
||
|
|
if (this.level.startFromHangar === true) {
|
||
|
|
this.gondula.jumpToPosition({ x: this.gondula.pos.x + (this.gondula.transform.up.x * -244), y: this.gondula.pos.y + (this.gondula.transform.up.y * -244), z: this.gondula.pos.z + (this.gondula.transform.up.z * -244) });//y 468-128-96 init start
|
||
|
|
this.shipAnchor.jumpToPosition({ x: this.gondula.pos.x + (this.gondula.transform.up.x * -96), y: this.gondula.pos.y + (this.gondula.transform.up.y * -96), z: this.gondula.pos.z + (this.gondula.transform.up.z * -96) }, true);
|
||
|
|
this.ship.jumpToPosition({ x: this.gondula.pos.x + (this.gondula.transform.up.x * -96), y: this.gondula.pos.y + (this.gondula.transform.up.y * -96), z: this.gondula.pos.z + (this.gondula.transform.up.z * -96) }, true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
inputPlayer() {
|
||
|
|
|
||
|
|
let gamepad = null;
|
||
|
|
gamepad = navigator.getGamepads()[Math.max(0, gamepadsConnected - 1)];
|
||
|
|
if (gamepad === undefined) {
|
||
|
|
gamepad = null;
|
||
|
|
}
|
||
|
|
|
||
|
|
this.keyInput.spd = 0;
|
||
|
|
//this.keyInput.roll = 0;
|
||
|
|
this.keyInput.pitch = 0;
|
||
|
|
|
||
|
|
//acceleration
|
||
|
|
if (INPUTS.triggerRight.amount > 0.1) {
|
||
|
|
this.input.spd = this.acceleration;
|
||
|
|
this.keyInput.spd = 1;
|
||
|
|
} else {
|
||
|
|
this.input.spd = this.deceleration;
|
||
|
|
if (INPUTS.triggerLeft.amount > 0.1) {//redundant?
|
||
|
|
this.keyInput.spd = -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (INPUTS.triggerLeft.amount > 0.1) {
|
||
|
|
this.input.spd = this.brakes;
|
||
|
|
this.keyInput.spd = -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
//pitch with mouse //todo: pitch also with gamepad
|
||
|
|
if (this.scene.hand.useControllerMouse === false) {
|
||
|
|
this.keyInput.pitch = Math.max(-1, Math.min(this.scene.hand.pos.y * 0.01, 1));
|
||
|
|
} else {
|
||
|
|
//gamepad
|
||
|
|
//console.log(INPUTS.stickRight.vertical)
|
||
|
|
if (gamepad !== null) { //todo INFO + if options enabled gamepad control
|
||
|
|
let sra = Math.abs(INPUTS.stickRight.vertical);
|
||
|
|
let sla = Math.abs(INPUTS.stickLeft.vertical);
|
||
|
|
this.keyInput.pitch = (sra > sla ? (INPUTS.stickRight.vertical * -1) : (INPUTS.stickLeft.vertical * -1));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//if (this.keyInput.pitch <= -0.5 && this.jumping === false) {
|
||
|
|
if (this.jumping === false) {
|
||
|
|
if (this.keyInput.pitch - this.keyInput.previous.pitch < -0.5) {
|
||
|
|
this.jumping = true;
|
||
|
|
this.jumpingLasting = 30;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//instant acceleration with bonus
|
||
|
|
//todo: slipstreaming is the same, but without better acceleration
|
||
|
|
/*
|
||
|
|
if(this.scene.keys.space.isDown){
|
||
|
|
this.input.spd = 1;
|
||
|
|
this.speedBonus = 4;
|
||
|
|
this.speed += 4;
|
||
|
|
this.speed = Math.min(this.speedMax + this.speedBonus, this.speed);
|
||
|
|
this.speed = this.speedMax + this.speedBonus;
|
||
|
|
}else{
|
||
|
|
this.speedBonus = 0;
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
|
||
|
|
//roll
|
||
|
|
if (this.scene.hand.useControllerMouse === false) {
|
||
|
|
if (INPUTS.stickLeft.horizontal !== 0) {
|
||
|
|
if (INPUTS.stickLeft.horizontal > 0) {
|
||
|
|
if (this.keyInput.roll < 1) {
|
||
|
|
this.keyInput.roll += 0.02 * this.scene.dt;
|
||
|
|
this.keyInput.roll = Math.min(this.keyInput.roll, 1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (INPUTS.stickLeft.horizontal < 0) {
|
||
|
|
if (this.keyInput.roll > -1) {
|
||
|
|
this.keyInput.roll -= 0.02 * this.scene.dt;
|
||
|
|
this.keyInput.roll = Math.max(this.keyInput.roll, -1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
if (this.keyInput.roll < 0) {
|
||
|
|
this.keyInput.roll += 0.1 * this.scene.dt;
|
||
|
|
this.keyInput.roll = Math.min(this.keyInput.roll, 0);
|
||
|
|
}
|
||
|
|
if (this.keyInput.roll > 0) {
|
||
|
|
this.keyInput.roll -= 0.1 * this.scene.dt;
|
||
|
|
this.keyInput.roll = Math.max(this.keyInput.roll, 0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
this.input.roll = this.keyInput.roll;
|
||
|
|
} else {
|
||
|
|
this.input.roll = Math.abs(INPUTS.stickLeft.horizontal) > 0.2 ? INPUTS.stickLeft.horizontal : 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if (this.scene.hand.pressed === true && isMobile === true) {
|
||
|
|
//todo: maybe only look around with touch when touching in upper area
|
||
|
|
let hAmt = (this.scene.hand.pos.x - this.scene.hand.start.x) * 0.005;
|
||
|
|
if (hAmt > 0.05 || hAmt < 0.05) {
|
||
|
|
this.input.roll += hAmt;
|
||
|
|
}
|
||
|
|
this.input.roll = Math.max(-1, Math.min(1, this.input.roll));
|
||
|
|
|
||
|
|
let vAmt = (this.scene.hand.pos.y - this.scene.hand.start.y) * 0.005;
|
||
|
|
if (vAmt > 0.05) {
|
||
|
|
this.input.spd = this.brakes;
|
||
|
|
this.keyInput.spd = -1;
|
||
|
|
this.keyInput.pitch = -1;
|
||
|
|
} else {
|
||
|
|
this.input.spd = this.acceleration;
|
||
|
|
this.keyInput.spd = 1;
|
||
|
|
this.keyInput.pitch = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
this.scene.hand.start.x = this.scene.hand.pos.x;
|
||
|
|
//this.scene.hand.start.y = this.scene.hand.pos.y;
|
||
|
|
}
|
||
|
|
if (this.scene.hand.pressed === false && isMobile === true) {
|
||
|
|
this.input.spd = this.deceleration;
|
||
|
|
this.keyInput.spd = -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
//let curveDelta = Math.max(-1, Math.min((this.last.curveAmt - this.curveAmt), 1));
|
||
|
|
/*if(this.curveAmt > this.ai.curveRec){
|
||
|
|
this.ai.curveRec = this.curveAmt;
|
||
|
|
console.log("new rec");
|
||
|
|
}else if(this.curveAmt < this.ai.curveRec){
|
||
|
|
console.log("wrong dir")
|
||
|
|
this.ai.curveRec = -9999;
|
||
|
|
}*/
|
||
|
|
//if(Math.abs(curveDelta) > 0.12){
|
||
|
|
//console.log(curveDelta) //true is good
|
||
|
|
//}
|
||
|
|
//console.log(this.curveAmt)
|
||
|
|
//console.log(this.last.speedBonus - this.speedBonus)
|
||
|
|
//console.log(this.curveAmt > this.last.curveAmt)
|
||
|
|
//console.log(this.last.curveAmt - this.curveAmt)
|
||
|
|
//
|
||
|
|
|
||
|
|
this.keyInput.previous.pitch = this.keyInput.pitch;
|
||
|
|
this.keyInput.previous.spd = this.keyInput.spd;
|
||
|
|
this.keyInput.previous.roll = this.keyInput.roll;
|
||
|
|
}
|
||
|
|
|
||
|
|
inputAI(_bonusRef) {
|
||
|
|
//dumb forward
|
||
|
|
this.input.spd = this.acceleration;
|
||
|
|
this.keyInput.spd = 1;
|
||
|
|
//this.input.roll = 0;
|
||
|
|
//this.keyInput.pitch = 0;
|
||
|
|
|
||
|
|
let keyThink = {
|
||
|
|
spd: 0,
|
||
|
|
roll: 0,
|
||
|
|
pitch: 0
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
let avoid = [0, 0, 0]
|
||
|
|
//check Collisions
|
||
|
|
let collCheckArr = [
|
||
|
|
{//check forward of ship
|
||
|
|
pos: {
|
||
|
|
x: this.shipAnchor.pos.x,
|
||
|
|
y: this.shipAnchor.pos.y,
|
||
|
|
z: this.shipAnchor.pos.z
|
||
|
|
},
|
||
|
|
dir: {
|
||
|
|
x: this.shipAnchor.transform.forward.x,
|
||
|
|
y: this.shipAnchor.transform.forward.y,
|
||
|
|
z: this.shipAnchor.transform.forward.z
|
||
|
|
},
|
||
|
|
hit: []
|
||
|
|
}, {//check forward right of ship for booster
|
||
|
|
pos: {
|
||
|
|
x: this.shipAnchor.pos.x + (this.shipAnchor.transform.right.x * 48),
|
||
|
|
y: this.shipAnchor.pos.y + (this.shipAnchor.transform.right.y * 48),
|
||
|
|
z: this.shipAnchor.pos.z + (this.shipAnchor.transform.right.z * 48)
|
||
|
|
},
|
||
|
|
dir: {
|
||
|
|
x: this.shipAnchor.transform.forward.x,
|
||
|
|
y: this.shipAnchor.transform.forward.y,
|
||
|
|
z: this.shipAnchor.transform.forward.z
|
||
|
|
},
|
||
|
|
hit: []
|
||
|
|
}, {//check forward left of ship for booster
|
||
|
|
pos: {
|
||
|
|
x: this.shipAnchor.pos.x + (this.shipAnchor.transform.right.x * -48),
|
||
|
|
y: this.shipAnchor.pos.y + (this.shipAnchor.transform.right.y * -48),
|
||
|
|
z: this.shipAnchor.pos.z + (this.shipAnchor.transform.right.z * -48)
|
||
|
|
},
|
||
|
|
dir: {
|
||
|
|
x: this.shipAnchor.transform.forward.x,
|
||
|
|
y: this.shipAnchor.transform.forward.y,
|
||
|
|
z: this.shipAnchor.transform.forward.z
|
||
|
|
},
|
||
|
|
hit: []
|
||
|
|
}
|
||
|
|
];
|
||
|
|
let toCollideWith = [];
|
||
|
|
for (let o of this.level.trackBuilder.obstacles) {
|
||
|
|
if (o.data.id + 1 > this.splineId) {
|
||
|
|
if (o.trigger.isTrigger === false) {
|
||
|
|
toCollideWith.push(o);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for (let m of toCollideWith) {
|
||
|
|
if (m.flags.update === true) {
|
||
|
|
//m.update();
|
||
|
|
//INFOalready updated in the actual update
|
||
|
|
}
|
||
|
|
for (let q of m.collisionData) {
|
||
|
|
for (let c of collCheckArr) {
|
||
|
|
let hitData = this.scene.geometryController.collide(q, c);
|
||
|
|
if (hitData.pt !== null) {
|
||
|
|
hitData.model = m;
|
||
|
|
c.hit.push(hitData);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
let alreadyColliding = false;
|
||
|
|
let returnColl = collCheckArr;
|
||
|
|
//resolve collision with forward
|
||
|
|
if (returnColl[0].hit.length > 0) {
|
||
|
|
//filter relevant = nearest hit
|
||
|
|
let dist = 9999;
|
||
|
|
let nearestHit = returnColl[0].hit[0];
|
||
|
|
for (let [i, n] of returnColl[0].hit.entries()) {
|
||
|
|
let d = eud.distance([this.shipAnchor.pos.x, this.shipAnchor.pos.y, this.shipAnchor.pos.z], returnColl[0].hit[i].pt)
|
||
|
|
if (d < dist) {
|
||
|
|
dist = d;
|
||
|
|
nearestHit = returnColl[0].hit[i];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (dist < 2024) {
|
||
|
|
avoid[0] = dist;
|
||
|
|
}
|
||
|
|
if (dist < 128) {
|
||
|
|
alreadyColliding = true;
|
||
|
|
if (nearestHit.model.trigger.isTrigger === false) {
|
||
|
|
//console.log(returnColl[0]);
|
||
|
|
/*
|
||
|
|
if(this.speed > 0){
|
||
|
|
this.scene.soundManager.playRandomSound(this.scene.soundManager.bumpSound);
|
||
|
|
}
|
||
|
|
|
||
|
|
this.input.spd = 0;
|
||
|
|
this.speed = 0;
|
||
|
|
if(nearestHit.model.data.roll !== undefined){
|
||
|
|
this.input.roll = nearestHit.model.data.roll * 2;
|
||
|
|
}*/
|
||
|
|
|
||
|
|
} else {
|
||
|
|
//nearestHit.model.updateTrigger();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//check booster only if collision free
|
||
|
|
if (alreadyColliding === false) {
|
||
|
|
//resolve collision with forward right and then left of ship for boost
|
||
|
|
for (let j = 1; j < 3; j++) {
|
||
|
|
if (returnColl[j].hit.length > 0) {
|
||
|
|
//filter relevant = nearest hit
|
||
|
|
let dist = 9999;
|
||
|
|
let nearestHit = returnColl[j].hit[0];
|
||
|
|
for (let [i, n] of returnColl[j].hit.entries()) {
|
||
|
|
let d = eud.distance([returnColl[j].pos.x, returnColl[j].pos.y, returnColl[j].pos.z], returnColl[j].hit[i].pt)
|
||
|
|
if (d < dist) {
|
||
|
|
dist = d;
|
||
|
|
nearestHit = returnColl[j].hit[i];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (dist < 2024) {
|
||
|
|
avoid[j] = dist;
|
||
|
|
}
|
||
|
|
if (dist < 128) {
|
||
|
|
if (nearestHit.model.trigger.isTrigger === false) {
|
||
|
|
/*if(this.speed > (this.speedMax * 0.25) && this.input.spd >= 0){
|
||
|
|
this.input.spd = 1;
|
||
|
|
this.speed = this.speedMax * this.nearmissBoost;
|
||
|
|
if(this.isPlayer === true){
|
||
|
|
if(this.scene.cam.fov < 3.5){//todo: find a good value for the boost effect
|
||
|
|
this.scene.cam.fov += 1 * this.scene.dt;
|
||
|
|
this.scene.cam.fov = Math.min(this.scene.cam.fov, 3.5);
|
||
|
|
}
|
||
|
|
//sound
|
||
|
|
this.scene.soundManager.playRandomSound(this.scene.soundManager.swooshSound);
|
||
|
|
}
|
||
|
|
}*/
|
||
|
|
} else {
|
||
|
|
//nearestHit.model.updateTrigger();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//switch to dodge mode if obstacle comes up
|
||
|
|
if (avoid[0] > 0 || avoid[1] > 0 || avoid[2] > 0) {
|
||
|
|
this.ai.navState = this.ai.navStates.dodge;
|
||
|
|
}
|
||
|
|
|
||
|
|
//smaller than 0 delta is good
|
||
|
|
let curveDelta = this.last.curveAmt - this.curveAmt;//Math.max(-1, Math.min((this.last.curveAmt - this.curveAmt) , 1));
|
||
|
|
let speedDelta = this.last.speedBonus - this.speedBonus;
|
||
|
|
//cooling strategy?
|
||
|
|
/*if(curveDelta > 0){
|
||
|
|
this.input.roll = -curveDelta;
|
||
|
|
}*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
//todo: best one yet
|
||
|
|
this.input.roll = this.ai.prefRoll;
|
||
|
|
if(curveDelta > 0){
|
||
|
|
if(this.ai.waitRoll <= 0){
|
||
|
|
this.ai.prefRoll *= -1;
|
||
|
|
this.input.roll = 0;
|
||
|
|
//wait a bit until switching roll direction again
|
||
|
|
if(this.curveAmt > 0.01){
|
||
|
|
this.ai.waitRoll = 1;
|
||
|
|
}else{
|
||
|
|
this.ai.waitRoll = 15;
|
||
|
|
}
|
||
|
|
}else{
|
||
|
|
this.ai.waitRoll -= 1 * this.scene.dt;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
switch (this.ai.navState) {
|
||
|
|
case this.ai.navStates.seek:
|
||
|
|
//todo: works okay-ish but still gets overpowered by curveAmt delta fluctuations when already on right track or halfway between good or bad
|
||
|
|
//todo: because the fluctuation values are as small as a roll would be
|
||
|
|
|
||
|
|
if (this.curveAmt > this.ai.curveRec) {
|
||
|
|
this.ai.curveRec = this.curveAmt;
|
||
|
|
//this.input.roll = this.ai.prefRoll;
|
||
|
|
keyThink.roll = this.ai.prefRoll;
|
||
|
|
this.ai.lastGoodPrefRoll = this.ai.prefRoll;
|
||
|
|
//console.log(curveDelta)
|
||
|
|
}
|
||
|
|
if (curveDelta > 0 && curveDelta < 0.003) {
|
||
|
|
//console.log("flipping")
|
||
|
|
//this.ai.prefRoll *= -1;
|
||
|
|
this.ai.prefRoll = this.ai.lastGoodPrefRoll * -1;
|
||
|
|
}
|
||
|
|
if (this.curveAmt < 0) {
|
||
|
|
this.ai.curveRec = -9999;
|
||
|
|
//console.log("wrong side")
|
||
|
|
} else {
|
||
|
|
this.ai.waitRoll -= 1 * this.scene.dt;
|
||
|
|
if (this.ai.waitRoll <= 0) {
|
||
|
|
this.ai.waitRoll = 30;
|
||
|
|
this.ai.curveRec = -9999;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
this.aiFindPitch();
|
||
|
|
|
||
|
|
break;
|
||
|
|
case this.ai.navStates.wait:
|
||
|
|
this.ai.waitRoll -= 1 * this.scene.dt;
|
||
|
|
if (this.ai.waitRoll <= 0 || curveDelta >= 2) {
|
||
|
|
if (curveDelta > 2) {
|
||
|
|
//console.log("curve changed > seek");
|
||
|
|
}
|
||
|
|
this.ai.navState = this.ai.navStates.seek;
|
||
|
|
this.ai.curveRec = -9999;
|
||
|
|
}
|
||
|
|
this.aiFindPitch();
|
||
|
|
break;
|
||
|
|
case this.ai.navStates.dodge:
|
||
|
|
//dodge
|
||
|
|
let finishedDodging = true;
|
||
|
|
if (avoid[0] > 0) {//middle
|
||
|
|
//this.input.roll = this.ai.prefRoll;
|
||
|
|
keyThink.roll = this.ai.prefRoll;
|
||
|
|
if (avoid[0] < 1024) {
|
||
|
|
this.input.spd = this.brakes;
|
||
|
|
} else {
|
||
|
|
this.input.spd = this.deceleration;
|
||
|
|
}
|
||
|
|
this.keyInput.spd = -1;
|
||
|
|
this.aiFindPitch(false);//this.keyInput.pitch = -1;
|
||
|
|
//console.log("collision happening or imminent")
|
||
|
|
finishedDodging = false;
|
||
|
|
}
|
||
|
|
else if (avoid[1] > 0) {//right
|
||
|
|
//this.input.roll = -1;
|
||
|
|
keyThink.roll = -1;
|
||
|
|
this.ai.prefRoll = -1;
|
||
|
|
this.input.spd = this.acceleration;
|
||
|
|
this.keyInput.spd = 1;
|
||
|
|
this.aiFindPitch();//this.keyInput.pitch = 1;
|
||
|
|
//console.log("left")
|
||
|
|
finishedDodging = false;
|
||
|
|
}
|
||
|
|
else if (avoid[2] > 0) {//left
|
||
|
|
//this.input.roll = 1;
|
||
|
|
keyThink.roll = 1;
|
||
|
|
this.ai.prefRoll = 1;
|
||
|
|
this.input.spd = this.acceleration;
|
||
|
|
this.keyInput.spd = 1;
|
||
|
|
this.aiFindPitch();//this.keyInput.pitch = 1;
|
||
|
|
//console.log("right")
|
||
|
|
finishedDodging = false;
|
||
|
|
}
|
||
|
|
if (finishedDodging === true) {
|
||
|
|
this.ai.navState = this.ai.navStates.seek;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
this.aiFindRoll(keyThink.roll);
|
||
|
|
}
|
||
|
|
|
||
|
|
aiFindRoll(_thinkRoll) {
|
||
|
|
if (_thinkRoll !== 0) {
|
||
|
|
if (_thinkRoll > 0) {
|
||
|
|
if (this.keyInput.roll < 1) {
|
||
|
|
this.keyInput.roll += 0.02 * this.scene.dt;
|
||
|
|
this.keyInput.roll = Math.min(this.keyInput.roll, 1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (_thinkRoll < 0) {
|
||
|
|
if (this.keyInput.roll > -1) {
|
||
|
|
this.keyInput.roll -= 0.02 * this.scene.dt;
|
||
|
|
this.keyInput.roll = Math.max(this.keyInput.roll, -1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
if (this.keyInput.roll < 0) {
|
||
|
|
this.keyInput.roll += 0.1 * this.scene.dt;
|
||
|
|
this.keyInput.roll = Math.min(this.keyInput.roll, 0);
|
||
|
|
}
|
||
|
|
if (this.keyInput.roll > 0) {
|
||
|
|
this.keyInput.roll -= 0.1 * this.scene.dt;
|
||
|
|
this.keyInput.roll = Math.max(this.keyInput.roll, 0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
this.input.roll = this.keyInput.roll;
|
||
|
|
}
|
||
|
|
|
||
|
|
aiFindPitch(_allowHeat = true) {
|
||
|
|
//let distToPerfectPitchPlanned = 64 - (32 * this.curveAmt) - (32 * this.pitch.current) - (this.pitch.current * 32);
|
||
|
|
//this.distToPerfectPitch = Math.max(-64, Math.min(distToPerfectPitchPlanned, 64));
|
||
|
|
|
||
|
|
if (_allowHeat === true) {
|
||
|
|
if (this.distToPerfectPitch > 1) {
|
||
|
|
this.keyInput.pitch += 0.001 * this.scene.dt;
|
||
|
|
} else {
|
||
|
|
this.keyInput.pitch -= 0.01 * this.scene.dt;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
if (this.distToPerfectPitch > 32) {
|
||
|
|
this.keyInput.pitch += 0.001 * this.scene.dt;
|
||
|
|
} else {
|
||
|
|
this.keyInput.pitch -= 0.01 * this.scene.dt;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|