/// <summary> /// Returns whether the given object is within the bounds of this AreaTrigger. /// </summary> /// <param name="chr"></param> /// <returns></returns> public bool IsInArea(Character chr) { if (chr.Map.Id != MapId) { return false; } if (Radius > 0) // Sphere { var distSq = chr.GetDistanceSq(Position); if (distSq > MaxDistSq) { LogManager.GetCurrentClassLogger().Warn("Character {0} tried to trigger {1} while being {2} yards away.", chr, this, Math.Sqrt(distSq)); return false; } } else // Box { // 2PI = 360 degrees. Keep in mind that in-game orientation is counter-clockwise. var rotation = 2 * MathUtil.PI - BoxYaw; var sinval = Math.Sin(rotation); var cosval = Math.Cos(rotation); var playerBoxDistX = chr.Position.X - Position.X; var playerBoxDistY = chr.Position.Y - Position.Y; var rotPlayerX = Position.X + playerBoxDistX * cosval - playerBoxDistY * sinval; var rotPlayerY = Position.Y + playerBoxDistY * cosval + playerBoxDistX * sinval; // Box edges are parallel to coordinate axis, so we can treat every dimension independently. var dx = rotPlayerX - Position.X; var dy = rotPlayerY - Position.Y; var dz = chr.Position.Z - Position.Z; if ((Math.Abs(dx) > BoxLength / 2 + tollerance) || (Math.Abs(dy) > BoxWidth / 2 + tollerance) || (Math.Abs(dz) > BoxHeight / 2 + tollerance)) { return false; } } return true; }
/// <summary> /// Tries to select the nearest GO that is in front of the character /// </summary> /// <returns>The newly selected GO.</returns> public GameObject SelectClosest(Character chr) { var gos = chr.GetObjectsInRadius(MaxSearchRadius, ObjectTypes.GameObject, true, 0); var sqDist = float.MaxValue; GameObject sel = null; foreach (GameObject go in gos) { // TODO: Go by angle instead of distance //var angle = chr.GetAngleTowards(go); if (sel == null || (go.IsInFrontOf(chr) && chr.GetDistanceSq(go) < sqDist)) { sel = go; } } this[chr] = sel; return sel; }