} // end of Free() /// <summary> /// Old-style action. Should be replaced? TargetDirectionAction? /// /// We still use this for stuff like shooting. /// /// WHEN See Apple DO Shoot /// gameThing is the nearest apple /// direction is the direction to shoot /// distance is distance to apple /// /// WHEN GamePad AButton DO Shoot /// gameThing is null /// direction is forward /// distance is 1 /// /// </summary> /// <param name="distance"></param> /// <param name="direction"></param> /// <param name="gameThing"></param> /// <param name="reflex"></param> /// <param name="canBlend"></param> /// <param name="specialInstruction"></param> /// <returns></returns> static public Attractor AllocAttractor(float distance, Vector3 direction, GameThing gameThing, Reflex reflex, bool canBlend = false, BaseAction.SpecialInstruction specialInstruction = BaseAction.SpecialInstruction.None) { Attractor attractor; // Recycle an attractor if possible. If not, create a new one. if (AttractorFreeList.Count > 0) { attractor = AttractorFreeList[AttractorFreeList.Count - 1]; AttractorFreeList.RemoveAt(AttractorFreeList.Count - 1); } else { attractor = new Attractor(); } // Fill in the data. attractor.Init(distance, direction, gameThing, reflex, canBlend, specialInstruction); return(attractor); } // end of AllocAttractor()
} // end of PostBrainUpdate() protected override bool DoPush(BaseAction effector, GameThing directObject, bool quiet, bool reverse) { Pushing = true; PushingReverse = reverse; return(base.DoPush(effector, directObject, quiet, reverse)); } // end of DoPush()
} // end of PlayEmoSwearing() public static void PlayEmoNone(GameThing emitter) { emoFlowers.Stop(emitter); emoLove.Stop(emitter); emoStars.Stop(emitter); emoSwearing.Stop(emitter); } // end of PlayEmoNone()
} // end of CheckCollisions() public void HitTarget(GameThing hitThing, HitInfo hitInfo) { if (hitThing != null) { // Tell the launcher what we hit. launcher.OnMissileHit(hitThing, hitInfo.Center, verbPayload, damage); // Apply the damage to the target. // We only need to do this if the launcher is dead. Otherwise the above // notification will get processed and the damage will be taken into // account there. Yes, this is kind of confusing and should be rethought // and cleaned up. // TODO (****) if (Launcher.CurrentState == GameThing.State.Inactive) { bool targetDied = false; hitThing.DoDamage(-damage, verbPayload, true, false, Launcher, out targetDied); } // Kill off the missile. missile.Deactivate(); // Gratuitous effects. PlayExplodeEffect(hitInfo.Center); } } // end of HitTarget()
public override void ThingUpdate(GameActor gameActor, GameThing gameThing, Vector3 direction, float range) { if (terrainSensor != null) { terrainSensor.ThingUpdate(gameActor, gameThing, direction, range); } }
public override void ThingUpdate(GameActor gameActor, GameThing gameThing, Vector3 direction, float range) { if (gameActor.ReadyToProcessEOP || gameThing.ReadyToProcessEOP) { senseSet.Add(gameThing, direction, range); } }
//helper function to determine if a given actor is selected (only selected actors snap) private bool IsSelectedActor(GameThing thing) { GameActor actor = thing as GameActor; //no selected actors in sim mode if (InGame.inGame.CurrentUpdateMode == InGame.UpdateMode.RunSim) { return(false); } if (GamePadInput.ActiveMode == GamePadInput.InputMode.KeyboardMouse && InGame.inGame.mouseEditUpdateObj.ToolBox.EditObjectsToolInstance.SelectedActor == actor) { return(true); } if (GamePadInput.ActiveMode == GamePadInput.InputMode.Touch && InGame.inGame.touchEditUpdateObj.ToolBox.EditObjectsToolInstance.FocusActor == actor) { return(true); } if (GamePadInput.ActiveMode == GamePadInput.InputMode.GamePad && InGame.inGame.editObjectUpdateObj.selectedObject == actor) { return(true); } return(false); }
/// <summary> /// Set up a distortion like new. /// </summary> /// <param name="owner"></param> /// <param name="inLife"></param> /// <param name="inMaxScale"></param> private void Setup(GameThing owner, float inLife, Vector3 inMaxScale) { this.owner = owner; lifeSpan = inLife; maxScale = inMaxScale; expires = true; rampUp = 0.2f; rampDown = 0.8f; bumpRadius = 1.0f; bumpStrength = 1.0f; bumpScale = new Vector4(3.0f, 3.0f, -3.0f, 3.0f); //bumpScale = new Vector4(1.0f, 1.0f, -1.0f, 1.0f); bumpScroll = new Vector4(0.0f, 0.0f, 0.0f, 0.0f); bumpRate = new Vector4(0.017f, 0.11f, 0.019f, -0.09f); //bumpRate = new Vector4(0.00f, 0.0f, 0.0f, -0.0f); birth = 0.0f; bloom = false; minScale = new Vector3(1.0f); scales = new Vector4(1.0f, 0.0f, 1.0f, 0.5f); numScaleBeats = 2; scale = new Vector3(1.0f); opacity = 0.0f; doBump = false; bumpTint = new Vector4(0.0f, 0.0f, 0.0f, 1.0f); }
} // end of UpdateColorPalette() // // TODO (****) These are (mostly) identical to the one in InGameEditObject. Should figure out how to share. // protected void UpdateAura() { if (DistortionManager.EnabledSM2 || DistortionManager.EnabledSM3) { /// If we have an object under edit focus, we'll /// want to highlight it. If it is selected, we /// highlight it red, else blue. /// First version, only supporting GameThing. /// Will probably want to give GameThing and Waypoint /// (and anything else "highlight"-able) a common base /// class, rather than let this continue this cut&paste /// love fest. GameThing focusThing = editFocusObject as GameThing; if (focusThing != null) { MakeAura(focusThing); Debug.Assert(selectionHighLight != null); selectionHighLight.TintAura(0.0f, 0.0f, 4.0f); } else { RemoveAura(); } } }
/// <summary> /// If nothing in the list is me (or descendent) already playing, /// Play myself and add myself to the list. /// Returns the new audiocue if it started one, else null. /// </summary> /// <param name="list"></param> public virtual AudioCue Play(GameThing emitter, List <AudioCue> list) { for (int i = 0; i < list.Count; ++i) { AudioCue cue = list[i]; Sound v = cue.Sound; if ((v != null) && v.BelongsTo(this)) { /// Already playing, just bail. return(null); } } /// Start a random child playing Sound leaf = Select(); AudioCue toplay = leaf.Play(emitter); if (emitter != null) { toplay.OnComplete += emitter.OnAudioCueComplete; } /// Add leaf to list list.Add(toplay); return(toplay); }
public override void PreCollisionTestUpdate(GameThing thing) { Movement movement = thing.Movement; DesiredMovement desiredMovement = thing.DesiredMovement; GameActor.State state = thing.CurrentState; float secs = Time.GameTimeFrameSeconds; if (state == GameActor.State.Active) { // Apply DesiredMovement values to current movement. ApplyDesiredMovement(movement, desiredMovement); float height = 0; bool bounce = CollideWithGround(movement, ref height); // Apply external force. movement.Velocity += desiredMovement.ExternalForce.GetValueOrDefault() / thing.Mass * secs; // Apply drag to velocity. ApplyFriction(movement, desiredMovement, applyVertical: true); // Apply velocity to position. movement.Position += movement.Velocity * secs; } }
public AudioCue GetCue(string name, GameThing thing) { AudioCue cue; if (spareCues.Count > 0) { // Reuse a spare AudioCue instance cue = spareCues[0]; spareCues.RemoveAt(0); } else { // No spare AudioCue instances available, so create a new one cue = new AudioCue(); } /// Ugly hack to disable 3d for non-positional sounds. /// Later we'll know whether a given sound is non-positional by examining its tag set. if (name.StartsWith("Mystery") || name.StartsWith("Driving") || name.StartsWith("Dramatic")) { thing = null; } // Initialize the sound cue cue.Set(SoundBank.GetCue(name), thing); // Apply initial 3D audio values cue.Apply3D(listener); // Keep track of the audio cue until it completes activeCues.Add(cue); return(cue); }
private void CheckWin(GameThing other) { if (other is Player) { GameController.game.WinLevel(); (other as Player).YouWon(); } }
/// <summary> /// Set up with a sound and an optional thing to follow. /// Doesn't start playing, that requires a separate call. /// </summary> /// <param name="cue"></param> /// <param name="thing"></param> public void Set(Cue cue, GameThing thing) { played = false; this.thing = thing; this.spatial = (thing != null); BokuGame.Release(ref this.cue); this.cue = cue; }
//helper function to determine all viable snap candidates given an actor and a starting position // will automatically reject candidates outside the configured min snap offset // will also automatically weight the previous frame's results higher to reduce jitter between two close snap points private void AddToCandidates(GameThing thing, Vector3 snapFromPosition, int sourceIndex, ref List <CandidateConnection> snapCandidates) { //loop over all game things looking for pipes for (int i = 0; i < InGame.inGame.gameThingList.Count; i++) { GameActor actor = InGame.inGame.gameThingList[i] as GameActor; if (actor != null && actor.Movement != null && actor != (thing as GameActor)) { if (actor.Chassis != null && actor.Chassis is PipeChassis) { //found a pipe that isn't ourself, look for candidates PipeChassis targetPipe = actor.Chassis as PipeChassis; List <PipeConnection> potentialSnapPoints = GenerateConnections(actor, actor.Movement.Position); //weight each candidate based on how far away it is - if too far, reject it completely foreach (PipeConnection nextSnapPoint in potentialSnapPoints) { Vector3 snapVector = nextSnapPoint.SourcePos - snapFromPosition; snapVector.Z = 0.0f; float distance = snapVector.Length(); //if distance is in max offset or, if it's exactly where we snapped to last time, allow for double the radius to consider it valid if (distance <= kMaxSnapOffset * Parent.ReScale || (m_bIsSnapped && m_lastSnapSourceIndex == sourceIndex && distance < kMaxSnapOffset * Parent.ReScale * 2.0f)) { float weight = 1.0f - MathHelper.Clamp(distance / kMaxSnapOffset, 0.0f, 1.0f); bool retainSnap = false; //special case: were we previously snapped to this exact target, from the same source? // if so, add some weight - we'd prefer to stay in place if (m_bIsSnapped && m_lastSnapSourceIndex == sourceIndex) { float distanceToLastSnapped = (m_lastSnapTarget - nextSnapPoint.SourcePos).Length(); if (distanceToLastSnapped < 0.001f) { weight += 1.0f; retainSnap = true; } } //found a candidate, add it to the lsit CandidateConnection newCandidate = new CandidateConnection { SourceConnectionIndex = sourceIndex, SnapToPosition = nextSnapPoint.SourcePos, UpDir = nextSnapPoint.SourceUpDir, CenterPosition = actor.Movement.Position, Weight = weight, RetainSnap = retainSnap }; snapCandidates.Add(newCandidate); } } } } } }
} // end of PlayCollision() /// <summary> /// Play audio for actor/terrrain collision /// </summary> /// <param name="actor"></param> /// <param name="material">Material index.</param> public static void PlayCollision(GameThing actor, ushort material) { // Get the proper collision sound from the material index. if (!TerrainMaterial.IsValid(material, false, false)) { //Debug.Assert(false, "Why do we have an invalid material here?"); // Why? Well because we sometimes clear the material in the feeler // collision testing. So it's no longer a valid way to tell what // terrain we're over. In general, it works when we're on the ground // but not when jumping. Argh. collisionMetalSoft.Play(actor); return; } PlayActorCollision(actor); CollisionSound cs = TerrainMaterial.Get(material).CollisionSound; switch (cs) { case CollisionSound.plasticHard: collisionPlasticHard.Play(actor); break; case CollisionSound.plasticSoft: collisionPlasticSoft.Play(actor); break; case CollisionSound.metalHard: collisionMetalHard.Play(actor); break; case CollisionSound.metalSoft: collisionMetalSoft.Play(actor); break; case CollisionSound.rover: collisionRover.Play(actor); break; case CollisionSound.dirt: collisionDirt.Play(actor); break; case CollisionSound.grass: collisionGrass.Play(actor); break; case CollisionSound.rock: collisionRock.Play(actor); break; default: break; } } // end of PlayCollision()
} // end of PlayGive() public static void PlayGlow(GameThing emitter) { // This audio effect breaks the levels Sequencer and Drive & Play. These levels // use the glow effect to indicate which rock is playing a sound. When the glow // effect itself makes a sound, chaos ensues, masking the beautiful music these // levels create. //glow.Play(emitter); } // end of PlayGlow()
/// <summary> /// Returns true if this thing should be excluded from being hit. /// </summary> /// <param name="thing"></param> /// <returns></returns> private bool ExcludedHitThing(GameActor shooter, GameThing thing) { return((thing == null) || (thing as CruiseMissile != null) || (thing == shooter) || (thing.ActorHoldingThis == shooter) || ((thing.CurrentState != GameThing.State.Active) && (thing.ActorHoldingThis == null))); }
/// <summary> /// Will actually start playing, but assumes /// accompanying bookkeeping has been done. Use Play(list) instead. /// </summary> internal AudioCue Play(GameThing emitter) { AudioCue cue = BokuGame.Audio.GetCue(cuename, emitter, Spatial); cue.Play(); cue.Sound = this; cues.Add(cue); return(cue); }
/// <summary> /// Set up with a spatialized sound with a fixed position. /// Doesn't start playing, that requires a separate call. /// </summary> /// <param name="cue"></param> /// <param name="thing"></param> public void Set(Cue cue, Vector3 position) { played = false; this.thing = null; this.spatial = true; this.position = position; BokuGame.Release(ref this.cue); this.cue = cue; }
} // end of Playing() #endregion #region Internal private void Restart(AudioCue audioCue, GameThing emitter) { audioCue.Reset(); Cue cue = BokuGame.Audio.SoundBank.GetCue(soundName); audioCue.Set(cue, emitter); audioCue.Play(); frame = Time.FrameCounter; lastTime = Time.WallClockTotalSeconds; } // end of Restart()
/// <summary> /// Remove all SensorTargets referencing 'thing' /// </summary> /// <param name="dropThing"></param> public void Remove(GameThing thing) { if (sensorTargets.ContainsKey(thing.UniqueNum)) { SensorTarget target = sensorTargets[thing.UniqueNum]; sensorTargets.Remove(thing.UniqueNum); target.UnRef(); dirty = true; } }
} // end of SetLoopedAnimationWeights() #endregion #region Internal /// <summary> /// Check if we're close enough to the surface to cause some ripples. /// WaveEffect goes from 0=>1 as we approach the surface. /// </summary> /// <param name="thing"></param> /// <param name="waveEffect"></param> protected override void CheckRipples(GameThing thing, float waveEffect) { if (waveEffect > 0.75f) { float scale = (waveEffect - 0.75f) / (0.9f - 0.75f); scale = MyMath.Clamp <float>(scale, 0.0f, 1.0f); scale = 0.3f + scale * (1.0f - 0.3f); base.CheckRipples(thing, thing.CollisionRadius * scale); } }
/// <summary> /// Called in the case where a gamething is a single Target /// </summary> /// <param name="gameThing"></param> /// <param name="range"></param> public void Init(GameThing gameThing, Vector3 direction, float range) { this.gameThing = gameThing; this.classification = gameThing.Classification; this.movement = gameThing.Movement; this.position = movement.Position; this.direction = direction; this.range = range; this.sensedAt = Time.GameTimeTotalSeconds; this.Tag = null; }
/// <summary> /// Look to see if we're intersecting the water surface and if so kick off /// some ripples. Note that we look farther below than above, so if we're /// flying low over water we make a wake. /// </summary> /// <param name="thing"></param> /// <param name="waterHeight"></param> protected override void CheckRipples(GameThing thing, float waterHeight) { Vector3 collCenter = thing.WorldCollisionCenter; float collRad = thing.WorldCollisionRadius; if ((waterHeight - Terrain.WaveHeight < collCenter.Z + collRad) && (waterHeight > collCenter.Z - collRad * 1.5f)) { base.CheckRipples(thing, collRad); } }
/// <summary> /// Look to see if we are intersecting (or near enough) the water surface, /// and if so kick off some ripples. Note how much we have to expand our /// tiny collision radius here to get good results. /// </summary> /// <param name="movement"></param> /// <param name="collCenter"></param> /// <param name="collRad"></param> /// <param name="waterHeight"></param> private void CheckRipples(GameThing thing, Vector3 collCenter, float collRad, float waterHeight) { if (!thing.Invisible) { if ((waterHeight - Terrain.WaveHeight < collCenter.Z + collRad * 6.0f) && (waterHeight > collCenter.Z - collRad * 8.0f)) { base.CheckRipples(thing, collRad * 3.0f); } } }
} // end of PostCollisionTestUpdate() #endregion #region Internal protected override void BounceOffGround(GameThing thing, float terrainHeight, Vector3 terraNormal) { Movement movement = thing.Movement; base.BounceOffGround(thing, terrainHeight, terraNormal); if (movement.Altitude < terrainHeight) { movement.Altitude = 2.0f * terrainHeight - movement.Altitude; } }
public void Init(float distance, Vector3 value, GameThing gameThing, Reflex reflex, bool canBlend, SpecialInstruction specialInstruction) { this.Distance = distance; this.GameThing = gameThing; this.Reflex = reflex; this.Value = value; this.Used = false; this.ActedOn = false; this.CanBlend = canBlend; this.specialInstruction = specialInstruction; }
public void Reset() { if (OnComplete != null) { OnComplete(this); } OnComplete = null; played = false; thing = null; cue = null; }
/// <summary> /// Add a distortion field to the scene, shape based on the GameThing passed in. /// </summary> /// <param name="moldOwner"></param> /// <param name="life"></param> /// <param name="maxSize"></param> /// <returns></returns> public static Distortion Add(GameThing thing, float life, Vector3 maxSize) { if (EnabledSM2 || EnabledSM3) { Distortion lie = Distortion.Acquire(thing, life, maxSize); lies.Add(lie); return(lie); } return(null); }