import GL_Vec3 from "../../additionalMath/gl_vec3.js"; import PanelEndOfRace from "../../ui/panelEndOfRace.js"; import PanelEndOfCanyon from "../../ui/panelEndOfCanyon.js"; import PanelEscapeMenu from "../../ui/panelEscapeMenu.js"; import PanelRaceTutorial from "../../ui/panelRaceTutorial.js"; import PanelWelcome from "../../ui/panelWelcome.js"; import UI from "../../ui/racing/ui.js"; import ShipManager from "../racing/shipManager.js"; import TrackBuilder from "../racing/trackBuilder.js"; import Transform from "../transform.js"; export default class LevelQuadRingsTest { constructor(_scene, _params) { this.scene = _scene; this.params = _params; this.startFromHangar = this.params.startFromHangar; //set false if switching track without going back to hangar this.states = { startFromHangar: 0, countDown: 1, race: 2, pause: 3, //finished: 4,//maybe not needed as race and pause needs to happen still }; this.state = this.states.countDown; this.raceModes = { hotlap: 0, //get the best time (practice?) timetrial: 1, //arcade timer runs down and gets extra time when passing checkpoints or collected obstacle: 2, //gain points by near misses qualifying: 3, //three laps to set the fastest time qualifyingTraffic: 4, //same as above but with enemies that could impede you grandprix: 5, //normal race against the ai canyon: 6, //1v1 rack up points as the hunter by slipstreaming, lose them when being hunted knockout: 7, //each lap or after a timer, the last position is elimated hunt: 8, //runout the enemies (sprint track?) passthebomb: 9, //pass the bomb by slipstream to someone before the timer runs out crazy: 10, //each lap you have to crack a harder time overtake: 11, //get pointns for each overtake within a time, tutorial: 99, }; this.raceMode = this.params.raceMode !== undefined ? this.params.raceMode : 5; //this.raceMode = this.raceModes.canyon;//hotlap grandprix canyon this.raceModeData = {}; this.maxLaps = this.params.maxLaps !== undefined ? this.params.maxLaps : 5; this.stopAfterRingId = this.params.stopAfterRingId !== undefined ? this.params.stopAfterRingId : 0; this.countdown = { current: Date.now(), start: Date.now(), texts: ["THREE", "TWO", "ONE", "GO!", ""], step: 0, knockout: 0, go: false, }; this.finishedRace = false; this.grid = []; this.tutorialStep = -1; this.tutorialHoldVar = 0; this.tutorialHoldVarMax = 500; //this.scene.player.jumpToPosition({ x: 0, y: 0, z: -128 }); //this.scene.player.dir.pitch = 0; this.scene.player = this.scene.playerGame; this.scene.cam = this.scene.camGame; /* console.log("--DATA--") console.log(this.scene.player); console.log(this.scene.player.id); console.log(this.scene.player.mode); console.log(this.scene.player.moveMode); */ //INFOif no difference try locking the mouse / well maybe unlocking? //this.scene.player.setMode(PLAYERMODE.INTERACT); //this.scene.player.panel = new PanelWelcome(this.scene); this.trackBuilder = new TrackBuilder(this.scene, this); this.ui = new UI(this.scene, this); this.camRig = this.scene.geometryController.loadModel("hoverShip", "modDebugTile", { x: 0, y: 64, z: 256 }); this.camRig.quadDate = []; //this.camRig.flags.draw = true; this.playerShip = new ShipManager(this.scene, this, 999, true, false, this.params.playerShipModel); this.playerShip.name = "Player"; this.playerShip.ship.data = { slipstreamLength: 2024, name: "Player" }; this.playerIsShip = true; this.ui.registerShip(this.playerShip); this.aiShips = []; switch (this.raceMode) { case this.raceModes.hotlap: case this.raceModes.timetrial: case this.raceModes.obstacle: case this.raceModes.qualifying: break; case this.raceModes.qualifyingTraffic: case this.raceModes.grandprix: case this.raceModes.knockout: case this.raceModes.passthebomb: let names = ["Bonez", "Foxxy", "Glaze", "Roki", "Hog", "Roach", "Scooter", "Jay"]; //let names = ["Jay", "Jay", "Jay", "Jay", "Jay", "Jay", "Jay", "Jay"]; let colors = ["Yellow", "Blue", "Green", "Red"]; for (let i = 0; i < 7; i++) { this.aiShips.push(new ShipManager(this.scene, this, i, false, true)); this.aiShips[this.aiShips.length - 1].autopilot = true; this.aiShips[this.aiShips.length - 1].ai.prefRoll = Math.random() > 0.5 ? -1 : 1; this.aiShips[this.aiShips.length - 1].speedMax += -0.5 + Math.random() * 2; this.aiShips[this.aiShips.length - 1].rollAcceleration += Math.random() * 0.01; this.aiShips[this.aiShips.length - 1].acceleration += Math.random() * 0.01; this.aiShips[this.aiShips.length - 1].setShipColor(colors[i % 4]); this.aiShips[this.aiShips.length - 1].name = names[i]; this.aiShips[this.aiShips.length - 1].ship.data = { slipstreamLength: 2024, name: names[i] }; //add ship to the ui (minimap) //this.ui.registerShip(this.aiShips[this.aiShips.length - 1]); } break; case this.raceModes.canyon: this.aiShips.push(new ShipManager(this.scene, this, 0, false, true, "modHoverCarTinnemann00")); this.aiShips[this.aiShips.length - 1].autopilot = true; this.aiShips[this.aiShips.length - 1].ai.prefRoll = Math.random() > 0.5 ? -1 : 1; //this.aiShips[this.aiShips.length - 1].speedMax += -0.5 + (Math.random() * 2); //this.aiShips[this.aiShips.length - 1].speedMax += 1; this.aiShips[this.aiShips.length - 1].rollAcceleration += 0.01; this.aiShips[this.aiShips.length - 1].rollSpeedMax += 0.1; this.aiShips[this.aiShips.length - 1].rollSpeedMin -= 0.1; this.aiShips[this.aiShips.length - 1].acceleration += 0.01; this.aiShips[this.aiShips.length - 1].setShipColor("Yellow"); this.aiShips[this.aiShips.length - 1].name = "Roki"; this.aiShips[this.aiShips.length - 1].ship.data = { slipstreamLength: 2024, name: "Roki" }; //add ship to the ui (minimap) //this.ui.registerShip(this.aiShips[this.aiShips.length - 1]); this.raceModeData = { playerIsHunter: true, points: { overall: 0, rounds: [0, 0] } } break; case this.raceModes.hunt: break; case this.raceModes.crazy: break; case this.raceModes.tutorial: this.aiShips.push(new ShipManager(this.scene, this, 0, false, true, "modHoverCarTinnemann00")); //modHoverCarWipeOutStyle this.aiShips[this.aiShips.length - 1].autopilot = true; this.aiShips[this.aiShips.length - 1].ai.prefRoll = Math.random() > 0.5 ? -1 : 1; //this.aiShips[this.aiShips.length - 1].speedMax = 8; this.aiShips[this.aiShips.length - 1].rollAcceleration += Math.random() * 0.01; this.aiShips[this.aiShips.length - 1].acceleration += Math.random() * 0.01; this.aiShips[this.aiShips.length - 1].setShipColor("Yellow"); this.aiShips[this.aiShips.length - 1].name = "Roki"; this.aiShips[this.aiShips.length - 1].ship.data = { slipstreamLength: 2024, name: "Roki", conversation: { fileName: "diaDemoRaceTutorial", treePosition: 0, }, }; //add ship to the ui (minimap) //this.ui.registerShip(this.aiShips[this.aiShips.length - 1]); break; default: break; } for (let ai of this.aiShips) { ai.character = this.scene.characters.filter(el => el.name === ai.name)[0]; this.ui.registerShip(ai); } this.camOffset = { pos: { x: 0, y: 0, z: 0 }, dir: { yaw: 0, pitch: 0, roll: 0, spd: { yaw: 0.04, pitch: 0.04, roll: 0.04 } }, target: { pos: { x: 0, y: 0, z: 0 }, dir: { yaw: 0, pitch: 0, roll: 0, spd: { yaw: 0.04, pitch: 0.04, roll: 0.04 } }, }, virtualMouse: { delta: { x: 0, y: 0 }, lastPos: { x: 0, y: 0 }, pos: { x: 0, y: 0 }, }, }; this.situation = { actions: { hit: { //player bumping into ai who: "", priority: 0, time: 0 }, slipstream: { //player slipstreaming ai who: "", priority: 0, time: 0 }, slipstreamed: { //ai slipstreaming behind player who: "", priority: 0, time: 0 }, gainPosition: { //player overtakes ai who: "", priority: 0, time: 0 }, loosePosition: { //ai overtakes player who: "", priority: 0, time: 0 }, mishap: { //player crashes near ai who: "", priority: 0, time: 0 }, win: { //ai wins who: "", priority: 1, time: 0 }, loose: { //player wins / rival looses who: "", priority: 0, time: 0 } } } //IMPORTANT for building models //this.toModel = this.createDefaultRing(); this.toModel = this.scene.geometryController.loadModel("ring DEFAULT", "modRingD64R128RoundCanyon", { x: -512, y: 0, z: 0 }); this.toModel.flags.draw = true; /*for(let j = 1 ; j < 8 ; j++){ for(let i = 0; i < 20 ; i++){ let q = this.toModel.quadData[i]; this.toModel.addQuadFromData({ type: "quad", frame: q.frame, texture: "atlasAll", position: { x: 0, y: 0, z: 0 }, points: [ {//hinten rechts x: q.points[0].x, y: q.points[0].y, z: q.points[0].z + (j * 64) + 0 },{//hinten links x: q.points[1].x, y: q.points[1].y, z: q.points[1].z + (j * 64) + 0 },{//vorne links x: q.points[2].x, y: q.points[2].y, z: q.points[2].z + (j * 64) + 0 },{//vorne rechts x: q.points[3].x, y: q.points[3].y, z: q.points[3].z + (j * 64) + 0 } ] }); } }*/ this.helpModel0 = this.scene.geometryController.loadModel("ring DEFAULT help 0", "modRingD64R128RoundCanyon", { x: -512, y: 0, z: 64 }); this.helpModel0.flags.draw = true; this.helpModel1 = this.scene.geometryController.loadModel("ring DEFAULT help 1", "modRingD64R128RoundCanyon", { x: -512, y: 0, z: 128 }); this.helpModel1.flags.draw = true; //this.helpModel2 = this.scene.geometryController.loadModel("ring DEFAULT help 2", "modRingD64R128", { x: -512, y: 0, z: 128 + 64 }); //this.helpModel2.flags.draw = true; //this.helpModel3 = this.scene.geometryController.loadModel("ring DEFAULT help 3", "modRingD64R128", { x: -512, y: 0, z: 128 + 128 }); //this.helpModel3.flags.draw = true; //this.helpModel4 = this.scene.geometryController.loadModel("ring DEFAULT help 4", "modRingD64R128", { x: -512, y: 0, z: 128 + 192}); //this.helpModel4.flags.draw = true; // //this.helpModel5 = this.scene.geometryController.loadModel("ring DEFAULT help 5", "modRingD64R128", { x: -512, y: 0, z: 320 + 64 }); //this.helpModel5.flags.draw = true; //this.helpModel6 = this.scene.geometryController.loadModel("ring DEFAULT help 6", "modRingD64R128", { x: -512, y: 0, z: 320 + 128 }); //this.helpModel6.flags.draw = true; //this.helpModel7 = this.scene.geometryController.loadModel("ring DEFAULT help 7", "modRingD64R128", { x: -512, y: 0, z: 320 + 192 }); //this.helpModel7.flags.draw = true; //this.helpModel1.rotateAroundAxis([0, 0, 1], Math.PI * 0.25) //this.helpModel2 = this.scene.geometryController.loadModel("ring DEFAULT help 3", "modRingD64R128Quadrat", { x: -512, y: 0, z: 128+64 }); //this.helpModel2.flags.draw = true; //preload Textures let textureArray0 = this.trackBuilder.textureArrays.canyon[0]; let textureArray1 = this.trackBuilder.textureArrays.canyon[0]; let textureArray2 = this.trackBuilder.textureArrays.canyon[0]; //let textureArray3 = this.trackBuilder.textureArrays.darkMetalRing[0]; for(let [i, t] of textureArray0.entries()){this.toModel.quadData[i].setTexture(t.texture, t.frame);} for(let [i, t] of textureArray1.entries()){this.helpModel0.quadData[i].setTexture(t.texture, t.frame);} for(let [i, t] of textureArray2.entries()){this.helpModel1.quadData[i].setTexture(t.texture, t.frame);} //for(let [i, t] of textureArray3.entries()){this.helpModel2.quadData[i].setTexture(t.texture, t.frame);} //IMPORTANT end of builder //debug change track this.scene.keys.m.on( "up", (_key, _event) => { if (this.scene.editor.enabled === false) { let tid = this.trackBuilder.currentTrackId + 1; if (tid >= 4) { tid = 0; } this.loadTrack(tid); //restart all ships for (let ai of this.aiShips) { ai.lapTimes = []; ai.fastestLap = 0; ai.last.fastestLap = 0; } this.playerShip.lapTimes = []; this.playerShip.fastestLap = 0; this.playerShip.last.fastestLap = 0; this.playerShip.autopilot = false; this.ui.show(); this.finishedRace = false; } }, this, ); //get in and out of craft this.scene.keys.z.on( "up", (_key, _event) => { if (this.scene.editor.enabled === false) { this.playerIsShip = !this.playerIsShip; if (this.playerIsShip === false) { this.scene.player = this.scene.playerWalk; this.scene.cam = this.scene.camWalk; //this.scene.player.jumpToPosition({ x: 304, y: 512 - 56, z: -160 }); this.scene.player.jumpToPosition({ x: this.playerShip.shipAnchor.pos.x, y: this.playerShip.shipAnchor.pos.y, z: this.playerShip.shipAnchor.pos.z }); this.scene.player.dir.pitch = 0; } else { this.scene.player = this.scene.playerGame; this.scene.cam = this.scene.camGame; } } }, this, ); //toggle autopilot this.scene.keys.space.on( "up", (_key, _event) => { if (this.scene.editor.enabled === false) { this.playerShip.autopilot = !this.playerShip.autopilot; } }, this, ); //hide all models for (let s of this.trackBuilder.spline) { if (s.model !== null) { s.model.flags.draw = false; } } //debug laoding screen this.graLoading = this.scene.add.graphics(); this.graLoading.fillStyle(0x000000, 0.9); this.graLoading.fillRect(this.scene.left, this.scene.top, this.scene.game.config.width, this.scene.game.config.height); this.graLoading.depth = 9998; this.graLoading.alpha = 0; this.txtLoading = this.scene.add.bitmapText(0, 0, "uiFont", "LOADING TRACK", 14, 0).setOrigin(0.5).setLetterSpacing(0); this.txtLoading.depth = 9999; this.txtLoading.alpha = 0; this.testCounter = 0; this.testPic = 0; //add hangar this.hangarDoorLeft = this.scene.geometryController.loadModel("hangar door left", "modHangarDoor", { x: -64, y: 468 - 1, z: 128 }); // x: 48, y: 56, z: 96 + 188 this.hangarDoorLeft.flags.draw = true; this.hangarDoorRight = this.scene.geometryController.loadModel("hangar door right", "modHangarDoor", { x: 64, y: 468 - 1, z: 128 }); // x: 48, y: 56, z: 96 + 188 this.hangarDoorRight.flags.draw = true; this.hangarDoorRight.rotateAroundAxis([0, -1, 0], Math.PI); this.hangarMain = this.scene.geometryController.loadModel("hangar main", "modHangarMain", { x: -176, y: 568, z: 128 - 48 }); this.hangarMain.flags.draw = true; //jump down id you start from hangar if (this.startFromHangar === true) { this.state = this.states.startFromHangar; //INFO hacky way of preventing lookaround instead of pitching this.scene.player.setMode(PLAYERMODE.INTERACT); this.playerShip.splineId = 1; //let splg = this.trackBuilder.spline[this.playerShip.splineId]; this.playerShip.gondula.jumpToPosition({ x: 0, y: 0 + 468 - 128 - 96, z: 64 }); this.playerShip.shipAnchor.jumpToPosition({ x: this.playerShip.gondula.pos.x, y: this.playerShip.gondula.pos.y + 96, z: this.playerShip.gondula.pos.z }, true); this.playerShip.ship.jumpToPosition({ x: this.playerShip.gondula.pos.x, y: this.playerShip.gondula.pos.y + 96, z: this.playerShip.gondula.pos.z }, true); //this.scene.editor.toggleEditor(); } else { //this.playerShip.camera = this.playerShip.cameras.thirdPersonFollow; this.playerShip.camera = OPTIONS.config.preferredCam; //INFO this code is also used in listenToSwitchCamera if (this.playerShip.camera === 1 || this.playerShip.camera === 2) { if (this.playerShip.ship.flags.draw === true) { this.playerShip.ship.flags.draw = false; this.playerShip.ship.flags.drawn = false; for (let q of this.playerShip.ship.quadData) { q.clearQuads(); } //this.playerShip.ship.depthMod = -100000; } } else { if (this.playerShip.ship.flags.draw === false) { this.playerShip.ship.flags.draw = true; } //this.playerShip.ship.depthMod = 48; } } this.state = this.states.startFromHangar; if (this.params.startFromHangar === false) { this.state = this.states.countDown; } //todo: this lags a lot when loading in (because of the tracklength actually) but its not elegant wwhen coming from the hangar and not moving smoothly this.loadTrack(9999); setTimeout(() => { this.loadTrack(this.params.track); if (this.params.startFromHangar === false) { this.state = this.states.countDown; } }, 10); /* setInterval(() => { console.log(this.countdown.step + " : " + this.countdown.current); }, 1000); */ //prepare music tracks in custom race this.musicTracks = [this.scene.soundManager.musicAcidLoop00, this.scene.soundManager.musicAcidLoop01]; this.musicTrack = this.musicTracks[Math.floor(Math.random() * this.musicTracks.length)]; } update(_delta) { this.ui.txtDelta.setText(String(this.scene.dt.toFixed(2))); this.resetSituation(); if (this.musicTrack.howlGroup.playing() === false) { this.scene.soundManager.playSound(this.musicTrack); } //general update this.playerShip.update(); //setup pos arr if (this.finishedRace === false) { this.grid = []; this.grid.push(this.playerShip); } for (let ai of this.aiShips) { ai.update(); if (this.finishedRace === false) { this.grid.push(ai); } } if (this.finishedRace === false) { let positionPrevious = this.playerShip.position; this.grid.sort((a, b) => { return b.raceProgress - a.raceProgress; }); for (let [i, shipManager] of this.grid.entries()) { shipManager.position = i; } if (this.playerShip.position !== -1) { let positionChange = this.playerShip.position - positionPrevious; if (positionChange < 0 && this.playerShip.position < this.grid.length - 1) {//gained position(s) this.situation.actions.gainPosition.who = this.grid[this.playerShip.position + 1].ship.data.name; //console.log(this.situation.actions.gainPosition.who) this.situation.actions.gainPosition.priority += 1; } if (positionChange > 0 && this.playerShip.position > 0) {//lost positions this.situation.actions.loosePosition.who = this.grid[this.playerShip.position - 1].ship.data.name; //console.log(this.situation.actions.loosePosition.who) this.situation.actions.loosePosition.priority += 1; } } } //update ui for laptimes and position this.ui.txtLapTime.setText("LAP: " + timeToLapTime(this.playerShip.elapsedTime)); if (this.playerShip.position > -1) { let affix = "th"; if (this.playerShip.position === 0) { affix = "ST"; } if (this.playerShip.position === 1) { affix = "ND"; } if (this.playerShip.position === 2) { affix = "RD"; } this.ui.txtLapPos.setText("POS: " + String(this.playerShip.position + 1) + affix); } if (this.scene.player === this.scene.playerGame) { if (this.hangarDoorRight.pos.x > 0) { this.hangarDoorLeft.jumpToPosition({ x: Math.min(0, this.hangarDoorLeft.pos.x + 0.1 * this.scene.dt), y: this.hangarDoorLeft.pos.y, z: this.hangarDoorLeft.pos.z }, true); this.hangarDoorRight.jumpToPosition( { x: Math.max(0, this.hangarDoorRight.pos.x - 0.1 * this.scene.dt), y: this.hangarDoorRight.pos.y, z: this.hangarDoorRight.pos.z }, true, ); } else { this.scene.geometryController.destroyModelById(this.hangarMain.id); this.scene.geometryController.destroyModelById(this.hangarDoorLeft.id); this.scene.geometryController.destroyModelById(this.hangarDoorRight.id); } switch (this.state) { case this.states.startFromHangar: if (this.trackBuilder.spline.length > 0) { this.updateFromHangar(); } break; case this.states.countDown: //INFO: this prevents it crashing when loading in "directly" to a race if (this.trackBuilder.spline.length > 0) { this.updateCountDown(); } break; case this.states.race: if (this.trackBuilder.spline.length > 0) { this.updateRacing(); //update tutorial if in tutorial obviously if (this.raceMode === this.raceModes.tutorial) { this.updateTutorial(); } else if (this.raceMode === this.raceModes.canyon) { if (this.finishedRace === false) { this.updateCanyon(); } } //if (this.scene.quartJustChanged === true) { this.assessSituation(); //} } break; default: break; } } else { //todo: use the ui.hide function when exiting craft /* this.ui.txtBestLapTime.alpha = 0; this.ui.txtLastLapTime.alpha = 0; this.ui.txtLapTime.alpha = 0; this.ui.txtDelta.alpha = 0; this.ui.txtHelper.alpha = 0; */ } //this.scene.player.jumpToPosition({ x: this.ref.pos.x + (this.ref.transform.forward.x * -128), y: this.ref.pos.y + (this.ref.transform.forward.y * -128), z: this.ref.pos.z + (this.ref.transform.forward.z * -128) }, true); this.ui.update(_delta); if (INPUTS.btnStickLeft.justPressed === true && this.scene.player.panel === null && this.scene.paused === false) { this.ui.toggleVisibility(); } if (this.scene.keys.escape.isDown || INPUTS.btnStart.justPressed) { if (this.scene.player.panel === null) { //todo: fix auto clicking on back when it was oopen once and the mosue is still on the back button position (locked) /*if(this.scene.input.mouse.locked === true){ this.scene.hand.setMouseLock(false); }*/ this.ui.hide(); this.scene.player.hideUI(); this.scene.player.setMode(PLAYERMODE.INTERACT); this.scene.player.panel = new PanelEscapeMenu(this.scene, this, this.state); this.scene.paused = true; this.state = this.states.pause; //todo stop engine sound this.scene.soundManager.stopSound(this.scene.soundManager.engineSound); //this.scene.soundManager.stopSound(this.scene.soundManager.engineRotorSound); this.scene.soundManager.stopSound(this.scene.soundManager.scrapeSound); this.scene.soundManager.stopSound(this.scene.soundManager.heatWarningSound); } } //hide ui for editor and photomode usage if (this.state !== this.states.pause) { if (this.scene.editor.enabled === true) { this.ui.hide(); } else { if (this.finishedRace === false && this.raceMode !== this.raceModes.tutorial) { this.ui.show(); } } } } updateFromHangar() { this.listenToSwitchCamera(); this.toggleDrawByViewDistance(); this.playerShip.updateFromHangar(); for (let ai of this.aiShips) { ai.updateFromHangar(); } //console.log(this.playerShip.gondula.pos.y) if (this.playerShip.gondula.pos.y <= 0) { this.playerShip.camera = this.playerShip.cameras.thirdPersonFollow; //this.state = this.states.countDown; } this.moveCamera(); } updateCountDown() { //count down if (this.countdown.step < 5) { if (this.countdown.step < 4) { this.ui.txtCountdown.alpha -= this.ui.txtCountdown.alpha * (0.05 * this.scene.dt); } else { //fade GO out slower then the numbers this.ui.txtCountdown.alpha -= this.ui.txtCountdown.alpha * (0.01 * this.scene.dt); } //stall countdown if coming from hangar, to ensure that the player arrives in the tunnel if (this.playerShip.gondula.pos.y < 100) { //todo: make this a eud distance from ref spline this.countdown.current = Date.now() - this.countdown.start; } else { this.countdown.start = Date.now(); } //check if a second has passed and show countdown if (this.countdown.current - this.countdown.step * 1000 >= 1000) { this.ui.txtCountdown.setText(this.countdown.texts[this.countdown.step]); this.ui.txtCountdown.alpha = 1; this.countdown.step += 1; this.scene.soundManager.playSpecificSound(this.scene.soundManager.raceAnnouncer, this.countdown.step); if (this.countdown.step === 4) { this.state = this.states.race; if (this.raceMode === this.raceModes.tutorial && this.tutorialStep === -1) { this.cycleTutorial(); } } } } this.listenToSwitchCamera(); this.toggleDrawByViewDistance(); if (this.startFromHangar === true) { this.playerShip.updateFromHangar(); for (let ai of this.aiShips) { ai.updateFromHangar(); } let d = eud.distance( [this.playerShip.gondula.pos.x, this.playerShip.gondula.pos.y, this.playerShip.gondula.pos.z], [this.trackBuilder.spline[this.playerShip.splineId].x, this.trackBuilder.spline[this.playerShip.splineId].y, this.trackBuilder.spline[this.playerShip.splineId].z], ); if (d <= this.scene.dt) { this.playerShip.camera = this.playerShip.cameras.thirdPersonFollow; //this.state = this.states.countDown; } } else { if (this.trackBuilder.spline.length > 0) { this.playerShip.updateRacing(); for (let ai of this.aiShips) { ai.updateRacing(); } } } //move camera this.moveCamera(); } updateRacing() { //finish count down if (this.countdown.step < 5) { this.ui.txtCountdown.alpha -= this.ui.txtCountdown.alpha * (0.01 * this.scene.dt); this.countdown.current = Date.now() - this.countdown.start; if (this.countdown.current - this.countdown.step * 1000 >= 1000) { this.ui.txtCountdown.setText(this.countdown.texts[this.countdown.step]); this.ui.txtCountdown.alpha = 1; this.countdown.step += 1; if (this.countdown.step === 5) { this.ui.txtCountdown.alpha = 0; } } } //listen to input this.listenToSwitchCamera(); //how many rings should be rendered! viewdist this.toggleDrawByViewDistance(); for (let o of this.trackBuilder.obstacles) { if (o.flags.update === true) { o.update(); } } this.playerShip.updateRacing(); for (let ai of this.aiShips) { ai.updateRacing(); } //update player ui if (this.playerShip.temp >= 999) { this.ui.txtLower.setText("!!!OVERHEAT WARNING!!!"); } else { this.ui.txtLower.setText(""); } //this.ui.txtHelper.setText("SPD: " + String(this.playerShip.speed.toFixed(2)) + " BON: " + String(this.playerShip.speedBonus.toFixed(2)) + " TMP: " + String(Math.floor(this.playerShip.temp)) + " ID: " + String(zeroPad(this.playerShip.splineId, 6))); this.ui.txtHelper.setText( "BON: " + String(this.playerShip.speedBonus.toFixed(2)) + " TMP: " + String(Math.floor(this.playerShip.temp)) + " ID: " + String(zeroPad(this.playerShip.splineId, 6)), ); this.ui.txtTachoSpd.setText(String(Math.floor(this.playerShip.speed * 10)) + " SPD"); //this.ui.tachoHighlight.x = (this.scene.game.config.width * -0.5) + 16 - 133 + Math.min(133, (133 * (this.playerShip.speed / this.playerShip.speedMax))); this.ui.tachoHighlight.x = this.scene.game.config.width * -0.5 + 16 - 133 + Math.min(133, 133 * ((this.playerShip.speed + 0) / (this.playerShip.speedMax + this.playerShip.speedBonus))); //ref: (this.speed + this.speedBonus) / (this.speedMax + this.speedBonus) this.ui.tachoOverspeed.x = this.scene.game.config.width * -0.5 + 16 - 133 + Math.min(133, 133 * ((this.playerShip.speed + this.playerShip.speedBonus) / (this.playerShip.speedMax + this.playerShip.speedBonus))); let curveDelta = this.playerShip.last.curveAmt - this.playerShip.curveAmt; //this.ui.txtLower.setText("AMT: " + String(this.playerShip.curveAmt.toFixed(4)) + " DEL: " + String(curveDelta.toFixed(4)) + " GOD: " + String(curveDelta < 0)); //sign for rad (roll of ship / gondula relative to track ring transform) let sig = 1; if (this.playerShip.angleToTrackMod >= 0) { sig = 1; } else { sig = -1; } //get player rotation on track - a pi/8 offset for the 16 segments of the collision circles let rad = (this.playerShip.angleToTrack * -1 + 1) * sig * (Math.PI * 0.5) - 0.39269; //console.log(rad) this.ui.txtLower.setText("AMT: " + String(this.playerShip.curveAmt.toFixed(4)) + " DEL: " + String(curveDelta.toFixed(4)) + " RAD: " + String(rad)); //push all obstacles in range to lit array with their 0-15 range of roll if (this.scene.quartJustChanged === true) { let lit = []; for (let o of this.trackBuilder.obstacles) { if (o.data.id < this.playerShip.splineId + 99 && o.data.id >= this.playerShip.splineId && o.data.ignoreRadar === false) { let dist = Math.floor(((o.data.id - this.playerShip.splineId) / 100) * 6); if (dist > 5) { dist -= 6; } if (dist < 0) { dist += 6; } //todo: add rolls inbetween obstacle and player to the calculation let diff = rad - (o.data.roll === undefined ? o.data.angle : o.data.angle + o.data.roll); let toSeg = Math.floor((diff + Math.PI) / (Math.PI / 8)); //add offset and additional blockers if (toSeg > 15) { toSeg -= 16; } if (toSeg < 0) { toSeg += 16; } //console.log(toSeg) lit.push({ obstacle: o, diff: diff, seg: toSeg, dist: dist }); } } for (let q of this.ui.dangerCirclets) { for (let s of q) { s.alpha = 0; } } for (let l of lit) { //console.log(l.seg, l.dist) if (l.seg >= 0 && l.seg < 16 && l.dist >= 0 && l.dist <= 5) { let tos = []; tos.push(l.seg); tos[0] += l.obstacle.data.collisionRadar.offset; for (let a of l.obstacle.data.collisionRadar.additionals) { tos.push(tos[0] + a); } for (let t of tos) { let tCorrected = t; if (tCorrected > 15) { tCorrected -= 16; } if (tCorrected < 0) { tCorrected += 16; } this.ui.dangerCirclets[tCorrected][l.dist].alpha = 1; } //let s = this.ui.dangerCirclets[l.seg][l.dist]; //s.alpha = 1; } } } this.ui.pitchLimit.y = this.ui.pitchPosY + 64 - 32 * this.playerShip.curveAmt - 32 * this.playerShip.pitch.current; //ship sound if (this.state !== this.states.pause) { if (this.scene.soundManager.engineSound.howlGroup.playing() === false) { this.scene.soundManager.playSound(this.scene.soundManager.engineSound); //this.scene.soundManager.playSound(this.scene.soundManager.engineRotorSound); } else { this.scene.soundManager.engineSound.howlGroup.rate(0.1 + 0.9 * Math.min(1, this.playerShip.speed / this.playerShip.speedMax)); //this.scene.soundManager.engineRotorSound.howlGroup.rate(0.1 + (0.9 * Math.min(1, (this.playerShip.speed + this.playerShip.speedBonus) / (this.playerShip.speedMax + this.playerShip.speedBonus)))); } if (this.playerShip.scraping === true && this.finishedRace === false) { if (this.scene.soundManager.scrapeSound.howlGroup.playing() === false) { this.scene.soundManager.playSound(this.scene.soundManager.scrapeSound); } } else { this.scene.soundManager.stopSound(this.scene.soundManager.scrapeSound); } if (this.playerShip.temp >= 900 && this.finishedRace === false) { if (this.scene.soundManager.heatWarningSound.howlGroup.playing() === false) { this.scene.soundManager.playSound(this.scene.soundManager.heatWarningSound); } } else { this.scene.soundManager.stopSound(this.scene.soundManager.heatWarningSound); } } //move camera this.moveCamera(); /* INFO keep an eye out for this if its buggy when not used also the function nthat hides it if(this.finishedRace === false){ this.ui.txtBestLapTime.alpha = 1; this.ui.txtLastLapTime.alpha = 1; this.ui.txtLapTime.alpha = 1; this.ui.txtDelta.alpha = 1; this.ui.txtHelper.alpha = 1; } */ } updateCanyon() { //console.log(this.playerShip.splineId - this.aiShips[0].splineId); - points = behind if (this.raceModeData.playerIsHunter === true) { let playerBehind = true; let amt = this.playerShip.splineId - this.aiShips[0].splineId; if (this.aiShips[0].crossedFinish === false) { amt -= this.trackBuilder.spline.length; } if (this.playerShip.lapTimes.length === this.aiShips[0].lapTimes.length) { if (amt > 0) { playerBehind = false; } amt += 40; if (this.playerShip.slipstreaming === true) { amt *= 1.5; } if (playerBehind === false) { amt *= 2; } } else { amt = 0; } if (amt < 0) { amt = 0; } amt = Math.floor(amt); this.raceModeData.points.overall += amt; this.raceModeData.points.rounds[0] += amt; this.ui.txtBestLapTime.setText(""); this.ui.txtLastLapTime.setText(`DLT: ${amt}`); this.ui.txtLapTime.setText(`PTS: ${this.raceModeData.points.overall}`); } else { let playerBehind = false; let amt = this.aiShips[0].splineId - this.playerShip.splineId; if (this.playerShip.crossedFinish === false) { amt -= this.trackBuilder.spline.length; } if (this.playerShip.lapTimes.length === this.aiShips[0].lapTimes.length) { if (amt > 0) { playerBehind = true; } amt += 40; if (this.aiShips[0].slipstreaming === true) { amt *= 1.5; } if (playerBehind === true) { amt *= 2; } } else { amt = 0; } if (amt < 0) { amt = 0; } amt = Math.floor(amt); this.raceModeData.points.overall -= amt; this.raceModeData.points.rounds[1] += amt; this.ui.txtBestLapTime.setText(""); this.ui.txtLastLapTime.setText(`DLT: ${amt}`); this.ui.txtLapTime.setText(`PTS: ${this.raceModeData.points.overall}`); } if (this.aiShips[0].splineId - this.playerShip.splineId > 44) { this.aiShips[0].speedMax *= 0.9; } else { this.aiShips[0].speedMax = 16; } } startNewCanyon() { this.ui.txtBestLapTime.setText(`POT: ${this.raceModeData.points.overall}`); if (this.playerShip.lapTimes.length >= this.maxLaps) { this.finishedRace = true; } if (this.finishedRace === false) { //pause and show mid result, result screen will soft restart the race for second round this.state = this.states.pause; this.scene.soundManager.stopSound(this.scene.soundManager.engineSound); //this.scene.soundManager.stopSound(this.scene.soundManager.engineRotorSound); this.scene.soundManager.stopSound(this.scene.soundManager.scrapeSound); this.scene.soundManager.stopSound(this.scene.soundManager.heatWarningSound); this.ui.hide(); //show mid results this.scene.player.hideUI(); this.scene.player.setMode(PLAYERMODE.INTERACT); this.scene.player.panel = new PanelEndOfCanyon(this.scene, this, this.state); } if (this.finishedRace === true && this.scene.player.panel === null) { //end for real now this.playerShip.autopilot = true; this.ui.hide(); //show end results this.scene.player.hideUI(); this.scene.player.setMode(PLAYERMODE.INTERACT); this.scene.player.panel = new PanelEndOfCanyon(this.scene, this, this.state); //if is demo? if (this.raceModeData.points.overall > 0) { //you won the race flagManager.setFlag("wonDemoRace", "true"); } flagManager.setFlag("demoProgress", "3"); } } startNewLap() { this.ui.txtLastLapTime.setText("LST: " + timeToLapTime(this.playerShip.elapsedTime)); let newRecord = false; let finalLap = false; if (this.playerShip.lapTimes.length + 1 === this.maxLaps) { finalLap = true; } if (this.playerShip.lapTimes.length >= this.maxLaps) { this.finishedRace = true; } let r = this.playerShip.lapTimes[this.playerShip.fastestLap]; let lapNo = this.playerShip.fastestLap + 1; this.ui.txtBestLapTime.setText("BST: " + timeToLapTime(r.time) + " [L" + lapNo + "]"); if (this.playerShip.fastestLap !== this.playerShip.last.fastestLap) { newRecord = true; } //make the correct sound (new record, finallap, knockedout etc) if (newRecord === true && finalLap === false) { this.scene.soundManager.playSpecificSound(this.scene.soundManager.raceAnnouncer, 0); } if (finalLap === true) { this.scene.soundManager.playSpecificSound(this.scene.soundManager.raceAnnouncer, 5); } // if (this.finishedRace === true && this.scene.player.panel === null) { this.playerShip.autopilot = true; this.ui.hide(); //show end results this.scene.player.hideUI(); this.scene.player.setMode(PLAYERMODE.INTERACT); this.scene.player.panel = new PanelEndOfRace(this.scene, this, this.state); if (this.raceMode === this.raceModes.canyon) { if (this.playerShip.position === 0) { //you won the race flagManager.setFlag("wonDemoRace", "true"); } flagManager.setFlag("demoProgress", "1"); } //this.scene.paused = true; //this.state = this.states.pause; //this.scene.soundManager.stopSound(this.scene.soundManager.engineSound); } } listenToSwitchCamera() { if (INPUTS.btnY.justReleased) { if (this.scene.editor.enabled === false) { this.playerShip.camera += 1; if (this.playerShip.camera >= 4) { this.playerShip.camera = 0; } //hide ship if in pov cams if (this.playerShip.camera === 1 || this.playerShip.camera === 2) { if (this.playerShip.ship.flags.draw === true) { this.playerShip.ship.flags.draw = false; this.playerShip.ship.flags.drawn = false; for (let q of this.playerShip.ship.quadData) { q.clearQuads(); } //this.playerShip.ship.depthMod = -100000; } } else { if (this.playerShip.ship.flags.draw === false) { this.playerShip.ship.flags.draw = true; } //this.playerShip.ship.depthMod = 48; } OPTIONS.config.preferredCam = this.playerShip.camera; } } } toggleDrawByViewDistance() { let frontLimit = Math.min(60, this.trackBuilder.spline.length); //60 let rearLimit = Math.min(62, this.trackBuilder.spline.length - 1); //59 for (let i = 0; i < frontLimit; i++) { let fsid = this.playerShip.splineId + i; if (fsid >= this.trackBuilder.spline.length) { fsid -= this.trackBuilder.spline.length; } if (this.trackBuilder.spline[fsid].model !== null) { this.trackBuilder.spline[fsid].model.flags.draw = true; } if (this.trackBuilder.spline[this.playerShip.splineId].model !== null) { this.trackBuilder.spline[this.playerShip.splineId].model.flags.draw = true; } } for (let i = 0; i < rearLimit; i++) { let rsid = this.playerShip.splineId - i; if (rsid < 0) { rsid += this.trackBuilder.spline.length; } if (i < rearLimit - 3) { if (this.trackBuilder.spline[rsid].model !== null) { this.trackBuilder.spline[rsid].model.flags.draw = true; } } else { if (this.trackBuilder.spline[rsid].model !== null) { this.trackBuilder.spline[rsid].model.flags.draw = false; } } } } moveCamera() { let gamepad = null; gamepad = navigator.getGamepads()[Math.max(0, gamepadsConnected - 1)]; if (gamepad === undefined) { gamepad = null; } //this.scene.cam.zoom = 800 - (this.playerShip.speed * 10); if (this.playerShip.speed + 1 >= this.playerShip.speedMax) { //todo: find better way to show speed when super fast and especially when slipstreaming and dodging closely //this.scene.cam.fov = 2.5 + Math.min(2, 2 - (this.playerShip.speedMax - this.playerShip.speed)); if (this.scene.cam.fov < 3) { this.scene.cam.fov += 0.1 * this.scene.dt; this.scene.cam.fov = Math.min(3, this.scene.cam.fov); } else { this.scene.cam.fov -= 0.01 * this.scene.dt; this.scene.cam.fov = Math.max(2.5, this.scene.cam.fov); } } else { if (this.scene.cam.fov > 2.5) { this.scene.cam.fov -= 0.1 * this.scene.dt; this.scene.cam.fov = Math.max(2.5, this.scene.cam.fov); } } switch (this.playerShip.camera) { case this.playerShip.cameras.thirdPersonFollow: this.scene.player.jumpToPosition( { x: this.playerShip.shipAnchor.pos.x + this.playerShip.shipAnchor.transform.forward.x * -160 + this.playerShip.shipAnchor.transform.up.x * (48 - (this.playerShip.flightRadiusUpperLimit - this.playerShip.flightRadius)), y: this.playerShip.shipAnchor.pos.y + this.playerShip.shipAnchor.transform.forward.y * -160 + this.playerShip.shipAnchor.transform.up.y * (48 - (this.playerShip.flightRadiusUpperLimit - this.playerShip.flightRadius)), z: this.playerShip.shipAnchor.pos.z + this.playerShip.shipAnchor.transform.forward.z * -160 + this.playerShip.shipAnchor.transform.up.z * (48 - (this.playerShip.flightRadiusUpperLimit - this.playerShip.flightRadius)), }, true, ); /*this.scene.player.jumpToPosition({ x: this.playerShip.gondula.pos.x + (this.playerShip.shipAnchor.transform.forward.x * -128) + (this.playerShip.shipAnchor.transform.up.x * -64), y: this.playerShip.gondula.pos.y + (this.playerShip.shipAnchor.transform.forward.y * -128) + (this.playerShip.shipAnchor.transform.up.y * -64), z: this.playerShip.gondula.pos.z + (this.playerShip.shipAnchor.transform.forward.z * -128) + (this.playerShip.shipAnchor.transform.up.z * -64) }, true);*/ break; case this.playerShip.cameras.firstPersonCockpit: //todo: pin the camera better to cockpit and do smth about the ship model this.scene.player.jumpToPosition( { x: this.playerShip.ship.pos.x + this.playerShip.ship.transform.forward.x * 16 + this.playerShip.ship.transform.up.x * 32, y: this.playerShip.ship.pos.y + this.playerShip.ship.transform.forward.y * 16 + this.playerShip.ship.transform.up.y * 32, z: this.playerShip.ship.pos.z + this.playerShip.ship.transform.forward.z * 16 + this.playerShip.ship.transform.up.z * 32, }, true, ); break; case this.playerShip.cameras.firstPersonBumper: this.scene.player.jumpToPosition( { x: this.playerShip.gondula.pos.x + this.playerShip.gondula.transform.forward.x * 72 + this.playerShip.ship.transform.up.x * 8 + this.playerShip.gondula.transform.up.x * -this.playerShip.flightRadius, y: this.playerShip.gondula.pos.y + this.playerShip.gondula.transform.forward.y * 72 + this.playerShip.ship.transform.up.y * 8 + this.playerShip.gondula.transform.up.y * -this.playerShip.flightRadius, z: this.playerShip.gondula.pos.z + this.playerShip.gondula.transform.forward.z * 72 + this.playerShip.ship.transform.up.z * 8 + this.playerShip.gondula.transform.up.z * -this.playerShip.flightRadius, }, true, ); break; case this.playerShip.cameras.thirdPersonOrbit: this.scene.player.jumpToPosition( { x: this.playerShip.shipAnchor.pos.x + this.scene.cam.transform.forward.x * -128 + this.playerShip.shipAnchor.transform.up.x * 32, y: this.playerShip.shipAnchor.pos.y + this.scene.cam.transform.forward.y * -128 + this.playerShip.shipAnchor.transform.up.y * 32, z: this.playerShip.shipAnchor.pos.z + this.scene.cam.transform.forward.z * -128 + this.playerShip.shipAnchor.transform.up.z * 32, }, true, ); break; default: this.scene.player.jumpToPosition( { x: this.playerShip.shipAnchor.pos.x + this.playerShip.shipAnchor.transform.forward.x * -128 + this.playerShip.shipAnchor.transform.up.x * 32, y: this.playerShip.shipAnchor.pos.y + this.playerShip.shipAnchor.transform.forward.y * -128 + this.playerShip.shipAnchor.transform.up.y * 32, z: this.playerShip.shipAnchor.pos.z + this.playerShip.shipAnchor.transform.forward.z * -128 + this.playerShip.shipAnchor.transform.up.z * 32, }, true, ); break; } /* //old direct sometimes jittery but working method this.scene.cam.transform.up.x = this.playerShip.shipAnchor.transform.up.x; this.scene.cam.transform.up.y = this.playerShip.shipAnchor.transform.up.y; this.scene.cam.transform.up.z = this.playerShip.shipAnchor.transform.up.z; this.scene.cam.transform.right.x = this.playerShip.shipAnchor.transform.right.x; this.scene.cam.transform.right.y = this.playerShip.shipAnchor.transform.right.y; this.scene.cam.transform.right.z = this.playerShip.shipAnchor.transform.right.z; this.scene.cam.transform.forward.x = this.playerShip.shipAnchor.transform.forward.x; this.scene.cam.transform.forward.y = this.playerShip.shipAnchor.transform.forward.y; this.scene.cam.transform.forward.z = this.playerShip.shipAnchor.transform.forward.z; //this.camOffset.dir.yaw += ((this.scene.player.dir.yaw - this.camOffset.dir.yaw) * 0.1); //this.camOffset.dir.pitch += ((this.scene.player.dir.pitch - this.camOffset.dir.pitch) * 0.1); this.camOffset.dir.yaw = this.scene.player.dir.yaw; this.camOffset.dir.pitch = this.scene.player.dir.pitch; this.scene.cam.rotateAroundAxis(this.playerShip.gondula.transform.toVectorArray(this.scene.cam.transform.up), this.camOffset.dir.yaw * -1); this.scene.cam.rotateAroundAxis(this.playerShip.gondula.transform.toVectorArray(this.scene.cam.transform.right), this.camOffset.dir.pitch); */ //INFO IMPORTANT move camRig vorher und slerp cam to rig //this coulod maybe work!! //todo: keep an eye on that - using .ship. instead of anchor seems cool but a bit too exagerated this.camRig.transform.up.x = this.playerShip.ship.transform.up.x; this.camRig.transform.up.y = this.playerShip.ship.transform.up.y; this.camRig.transform.up.z = this.playerShip.ship.transform.up.z; this.camRig.transform.right.x = this.playerShip.shipAnchor.transform.right.x; this.camRig.transform.right.y = this.playerShip.shipAnchor.transform.right.y; this.camRig.transform.right.z = this.playerShip.shipAnchor.transform.right.z; this.camRig.transform.forward.x = this.playerShip.ship.transform.forward.x; this.camRig.transform.forward.y = this.playerShip.ship.transform.forward.y; this.camRig.transform.forward.z = this.playerShip.ship.transform.forward.z; if (this.playerShip.camera === this.playerShip.cameras.thirdPersonOrbit) { //todo: this should be only working when in specific camera and ui be hidden or reacting //scene.hand.vel is never not 0 if mouse is locked (always when gamepad is connected) /*if(this.scene.hand.vel.x !== 0){ this.camOffset.dir.yaw += ((this.scene.hand.vel.x) * this.scene.player.dir.spd.yaw); } if(this.scene.hand.vel.y !== 0){ this.camOffset.dir.pitch += ((this.scene.hand.vel.y) * this.scene.player.dir.spd.pitch); }*/ this.camOffset.virtualMouse.delta.x = 0; this.camOffset.virtualMouse.delta.y = 0; //let velocity = {delta: {x: 0, y: 0}, lastPos: {x: 0, y: 0}} if (this.scene.hand.useControllerMouse === false) { this.camOffset.virtualMouse.pos.x = this.scene.hand.pos.x; this.camOffset.virtualMouse.pos.y = this.scene.hand.pos.y; this.camOffset.virtualMouse.delta.x = this.scene.hand.pos.x - this.camOffset.virtualMouse.lastPos.x; this.camOffset.virtualMouse.delta.y = this.scene.hand.pos.y - this.camOffset.virtualMouse.lastPos.y; this.camOffset.virtualMouse.lastPos.x = this.scene.hand.pos.x; //gets ignotred because of reset so velocity needs to be somethign in the cam rig or smth like that this.camOffset.virtualMouse.lastPos.y = this.scene.hand.pos.y; } 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)); this.camOffset.virtualMouse.delta.x = INPUTS.stickRight.horizontal * -1; this.camOffset.virtualMouse.delta.y = INPUTS.stickRight.vertical * -1; } } if (this.camOffset.virtualMouse.delta.x !== 0) { this.camOffset.dir.yaw += this.camOffset.virtualMouse.delta.x * this.scene.player.dir.spd.yaw; } if (this.camOffset.virtualMouse.delta.y !== 0) { this.camOffset.dir.pitch += this.camOffset.virtualMouse.delta.y * this.scene.player.dir.spd.pitch; } } else { this.camOffset.dir.yaw = 0; this.camOffset.dir.pitch = 0; } //try to look ahead of corner if (this.playerShip.camera === this.playerShip.cameras.firstPersonBumper) { this.camOffset.target.dir.pitch = this.playerShip.curveAmt * -0.5; } else if (this.playerShip.camera === this.playerShip.cameras.thirdPersonFollow) { this.camOffset.target.dir.pitch = this.playerShip.curveAmt * -0.25; } else { this.camOffset.target.dir.pitch = 0; } this.camOffset.dir.pitch += (this.camOffset.target.dir.pitch - this.camOffset.dir.pitch) * 0.1; this.camOffset.dir.pitch = Math.max(-HALFPI, Math.min(HALFPI, this.camOffset.dir.pitch)); this.camRig.rotateAroundAxis(this.playerShip.gondula.transform.toVectorArray(this.camRig.transform.up), this.camOffset.dir.yaw); this.camRig.rotateAroundAxis(this.playerShip.gondula.transform.toVectorArray(this.camRig.transform.right), this.camOffset.dir.pitch); let rotFactor = 0.5; let targetRot = [0, 0, 0, 0]; targetRot = gl_quat.rotationTo( targetRot, this.scene.cam.transform.toVectorArray(this.scene.cam.transform.right), this.scene.cam.transform.toVectorArray(this.camRig.transform.right), //playerShip.ship for rotation with ship ); let rot = [0, 0, 0, 0]; rot = gl_quat.slerp(rot, this.scene.cam.transform.rotationQuat, targetRot, rotFactor); this.scene.cam.rotateByQuaternion(rot); targetRot = [0, 0, 0, 0]; targetRot = gl_quat.rotationTo( targetRot, this.scene.cam.transform.toVectorArray(this.scene.cam.transform.up), this.scene.cam.transform.toVectorArray(this.camRig.transform.up), //playerShip.ship for rotation with ship ); rot = [0, 0, 0, 0]; rot = gl_quat.slerp(rot, this.scene.cam.transform.rotationQuat, targetRot, rotFactor); this.scene.cam.rotateByQuaternion(rot); targetRot = [0, 0, 0, 0]; targetRot = gl_quat.rotationTo( targetRot, this.scene.cam.transform.toVectorArray(this.scene.cam.transform.forward), this.scene.cam.transform.toVectorArray(this.camRig.transform.forward), //playerShip.ship for rotation with ship ); rot = [0, 0, 0, 0]; rot = gl_quat.slerp(rot, this.scene.cam.transform.rotationQuat, targetRot, rotFactor); this.scene.cam.rotateByQuaternion(rot); /*//todo: find a way to also move the camera after all the smooth to track rotation. Currently that does not work as intended... //new method that tries to blend cam rig rotation with always rotating to ship anchor w/o overrides that tween back and forth to infinity and beyond let rotFactor = 0.05; let targetRot = [0, 0, 0, 0]; //let out = [0, 0, 0]; //out = gl_vec3.cross(out, this.scene.cam.transform.toVectorArray(this.scene.cam.transform.forward), this.scene.cam.transform.toVectorArray(this.camRig.transform.up)), targetRot = gl_quat.rotationTo(targetRot, this.scene.cam.transform.toVectorArray( this.scene.cam.transform.right), //out, this.scene.cam.transform.toVectorArray( this.playerShip.shipAnchor.transform.right) //playerShip.ship for rotation with ship ) let rot = [0, 0, 0, 0]; rot = gl_quat.slerp(rot, this.scene.cam.transform.rotationQuat, targetRot, rotFactor); this.scene.cam.rotateByQuaternion(rot); targetRot = [0, 0, 0, 0]; //out = [0, 0, 0]; //out = gl_vec3.cross(out, this.scene.cam.transform.toVectorArray(this.scene.cam.transform.right), this.scene.cam.transform.toVectorArray(this.camRig.transform.forward)), targetRot = gl_quat.rotationTo(targetRot, this.scene.cam.transform.toVectorArray( this.scene.cam.transform.up), //out, this.scene.cam.transform.toVectorArray( this.playerShip.shipAnchor.transform.up) //playerShip.ship for rotation with ship ) rot = [0, 0, 0, 0]; rot = gl_quat.slerp(rot, this.scene.cam.transform.rotationQuat, targetRot, rotFactor); this.scene.cam.rotateByQuaternion(rot); targetRot = [0, 0, 0, 0]; //out = [0, 0, 0]; //out = gl_vec3.cross(out, this.scene.cam.transform.toVectorArray(this.scene.cam.transform.up), this.scene.cam.transform.toVectorArray(this.camRig.transform.right)), targetRot = gl_quat.rotationTo(targetRot, this.scene.cam.transform.toVectorArray( this.scene.cam.transform.forward), //out, this.scene.cam.transform.toVectorArray( this.playerShip.shipAnchor.transform.forward) //playerShip.ship for rotation with ship ) rot = [0, 0, 0, 0]; rot = gl_quat.slerp(rot, this.scene.cam.transform.rotationQuat, targetRot, rotFactor); this.scene.cam.rotateByQuaternion(rot); //this.camRig.transform.up.x = this.scene.cam.transform.up.x; //this.camRig.transform.up.y = this.scene.cam.transform.up.y; //this.camRig.transform.up.z = this.scene.cam.transform.up.z; //this.camRig.transform.right.x = this.scene.cam.transform.right.x; //this.camRig.transform.right.y = this.scene.cam.transform.right.y; //this.camRig.transform.right.z = this.scene.cam.transform.right.z; //this.camRig.transform.forward.x = this.scene.cam.transform.forward.x; //this.camRig.transform.forward.y = this.scene.cam.transform.forward.y; //this.camRig.transform.forward.z = this.scene.cam.transform.forward.z; //this.camOffset.dir.yaw = this.scene.player.dir.yaw; //this.camOffset.dir.pitch = this.scene.player.dir.pitch; //this.camRig.rotateAroundAxis(this.playerShip.gondula.transform.toVectorArray(this.camRig.transform.up), this.camOffset.dir.yaw); //this.camRig.rotateAroundAxis(this.playerShip.gondula.transform.toVectorArray(this.camRig.transform.right), this.camOffset.dir.pitch); //this.scene.cam.rotateAroundAxis(this.playerShip.gondula.transform.toVectorArray(this.scene.cam.transform.up), this.camOffset.dir.yaw * -1); //this.scene.cam.rotateAroundAxis(this.playerShip.gondula.transform.toVectorArray(this.scene.cam.transform.right), this.camOffset.dir.pitch); */ } assessSituation() { //let who = ""; let action = null; if (this.situation.actions.win.who !== "") { action = this.situation.actions.win; let character = this.aiShips.filter(el => el.name === action.who)[0].character; this.ui.addReaction("charSheetExpressions", character.reactions.cheer[Math.floor(Math.random() * character.reactions.cheer.length)], character); } else if (this.situation.actions.loose.who !== "") { action = this.situation.actions.loose; let character = this.aiShips.filter(el => el.name === action.who)[0].character; this.ui.addReaction("charSheetExpressions", character.reactions.angry[Math.floor(Math.random() * character.reactions.angry.length)], character); } else if (this.situation.actions.hit.who !== "") { action = this.situation.actions.hit; let character = this.aiShips.filter(el => el.name === action.who)[0].character; this.ui.addReaction("charSheetExpressions", character.reactions.hit[Math.floor(Math.random() * character.reactions.hit.length)], character); } else if (this.situation.actions.gainPosition.who !== "") { action = this.situation.actions.gainPosition; let character = this.aiShips.filter(el => el.name === action.who)[0].character; this.ui.addReaction("charSheetExpressions", character.reactions.angry[Math.floor(Math.random() * character.reactions.angry.length)], character); } else if (this.situation.actions.loosePosition.who !== "") { action = this.situation.actions.loosePosition; let character = this.aiShips.filter(el => el.name === action.who)[0].character; this.ui.addReaction("charSheetExpressions", character.reactions.haha[Math.floor(Math.random() * character.reactions.haha.length)], character); } else if (this.situation.actions.slipstream.who !== "") { action = this.situation.actions.slipstream; let character = this.aiShips.filter(el => el.name === action.who)[0].character; this.ui.addReaction("charSheetExpressions", character.reactions.thinking[Math.floor(Math.random() * character.reactions.thinking.length)], character); } else if (this.situation.actions.slipstreamed.who !== "") { action = this.situation.actions.slipstreamed; let character = this.aiShips.filter(el => el.name === action.who)[0].character; this.ui.addReaction("charSheetExpressions", character.reactions.taunt[Math.floor(Math.random() * character.reactions.taunt.length)], character); } else if (this.situation.actions.mishap.who !== "") { action = this.situation.actions.mishap; let character = this.aiShips.filter(el => el.name === action.who)[0].character; this.ui.addReaction("charSheetExpressions", character.reactions.haha[Math.floor(Math.random() * character.reactions.haha.length)], character); } /* who = this.situation.actions.hit.who; let actions = [ this.situation.actions.hit, this.situation.actions.gainPosition, this.situation.actions.loosePosition, this.situation.actions.mishap, this.situation.actions.slipstream, this.situation.actions.slipstreamed, this.situation.actions.win, this.situation.actions.loose ] actions = actions.sort((a, b) => { a.priority - b.priority }); console.log(actions[0].priority); if (actions[0].priority > 0) { who = actions[0].who; if (who !== "") { if (actions[0] == this.situation.actions.hit) { console.log("hit someone") let character = this.aiShips.filter(el => el.name === who)[0].character; this.ui.addReaction("charSheetExpressions", character.reactions.hit[Math.floor(Math.random() * character.reactions.hit.length)]); } else if (actions[0] == this.situation.actions.gainPosition) { console.log("gained a position") } else { console.log(actions[0]); } } } */ } resetSituation() { this.situation = { actions: { hit: { //player bumping into ai who: "", priority: 0, time: 0 }, slipstream: { //player slipstreaming ai who: "", priority: 0, time: 0 }, slipstreamed: { //ai slipstreaming behind player who: "", priority: 0, time: 0 }, gainPosition: { //player overtakes ai who: "", priority: 0, time: 0 }, loosePosition: { //ai overtakes player who: "", priority: 0, time: 0 }, mishap: { //player crashes near ai who: "", priority: 0, time: 0 }, win: { //ai wins who: "", priority: 0, time: 0 }, loose: { //player wins / rival looses who: "", priority: 0, time: 0 } } } } loadTrack(_track = 0, _pos = 7) { this.graLoading.alpha = 1; this.txtLoading.alpha = 1; setTimeout(() => { this.trackBuilder.loadTrack(_track); if (this.raceMode === this.raceModes.canyon) { if (this.raceModeData.playerIsHunter === true) { this.playerShip.restartOnFromSplineId(1); this.aiShips[0].restartOnFromSplineId((0 + 1) * 5 + 1, Math.PI * 0.25 * (0 + 1)); } else { this.playerShip.restartOnFromSplineId((0 + 1) * 5 + 1, Math.PI * 0.25 * (0 + 1)); this.aiShips[0].restartOnFromSplineId(1); } } else { //normal racing this.playerShip.restartOnFromSplineId(1); for (let [i, ai] of this.aiShips.entries()) { ai.restartOnFromSplineId((i + 1) * 5 + 1, Math.PI * 0.25 * (i + 1)); } } /* this.playerShip.splineId = 0; let splg = this.trackBuilder.spline[this.playerShip.splineId]; this.playerShip.gondula.jumpToPosition({x: splg.x, y: splg.y, z: splg.z}); let targetRot = [0, 0, 0, 0]; targetRot = gl_quat.rotationTo(targetRot, this.playerShip.gondula.transform.toVectorArray( this.playerShip.gondula.transform.forward), [0, 0, 1] ) this.playerShip.gondula.rotateByQuaternion(targetRot); targetRot = [0, 0, 0, 0]; targetRot = gl_quat.rotationTo(targetRot, this.playerShip.gondula.transform.toVectorArray( this.playerShip.gondula.transform.right), [1, 0, 0] ) this.playerShip.gondula.rotateByQuaternion(targetRot); targetRot = [0, 0, 0, 0]; targetRot = gl_quat.rotationTo(targetRot, this.playerShip.gondula.transform.toVectorArray( this.playerShip.gondula.transform.up), [0, -1, 0] ) this.playerShip.gondula.rotateByQuaternion(targetRot); this.playerShip.speed = 0; */ this.graLoading.alpha = 0; this.txtLoading.alpha = 0; this.countdown.start = Date.now(); this.countdown.current = Date.now() - this.countdown.start; this.countdown.step = 0; this.countdown.go = false; this.state = this.states.countDown; }, 10); } updateTutorial() { switch (this.tutorialStep) { case 0: this.playerShip.speed = 0; this.playerShip.input.roll = 0; this.aiShips[0].speed = 0; this.aiShips[0].input.roll = 0; break; case 1: //just rolling and checking pitch HEAT ZONE this.playerShip.speed = 0; //this.playerShip.input.roll = 0; this.playerShip.rollSpeedMax = 1; this.playerShip.rollSpeedMin = -1; this.aiShips[0].speed = 0; this.aiShips[0].input.roll = 0; this.aiShips[0].rollSpeedMax = 1; this.aiShips[0].rollSpeedMin = -1; //console.log(this.playerShip.distToPerfectPitch) if (this.playerShip.distToPerfectPitch > 0 && this.playerShip.distToPerfectPitch < 32) { this.tutorialHoldVar += this.scene.dt; if (this.tutorialHoldVar >= this.tutorialHoldVarMax) { this.cycleTutorial(); } } else { if (this.tutorialHoldVar > 0) { this.tutorialHoldVar -= this.scene.dt; } } //console.log(this.tutorialHoldVar) break; case 2: this.playerShip.speed = 0; this.playerShip.input.roll = 0; this.aiShips[0].speed = 0; this.aiShips[0].input.roll = 0; break; case 3: if (this.aiShips[0].splineId - this.playerShip.splineId > 44) { this.aiShips[0].speed = 0; } break; case 4: this.playerShip.speed = 0; this.playerShip.input.roll = 0; this.aiShips[0].speed = 0; this.aiShips[0].input.roll = 0; break; case 5: //sllipstreaming if (this.aiShips[0].splineId - this.playerShip.splineId > 44) { this.aiShips[0].speed = 0; } if (this.aiShips[0].splineId - this.playerShip.splineId < -20) { if (this.tutorialHoldVar > 10) { //this.tutorialHoldVar += 4 * this.scene.dt; //if (this.tutorialHoldVar >= this.tutorialHoldVarMax * 0.25) { this.cycleTutorial(); //} } } if (this.playerShip.slipstreaming === true) { this.aiShips[0].speedMax = 14; this.tutorialHoldVar += 1 * this.scene.dt; if (this.tutorialHoldVar >= this.tutorialHoldVarMax) { this.cycleTutorial(); } } else { this.aiShips[0].speedMax = 12; if (this.tutorialHoldVar > 0) { this.tutorialHoldVar -= 0.1 * this.scene.dt; } } break; case 6: break; case 7://free time trial //catch up and wait mechanic if (this.aiShips[0].splineId - this.playerShip.splineId > 44) { this.aiShips[0].speedMax = 5; } else if (this.aiShips[0].splineId - this.playerShip.splineId < -44) { this.aiShips[0].speedMax = 18; } else { this.aiShips[0].speedMax = 16; } this.playerShip.temp *= 0.5; if (this.playerShip.lapTimes.length >= 1) { this.cycleTutorial(); } break; case 8: break; /* case 99: //speedcheck if (Math.floor(this.playerShip.speed * 10) >= 200) { this.tutorialHoldVar += this.scene.dt; if (this.playerShip.scraping === false && this.tutorialHoldVar > 300) { this.cycleTutorial(); } } break; case 5: //this.playerShip.speed = 0; //this.playerShip.input.roll = 0; //this.aiShips[0].speed = 0; //this.aiShips[0].input.roll = 0; //this.aiShips[0].input.pitch = 0; if (this.aiShips[0].splineId - this.playerShip.splineId > 44) { this.aiShips[0].speed = 0; } if (this.playerShip.slipstreaming === true) { this.tutorialHoldVar += 1 * this.scene.dt; if (this.tutorialHoldVar >= this.tutorialHoldVarMax) { this.cycleTutorial(); } } else { if (this.tutorialHoldVar > 0) { this.tutorialHoldVar -= 0.1 * this.scene.dt; } } break; */ /* case 993://how to slipstream if (this.aiShips[0].splineId - this.playerShip.splineId > 44) { this.aiShips[0].speed = 0; } if (this.playerShip.position === 0 && this.aiShips[0].splineId - this.playerShip.splineId < -10 && this.playerShip.slipsteamTime > 30) { this.cycleTutorial(); } break; case 5: if (this.aiShips[0].splineId - this.playerShip.splineId > 44) { this.aiShips[0].speed = 0; } if (this.playerShip.position === 1 && this.aiShips[0].splineId - this.playerShip.splineId > 20) { this.cycleTutorial(); } break; */ default: console.log(`could not find step ${this.tutorialStep} in tutorial update`); this.cycleTutorial(); break; } } cycleTutorial() { /* 0. look at your pitch 1. speedcheck to 200 for X seconds / keep in speedzone for X seconds 3. playground 1 / gather coins at shown ideal line (small but curve map with at least a hump not only a circle - 180 right, up down, 180 right straight) (X. jump to start again) or at least let Roki show up in front of you ---maybe go back to hangar? 4. follow in slipstream for X seconds in same map that you played around 5. overtake (2 times?) throug slipstream */ this.tutorialStep += 1; console.log(`tutorial step ${this.tutorialStep}`); switch (this.tutorialStep) { case 0: //how to accelerate this.ui.txtProgress.setText(""); //start conversation this.ui.hide(); this.scene.player.hideUI(); this.scene.player.setMode(PLAYERMODE.INTERACT); this.scene.player.panel = new PanelRaceTutorial(this.scene, this, this.state, this.tutorialStep); //this.scene.paused = true; //this.state = this.states.pause; this.playerShip.speedMax = 1; this.playerShip.speed = 0; this.playerShip.rollSpeedMax = 0.1; this.playerShip.rollSpeedMin = -0.1; this.playerShip.autopilot = true; this.aiShips[0].speedMax = 1; this.playerShip.speed = 0; this.aiShips[0].rollSpeedMax = 0.1; this.aiShips[0].rollSpeedMin = -0.1; break; case 1: this.ui.txtProgress.setText("keep pitch indicator in the white HEAT ZONE"); this.playerShip.autopilot = false; break; case 2: //start collectathon 1 //how to slipstream this.ui.txtProgress.setText(""); //start conversation this.ui.hide(); this.scene.player.hideUI(); this.scene.player.setMode(PLAYERMODE.INTERACT); this.scene.player.panel = new PanelRaceTutorial(this.scene, this, this.state, this.tutorialStep); this.playerShip.speedMax = 1; this.playerShip.rollSpeedMax = 0.1; this.playerShip.rollSpeedMin = -0.1; this.playerShip.autopilot = true; this.aiShips[0].speedMax = 1; this.aiShips[0].rollSpeedMax = 0.1; this.aiShips[0].rollSpeedMin = -0.1; this.trackBuilder.createObstacles(this.trackBuilder.currentTrackId, [ /*{sp: this.trackBuilder.spline[50], angle: Math.PI * 0.25, radius: 0, model: "modObstSteam", name: "steam 0"}, {sp: this.trackBuilder.spline[50], angle: Math.PI * 0.75, radius: 0, model: "modObstSteam", name: "steam 1"}, {sp: this.trackBuilder.spline[50], angle: Math.PI * -0.25, radius: 0, model: "modObstSteam", name: "steam 2"}, {sp: this.trackBuilder.spline[50], angle: Math.PI * -0.75, radius: 0, model: "modObstSteam", name: "steam 3"}*/ { sp: this.trackBuilder.spline[0], angle: Math.PI * 0.5, radius: 100, model: "modRacingPickup", name: "token 0" }, { sp: this.trackBuilder.spline[20], angle: Math.PI * 0.5, radius: 100, model: "modRacingPickup", name: "token 1" }, { sp: this.trackBuilder.spline[40], angle: Math.PI * 0.5, radius: 100, model: "modRacingPickup", name: "token 2" }, { sp: this.trackBuilder.spline[60], angle: Math.PI * 0.5, radius: 100, model: "modRacingPickup", name: "token 3" }, { sp: this.trackBuilder.spline[80], angle: Math.PI * 0.5, radius: 100, model: "modRacingPickup", name: "token 4" }, { sp: this.trackBuilder.spline[100], angle: Math.PI * 0.25, radius: 100, model: "modRacingPickup", name: "token 5" }, { sp: this.trackBuilder.spline[120], angle: Math.PI * 0, radius: 100, model: "modRacingPickup", name: "token 6" }, { sp: this.trackBuilder.spline[140], angle: Math.PI * -0.25, radius: 100, model: "modRacingPickup", name: "token 7" }, { sp: this.trackBuilder.spline[160], angle: Math.PI * -0.5, radius: 100, model: "modRacingPickup", name: "token 10" }, { sp: this.trackBuilder.spline[180], angle: Math.PI * -0.5, radius: 100, model: "modRacingPickup", name: "token 11" }, { sp: this.trackBuilder.spline[200], angle: Math.PI * -0.5, radius: 100, model: "modRacingPickup", name: "token 12" }, { sp: this.trackBuilder.spline[220], angle: Math.PI * -0.5, radius: 100, model: "modRacingPickup", name: "token 13" }, { sp: this.trackBuilder.spline[240], angle: Math.PI * -0.5, radius: 100, model: "modRacingPickup", name: "token 14" }, { sp: this.trackBuilder.spline[260], angle: Math.PI * -0.25, radius: 100, model: "modRacingPickup", name: "token 15" }, { sp: this.trackBuilder.spline[280], angle: Math.PI * 0, radius: 100, model: "modRacingPickup", name: "token 16" }, { sp: this.trackBuilder.spline[300], angle: Math.PI * 0.25, radius: 100, model: "modRacingPickup", name: "token 17" }, ]); this.tutorialHoldVar = 0; this.tutorialHoldVarMax = 16; for (let o of this.trackBuilder.obstacles) { o.data.ignoreRadar = false; o.trigger.isTrigger = true; o.updateTrigger = () => { if (o.trigger.other.name === "Player") { this.scene.geometryController.destroyModelById(o.id); this.scene.soundManager.playSound(this.scene.soundManager.computerStartSound); this.tutorialHoldVar += 1; this.ui.txtProgress.setText(`${this.tutorialHoldVar} of 16 token`); o.data.ignoreRadar = true; console.log(this.tutorialHoldVar); if (this.tutorialHoldVar >= this.tutorialHoldVarMax) { this.cycleTutorial(); } } }; } break; /*case 99: this.playerShip.speedMax = 16; this.playerShip.rollSpeedMax = 1; this.playerShip.rollSpeedMin = -1; this.playerShip.autopilot = false; this.ui.show(); this.aiShips[0].speedMax = 16; this.aiShips[0].rollSpeedMax = 1; this.aiShips[0].rollSpeedMin = -1; break;*/ case 3: console.log("tutorial cycled to 3! free to race and collect the coins"); this.ui.txtProgress.setText(`${this.tutorialHoldVar} of 16 token`); this.playerShip.speedMax = 12; this.playerShip.rollSpeedMax = 1; this.playerShip.rollSpeedMin = -1; this.playerShip.autopilot = false; this.ui.show(); this.aiShips[0].speedMax = 11; this.aiShips[0].rollSpeedMax = 1; this.aiShips[0].rollSpeedMin = -1; break; case 4: this.ui.txtProgress.setText(""); console.log("tutorial for slipstream / overtake"); //start conversation this.ui.hide(); this.scene.player.hideUI(); this.scene.player.setMode(PLAYERMODE.INTERACT); this.scene.player.panel = new PanelRaceTutorial(this.scene, this, this.state, this.tutorialStep); this.playerShip.speedMax = 1; this.playerShip.rollSpeedMax = 0.1; this.playerShip.rollSpeedMin = -0.1; this.playerShip.autopilot = true; this.aiShips[0].speedMax = 1; this.aiShips[0].rollSpeedMax = 0.1; this.aiShips[0].rollSpeedMin = -0.1; break; case 5: console.log("go slipstreaming"); this.ui.txtProgress.setText("stay in Roki's SLIPSTREAM"); this.playerShip.speedMax = 14; this.playerShip.rollSpeedMax = 1; this.playerShip.rollSpeedMin = -1; this.playerShip.autopilot = false; this.playerShip.crashPoints = 0; this.ui.show(); this.aiShips[0].speedMax = 13; this.aiShips[0].rollSpeedMax = 1; this.aiShips[0].rollSpeedMin = -1; this.aiShips[0].pitch.max = 0.75; this.aiShips[0].pitch.min = -0.75; this.tutorialHoldVar = 0; this.tutorialHoldVarMax = 1000; this.startFromHangar = false; this.params.startFromHangar = false; this.loadTrack(9001); //restart all ships for (let ai of this.aiShips) { ai.lapTimes = []; ai.fastestLap = 0; ai.last.fastestLap = 0; } this.playerShip.lapTimes = []; this.playerShip.fastestLap = 0; this.playerShip.last.fastestLap = 0; this.playerShip.autopilot = false; this.ui.show(); this.finishedRace = false; this.maxLaps = 9999; break; case 6: console.log("tutorial for end"); this.ui.txtProgress.setText(""); if (this.playerShip.crashPoints > 0) { this.aiShips[0].ship.data.conversation.treePosition = 15; } if (this.aiShips[0].splineId - this.playerShip.splineId < -20) { this.aiShips[0].ship.data.conversation.treePosition = 22; if (this.playerShip.crashPoints > 0) { this.aiShips[0].ship.data.conversation.treePosition = 21; } } this.playerShip.crashPoints = 0; //start conversation this.ui.hide(); this.scene.player.hideUI(); this.scene.player.setMode(PLAYERMODE.INTERACT); this.scene.player.panel = new PanelRaceTutorial(this.scene, this, this.state, this.tutorialStep); this.playerShip.speedMax = 1; this.playerShip.rollSpeedMax = 0.1; this.playerShip.rollSpeedMin = -0.1; this.playerShip.autopilot = true; this.aiShips[0].speedMax = 1.5; this.aiShips[0].rollSpeedMax = 0.1; this.aiShips[0].rollSpeedMin = -0.1; this.aiShips[0].pitch.max = 1; this.aiShips[0].pitch.min = -1; break; case 7: console.log("free time trial"); this.playerShip.speedMax = 16; this.playerShip.rollSpeedMax = 1; this.playerShip.rollSpeedMin = -1; this.playerShip.autopilot = false; this.playerShip.crashPoints = 0; this.ui.show(); this.aiShips[0].speedMax = 16; this.aiShips[0].rollSpeedMax = 1; this.aiShips[0].rollSpeedMin = -1; this.aiShips[0].pitch.max = 1; this.aiShips[0].pitch.min = -1; this.startFromHangar = false; this.params.startFromHangar = false; this.loadTrack(9002); //restart all ships for (let ai of this.aiShips) { ai.lapTimes = []; ai.fastestLap = 0; ai.last.fastestLap = 0; } this.playerShip.lapTimes = []; this.playerShip.fastestLap = 0; this.playerShip.last.fastestLap = 0; this.playerShip.autopilot = false; this.ui.show(); this.finishedRace = false; this.maxLaps = 99; /* console.log("tutorial end after slipstream"); //start conversation this.ui.hide(); this.scene.player.hideUI(); this.scene.player.setMode(PLAYERMODE.INTERACT); this.scene.player.panel = new PanelRaceTutorial(this.scene, this, this.state, this.tutorialStep); this.playerShip.speedMax = 1; this.playerShip.rollSpeedMax = 0.1; this.playerShip.rollSpeedMin = -0.1; this.playerShip.autopilot = true; this.aiShips[0].speedMax = 1; this.aiShips[0].rollSpeedMax = 0.1; this.aiShips[0].rollSpeedMin = -0.1; */ break; case 8: //start conversation this.ui.hide(); this.scene.player.hideUI(); this.scene.player.setMode(PLAYERMODE.INTERACT); this.scene.player.panel = new PanelRaceTutorial(this.scene, this, this.state, this.tutorialStep); this.playerShip.speedMax = 1; this.playerShip.rollSpeedMax = 0.1; this.playerShip.rollSpeedMin = -0.1; this.playerShip.autopilot = true; this.aiShips[0].speedMax = 1; this.aiShips[0].rollSpeedMax = 0.1; this.aiShips[0].rollSpeedMin = -0.1; /* this.playerShip.autopilot = true; this.ui.hide(); //show end results this.maxLaps = -1; this.scene.player.hideUI(); this.scene.player.setMode(PLAYERMODE.INTERACT); this.scene.player.panel = new PanelEndOfRace(this.scene, this, this.state); if (this.raceMode === this.raceModes.tutorial) { if (this.playerShip.position === 0) { //you won the race flagManager.setFlag("wonDemoRace", "true"); } flagManager.setFlag("demoProgress", "1"); } */ break; /*/ case 94://resolve slipstream if (this.playerShip.crashPoints > 0) { this.playerShip.crashPoints = 0; this.aiShips[0].ship.data.conversation.treePosition = 8; } //start conversation this.ui.hide(); this.scene.player.hideUI(); this.scene.player.setMode(PLAYERMODE.INTERACT); this.scene.player.panel = new PanelRaceTutorial(this.scene, this, this.state, this.tutorialStep); this.playerShip.speedMax = 1; this.playerShip.rollSpeedMax = 0.1; this.playerShip.rollSpeedMin = -0.1; this.playerShip.autopilot = true; this.aiShips[0].speedMax = 1; this.aiShips[0].rollSpeedMax = 0.1; this.aiShips[0].rollSpeedMin = -0.1; break; case 5://fall back to second this.playerShip.speedMax = 10; this.playerShip.rollSpeedMax = 1; this.playerShip.rollSpeedMin = -1; this.playerShip.autopilot = false; this.ui.show(); this.aiShips[0].speedMax = 16; this.aiShips[0].rollSpeedMax = 1; this.aiShips[0].rollSpeedMin = -1; break; case 6://show extra controls and object avoid if (this.playerShip.crashPoints > 0) { this.playerShip.crashPoints = 0; this.aiShips[0].ship.data.conversation.treePosition = 8; } //start conversation this.ui.hide(); this.scene.player.hideUI(); this.scene.player.setMode(PLAYERMODE.INTERACT); this.scene.player.panel = new PanelRaceTutorial(this.scene, this, this.state, this.tutorialStep); this.playerShip.speedMax = 1; this.playerShip.rollSpeedMax = 0.1; this.playerShip.rollSpeedMin = -0.1; this.playerShip.autopilot = true; this.aiShips[0].speedMax = 1; this.aiShips[0].rollSpeedMax = 0.1; this.aiShips[0].rollSpeedMin = -0.1; break; case 7://fall back to second this.playerShip.speedMax = 16; this.playerShip.rollSpeedMax = 1; this.playerShip.rollSpeedMin = -1; this.playerShip.autopilot = false; this.ui.show(); this.aiShips[0].speedMax = 18; this.aiShips[0].rollSpeedMax = 1; this.aiShips[0].rollSpeedMin = -1; this.startFromHangar = false; this.params.startFromHangar = false; this.loadTrack(0); //restart all ships for (let ai of this.aiShips) { ai.lapTimes = []; ai.fastestLap = 0; ai.last.fastestLap = 0; } this.playerShip.lapTimes = []; this.playerShip.fastestLap = 0; this.playerShip.last.fastestLap = 0; this.playerShip.autopilot = false; this.ui.show(); this.finishedRace = false; this.maxLaps = 3; break;*/ default: console.log(`could not find tutorial step ${this.tutorialStep}`); break; } } createDefaultRing() { //first Ring Test let ring = this.scene.geometryController.loadModel("ring DEFAULT", "modDebugTile", { x: 0, y: 0, z: 0 }); ring.flags.draw = true; let ringPts = []; let r = 128; let iter = 0; for (let i = 0; i < Math.PI * 2; i += Math.PI / 8) { let xx = Math.cos(i) * r; let yy = Math.sin(i) * r; ringPts.push({ x: xx, y: yy, z: 0 }); iter += 1; } //console.log(ringPts) let texture = "sprDebugTexture"; for (let i = 0; i < ringPts.length - 1; i++) { ring.addQuadFromData({ //this.scene, this.id, no, _q.type, pos, _q.points, _q.texture, _q.frame type: "quad", frame: texture, texture: "atlasAll", position: { x: 0, y: 0, z: 0 }, points: [ { //hinten rechts x: ringPts[i].x, y: ringPts[i].y, z: -this.trackBuilder.ringDeepness, }, { //hinten links x: ringPts[i + 1].x, y: ringPts[i + 1].y, z: -this.trackBuilder.ringDeepness, }, { //vorne links x: ringPts[i + 1].x, y: ringPts[i + 1].y, z: 0, }, { //vorne rechts x: ringPts[i].x, y: ringPts[i].y, z: 0, }, ], }); } ring.addQuadFromData({ type: "quad", frame: texture, texture: "atlasAll", position: { x: 0, y: 0, z: 0 }, points: [ { x: ringPts[ringPts.length - 1].x, y: ringPts[ringPts.length - 1].y, z: -this.trackBuilder.ringDeepness, }, { x: ringPts[0].x, y: ringPts[0].y, z: -this.trackBuilder.ringDeepness, }, { x: ringPts[0].x, y: ringPts[0].y, z: 0, }, { x: ringPts[ringPts.length - 1].x, y: ringPts[ringPts.length - 1].y, z: 0, }, ], }); //outer Ring ringPts = []; iter = 0; r = 256; for (let i = 0; i < Math.PI * 2; i += Math.PI / 8) { let xx = Math.cos(i) * r; let yy = Math.sin(i) * r; ringPts.push({ x: xx, y: yy, z: 0 }); iter += 1; } texture = "sprDebugTexture"; for (let i = 0; i < ringPts.length - 1; i++) { ring.addQuadFromData({ //this.scene, this.id, no, _q.type, pos, _q.points, _q.texture, _q.frame type: "quad", frame: texture, texture: "atlasAll", position: { x: 0, y: 0, z: 0 }, points: [ { //hinten rechts x: ringPts[i].x, y: ringPts[i].y, z: -this.trackBuilder.ringDeepness, }, { //hinten links x: ringPts[i + 1].x, y: ringPts[i + 1].y, z: -this.trackBuilder.ringDeepness, }, { //vorne links x: ringPts[i + 1].x, y: ringPts[i + 1].y, z: 0, }, { //vorne rechts x: ringPts[i].x, y: ringPts[i].y, z: 0, }, ], }); } ring.addQuadFromData({ type: "quad", frame: texture, texture: "atlasAll", position: { x: 0, y: 0, z: 0 }, points: [ { x: ringPts[ringPts.length - 1].x, y: ringPts[ringPts.length - 1].y, z: -this.trackBuilder.ringDeepness, }, { x: ringPts[0].x, y: ringPts[0].y, z: -this.trackBuilder.ringDeepness, }, { x: ringPts[0].x, y: ringPts[0].y, z: 0, }, { x: ringPts[ringPts.length - 1].x, y: ringPts[ringPts.length - 1].y, z: 0, }, ], }); /* ring.addQuadFromData({ type: "collisionQuad", position: { x: 0, y: 0, z: 0 }, points: [ {//hinten rechts x: 128, y: 128, z: -this.trackBuilder.ringDeepness },{//hinten links x: -128, y: 128, z: -this.trackBuilder.ringDeepness },{//vorne links x: -128, y: 128, z: 0 },{//vorne rechts x: 128, y: 128, z: 0 } ] }); */ //ring.deleteQuad(ring.quadData[0]) return ring; } destroy() { this.ui.destroy(); this.trackBuilder.clearTrack(); this.playerShip.destroy(); for (let ai of this.aiShips) { ai.destroy(); } } }