/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ * Spawns a new set of grenades. networkSpawn allows us to determine if the server is spawning the grenades and if it's a local spawn, we'll tell the server we've fired grenades * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ public static void CreateGrenade(ShipRefs ship) { // if we're a player then play a 2D deployment sound if (ship.IsPlayer) { AudioHelpers.PlayOneShot(AudioHelpers.GetAudioClip(AudioHelpers.Weapons_MineDrop), AudioHelpers.E_AUDIOCHANNEL.SFX, 1.0f, 1.0f); } // create the grenades GrenadeObject.CreateNew(ship.transform.TransformPoint(-GrenadeSpawnSpread, 0.0f, ship.MeshBoundsFront.z), ship.RBody.rotation, ship); GrenadeObject.CreateNew(ship.transform.TransformPoint(0.0f, 0.0f, 1.0f), ship.RBody.rotation, ship); GrenadeObject.CreateNew(ship.transform.TransformPoint(GrenadeSpawnSpread, 0.0f, ship.MeshBoundsFront.z), ship.RBody.rotation, ship); }
/* This is called every time a ship passes the mid line. r is the reference to the ship that has passed. */ public override void OnShipTriggerMidLine(ShipRefs r) { // validate the lap so it can be updated next time the player triggers the start line r.LapValidated = true; r.MiddleSection = r.CurrentSection; if (r.IsPlayer && !r.PassedValidationGate) { AudioHelpers.PlayOneShot(AudioHelpers.UI_Checkpoint, AudioHelpers.E_AUDIOCHANNEL.INTERFACE, 1.0f, 1.0f); CalculateAndDisplayRelativeTime(r); r.PassedValidationGate = true; } }
/*----------------------------------------------------------------------------------------------------------------------- * Assuming the prefab is setup correctly with the environment collider being solid and the ship collider being a trigger, * this will trigger when the environment collider starts to collide with something. * ----------------------------------------------------------------------------------------------------------------------*/ private void OnCollisionEnter(Collision other) { int otherLayer = other.gameObject.layer; /*------------------------------------------------------ * Determine if we've hit the track or floor. * We could also determine if we hit a wall by using: * * bool hitwall = otherLayer == LayerIDs.TrackWall; * -----------------------------------------------------*/ bool hitFloor = otherLayer == LayerIDs.SmoothFloor || other.gameObject.layer == LayerIDs.FakeFloor || other.gameObject.layer == LayerIDs.TrackFloor; // reflect the grenade if (hitFloor) { Vector3 bounceNormal = other.contacts[0].normal; // reflect the forward vector of the grenade Vector3 forward = transform.forward; forward = Vector3.Reflect(forward, bounceNormal); transform.forward = forward; Body.AddForce(bounceNormal * StatBounceForce, ForceMode.VelocityChange); StatBounceForce *= 0.9f; // play Impact Sound AudioHelpers.PlayOneShot(AudioHelpers.GetAudioClip(AudioHelpers.Ship_FloorHit), AudioHelpers.E_AUDIOCHANNEL.SFX, 0.4f, 1.0f, transform.position, null, 15.0f, 30.0f); if (BounceCount > StatMaxBounces) { DestroyProjectile(null); } // temporary bounce count immunity if (Lifetime > 0.5f) { ++BounceCount; } } else { DestroyProjectile(null); } }
/* This is called every time a ship passes the start line, r is the reference to the ship that has passed. */ public override void OnShipTriggerStartLine(ShipRefs r) { /* If this lap has been validated or the ship hasn't done any laps yet, then we want to do some stuff. */ if (r.LapValidated || r.CurrentLap == 0) { // invalidate the lap again r.LapValidated = false; /* If the ship has finished a lap and is not on the last lap then we want to store and display some information. */ if (r.CurrentLap > 0 && r.CurrentLap <= Race.MaxLaps) { if (r.IsPlayer) { /* Update best time */ if ((r.CurrentLapTime < r.BestLapTime || !r.HasBestLapTime) && !r.LoadedBestLapTime) { r.BestLapTime = r.CurrentLapTime; r.HasBestLapTime = true; } /* Perfect lap notification */ if (r.IsPerfectLap) { // this triggers an onscreen message to appear. You can provide a color or you can write it using richtext in the string. BallisticEvents.Ui.CallOnTriggerMessage("PERFECT LAP", r, ScriptableHud.BnGAccent); // this plays a voice, you can feed this any sound you want (if you load your own you can also use that). AudioHelpers.PlayVoice(AudioHelpers.Voice_PerfectLap); } /* Interface sounds */ if (r.CurrentLap == Race.MaxLaps - 1) { BallisticEvents.Ui.CallOnTriggerMessage("FINAL LAP", r, ScriptableHud.BnGAccent); AudioHelpers.PlayVoice(AudioHelpers.Voice_FinalLap); } AudioHelpers.PlayOneShot(AudioHelpers.UI_Checkpoint, AudioHelpers.E_AUDIOCHANNEL.INTERFACE, 1.0f, 1.0f); } // set values for current lap r.LapTimes[r.CurrentLap - 1] = r.CurrentLapTime; r.PerfectLaps[r.CurrentLap - 1] = r.IsPerfectLap; } /* Tasks for when the ship has completed the race */ if (r.CurrentLap >= Race.MaxLaps && !r.FinishedEvent && !r.Eliminated) { r.FinishedEvent = true; // calling this does some needed config to mark the ship as having finished RaceHelpers.FinishRace(r); // if this is a player ship then set the ship as an AI ship and then save the time if (r.IsPlayer) { // destroy the ship camera and replace it with the finished camera Object.Destroy(r.ShipCamera.GetComponent <ShipCamera>()); ShipFCam finishCam = r.ShipCamera.gameObject.AddComponent <ShipFCam>(); finishCam.r = r; r.IsAi = true; SaveTime(r); } } /* Reset timers and states */ // this resets the current laps time to zero r.CurrentLapTime = 0.0f; r.IsPerfectLap = true; ++r.CurrentLap; r.PassedValidationGate = false; // this clears the hit weapon pads so ships can use them again r.ClearHitPads(); BallisticEvents.Race.CallOnShipLapUpdate(r); // this calculates the time between this ship and another (depending on the ships position) if (r.IsPlayer) { CalculateAndDisplayRelativeTime(r); } // give the ship a turbo PickupRegistry.GivePickupToShip(r, PickupRegistry.FindPickupByName("turbo")); } }