public KnightyCamera(string name) : base(name) { var sceneMgr = LKernel.GetG<SceneManager>(); // make our camera and set some properties Camera = sceneMgr.CreateCamera(name); Camera.NearClipDistance = 0.1f; Camera.FarClipDistance = 700f; Camera.AutoAspectRatio = true; // create the nodes we're going to interpolate CameraNode = sceneMgr.RootSceneNode.CreateChildSceneNode(name + "_KnightyCameraNode", new Vector3(0, Settings.Default.CameraNodeYOffset, Settings.Default.CameraNodeZOffset)); TargetNode = sceneMgr.RootSceneNode.CreateChildSceneNode(name + "_KnightyCameraTargetNode", new Vector3(0, Settings.Default.CameraTargetYOffset, 0)); CameraNode.SetAutoTracking(true, TargetNode); CameraNode.SetFixedYawAxis(true); CameraNode.AttachObject(Camera); // create the fixed nodes that are attached to the kart followKart = LKernel.GetG<PlayerManager>().MainPlayer.Kart; kartCamNode = followKart.RootNode.CreateChildSceneNode(name + "_KartKnightyCameraNode", new Vector3(0, Settings.Default.CameraNodeYOffset, Settings.Default.CameraNodeZOffset)); kartTargetNode = followKart.RootNode.CreateChildSceneNode(name + "_KartKnightyCameraTargetNode", new Vector3(0, Settings.Default.CameraTargetYOffset, 0)); CameraNode.Position = kartCamNode._getDerivedPosition(); TargetNode.Position = kartTargetNode._getDerivedPosition(); // initialise some stuff for the ray casting rayLength = (CameraNode.Position - TargetNode.Position).Length; world = LKernel.GetG<PhysicsMain>().World; }
/// <summary> /// USE THE LThingHelperManager FOR THIS! /// </summary> public Skidder(Kart kart, float duration = 0.5f) { this.kart = kart; this.duration = duration; PhysicsMain.PreSimulate += PreSimulate; }
/// <summary> /// Creates a wheel. /// </summary> /// <param name="wheelName"> /// The name of the wheel type you want to create. Should be the same as the filename, minus the extension. Case sensitive! /// </param> public Wheel CreateWheel(string wheelName, WheelID ID, Kart owner, Vector3 position, string meshName) { IDictionary<string, float> dict = wheels[wheelName]; Wheel wheel = new Wheel(owner, position, ID, dict, meshName); return wheel; }
public void OnFirstFinish(Kart target) { if (target.Player == LKernel.Get<PlayerManager>().MainPlayer) { winnerLabel.Text = "You win!"; winnerGui.Visible = true; } else { winnerLabel.Text = "You lose!"; winnerGui.Visible = true; } }
/// <param name="thing">The connected lthing, used for updating sounds. You can pass null to skip updating sounds.</param> public KartMotionState(Kart kart, Vector3 position, Quaternion orientation, SceneNode node) : base(kart, position, orientation, node) { transform = new Matrix4(orientation); transform.MakeTransform(position, Vector3.UNIT_SCALE, orientation); this.node = node; this.kart = kart; lastPosition = position; lastOrientation = orientation; }
public void AttachToKart(Kart kart, Vector3 offset) { kart.Driver = this; this.Kart = kart; this.RootNode.Parent.RemoveChild(this.RootNode); kart.RootNode.AddChild(this.RootNode); this.RootNode.Position = offset; this.RootNode.Orientation = Quaternion.IDENTITY; this.RootNode.SetInitialState(); }
public void Detach() { if (kart != null) { if (Finished != null) Finished(this, kart); // reset it back to normal kart.ForEachWheel(w => { w.Friction = w.DefaultFrictionSlip; }); PhysicsMain.PreSimulate -= PreSimulate; kart = null; } }
public AttachCamera(string name) : base(name) { var sceneMgr = LKernel.GetG<SceneManager>(); Camera = sceneMgr.CreateCamera(name); Camera.NearClipDistance = 0.1f; Camera.FarClipDistance = 700f; Camera.AutoAspectRatio = true; FollowKart = LKernel.GetG<PlayerManager>().MainPlayer.Kart; CameraNode = FollowKart.RootNode.CreateChildSceneNode(name + "AttachCamera"); CameraNode.AttachObject(Camera); CameraNode.SetFixedYawAxis(true); }
void OnGround(Kart kart, CollisionWorld.ClosestRayResultCallback callback) { // we need to wait two "ticks" of the ray casting (0.1s total at time of writing) before we stop the emitter again // we could just wait one, but that's too short // the little boolean stuff is just a sort of "toggle" between the two ticks // we can't really unhook from the events because we've got multiple karts bool wait; if (waitDict.TryGetValue(kart, out wait)) { if (!wait) particles[kart].Emitting = false; else waitDict[kart] = true; } else waitDict[kart] = true; }
public ChaseCamera(string name) : base(name) { var sceneMgr = LKernel.GetG<SceneManager>(); Camera = sceneMgr.CreateCamera(name); Camera.NearClipDistance = 0.1f; Camera.FarClipDistance = 700f; Camera.AutoAspectRatio = true; CameraNode = sceneMgr.RootSceneNode.CreateChildSceneNode(name + "ChaseCamera"); CameraNode.AttachObject(Camera); CameraNode.SetFixedYawAxis(true); FollowKart = LKernel.GetG<PlayerManager>().MainPlayer.Kart; Camera.SetAutoTracking(true, FollowKart.RootNode, new Vector3(0, 0.4f, 0)); }
/// <summary> /// Just a little helper function to make a new orientation for us to use for our nlerpers /// </summary> /// <param name="kart">The kart we want to rotate</param> /// <returns>A quaternion representing the new orientation you want the kart to be when the nlerper's done.</returns> private Quaternion makeNewOrientation(Kart kart, StartOrStopState state) { // make the angle we need to rotate the kart by Radian angle; if ((state == StartOrStopState.StartDrifting && kart.DriftState == KartDriftState.StartLeft) || (state == StartOrStopState.StopDrifting && kart.DriftState == KartDriftState.StopRight)) { angle = -kart.DriftTransitionAngle; } else if ((state == StartOrStopState.StartDrifting && kart.DriftState == KartDriftState.StartRight) || (state == StartOrStopState.StopDrifting && kart.DriftState == KartDriftState.StopLeft)) { angle = kart.DriftTransitionAngle; } else throw new ApplicationException("How did we get here?"); Quaternion rot = new Quaternion(angle, kart.ActualOrientation.YAxis); Quaternion newOrientation = kart.ActualOrientation * rot; return newOrientation; }
/// <summary> /// Run when our short ray detects that we're not on the ground any more /// </summary> private void Liftoff(Kart kart, DynamicsWorld.ClosestRayResultCallback callback) { #if SELFRIGHTERS // make a new SRH SelfRighters.GetOrAdd(kart, new SelfRighter(kart)); #endif // we are in the air kart.IsInAir = true; CurrentlyDrivingOn[kart] = null; if (OnLiftoff != null) OnLiftoff(kart, callback); }
void OnPlayerLap(Kart kart, int newLapCount) { derpy.ChangeAnimation("FlagWave2"); timer.Change(3000, Timeout.Infinite); }
void OnPlayerFinish(Kart kart) { derpy.ChangeAnimation("FlagWave1"); }
void OnTouchdown(Kart kart, CollisionWorld.ClosestRayResultCallback callback) { particles[kart].Emitting = true; waitDict[kart] = false; }
/// <summary> /// update the particle emission rates depending on speed /// </summary> void OnGround(Kart kart, CollisionWorld.ClosestRayResultCallback callback) { float speed = System.Math.Abs(kart.VehicleSpeed); // if the kart is moving slowly, then just turn the particles completely off if (speed < 6) { if (kartSpeedStates[kart.OwnerID] != KartSpeedState.Slow) { // update this if we need to kartSpeedStates[kart.OwnerID] = KartSpeedState.Slow; BothEmitting(kart.OwnerID, false); } } // if we're moving at a medium speed else if (speed >= 6 && speed < 30) { if (kartSpeedStates[kart.OwnerID] != KartSpeedState.Medium) { // update this if we need to kartSpeedStates[kart.OwnerID] = KartSpeedState.Medium; if (callback.CollisionObject == dirtBody) DirtEmitting(kart.OwnerID, true); else if (callback.CollisionObject == grassBody) GrassEmitting(kart.OwnerID, true); } // make some new emission rates float dustEmissionRate = (speed / 30) * defaultDustEmissionRate; float grassEmissionRate = (speed / 30) * defaultGrassEmissionRate; float mudEmissionRate = (speed / 30) * defaultMudEmissionRate; // and update the particles Pair<WheelHelper, WheelHelper> pair = wheelHelpers[kart.OwnerID]; pair.first.dust.GetEmitter(0).EmissionRate = dustEmissionRate; pair.second.dust.GetEmitter(0).EmissionRate = dustEmissionRate; pair.first.grass.GetEmitter(0).EmissionRate = grassEmissionRate; pair.second.grass.GetEmitter(0).EmissionRate = grassEmissionRate; pair.first.mud.GetEmitter(0).EmissionRate = mudEmissionRate; pair.second.mud.GetEmitter(0).EmissionRate = mudEmissionRate; } // and if we're moving at a fast speed else { if (kartSpeedStates[kart.OwnerID] != KartSpeedState.Fast) { kartSpeedStates[kart.OwnerID] = KartSpeedState.Fast; // and update the particles Pair<WheelHelper, WheelHelper> pair = wheelHelpers[kart.OwnerID]; pair.first.dust.GetEmitter(0).EmissionRate = defaultDustEmissionRate; pair.second.dust.GetEmitter(0).EmissionRate = defaultDustEmissionRate; pair.first.grass.GetEmitter(0).EmissionRate = defaultGrassEmissionRate; pair.second.grass.GetEmitter(0).EmissionRate = defaultGrassEmissionRate; pair.first.mud.GetEmitter(0).EmissionRate = defaultMudEmissionRate; pair.second.mud.GetEmitter(0).EmissionRate = defaultMudEmissionRate; } } }
/// <summary> /// Detach from the kart /// </summary> public void DetachFromKart() { if (followKart == null) return; LKernel.GetG<Root>().FrameStarted -= FrameStarted; Launch.OnEveryUnpausedTenthOfASecondEvent -= EveryTenth; //this.RootNode.Position = Vector3.ZERO; // reattach it to the scene's root scene node so she still gets rendered followKart.RootNode.RemoveChild(interpNode); interpNode.Creator.RootSceneNode.AddChild(interpNode); followKart = null; }
/// <summary> /// Specifies a kart to follow around /// </summary> public void AttachToKart(Vector3 offset, Kart kart) { this.followKart = kart; // attach this to the kart's node interpNode.Parent.RemoveChild(interpNode); kart.RootNode.AddChild(interpNode); this.RootNode.Position = Vector3.ZERO; interpNode.Position = offset; LKernel.GetG<Root>().FrameStarted += FrameStarted; Launch.OnEveryUnpausedTenthOfASecondEvent += EveryTenth; }
// since the only times this method is called is inside #if NLERPERS, we can put this entire method inside it too #if NLERPERS /// <summary> /// Aligns the kart with the callback's normal /// </summary> /// <param name="useNlerp">Should we use a nlerper? If false, this just updates the orientation instantly.</param> private void AlignKartWithNormal(Kart kart, DynamicsWorld.ClosestRayResultCallback callback, bool useNlerp, float duration = 1) { // don't add a nlerper if we're drifting if (kart.IsDriftingAtAll) return; // don't bother if they're already within 1 degree of each other if (kart.ActualOrientation.YAxis.DirectionEquals(callback.HitNormalWorld, 0.01745f)) return; // get the rotation we need to do to rotate this kart to the ground's normal Quaternion rotTo = kart.ActualOrientation.YAxis.GetRotationTo(callback.HitNormalWorld); // rotTo * old orientation is the same as rotate(rotTo) on SceneNodes, but since this isn't a scene node we have to do it this way Quaternion newOrientation = rotTo * kart.ActualOrientation; if (useNlerp) { // if we already have a nlerper, get rid of it helperMgr.RemoveNlerper(kart); helperMgr.CreateNlerper(kart, duration, newOrientation); } else { // update our body kart.Body.SetOrientation(newOrientation); } }
/// <summary> /// Run when our kart is still on the ground /// </summary> private void Ground(Kart kart, DynamicsWorld.ClosestRayResultCallback callback) { // first get the object we're currently driving on CollisionObject current; if (CurrentlyDrivingOn.TryGetValue(kart, out current)) { // if it's different than the old one, then we need to run our event and update the dictionary if (current != callback.CollisionObject) { // run the event if (OnGroundChanged != null) OnGroundChanged(kart, callback.CollisionObject, CurrentlyDrivingOn[kart]); // and then update the dictionary CurrentlyDrivingOn[kart] = callback.CollisionObject; } } // run this too if (OnGround != null) OnGround(kart, callback); }
/// <summary> /// Run when our short ray penetrates the ground but we have not yet "landed" /// </summary> private void TouchDown(Kart kart, DynamicsWorld.ClosestRayResultCallback callback) { // now we have actually landed kart.IsInAir = false; #if NLERPERS // if we have a nlerper, get rid of it helperMgr.RemoveNlerper(kart); #endif #if SKIDDERS // add a skidder! helperMgr.CreateSkidder(kart, skidderDuration); #endif #if NLERPERS // align the kart just to make sure AlignKartWithNormal(kart, callback, true, 0.1f); #endif CurrentlyDrivingOn[kart] = callback.CollisionObject; if (OnTouchdown != null) OnTouchdown(kart, callback); }
/// <summary> /// Change the particles appropriately /// </summary> void OnGroundChanged(Kart kart, CollisionObject newGround, CollisionObject oldGround) { if (newGround == dirtBody) DirtEmitting(kart.OwnerID, true); else if (oldGround == dirtBody) DirtEmitting(kart.OwnerID, false); if (newGround == grassBody) GrassEmitting(kart.OwnerID, true); else if (oldGround == grassBody) GrassEmitting(kart.OwnerID, false); }
public SelfRighter(Kart kartToFlip) { kart = kartToFlip; PhysicsMain.PreSimulate += PreSimulate; }
/// <summary> /// Casts a ray downwards from the given kart /// </summary> /// <returns>The ray result callback</returns> private DynamicsWorld.ClosestRayResultCallback CastRay(Kart kart, float rayLength, DiscreteDynamicsWorld world) { // get a ray pointing downwards from the kart (-Y axis) Vector3 from = kart.ActualPosition + kart.ActualOrientation.YAxis; // have to move it up a bit Vector3 to = from - kart.ActualOrientation.YAxis * (rayLength + 1); // add 1 to compensate for the "moving up" we did to the "from" vector // make our ray var callback = new DynamicsWorld.ClosestRayResultCallback(from, to); // we only want the ray to collide with the environment and nothing else callback.CollisionFilterMask = rayFilterGroup; world.RayTest(from, to, callback); #if DEBUG //MogreDebugDrawer.Singleton.DrawLine(from, to, ColourValue.Red); #endif return callback; }
/// <summary> /// turn on the appropriate particles /// </summary> void OnTouchdown(Kart kart, CollisionWorld.ClosestRayResultCallback callback) { if (kart.VehicleSpeed > 4f || kart.VehicleSpeed < -4f) { if (callback.CollisionObject == dirtBody) DirtEmitting(kart.OwnerID, true); else if (callback.CollisionObject == grassBody) GrassEmitting(kart.OwnerID, true); } else { DirtEmitting(kart.OwnerID, false); GrassEmitting(kart.OwnerID, false); } }
/// <summary> /// turn off all particles /// </summary> void OnLiftoff(Kart kart, CollisionWorld.ClosestRayResultCallback callback) { BothEmitting(kart.OwnerID, false); }
public void Detach() { PhysicsMain.PreSimulate -= PreSimulate; kart = null; }
/// <summary> /// Run when our kart is currently in the air /// </summary> private void InAir(Kart kart, DynamicsWorld.ClosestRayResultCallback callback) { if (OnInAir != null) OnInAir(kart, callback); }
/// <summary> /// Gets the lap count for the given kart. /// </summary> public int GetLapCount(Kart kart) { return lapData[kart.OwnerID].second; }
/// <summary> /// Run when our long ray penetrates the ground /// </summary> private void GettingCloseToTouchingDown(Kart kart, DynamicsWorld.ClosestRayResultCallback callback, SelfRighter srh) { #if SELFRIGHTERS // getting rid of our SRH means that we're close to landing but we haven't landed yet srh.Detach(); SelfRighters.TryRemove(kart, out srh); #endif #if NLERPERS AlignKartWithNormal(kart, callback, true, 0.2f); #endif if (OnCloseToTouchdown != null) OnCloseToTouchdown(kart, callback); }