#include "script/common.lua" deadTime = 0 frame = 0 function rnd(mi, ma) return math.random(1000)/1000*(ma-mi) + mi end function rndVec(t) return Vec(rnd(-t, t), rnd(-t, t), rnd(-t, t)) end function init() vehicle = FindVehicle() blinkShape = FindShape("blink") detonatorShape = FindShape("detonator") gTarget = FindBody("target") oceanTrigger = FindTrigger("ocean") frame = 0 win = false winTimer = 0 winPos = Vec() explosionPos = Vec() deadCamDist = 10 deadTime = 0 deadExplosion = false deadExplosion2 = false deadExplosion3 = false dead = false end function update(dt) frame = frame + 1 if dead then deadCamDist = deadCamDist + 0.03 return end if frame%30 > 15 then SetShapeEmissiveScale(blinkShape, 1) else SetShapeEmissiveScale(blinkShape, 0) end end function tickExplosion(dt) deadTime = deadTime + dt if deadTime > 0.3 and not deadExplosion then Explosion(explosionPos, 4.0) SetString("level.state", "fail_dead") deadExplosion = true end if deadTime > 0.6 and not deadExplosion2 then Explosion(VecAdd(explosionPos, Vec(-2, 0, 2)), 4.0) deadExplosion2 = true end if deadTime > 0.9 and not deadExplosion3 then Explosion(VecAdd(explosionPos, Vec(-4, 0, -2)), 4.0) deadExplosion3 = true end local target = explosionPos local dir = VecNormalize(Vec(1, 1, -1)) local eye = VecAdd(target, VecScale(dir, deadCamDist)) local t = Transform(eye, QuatLookAt(eye, target)) SetCameraTransform(t, 90) SetTimeScale(0.2) ParticleTile(5) ParticleCollide(0) ParticleColor(1, 0.6, 0.4, 1, 0.3, 0.2) ParticleEmissive(6.0, 0.0, "easeout") ParticleAlpha(math.min(1.0, deadTime), 0) ParticleRadius(0.3, 5.0) for i=1, 5 do SpawnParticle(target, Vec(rnd(-5, 5), rnd(0, 2), rnd(-5,5)), rnd(0.5, 1.0)*(1.0+deadTime)*2.0) end ParticleReset() ParticleType("plain") ParticleColor(0.8, 0.75, 0.7) ParticleAlpha(math.min(1.0, deadTime), 0) ParticleRadius(0.4, 3.0) for i=1, 5 do SpawnParticle(target, Vec(rnd(-8, 8), rnd(0, 2), rnd(-8,8)), rnd(0.5, 1.0)*(1.0+deadTime)*2.0) end PointLight(VecAdd(target, Vec(0, 1, 0)), 1, 0.5, 0.2, 1000*math.min(1.0, deadTime)) end function tick(dt) local vt = GetVehicleTransform(vehicle) if dead then tickExplosion(dt) end if win then winTimer = winTimer + dt local target = winPos local dir = VecNormalize(Vec(1, 0.5, -1)) local eye = VecAdd(target, VecScale(dir, 40.0)) local t = Transform(eye, QuatLookAt(eye, target)) SetCameraTransform(t, 90) if winTimer > 1.0 then SetString("level.state", "win") end end DriveVehicle(vehicle, 1.0, 0, false) if not dead and not win then local mi, ma = GetShapeBounds(detonatorShape) local origin = VecLerp(mi, ma, 0.5) local dir = TransformToParentVec(vt, Vec(0, 0, -1)) QueryRejectShape(detonatorShape) QueryRequire("physical large") local LINE_DIST = 10 local hit, dist = QueryRaycast(origin, dir, LINE_DIST) if not hit then dist = LINE_DIST end local current = math.fmod(GetTime(), 1.0) - 0.5 for i=1, LINE_DIST do local p0 = VecAdd(origin, VecScale(dir, current)) local d = math.min(current + 0.5, dist) local p1 = VecAdd(origin, VecScale(dir, d)) DrawLine(p0, p1, 1, 1, 1, 0.5 * (1.0-(i/LINE_DIST))) current = current + 1.0 if current > dist then break end end if not dead and not win and IsShapeBroken(detonatorShape) then explosionPos = GetShapeWorldTransform(blinkShape).pos deadCamDist = 8 deadTime = 0 dead = true end end local fwd = TransformToParentVec(vt, Vec(0, 0, -1)) local vb = GetVehicleBody(vehicle) local com = TransformToParentPoint(GetBodyTransform(vb), Vec(0, 0, -3)) fwd[2] = 0 fwd = VecNormalize(fwd) ConstrainVelocity(vb, 0, com, fwd, 1, 0, 10000) if not dead and not win and IsVehicleInTrigger(oceanTrigger, vehicle) then win = true winPos = vt.pos SetTag(gTarget, "target", "cleared") end end