#include "script/wheels.lua" #include "script/common.lua" #include "script/explosion.lua" function init() enabled = true gateLocation = FindLocation("gate") gateTrigger = FindTrigger("gate") gateNearTrigger = FindTrigger("gatenear") gateDoneTrigger = FindTrigger("gatedone") gateNear = false gateDone = false doorLocation = FindLocation("door") doorTrigger = FindTrigger("door") doorRubbleTrigger = FindTrigger("rubble") doorDoneTrigger = FindTrigger("doordone") doorRubbleDone = false doorDone = false toolsLocation = FindLocation("tools") toolsTrigger = FindTrigger("tools") toolsDone = false fuseLocation = FindLocation("fuse") fuseOutsideTrigger = FindTrigger("fuseoutside") fuseInsideTrigger = FindTrigger("fuseinside") fuseLight = FindShape("fuselight") fuseBody = FindBody("fuse") fuseDone = false terminalTrigger = FindTrigger("terminal") terminalDone = false powerOn = LoadSound("LEVEL/script/tutorial/poweron.ogg") arrow = LoadSprite("gfx/arrowdown.png") vanspawn = FindLocation("vanspawn", true) vanspawnt = GetLocationTransform(vanspawn) vanholes = FindLocations("vanhole", true) vanholest = {} for i=1, #vanholes do vanholest[i] = GetLocationTransform(vanholes[i]).pos end vanspawned = {} --Time Machine timemachineplace = FindLocation("timemachineplace", true) timemachine_end = FindLocation("timemachine_end", true) timemachinetransform = GetLocationTransform(timemachineplace) cutscene_activated = false ready_for_scene = false cutscenetrigger = FindTriggers("cutscenetrigger", true) cutscenedelay = 0 stop_machine = FindTrigger("stop_machine", true) time_machine_speed = Vec(30, -1.93, 3) machine_up = false machine_pitch = false start_machine_transform = nil floating = false floating_adjusted = false level_vehicles = FindVehicles("", true) --timetravel lights travel_spark = FindLights("travel_spark", true) travel_lights_coef = 1 travel_lightintensity = 0.1 flash_time = 0 travel_flash = FindLight("travel_flash", true) travel_flash_van_time = nil cutscene_done = false --Disable all tools local tools = ListKeys("game.tool") for i=1,#tools do local k = "game.tool."..tools[i]..".enabled" if GetBool(k) then SetBool(k, false) end end SetString("game.player.tool", "none") --Turn off all the lights lights = FindShapes("light", true) for i=1, #lights do SetShapeEmissiveScale(lights[i], 0) end --gateDone = true --doorDone = true --toolsDone = true bus = FindBody("bus") busVel = Vec(0,0,0) busTransform = GetBodyTransform(bus) busSound = LoadSound("LEVEL/script/tutorial/bus.ogg") busActive = false wheelInit(bus) SetBool("savegame.mod.creditsdone", false) AppearSound = LoadSound("MOD/sound/time-travel-theme-stinger.ogg") WaitLoop = LoadLoop("MOD/sound/time-travel-theme-wait-loop.ogg") isLoopMusic = false stingettimer = 0 stingerplay = false stingerfinish = false end function drawArrow(location) local t = GetLocationTransform(location) t.rot = QuatLookAt(t.pos, GetCameraTransform().pos) local offset = 1.5 + math.sin(4.0*GetTime())*0.5 t.pos[2] = t.pos[2] + offset DrawSprite(arrow, t, 2, 2, .3, .3, .3, 3, false, true) DrawSprite(arrow, t, 2, 2, 1, 1, 1, 1, true, true) end function tick(dt) local current_time = GetTime() if not enabled then return end if current_time > 2.5 then if not busActive then PlaySound(busSound) busActive = true end local fwd = TransformToParentVec(busTransform, Vec(0, 0, 1)) busVel = VecAdd(busVel, VecScale(fwd, dt*2.0)) busTransform.pos = VecAdd(busTransform.pos, VecScale(busVel, dt)) wheelUpdate(-VecLength(busVel)) SetBodyTransform(bus, busTransform) end local curinput = GetString("game.input.curdevice") local p = GetPlayerPos() local hintimageInputOffsetX = 164 if not gateDone then if IsPointInTrigger(gateTrigger, p) then SetString("hud.hintimage", "ui/hud/tutorial/opendoor_empty_no_text.png") if curinput == "mouse" then SetString("hud.hintimage.input", "ui/hud/tutorial/mouse_rmb.png") SetInt("hud.hintimage.offsetx", 212) SetInt("hud.hintimage.offsety", 115) else local str = GetString("game.input.grab.icon") if str ~= "" then SetString("hud.hintimage.input", str) SetInt("hud.hintimage.offsetx", 212) SetInt("hud.hintimage.offsety", 120) end end SetString("hud.hintimage.text", GetTranslatedStringByKey("UI_TEXT_TUTORIAL_OPEN")) SetInt("hud.hintimage.text.offsety", 65) else if not gateNear and IsPointInTrigger(gateNearTrigger, p) then gateNear = true Command("pros.eventTutorial", 1) end if gateNear then SetString("hud.hintinfo", GetTranslatedStringByKey("UI_HUD_HINT_OPEN_THE")) drawArrow(gateLocation) else SetString("hud.hintinfo", GetTranslatedStringByKey("UI_HUD_HINT_WALK_HOME")) end end if IsPointInTrigger(gateDoneTrigger, p) then gateDone = true Command("pros.eventTutorial", 2) end elseif not doorDone then if IsPointInTrigger(doorTrigger, p) then if not doorRubbleDone and IsTriggerEmpty(doorRubbleTrigger) then doorRubbleDone = true end if doorRubbleDone then SetString("hud.hintimage", "ui/hud/tutorial/opendoor_empty_no_text.png") if curinput == "mouse" then SetString("hud.hintimage.input", "ui/hud/tutorial/mouse_rmb.png") SetInt("hud.hintimage.offsetx", 212) SetInt("hud.hintimage.offsety", 115) else local str = GetString("game.input.grab.icon") if str ~= "" then SetString("hud.hintimage.input", str) SetInt("hud.hintimage.offsetx", 212) SetInt("hud.hintimage.offsety", 120) end end SetString("hud.hintimage.text", GetTranslatedStringByKey("UI_TEXT_TUTORIAL_OPEN")) SetInt("hud.hintimage.text.offsety", 65) else SetString("hud.hintimage", "ui/hud/tutorial/empty.png") if curinput == "mouse" then SetString("hud.hintimage.input", "ui/hud/tutorial/mouse_rmb.png") SetInt("hud.hintimage.offsetx", hintimageInputOffsetX) SetInt("hud.hintimage.offsety", 120) else local str = GetString("game.input.grab.icon") if str ~= "" then SetString("hud.hintimage.input", str) SetInt("hud.hintimage.offsetx", hintimageInputOffsetX) SetInt("hud.hintimage.offsety", 120) end end SetString("hud.hintimage.text", GetTranslatedStringByKey("UI_TEXT_TUTORIAL_HOLD")) SetInt("hud.hintimage.text.offsety", 70) end else SetString("hud.hintinfo", GetTranslatedStringByKey("UI_HUD_HINT_GO_INSIDE")) drawArrow(doorLocation) end if IsPointInTrigger(doorDoneTrigger, p) then doorDone = true Command("pros.eventTutorial", 3) end elseif not toolsDone then if not IsPointInTrigger(toolsTrigger, p) then SetString("hud.hintinfo", GetTranslatedStringByKey("UI_HUD_HINT_PICK_UP")) drawArrow(toolsLocation) end if GetBool("game.tool.sledge.enabled") and GetBool("game.tool.spraycan.enabled") and GetBool("game.tool.extinguisher.enabled") then toolsDone = true Command("pros.eventTutorial", 4) ready_for_scene = true end elseif not fuseDone then --SetTag(fuseBody, "interact", GetTranslatedStringByKey("REPLACE_FUSE")) if IsPointInTrigger(fuseOutsideTrigger, p) then SetString("hud.hintimage", "ui/hud/tutorial/empty.png") if curinput == "mouse" then SetString("hud.hintimage.input", "ui/hud/tutorial/mouse_lmb.png") SetInt("hud.hintimage.offsetx", hintimageInputOffsetX) SetInt("hud.hintimage.offsety", 120) else local str = GetString("game.input.usetool.icon") if str ~= "" then SetString("hud.hintimage.input", str) SetInt("hud.hintimage.offsetx", hintimageInputOffsetX) SetInt("hud.hintimage.offsety", 120) end end SetString("hud.hintimage.text", GetTranslatedStringByKey("UI_TEXT_TUTORIAL_USE")) SetInt("hud.hintimage.text.offsety", 70) elseif IsPointInTrigger(fuseInsideTrigger, p) then SetString("hud.hintimage", "ui/hud/tutorial/empty.png") if curinput == "mouse" then SetString("hud.hintimage.input", "ui/hud/tutorial/flashlight_icon.png") SetInt("hud.hintimage.offsetx", hintimageInputOffsetX) SetInt("hud.hintimage.offsety", 120) else SetString("hud.hintimage", "ui/hud/tutorial/flashlight_empty.png") local str = GetString("game.input.flashlight.icon") if str ~= "" then SetString("hud.hintimage.input", str) SetInt("hud.hintimage.offsetx", hintimageInputOffsetX) SetInt("hud.hintimage.offsety", 120) end end SetString("hud.hintimage.text", GetTranslatedStringByKey("UI_TEXT_TUTORIAL_FLASHLIGHT")) SetInt("hud.hintimage.text.offsety", 70) else SetString("hud.hintinfo", GetTranslatedStringByKey("UI_HUD_HINT_REPLACE_THE")) drawArrow(fuseLocation) end if GetPlayerInteractBody() == fuseBody and InputPressed("interact") then PlaySound(powerOn) RemoveTag(fuseBody, "interact") fuseDone = true Command("pros.eventTutorial", 5) SetShapeEmissiveScale(fuseLight, 0) for i=1, #lights do SetShapeEmissiveScale(lights[i], 1) end --SetBodyTransform(timemachine, timemachinetransform) --SetBodyTransform(laptop, laptoptransform) --SetScreenEnabled(tv, true) --SetScreenEnabled(terminal, true) --SetTag(GetShapeBody(GetScreenShape(tv)), "interact") --SetTag(GetShapeBody(GetScreenShape(terminal)), "interact") end elseif not terminalDone then if travel_flash_van_time == nil and floating then terminalLocation = FindLocation("terminalLocation", true) SetString("hud.hintinfo", GetTranslatedStringByKey("UI_HUD_HINT_GO_INSIDE_2")) drawArrow(terminalLocation) if GetBool("game.player.usescreen") then terminalDone = true Command("pros.eventTutorial", 6) end end end if ready_for_scene and (IsPointInTrigger(cutscenetrigger[1], GetPlayerPos()) or IsPointInTrigger(cutscenetrigger[2], GetPlayerPos())) then cutscenedelay = current_time PlayMusic("MOD/sound/time-travel-theme-stinger.ogg") stingerplay = true for i = 1, #cutscenetrigger do Delete(cutscenetrigger[i]) end fuseDone = true end if ((current_time >= cutscenedelay + 1 and not IsHandleValid(cutscenetrigger[1])) and ready_for_scene) then for i=1, #travel_spark do Delete(travel_spark[i]) end ready_for_scene = false --StopMusic() isLoopMusic = true terrain = FindBody("terrain",true) SetTag(terrain, "unbreakable") Explosion(timemachinetransform.pos, 4) explosionLarge(timemachinetransform.pos) cutscene_activated = true Spawn("MOD/runtime/prefabs/hub_lockelle/time_machine.xml", timemachinetransform) wheels_lights = FindLights("shining", true) timemachine_body = FindBody("time_machine", true) timemachine_vehicle = FindVehicle("timemachine_vehicle", true) RemoveTag(timemachine_body, "interact") firewheel = FindBodies("firewheel", true) flash_time = 0.7 SetLightIntensity(travel_flash, travel_lightintensity) elseif current_time < cutscenedelay + 1 and ready_for_scene then Travelling_Sparks() end local vehicle_pos = GetBodyTransform(timemachine_body).pos if cutscene_activated then Machine_Entering(vehicle_pos) if flash_time > 0 then flash_time = flash_time - dt if flash_time <= 0 then Delete(travel_flash) else SetLightIntensity(travel_flash, travel_lightintensity - 0.5) end end end if IsHandleValid(timemachine_body) and not cutscene_activated and not floating then if GetBodyVelocity(timemachine_body)[2] < 0.001 then SetBodyDynamic(timemachine_body, false) local van_pos = vanspawnt.pos for i=1, #vanholest do MakeHole(vanholest[i], 12,12,12) end Explosion(van_pos, 2) for i=1, #vanholest do MakeHole(vanholest[i], 12,12,12) end vanspawned = Spawn("MOD/runtime/prefabs/hub_lockelle/van.xml", vanspawnt) laptop_body = FindBody("laptop", true) van_body = FindBody("van", true) vandoor_shape = FindShape("vandoor", true) travel_flash_van = FindLight("travel_flash_van", true) travel_flash_van_time = current_time + 0.7 SetLightIntensity(travel_flash_van, 3) floating = true start_machine_transform = GetBodyTransform(timemachine_body) local hit, dist = QueryRaycast(GetBodyTransform(timemachine_body), Vec(0,1,0), 5) if dist > 1 then start_machine_transform.pos[2] = start_machine_transform.pos[2] + 3.75 - dist end machine_transform = GetBodyTransform(timemachine_body) end elseif IsHandleValid(timemachine_body) and not cutscene_activated and floating then Machine_Float() end if travel_flash_van_time ~= nil and current_time > travel_flash_van_time then --SetBodyDynamic(vanspawned[1], false) Delete(travel_flash_van) travel_flash_van_time = nil end if isLoopMusic and stingerfinish then PlayMusic("MOD/sound/time-travel-theme-wait-loop.ogg") end --DrawBodyOutline(van, 0.5) if IsHandleValid(van_body) and VecLength(GetBodyVelocity(van_body)) > 0.8 and not cutscene_done then local vanmin, vanmax = GetBodyBounds(van_body) QueryRequire("physical dynamic large") QueryRejectBody(van_body) QueryRejectBody(timemachine_body) QueryRejectBody(laptop_body) QueryRejectShape(vandoor_shape) local shapelist = QueryAabbShapes(vanmin, vanmax) for i = 1, #shapelist do Delete(shapelist[i]) end elseif travel_flash_van_time == nil and IsHandleValid(van_body) and VecLength(GetBodyVelocity(van_body)) <= 0.8 and not cutscene_done then cutscene_done = true SetBodyAngularVelocity(van_body, Vec(0,0,0)) SetBodyVelocity(van_body, VecScale(GetBodyVelocity(van_body),-1)) end if stingerplay and not stingerfinish then stingettimer = stingettimer + dt if stingettimer > 14.5 then stingerfinish = true RemoveTag(vanspawned[1], "unbreakable") end end end function update(dt) --DebugCross(TransformToParentPoint(vanspawnt, Vec(4,0,0))) --DebugCross(TransformToParentPoint(vanspawnt, Vec(2,0,0))) if IsHandleValid(timemachine_body) then Floating_Dust() end if cutscene_activated then for i = 1, #firewheel do local fireplace = GetBodyTransform(firewheel[i]).pos SpawnFire(VecSub(fireplace, Vec(0,-0.5, 0))) end if not floating then local rocket_light = FindLights("rocket_light", true) for i = 1, #rocket_light do ParticleColor(0.48, 0.33, 0.68) explosionSparksCPP(GetLightTransform(rocket_light[i]).pos, math.random(4,8), 1) end end end end function Machine_Entering(v_pos) local com = TransformToLocalPoint(vt, Vec(0.5,19,8)) MakeHole(v_pos,5,5,5) for i = 1 ,#level_vehicles do local distance_vec = VecSub(GetVehicleTransform(level_vehicles[i]).pos, v_pos) if VecLength(distance_vec) < 1.5 then local imp = VecScale(VecNormalize(distance_vec), 10000) ApplyBodyImpulse(GetVehicleBody(level_vehicles[i]), GetVehicleTransform(level_vehicles[i]).pos, imp) end end SetBodyVelocity(timemachine_body, time_machine_speed) SetBodyAngularVelocity(timemachine_body, Vec(0.015, 1, 0.035)) time_machine_speed[1] = time_machine_speed[1] - 0.25 time_machine_speed[2] = time_machine_speed[2] + 0.025 time_machine_speed[3] = time_machine_speed[3] - 0.025 if time_machine_speed[1] <= -1.95 then cutscene_activated = false RemoveTag(terrain, "unbreakable") local rocket_light = FindLights("rocket_light", true) for i = 1, #rocket_light do SetLightIntensity(rocket_light[i], 0) end end end function Machine_Float() if machine_up then machine_transform.pos[2] = machine_transform.pos[2] + 0.001 else machine_transform.pos[2] = machine_transform.pos[2] - 0.001 end if machine_pitch and floating_adjusted then machine_transform.rot[1] = machine_transform.rot[1] + 0.0005 else machine_transform.rot[1] = machine_transform.rot[1] - 0.0005 end if not floating_adjusted then if machine_transform.rot[1] < -0.006 then machine_transform.rot[1] = machine_transform.rot[1] + 0.001 else machine_transform.rot[1] = machine_transform.rot[1] - 0.001 end if machine_transform.rot[2] < 0.38 then machine_transform.rot[2] = machine_transform.rot[2] + 0.001 else machine_transform.rot[2] = machine_transform.rot[2] - 0.001 end if machine_transform.rot[3] < 0.035 then machine_transform.rot[3] = machine_transform.rot[3] + 0.001 else machine_transform.rot[3] = machine_transform.rot[3] - 0.001 end if (machine_transform.rot[1] < 0 and machine_transform.rot[1] > -0.01) and(machine_transform.rot[3] > 0.02 and machine_transform.rot[3] < 0.04) and (machine_transform.rot[2] > 0.37 and machine_transform.rot[2] < 0.39) then floating_adjusted = true start_machine_transform.rot = GetBodyTransform(timemachine_body).rot end end SetBodyTransform(timemachine_body, machine_transform) if (machine_transform.pos[2] > start_machine_transform.pos[2] + 0.2 and machine_up) or (machine_transform.pos[2] < start_machine_transform.pos[2] - 0.2 and not machine_up) then machine_up = not machine_up end if machine_transform.rot[1] > start_machine_transform.rot[1] + 0.02 or machine_transform.rot[1] < start_machine_transform.rot[1] - 0.02 then machine_pitch = not machine_pitch end end function Floating_Dust() for i = 1, #wheels_lights do QueryRejectBody(timemachine_body) local wheelpos = GetLightTransform(wheels_lights[i]).pos local hit, dist = QueryRaycast(wheelpos, Vec(0, -1,0), 3) local pos = VecSub(wheelpos, VecScale(Vec(0,1,0), dist)) --pos[2] = pos[2] - 0.5 if hit then ParticleReset() ParticleColor(0.8, 0.75, 0.7) ParticleRadius(0.2, 0.6) ParticleAlpha(1, 0, "easeout") ParticleDrag(0.2) local x = rnd(-0.1, 0.1) local y = rnd(-0.1, 0.1) local z = rnd(-0.1, 0.1) local d = VecNormalize(Vec(x, y, z)) SpawnParticle(pos, VecScale(d, rnd(1,4)), rnd(0.3, 0.75)) end end end function Travelling_Sparks() local light_goal = GetLightTransform(travel_flash).pos light_goal[2] = light_goal[2] - 1 for i=1, #travel_spark do local light_shape = GetLightShape(travel_spark[i]) local light_body = GetShapeBody(light_shape) local light_shape_pos = GetBodyTransform(light_body).pos local dir = VecNormalize(VecSub(light_goal, light_shape_pos)) SetLightIntensity(travel_spark[i], 0.01 * travel_lightintensity) local new_pos = Transform(VecAdd(GetBodyTransform(light_body).pos, VecScale(dir, 0.05 * travel_lights_coef))) new_pos.pos[2] = new_pos.pos[2] + rnd(-0.1, 0.1) SetBodyTransform(light_body, new_pos) end travel_lights_coef = travel_lights_coef + 0.01 travel_lightintensity = travel_lightintensity * travel_lights_coef end