public PowerProjectile(World world, int actorSNO, Vector3D position, Vector3D aimPosition, float speed, float timetolive, float scale = 1.35f, float collisionError = 3f, float heightOffset = 0, float distanceOffset = 0, bool handleTranslation = false) : base(world, actorSNO) { this.startingPosition = new Vector3D(position); this.startingPosition.Z += heightOffset; this.speed = speed; this.timetolive = timetolive; this.collisionError = collisionError + heightOffset; //Timeout = new TickSecondsTimer(this.World.Game, timetolive / 1000f); //Save projectile creation tick this.creationTick = this.World.Game.TickCounter; // FIXME: This is hardcoded crap this.Field2 = 0x8; this.Field3 = 0x0; this.Scale = 1f; this.GBHandle.Type = (int)GBHandleType.Monster; this.GBHandle.GBID = 1; this.Field7 = 0x00000001; //this.Field8 = this.SNOId; this.Field10 = 0x1; this.Field11 = 0x1; this.Field12 = 0x1; this.Field13 = 0x1; this.CollFlags = 0x4; //Calculate Quaternion info this.radianAngle = PowerMath.AngleLookAt(startingPosition, aimPosition); //Assign quaternion info this.RotationAmount = (float)Math.Cos(this.radianAngle / 2); this.RotationAxis.X = 0f; this.RotationAxis.Y = 0f; this.RotationAxis.Z = (float)Math.Sin(this.radianAngle / 2); //Normalize position / aimPosition Vector Vector3D vel_normal = PowerMath.Normalize(new Vector3D(aimPosition.X - startingPosition.X, aimPosition.Y - startingPosition.Y, 0f)); this.velocity = new Vector3D(vel_normal.X * speed, vel_normal.Y * speed, vel_normal.Z * speed); //Adjust projectile distance from player this.startingPosition.X += this.velocity.X * distanceOffset; this.startingPosition.Y += this.velocity.Y * distanceOffset; this.Position = this.startingPosition; this.World.Enter(this); // Enter only once all fields have been initialized to prevent a run condition //If the creator dont specify he want to manipulate the projectil itself, launch it if (!handleTranslation) { this.launch(); } }
public TargetList GetEnemiesInBeamDirection(Vector3D startPoint, Vector3D direction, float length, float thickness = 0f) { Vector3D beamEnd = PowerMath.TranslateDirection2D(startPoint, direction, startPoint, length); float fixedActorRadius = 1.5f; // TODO: calculate based on actor.ActorData.Cylinder.Ax2 ? return(_GetTargetsInRadiusHelper(startPoint, length + thickness, -1, actor => PowerMath.CircleInBeam(new Circle(actor.Position.X, actor.Position.Y, fixedActorRadius), startPoint, beamEnd, thickness), _EnemyActorFilter)); }
public TargetList GetEnemiesInArcDirection(Vector3D center, Vector3D direction, float radius, float lengthDegrees) { Vector2F arcCenter2D = PowerMath.VectorWithoutZ(center); Vector2F arcDirection2D = PowerMath.VectorWithoutZ(direction); float arcLength = lengthDegrees * PowerMath.DegreesToRadians; float fixedActorRadius = 1.5f; // TODO: calculate based on actor.ActorData.Cylinder.Ax2 ? return(_GetTargetsInRadiusHelper(center, radius, -1, actor => PowerMath.ArcCircleCollides(arcCenter2D, arcDirection2D, radius, arcLength, new Circle(actor.Position.X, actor.Position.Y, fixedActorRadius)), _EnemyActorFilter)); }
private void _SetupMove(Vector3D destination, float speed) { Vector3D dir_normal = PowerMath.Normalize(new Vector3D(destination.X - this.Target.Position.X, destination.Y - this.Target.Position.Y, 0f)); // were not moving in 3d for now this.Velocity = new Vector3D(dir_normal.X * speed, dir_normal.Y * speed, dir_normal.Z * speed); this.ArrivalTime = new RelativeTickTimer(this.Target.World.Game, (int)(PowerMath.Distance2D(this.Target.Position, destination) / speed)); _startPosition = this.Target.Position; _endPosition = destination; _startTick = this.Target.World.Game.TickCounter; }
public Actor GetClosestTo(Vector3D position) { Actor closest = null; float closestDistance = float.MaxValue; foreach (Actor actor in this.Actors) { float distance = PowerMath.Distance2D(actor.Position, position); if (distance < closestDistance) { closest = actor; closestDistance = distance; } } return(closest); }
private void _SetupArcMove(Vector3D destination, float crestHeight, float gravity) { // TODO: handle when target and destination heights differ float absGravity = Math.Abs(gravity); float arcLength = (float)Math.Sqrt(2f * crestHeight / absGravity); int arrivalTicks = (int)(arcLength * 2f); float distance = PowerMath.Distance2D(this.Target.Position, destination); Vector3D normal = PowerMath.Normalize(new Vector3D(destination.X - this.Target.Position.X, destination.Y - this.Target.Position.Y, 0f)); this.Velocity = new Vector3D(normal.X * (distance / arrivalTicks), normal.Y * (distance / arrivalTicks), absGravity * arcLength); this.ArrivalTime = new RelativeTickTimer(this.Target.World.Game, arrivalTicks); _startPosition = this.Target.Position; _endPosition = destination; _startTick = this.Target.World.Game.TickCounter; _arcGravity = gravity; }
private void _CheckCollisions() { if (OnCollision == null) { return; } // check if we collided with anything since last update float radius = this.ActorData.Cylinder.Ax2; Circle startCircle = new Circle(_prevUpdatePosition.X, _prevUpdatePosition.Y, radius); // make a velocity representing the change to the current position Vector2F velocity = PowerMath.VectorWithoutZ(this.Position - _prevUpdatePosition); Actor hit = null; TargetList targets = this.Context.GetEnemiesInRadius(this.Position, radius + 25f); if (CollisionFilter != null) { targets.Actors.RemoveAll(actor => !CollisionFilter(actor)); } targets.SortByDistanceFrom(_prevUpdatePosition); foreach (Actor target in targets.Actors) { float targetRadius = 1.5f; // TODO: use target.ActorData.Cylinder.Ax2 ? if (PowerMath.MovingCircleCollides(startCircle, velocity, new Circle(target.Position.X, target.Position.Y, targetRadius))) { hit = target; break; } } if (hit != null) { OnCollision(hit); } }
public void SortByDistanceFrom(Vector3D position) { this.Actors = this.Actors.OrderBy(actor => PowerMath.Distance2D(actor.Position, position)).ToList(); }