public GetRelative ( |
||
other | ||
distance | int | |
return |
/// <summary> /// Gets creatures within a rectangle of specified radian rotation, /// length, and width. Outs the position of the opposite end of the /// rectangle. /// </summary> /// <param name="startPosition"></param> /// <param name="radianRotation"></param> /// <param name="rectLength"></param> /// <param name="rectWidth"></param> /// <param name="endPosition"></param> /// <returns></returns> public List <Creature> GetCreaturesInRectangle(Position startPosition, double radianRotation, int rectLength, int rectWidth, out Position endPosition) { int radius = rectWidth / 2; // Position at the opposite end of the rectangle from the startPosition endPosition = startPosition.GetRelative(radianRotation, rectLength); var startPoint = new Point(startPosition.X, startPosition.Y); var endPoint = new Point(endPosition.X, endPosition.Y); // Calculate the diagonal distance from the starting point to each of the rectangle's points on the opposite side var pointDist = Math.Sqrt((rectLength * rectLength) + (radius * radius)); // Rotation angle used to place the points of [pointDist] distance away in the correct position to form a rectangle // One negative and one positive rotation of a point [pointDist] distance away will provide two points of the rectangle var rotationAngle = Math.Asin(radius / pointDist); // Create a point [pointDist] away from the starting point, and rotate it both positively and negatively by [rotationAngle] // to generate two points on one side of the rectangle var posTemp1 = startPosition.GetRelative(endPosition, (int)(pointDist - rectLength)); var pointTemp1 = new Point(posTemp1.X, posTemp1.Y); var p1 = this.RotatePoint(pointTemp1, startPoint, rotationAngle); var p2 = this.RotatePoint(pointTemp1, startPoint, (rotationAngle * -1)); // Same method as points 1 and 2, starting from the end point instead to create two points on the opposite side var posTemp2 = endPosition.GetRelative(startPosition, (int)(pointDist - rectLength)); var pointTemp2 = new Point(posTemp2.X, posTemp2.Y); var p3 = this.RotatePoint(pointTemp2, endPoint, rotationAngle); var p4 = this.RotatePoint(pointTemp2, endPoint, (rotationAngle * -1)); // Get creatures within the four points calculated var creatureList = this.GetCreaturesInPolygon(p1, p2, p3, p4); return(creatureList); }
/// <summary> /// Handles skill usage. /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="packet"></param> public void Use(Creature attacker, Skill skill, Packet packet) { var targetAreaEntityId = packet.GetLong(); Send.Effect(attacker, 5, (byte)1, targetAreaEntityId); var cap = new CombatActionPack(attacker, skill.Info.Id); var aAction = new AttackerAction(CombatActionType.Attacker, attacker, skill.Info.Id, targetAreaEntityId); aAction.Options |= AttackerOptions.Result; aAction.Stun = UseStun; cap.Add(aAction); var attackerPosition = attacker.GetPosition(); // Calculate rectangular target area var targetAreaPos = new Position(targetAreaEntityId); var poe = targetAreaPos.GetRelative(attackerPosition, -800); var r = (Math.PI / 2) + Math.Atan2(attackerPosition.Y - targetAreaPos.Y, attackerPosition.X - targetAreaPos.X); var pivot = new Point(poe.X, poe.Y); var p1 = new Point(pivot.X - LaserRectWidth / 2, pivot.Y - LaserRectHeight / 2); var p2 = new Point(pivot.X - LaserRectWidth / 2, pivot.Y + LaserRectHeight / 2); var p3 = new Point(pivot.X + LaserRectWidth / 2, pivot.Y + LaserRectHeight / 2); var p4 = new Point(pivot.X + LaserRectWidth / 2, pivot.Y - LaserRectHeight / 2); p1 = this.RotatePoint(p1, pivot, r); p2 = this.RotatePoint(p2, pivot, r); p3 = this.RotatePoint(p3, pivot, r); p4 = this.RotatePoint(p4, pivot, r); // Attack targets var targets = attacker.Region.GetCreaturesInPolygon(p1, p2, p3, p4); foreach (var target in targets.Where(cr => !cr.IsDead && !cr.Has(CreatureStates.NamedNpc))) { var targetPosition = target.GetPosition(); var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); tAction.Options = TargetOptions.Result | TargetOptions.KnockDown; tAction.Stun = TargetStun; tAction.Delay = 1200; cap.Add(tAction); // Var2: 300/1000, based on rank. Could be damage? var damage = skill.RankData.Var2; // Increase damage CriticalHit.Handle(attacker, attacker.GetTotalCritChance(target.Protection), ref damage, tAction); // Reduce damage SkillHelper.HandleDefenseProtection(target, ref damage); ManaShield.Handle(target, ref damage, tAction); // Apply damage target.TakeDamage(tAction.Damage = 300, attacker); target.Stability = Creature.MinStability; // Aggro target.Aggro(attacker); // Check death if (target.IsDead) tAction.Options |= TargetOptions.FinishingKnockDown; // Knock back attacker.Shove(target, KnockbackDistance); } cap.Handle(); Send.SkillUse(attacker, skill.Info.Id, 0); }
public void GetRelative() { var pos1 = new Position(100, 100); var pos2 = new Position(100, 200); Assert.Equal(new Position(100, 250), pos1.GetRelative(pos2, 50)); Assert.Equal(new Position(100, 150), pos1.GetRelative(pos2, -50)); Assert.Equal(new Position(100, -50), pos1.GetRelative(pos2, -250)); var pos3 = new Position(50, 100); Assert.Equal(new Position(0, 100), pos1.GetRelative(pos3, 50)); Assert.Equal(new Position(100, 100), pos1.GetRelative(pos3, -50)); Assert.Equal(new Position(300, 100), pos1.GetRelative(pos3, -250)); var up = MabiMath.DegreeToRadian(90); var down = MabiMath.DegreeToRadian(270); var left = MabiMath.DegreeToRadian(180); var right = MabiMath.DegreeToRadian(0); Assert.Equal(new Position(100, 200), pos1.GetRelative(up, 100)); Assert.Equal(new Position(100, 0), pos1.GetRelative(down, 100)); Assert.Equal(new Position(0, 100), pos1.GetRelative(left, 100)); Assert.Equal(new Position(200, 100), pos1.GetRelative(right, 100)); }