示例#1
0
        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();
            }
        }
示例#2
0
        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));
        }
示例#3
0
        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));
        }
示例#4
0
        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;
        }
示例#5
0
        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);
        }
示例#6
0
        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;
        }
示例#7
0
        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);
            }
        }
示例#8
0
 public void SortByDistanceFrom(Vector3D position)
 {
     this.Actors = this.Actors.OrderBy(actor => PowerMath.Distance2D(actor.Position, position)).ToList();
 }