Esempio n. 1
0
        public static Vector2? GetFirstWallPoint(Vector2 from, Vector2 to, float step = 25)
        {
            var direction = (to - from).Normalized();

            for (float d = 0; d < from.Distance(to); d = d + step)
            {
                var testPoint = from + d*direction;
                var flags = NavMesh.GetCollisionFlags(testPoint.X, testPoint.Y);
                if (flags.HasFlag(CollisionFlags.Wall) || flags.HasFlag(CollisionFlags.Building))
                {
                    return from + (d - step)*direction;
                }
            }

            return null;
        }
Esempio n. 2
0
        public static Vector2 GetShortestWayPoint(List<Vector2> waypoints)
        {
            var shortestPos = new Vector2();
            foreach (var waypoint in waypoints)
            {
                if (shortestPos == new Vector2())
                {
                    shortestPos = waypoint;
                }
                else
                {
                    if (waypoint.Distance(ObjectManager.Player) < shortestPos.Distance(ObjectManager.Player))
                    {
                        shortestPos = waypoint;
                    }
                }
            }

            return shortestPos;
        }
Esempio n. 3
0
        /// <summary>
        /// Draws a line.
        /// </summary>
        /// <param name="sb"><see cref="ISpriteBatch"/> to draw to.</param>
        /// <param name="p1">First point of the line.</param>
        /// <param name="p2">Second point of the line.</param>
        /// <param name="color">Color of the line.</param>
        /// <param name="thickness">The thickness of the line in pixels. Default is 1.</param>
        public static void Draw(ISpriteBatch sb, Vector2 p1, Vector2 p2, Color color, float thickness = 1f)
        {
            if (sb == null)
            {
                Debug.Fail("sb is null.");
                return;
            }

            if (sb.IsDisposed)
            {
                Debug.Fail("sb is disposed.");
                return;
            }

            // Common properties set no matter the approach we use below
            _drawLineRect.Position = p1;
            _drawLineRect.FillColor = color;

            // If we have a perfectly vertical or horizontal line, we can avoid using rotation to speed up the calculation, so check for that first.
            // This is purely an optimization - the rotation approach works for all points still.
            if (p1.X == p2.X)
            {
                // Perfectly vertical
                _drawLineRect.Size = new Vector2(thickness, p2.Y - p1.Y);
                _drawLineRect.Rotation = 0;
            }
            else if (p1.Y == p2.Y)
            {
                // Perfectly horizontal
                _drawLineRect.Size = new Vector2(p2.X - p1.X, thickness);
                _drawLineRect.Rotation = 0;
            }
            else
            {
                // Treat as horizontal by setting the X as the distance and Y as the thickness, then rotate
                _drawLineRect.Size = new Vector2(p2.Distance(p1), thickness);
                _drawLineRect.Rotation = MathHelper.ToDegrees((float)Math.Atan2(p2.Y - p1.Y, p2.X - p1.X));
            }

            sb.Draw(_drawLineRect);
        }
Esempio n. 4
0
        public void Explode(Vector2 worldPosition, Entity damageSource, Character attacker = null)
        {
            prevExplosions.Add(new Triplet<Explosion, Vector2, float>(this, worldPosition, (float)Timing.TotalTime));
            if (prevExplosions.Count > 100)
            {
                prevExplosions.RemoveAt(0);
            }

            Hull hull = Hull.FindHull(worldPosition);
            ExplodeProjSpecific(worldPosition, hull);

            if (hull != null && !string.IsNullOrWhiteSpace(decal) && decalSize > 0.0f)
            {
                hull.AddDecal(decal, worldPosition, decalSize, isNetworkEvent: false);
            }

            float displayRange = attack.Range;

            Vector2 cameraPos = Character.Controlled != null ? Character.Controlled.WorldPosition : GameMain.GameScreen.Cam.Position;
            float cameraDist = Vector2.Distance(cameraPos, worldPosition) / 2.0f;
            GameMain.GameScreen.Cam.Shake = cameraShake * Math.Max((cameraShakeRange - cameraDist) / cameraShakeRange, 0.0f);
#if CLIENT
            if (screenColor != Color.Transparent)
            {
                Color flashColor = Color.Lerp(Color.Transparent, screenColor, Math.Max((screenColorRange - cameraDist) / screenColorRange, 0.0f));
                Screen.Selected.ColorFade(flashColor, Color.Transparent, screenColorDuration);
            }
#endif

            if (displayRange < 0.1f) { return; }

            if (attack.GetStructureDamage(1.0f) > 0.0f)
            {
                RangedStructureDamage(worldPosition, displayRange, attack.GetStructureDamage(1.0f), attack.GetLevelWallDamage(1.0f), attacker);
            }

            if (BallastFloraDamage > 0.0f)
            {
                RangedBallastFloraDamage(worldPosition, displayRange, BallastFloraDamage, attacker);
            }

            if (EmpStrength > 0.0f)
            {
                float displayRangeSqr = displayRange * displayRange;
                foreach (Item item in Item.ItemList)
                {
                    float distSqr = Vector2.DistanceSquared(item.WorldPosition, worldPosition);
                    if (distSqr > displayRangeSqr) continue;
                    
                    float distFactor = 1.0f - (float)Math.Sqrt(distSqr) / displayRange;

                    //damage repairable power-consuming items
                    var powered = item.GetComponent<Powered>();
                    if (powered == null || !powered.VulnerableToEMP) continue;
                    if (item.Repairables.Any())
                    {
                        item.Condition -= item.MaxCondition * EmpStrength * distFactor;
                    }

                    //discharge batteries
                    var powerContainer = item.GetComponent<PowerContainer>();
                    if (powerContainer != null)
                    {
                        powerContainer.Charge -= powerContainer.Capacity * EmpStrength * distFactor;
                    }
                }
            }

            if (MathUtils.NearlyEqual(force, 0.0f) && MathUtils.NearlyEqual(attack.Stun, 0.0f) && MathUtils.NearlyEqual(attack.GetTotalDamage(false), 0.0f))
            {
                return;
            }

            DamageCharacters(worldPosition, attack, force, damageSource, attacker);

            if (GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient)
            {
                foreach (Item item in Item.ItemList)
                {
                    if (item.Condition <= 0.0f) { continue; }
                    float dist = Vector2.Distance(item.WorldPosition, worldPosition);
                    float itemRadius = item.body == null ? 0.0f : item.body.GetMaxExtent();
                    dist = Math.Max(0.0f, dist - ConvertUnits.ToDisplayUnits(itemRadius));
                    if (dist > attack.Range) { continue; }

                    if (dist < attack.Range * 0.5f && applyFireEffects && !item.FireProof)
                    {
                        //don't apply OnFire effects if the item is inside a fireproof container
                        //(or if it's inside a container that's inside a fireproof container, etc)
                        Item container = item.Container;
                        bool fireProof = false;
                        while (container != null)
                        {
                            if (container.FireProof)
                            {
                                fireProof = true;
                                break;
                            }
                            container = container.Container;
                        }
                        if (!fireProof)
                        {
                            item.ApplyStatusEffects(ActionType.OnFire, 1.0f);
                            if (item.Condition <= 0.0f && GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
                            {
                                GameMain.NetworkMember.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnFire });
                            }
                        }                        
                    }

                    if (item.Prefab.DamagedByExplosions && !item.Indestructible)
                    {
                        float distFactor = 1.0f - dist / attack.Range;
                        float damageAmount = attack.GetItemDamage(1.0f) * item.Prefab.ExplosionDamageMultiplier;

                        Vector2 explosionPos = worldPosition;
                        if (item.Submarine != null) { explosionPos -= item.Submarine.Position; }

                        damageAmount *= GetObstacleDamageMultiplier(ConvertUnits.ToSimUnits(explosionPos), worldPosition, item.SimPosition);
                        item.Condition -= damageAmount * distFactor;
                    }
                }
            }
        }
Esempio n. 5
0
        public void Vector2DistanceTest()
        {
            var a = new Vector2(3.0f, 4.0f);
            var b = new Vector2(6.0f, 8.0f);

            var expectedResult = 5.0f;

            var r = a.Distance(b);

            Assert.Equal<float>(expectedResult, r);
        }
        public override void Update(NPC npc, ref int buffIndex)
        {
            npc.GetGlobalNPC <FargoSoulsGlobalNPC>().LeadPoison = true;
            if (npc.buffTime[buffIndex] == 2) //note: this totally also makes the npc reapply lead to themselves so its basically permanent debuff
            {
                for (int i = 0; i < 200; i++)
                {
                    NPC spread = Main.npc[i];

                    if (spread.active && !spread.townNPC && !spread.friendly && spread.lifeMax > 5 && !spread.HasBuff(mod.BuffType("LeadPoison")) && Vector2.Distance(npc.Center, spread.Center) < 50)
                    {
                        spread.AddBuff(mod.BuffType("LeadPoison"), 30);
                    }
                }
            }
        }
Esempio n. 7
0
 private float distance(Point A, Point B)
 {
     return(Vector2.Distance(A.Pos, B.Pos));
 }
    override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        //For the lancer to work, every instance of it must be named in capital letters "LANCER"
        #region Lancer
        if (animator.name == "LANCER")
        {
            if (m_accel >= 4)
            {
                speed  += m_accel * 3;
                m_accel = 1;
            }

            //gets the boolean "isAttached" from the lancer class. The attachment will always be true if the lancer contacted the player
            if (animator.GetComponent <LANCER>().isAttached == true)
            {
                //Change the enemy parent, being it now the playerShip
                animator.transform.parent = m_playerPosition.transform;
                animator.rootPosition     = new Vector3(0, 0, 0);
                //disable own collider for preventing bugs purpose
                animator.GetComponent <Collider2D>().enabled = false;
                m_accel = 0;
            }

            //IF the lancer isn't attached to player...
            if (animator.GetComponent <LANCER>().isAttached == false)
            {
                /*I don't know how this works, but basically if you put the .right of your object to be the subtraction of target position
                 * minus its own position, the object will rotate for that direction*/
                Vector3 _rot = animator.transform.right = m_playerPosition.position - animator.transform.position;
                animator.rootPosition = _rot;

                m_accel += 2f * Time.deltaTime;

                //if the distance between the enemy and the player is greater than the m_chasingDistance, move towards the player
                if (Vector2.Distance(animator.transform.position, m_playerPosition.transform.position) > m_chasingDistance)
                {
                    animator.transform.position = Vector2.MoveTowards(animator.transform.position, m_playerPosition.transform.position
                                                                      , speed * Time.deltaTime);
                }
                //if the distance between the enemy and the player is lesser than the m_retreatDistance, move towards the player
                if (Vector2.Distance(animator.transform.position, m_playerPosition.transform.position) < m_retreatDistance)
                {
                    animator.transform.position = Vector2.MoveTowards(animator.transform.position, m_playerPosition.transform.position
                                                                      , -speed * Time.deltaTime);
                }

                //if it is between the two above, do nothing;
                if (Vector2.Distance(animator.transform.position, m_playerPosition.transform.position) < m_chasingDistance &&
                    Vector2.Distance(animator.transform.position, m_playerPosition.transform.position) > m_retreatDistance)
                {
                    animator.transform.position = animator.transform.position;
                }

                //This is the controller that sets the enemy back to patrolling position the distance between player and enemy is greater than chasing distance time aggroRange
                else if (Vector2.Distance(animator.transform.position, m_playerPosition.transform.position) > m_chasingDistance * m_aggroRange)
                {
                    //setting the animator parameters
                    animator.SetBool("isPatrolling", true);
                    animator.SetBool("isAttacking", false);
                    //setting the stateofCombat to the scene manager
                    m_sceneManager.changeStateOfCombat(false);
                }
            }
        }
        #endregion

        #region Chase/Strafe Code

        if (Vector2.Distance(animator.transform.position, m_playerPosition.transform.position) > m_chasingDistance)
        {
            animator.transform.position = Vector2.MoveTowards(animator.transform.position, m_playerPosition.transform.position
                                                              , speed * Time.deltaTime);
        }
        //if the distance between the enemy and the player is lesser than the m_retreatDistance, move towards the player
        if (Vector2.Distance(animator.transform.position, m_playerPosition.transform.position) < m_retreatDistance)
        {
            animator.transform.position = Vector2.MoveTowards(animator.transform.position, m_playerPosition.transform.position
                                                              , -speed * Time.deltaTime);
        }

        //if it is between the two above, do nothing;
        if (Vector2.Distance(animator.transform.position, m_playerPosition.transform.position) < m_chasingDistance &&
            Vector2.Distance(animator.transform.position, m_playerPosition.transform.position) > m_retreatDistance)
        {
            animator.transform.position = animator.transform.position;
        }

        //This is the controller that sets the enemy back to patrolling position the distance between player and enemy is greater than chasing distance time aggroRange
        else if (Vector2.Distance(animator.transform.position, m_playerPosition.transform.position) > m_chasingDistance * m_aggroRange)
        {
            //setting the animator parameters
            animator.SetBool("isPatrolling", true);
            animator.SetBool("isAttacking", false);
            //setting the stateofCombat to the scene manager
            m_sceneManager.changeStateOfCombat(false);
        }

        #endregion
        if (m_playerPosition == null)
        {
            m_playerPosition = GameObject.FindGameObjectWithTag("Player").transform;
        }
    }
        // Update is called once per frame
        void Update()
        {
            if (PlayerMenuController.instance.defaultMenu == PlayerMenuController.instance.currentSelectedMenuGroup)
            {
                /////////////////////////////////////////
                //           Camera Control            //
                /////////////////////////////////////////
                cameraOffset = new Vector2(Input.GetAxis("ControllerAimHorizontal"), Input.GetAxis("ControllerAimVertical"));

                /////////////////////////////////////////
                //               Walking               //
                /////////////////////////////////////////
                float hspeed = Input.GetAxis("Horizontal");
                float vspeed = Input.GetAxis("Vertical");
                //Debug.Log("hspeed: " + hspeed);


                Animator animator  = GetComponentInChildren <Animator>();
                string   animState = "Idle";
                if (Mathf.Abs(cameraOffset.x) > 0 || Mathf.Abs(cameraOffset.y) > 0)
                {
                    //Camera control rotation
                    if (Mathf.Abs(cameraOffset.x) > Mathf.Abs(cameraOffset.y))
                    {
                        animState = cameraOffset.x > 0 ? "Right" : "Left";
                    }
                    else
                    {
                        animState = cameraOffset.y > 0 ? "Up" : "Down";
                    }
                    //Making the player move slower when aiming
                    hspeed = hspeed / 2f;
                    vspeed = vspeed / 2f;
                }
                else
                {
                    //Movement control rotation
                    if (hspeed != 0 || vspeed != 0)
                    {
                        if (Mathf.Abs(hspeed) > Mathf.Abs(vspeed))
                        {
                            animState = hspeed > 0 ? "Right" : "Left";
                        }
                        else
                        {
                            animState = vspeed > 0 ? "Up" : "Down";
                        }
                    }
                }

                rb.velocity = new Vector2(hspeed, vspeed);

                animator.speed = Vector2.Distance(Vector2.zero, rb.velocity);
                animator.Play(animState);

                /////////////////////////////////////////
                //             Interacting             //
                /////////////////////////////////////////
                //We only want to do the raycast if we are moving
                if (Mathf.Abs(hspeed) > 0 || Mathf.Abs(vspeed) > 0 || Mathf.Abs(cameraOffset.x) > 0 || Mathf.Abs(cameraOffset.y) > 0)
                {
                    RaycastHit2D hit = new RaycastHit2D();
                    if (Mathf.Abs(cameraOffset.x) > 0 || Mathf.Abs(cameraOffset.y) > 0)
                    {
                        aimDir = cameraOffset;
                    }
                    else
                    {
                        aimDir = rb.velocity;
                    }
                    hit = Physics2D.Raycast(transform.position, aimDir, 0.3f, LayerMask.GetMask("Interactable"));
                    if (hit)
                    {
                        GameObject tar = hit.collider.gameObject;
                        if (tar != previouslyTargetedObject)
                        {
                            if (tar.GetComponent <InteractableBase>())
                            {
                                if (previouslyTargetedObject)
                                {
                                    previouslyTargetedObject.GetComponent <SpriteRenderer>().color = previousColor;
                                }

                                previousColor = tar.GetComponent <SpriteRenderer>().color;
                                tar.GetComponent <SpriteRenderer>().color = Color.green;
                                previouslyTargetedObject = tar;
                            }
                        }
                    }
                    else
                    {
                        if (previouslyTargetedObject)
                        {
                            previouslyTargetedObject.GetComponent <SpriteRenderer>().color = previousColor;
                            previouslyTargetedObject = null;
                        }
                    }
                }

                if (Input.GetButtonDown("ControllerInteract"))
                {
                    if (previouslyTargetedObject)
                    {
                        if (previouslyTargetedObject.GetComponent <InteractableBase>())
                        {
                            StartCoroutine(previouslyTargetedObject.GetComponent <InteractableBase>().Interact());
                        }
                    }
                }

                /////////////////////////////////////////
                //              Fireball               //
                /////////////////////////////////////////
                if (Input.GetAxis("Shoot") >= 0.3f)
                {
                    if (fireballDebounce == false)
                    {
                        GameObject newObj = Instantiate(Resources.Load <GameObject>("Prefabs/Projectiles/Fireball"), transform.position, Quaternion.identity);
                        newObj.GetComponent <FireballTriggerHandler>().dir   = aimDir;
                        newObj.GetComponent <FireballTriggerHandler>().speed = 2f;
                        fireballDebounce = true;
                    }
                }
                else
                {
                    fireballDebounce = false;
                }

                //Finally we check for interacting
            }
        }
Esempio n. 10
0
            private void DrawLine(SpriteBatch spriteBatch)
            {
                if (this.active || (double)this._lineOpacity == 0.0)
                {
                    return;
                }
                Vector2 vector2_1 = Main.MouseScreen;
                Vector2 vector2_2 = new Vector2((float)(Main.screenWidth / 2), (float)(Main.screenHeight - 70));

                if (PlayerInput.UsingGamepad)
                {
                    vector2_1 = Vector2.Zero;
                }
                Vector2 v                  = vector2_1 - vector2_2;
                double  num1               = (double)Vector2.Dot(Vector2.Normalize(v), Vector2.UnitX);
                double  num2               = (double)Vector2.Dot(Vector2.Normalize(v), Vector2.UnitY);
                double  rotation           = (double)v.ToRotation();
                double  num3               = (double)v.Length();
                bool    flag1              = false;
                bool    toolAllowActuators = WiresUI.Settings.DrawToolAllowActuators;

                for (int index = 0; index < 6; ++index)
                {
                    if (toolAllowActuators || index != 5)
                    {
                        bool flag2 = WiresUI.Settings.ToolMode.HasFlag((Enum)(WiresUI.Settings.MultiToolMode)(1 << index));
                        if (index == 5)
                        {
                            flag2 = WiresUI.Settings.ToolMode.HasFlag((Enum)WiresUI.Settings.MultiToolMode.Actuator);
                        }
                        Vector2 vector2_3 = vector2_2 + Vector2.UnitX * (float)(45.0 * ((double)index - 1.5));
                        int     num4      = index;
                        if (index == 0)
                        {
                            num4 = 3;
                        }
                        if (index == 3)
                        {
                            num4 = 0;
                        }
                        switch (num4)
                        {
                        case 0:
                        case 1:
                            vector2_3 = vector2_2 + new Vector2((float)(45.0 + (toolAllowActuators ? 15.0 : 0.0)) * (float)(2 - num4), 0.0f) * this._lineOpacity;
                            break;

                        case 2:
                        case 3:
                            vector2_3 = vector2_2 + new Vector2((float)-(45.0 + (toolAllowActuators ? 15.0 : 0.0)) * (float)(num4 - 1), 0.0f) * this._lineOpacity;
                            break;

                        case 4:
                            flag2     = false;
                            vector2_3 = vector2_2 - new Vector2(0.0f, toolAllowActuators ? 22f : 0.0f) * this._lineOpacity;
                            break;

                        case 5:
                            vector2_3 = vector2_2 + new Vector2(0.0f, 22f) * this._lineOpacity;
                            break;
                        }
                        bool flag3 = false;
                        if (!PlayerInput.UsingGamepad)
                        {
                            flag3 = (double)Vector2.Distance(vector2_3, vector2_1) < 19.0 * (double)this._lineOpacity;
                        }
                        if (flag1)
                        {
                            flag3 = false;
                        }
                        if (flag3)
                        {
                            flag1 = true;
                        }
                        Texture2D texture2D1 = Main.wireUITexture[(WiresUI.Settings.ToolMode.HasFlag((Enum)WiresUI.Settings.MultiToolMode.Cutter) ? 8 : 0) + (flag3 ? 1 : 0)];
                        Texture2D texture2D2 = (Texture2D)null;
                        switch (index)
                        {
                        case 0:
                        case 1:
                        case 2:
                        case 3:
                            texture2D2 = Main.wireUITexture[2 + index];
                            break;

                        case 4:
                            texture2D2 = Main.wireUITexture[WiresUI.Settings.ToolMode.HasFlag((Enum)WiresUI.Settings.MultiToolMode.Cutter) ? 7 : 6];
                            break;

                        case 5:
                            texture2D2 = Main.wireUITexture[10];
                            break;
                        }
                        Color color1 = Color.White;
                        Color color2 = Color.White;
                        if (!flag2 && index != 4)
                        {
                            if (flag3)
                            {
                                color2 = new Color(100, 100, 100);
                                color2 = new Color(120, 120, 120);
                                color1 = new Color(200, 200, 200);
                            }
                            else
                            {
                                color2 = new Color(150, 150, 150);
                                color2 = new Color(80, 80, 80);
                                color1 = new Color(100, 100, 100);
                            }
                        }
                        Utils.CenteredRectangle(vector2_3, new Vector2(40f));
                        if (flag3)
                        {
                            if (Main.mouseLeft && Main.mouseLeftRelease)
                            {
                                switch (index)
                                {
                                case 0:
                                    WiresUI.Settings.ToolMode ^= WiresUI.Settings.MultiToolMode.Red;
                                    break;

                                case 1:
                                    WiresUI.Settings.ToolMode ^= WiresUI.Settings.MultiToolMode.Green;
                                    break;

                                case 2:
                                    WiresUI.Settings.ToolMode ^= WiresUI.Settings.MultiToolMode.Blue;
                                    break;

                                case 3:
                                    WiresUI.Settings.ToolMode ^= WiresUI.Settings.MultiToolMode.Yellow;
                                    break;

                                case 4:
                                    WiresUI.Settings.ToolMode ^= WiresUI.Settings.MultiToolMode.Cutter;
                                    break;

                                case 5:
                                    WiresUI.Settings.ToolMode ^= WiresUI.Settings.MultiToolMode.Actuator;
                                    break;
                                }
                            }
                            if (!Main.mouseLeft || Main.player[Main.myPlayer].mouseInterface)
                            {
                                Main.player[Main.myPlayer].mouseInterface = true;
                            }
                            this.OnWiresMenu = true;
                        }
                        int num5 = flag3 ? 1 : 0;
                        spriteBatch.Draw(texture2D1, vector2_3, new Rectangle?(), color1 * this._lineOpacity, 0.0f, texture2D1.Size() / 2f, this._lineOpacity, SpriteEffects.None, 0.0f);
                        spriteBatch.Draw(texture2D2, vector2_3, new Rectangle?(), color2 * this._lineOpacity, 0.0f, texture2D2.Size() / 2f, this._lineOpacity, SpriteEffects.None, 0.0f);
                    }
                }
                if (!Main.mouseLeft || !Main.mouseLeftRelease || flag1)
                {
                    return;
                }
                this.active = false;
            }
 private float distanceToPlayer(Vector3 other)
 {
     return(Vector2.Distance(new Vector2(playerTransform.position.x, playerTransform.position.z), new Vector2(other.x, other.z)));
 }
Esempio n. 12
0
        private ScriptLineView FindLineNearPosition(Vector2 worldPos)
        {
            var localPos = linesContainer.WorldToLocal(worldPos);

            return(linesContainer.Children().OrderBy(v => Vector2.Distance(localPos, v.layout.center)).FirstOrDefault() as ScriptLineView);
        }
Esempio n. 13
0
        public override void AI()
        {
            AITimer++;

            if ((Main.netMode == NetmodeID.MultiplayerClient || Main.netMode == NetmodeID.Server) && SelectHoverMP == 1)
            {
                Random = Main.rand.Next(PlayerCount().Count);
                SelectHoverMP++;
            }

            Player player = Main.player[Random];

            #region Difficulty modification

            if (UnderEightyHealth)
            {
                SpeedAdd       = 1f;
                npc.damage     = 60;
                SSDelay        = 15;
                ShieldDuration = 220;
                HoverCooldown  = 350;
            }

            if (UnderFiftyHealth)
            {
                MinionCount    = 3;
                SpeedAdd       = 2f;
                npc.damage     = 65;
                ShieldDuration = 230;
                HoverCooldown  = 300;
            }

            if (UnderThirtyHealth)
            {
                MinionCount    = 4;
                SpeedAdd       = 4f;
                npc.damage     = 70;
                SSDelay        = 10;
                ShieldDuration = 240;
                ShieldLife     = 2;
                HoverCooldown  = 200;
            }

            if (Main.expertMode && UnderThirtyHealth)
            {
                MinionCount    = 6;
                npc.damage     = 80;
                SSDelay        = 8;
                ShieldDuration = 250;
                ShieldLife     = 3;
                HoverCooldown  = 120;
            }

            #endregion

            #region DisappearanceManager

            npc.TargetClosest(true);

            if (!player.active || player.dead)
            {
                npc.TargetClosest(false);
                player = Main.player[npc.target];
                if (!player.active || player.dead)
                {
                    npc.velocity = new Vector2(0f, -10f);

                    if (npc.timeLeft > 10)
                    {
                        npc.timeLeft = 10;
                    }

                    return;
                }
            }

            #endregion

            #region Fail prevention

            if (AIStage > 4)
            {
                AIStage = STAGE_HOVER;
            }

            if (AITimer > 550)
            {
                AITimer = 0;
            }

            if (SSDone > 10)
            {
                SSDone = 6;
            }

            #endregion

            #region Hovering

            if (AIStage == STAGE_HOVER)
            {
                npc.dontTakeDamage = false;
                //Y Hovering

                if (Main.player[npc.target].position.Y != npc.position.Y + HoverDistance.Y)
                {
                    YHoverTimer++;

                    if (YHoverTimer > 10)
                    {
                        //Thanks UncleDanny and Thorium  team for this <3
                        if (Main.player[npc.target].position.Y < npc.position.Y + HoverDistance.Y)
                        {
                            npc.velocity.Y -= npc.velocity.Y > 0f ? 1f : 0.15f;
                        }

                        if (Main.player[npc.target].position.Y > npc.position.Y + HoverDistance.Y)
                        {
                            npc.velocity.Y += npc.velocity.Y < 0f ? 1f : 0.15f;
                        }
                    }
                }
                else
                {
                    npc.velocity.Y = 0;
                    YHoverTimer    = 0;
                }

                if (Vector2.Distance(new Vector2(player.Center.X, 0), new Vector2(npc.Center.X, 0)) != HoverDistance.X)
                {
                    XHoverTimer++;
                    if (XHoverTimer > 30)
                    {
                        npc.velocity.X = 2.5f * npc.direction + SpeedAdd * npc.direction;
                    }
                }
                else
                {
                    npc.velocity.X = 0;
                    XHoverTimer    = 0;
                }

                if (AITimer >= HoverCooldown)
                {
                    AdvanceStage(true, true);
                    ResetValues(false);
                    SelectHoverMP = 2;
                }

                if (AITimer <= 100)
                {
                    //Shield code here.
                }

                npc.netUpdate = true;
            }

            #endregion // Starts at 0 ticks.

            #region Slam || MP compatible

            if (AIStage == STAGE_SLAM)
            {
                Slam();
            }

            #endregion

            #region Shield || Regen stage.

            if (AIStage == STAGE_SHIELD)
            {
                if (AITimer > 0)
                {
                    if (AITimer == 1)
                    {
                        SoundHelper.PlayCustomSound("Sounds/ShipShield", npc.Center, 2.5f);
                    }
                    if (AITimer % 20 == 0)
                    {
                        RandomShieldLines();
                    }

                    npc.velocity.Y = -1f;

                    for (int k = 0; k < 10; k++)
                    {
                        if (Deg <= 360)
                        {
                            Deg++;

                            float
                                CPosX = npc.Center.X +
                                        ShieldDistance *
                                        (float)Math
                                        .Cos(Deg);     //To find the circumference you use formula: x = cX + r * cos(angle), where the x is the coordinate, cX is the center of the circle by X and r is radius.
                            float CPosY = npc.Center.Y + 16f + ShieldDistance * (float)Math.Sin(Deg);

                            for (int i = 0; i < 10; i++)
                            {
                                Dust dust = Main.dust[Dust.NewDust(new Vector2(CPosX, CPosY), 1, 1, 56)];
                                dust.noGravity = true;
                            }
                        }
                    }

                    if (Deg == 360)
                    {
                        Deg = 0;
                    }
                    npc.netUpdate = true;

                    if (Vector2.Distance(player.Center, npc.Center) <= ShieldDistance)
                    {
                        player.Hurt(
                            PlayerDeathReason.ByCustomReason(
                                player.name + "has been cut in half by the Frieza Force Shield"), 40, 1);
                        Dust dust = Main.dust[
                            Dust.NewDust(player.Center, player.width, player.height, 56)]; //need to pick a new dust
                        dust.noGravity = true;

                        if (player.position.X > npc.Center.X && player.Center.Y < npc.Center.Y) //4th qudrant
                        {
                            player.velocity = new Vector2(16f, 16f);
                        }
                        else if (player.position.X < npc.Center.X && player.Center.Y < npc.Center.Y) //3rd quadrant
                        {
                            player.velocity = new Vector2(-16f, 16f);
                        }
                        else if (player.position.X < npc.Center.X && player.Center.Y > npc.Center.Y) //2nd quadrant
                        {
                            player.velocity = new Vector2(-16f, -16f);
                        }
                        else if (player.position.X > npc.Center.X && player.Center.Y > npc.Center.Y) //1st quadrant
                        {
                            player.velocity = new Vector2(16f, -16f);
                        }
                    }

                    for (int i = 0; i <= Main.maxProjectiles; i++)
                    {
                        Projectile projectile = Main.projectile[i];

                        if (Vector2.Distance(projectile.Center, npc.Center) <= ShieldDistance && projectile.active)
                        {
                            projectile.velocity *= -1f;

                            for (int j = 0; j < 20; j++)
                            {
                                Dust dust = Main.dust[
                                    Dust.NewDust(projectile.position, projectile.width, projectile.height, 211)];
                                dust.noGravity = true;
                            }

                            projectile.hostile  = true;
                            projectile.friendly = false;

                            if (projectile.Center.X > player.Center.X * 0.5f
                                ) //Reference goes to Fargo for voring his epic code.
                            {
                                projectile.direction       = 1;
                                projectile.spriteDirection = 1;
                            }
                            else
                            {
                                projectile.direction       = -1;
                                projectile.spriteDirection = -1;
                            }

                            projectile.netUpdate = true;
                            npc.netUpdate        = true;
                        }
                        else if (Vector2.Distance(projectile.position, npc.Center) <= 6 * 16f)
                        {
                            projectile.Kill();
                            Dust dust = Main.dust[
                                Dust.NewDust(projectile.position, projectile.width, projectile.height, 211)];
                            dust.noGravity = true;
                        }
                    }
                }

                if (npc.life <= npc.lifeMax)
                {
                    npc.life += ShieldLife;
                }
                npc.netUpdate = true;

                if (AITimer >= ShieldDuration)
                {
                    AdvanceStage(true, true);
                    ResetValues(false);
                }
            }

            #endregion

            #region Minions

            if (AIStage == STAGE_MINION)
            {
                npc.velocity = new Vector2(0, -2f);
                if (AITimer == 0)
                {
                    TileX = (int)(npc.position.X + Main.rand.NextFloat(-7f * 16, 6f * 16));
                    TileY = (int)(npc.position.Y + Main.rand.NextFloat(-7f * 16, 6f * 16));
                    SummonFFMinions();
                    SummonSaibamen();
                }

                npc.netUpdate = true;

                if (AITimer == 60)
                {
                    ResetValues(false);
                    AdvanceStage(true, true);
                }
            }

            #endregion

            #region Hyper Stage

            if (AIStage == STAGE_HYPER)
            {
                npc.noTileCollide = true;

                if (HyperSlamsDone <= 4)
                {
                    npc.dontTakeDamage = true;
                    if (AITimer < 300)
                    {
                        DoChargeDust();
                        npc.dontTakeDamage = true;
                        npc.velocity       = new Vector2(0, -0.3f);
                        npc.netUpdate      = true;
                    }

                    if (AITimer > 300 && HyperPosition == Vector2.Zero)
                    {
                        npc.dontTakeDamage = false;
                        npc.netUpdate      = true;
                        npc.velocity       = Vector2.Zero;
                        if (AITimer == 301)
                        {
                            CircularDust(30, npc, 133, 10f, 1);
                            ChooseHyperPosition();
                        }

                        npc.netUpdate = true;
                    }

                    if (AITimer > 320 && HyperPosition != Vector2.Zero && npc.velocity == Vector2.Zero)
                    {
                        npc.dontTakeDamage = false;
                        DoLineDust();
                        npc.netUpdate = true;
                    }

                    if (AITimer == 310 && HyperPosition != Vector2.Zero)
                    {
                        npc.dontTakeDamage = false;
                        TeleportRight();
                        HyperSlamsDone++;
                        npc.netUpdate = true;
                    }

                    if (AITimer >= 350 && HyperPosition != Vector2.Zero)
                    {
                        HorizontalSlam();
                    }
                    npc.netUpdate = true;
                }
                else
                {
                    HorizontalSlamTimer = 0;
                    npc.dontTakeDamage  = false;
                    HyperSlamsDone      = 0;
                    AITimer             = 0;
                    ResetStage();
                    npc.netUpdate = true;
                }
            }

            #endregion

            #region Warp Stage

            if (AIStage == STAGE_WARP)
            {
                Warp();
            }

            #endregion
        }
        public override void AI()
        {
            // Gets the Player and Target Vector
            npc.TargetClosest(true);
            Player  player = Main.player[npc.target];
            Vector2 target = npc.HasPlayerTarget ? player.Center : Main.npc[npc.target].Center;

            // Ensures that the NPC is not rotated
            npc.rotation  = 0.0f;
            npc.netAlways = true;
            npc.TargetClosest(true);
            // Ensures NPC Life is not greater than its max life
            if (npc.life >= npc.lifeMax)
            {
                npc.life = npc.lifeMax;
            }
            // Handles Despawning
            if (npc.target < 0 || npc.target == 500 || player.dead || !player.active)
            {
                npc.TargetClosest(false);
                npc.direction  = 1;
                npc.velocity.Y = npc.velocity.Y - 0.1f;
                if (npc.timeLeft > 20)
                {
                    npc.timeLeft = 20;
                    return;
                }
            }
            // Increment AI
            ai++;
            // Movement
            npc.ai[0] = (float)ai * 1f;
            int distance = (int)Vector2.Distance(target, npc.Center);

            if ((double)npc.ai[0] < 300)
            {
                frame = 0;
                MoveTowards(npc, target, (float)(distance > 300 ? 13f : 7f), 30f);
                npc.netUpdate = true;
            }
            else if ((double)npc.ai[0] >= 300 && (double)npc.ai[0] < 450.0)
            {
                stunned     = true;
                frame       = 1;
                npc.defense = 1;
                npc.damage  = 1000;
                MoveTowards(npc, target, (float)(distance > 300 ? 13f : 7f), 30f);
                npc.netUpdate = true;
            }
            else if ((double)npc.ai[0] >= 450.0)
            {
                frame       = 0;
                stunned     = false;
                npc.damage  = 350;
                npc.defense = 100;
                if (!fastSpeed)
                {
                    fastSpeed = true;
                }
                else
                {
                    if ((double)npc.ai[0] % 50 == 0)
                    {
                        float   speed     = 12f;
                        Vector2 vector    = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)npc.height * 0.5f);
                        float   x         = player.position.X + (float)(player.width / 2) - vector.X;
                        float   y         = player.position.Y + (float)(player.height / 2) - vector.Y;
                        float   distance2 = (float)Math.Sqrt(x * x + y * y);
                        float   factor    = speed / distance2;
                        npc.velocity.X = x * factor;
                        npc.velocity.Y = y * factor;
                    }
                }
                npc.netUpdate = true;
            }
            // Attack
            if ((double)npc.ai[0] % (Main.expertMode ? 10 : 15) == 0 && !fastSpeed)
            {
                attackTimer++;
                if (attackTimer <= 2)
                {
                    frame          = 2;
                    npc.velocity.X = 1f;
                    npc.velocity.Y = 1f;
                    Vector2 shootPos = npc.Center;
                    float   accuracy = 5f * (npc.life / npc.lifeMax);
                    Vector2 shootVel = target - shootPos + new Vector2(Main.rand.NextFloat(-accuracy, accuracy), Main.rand.NextFloat(-accuracy, accuracy));
                    shootVel.Normalize();
                    shootVel *= 14.5F;
                    for (int i = 0; i < (Main.expertMode ? 5 : 3); i++)
                    {
                        Projectile.NewProjectile(shootPos.X + (float)(-100 * npc.direction) + (float)Main.rand.Next(-40, 41), shootPos.Y - (float)Main.rand.Next(-50, 40), shootVel.X, shootVel.Y, mod.ProjectileType("MightOfTheUnderworldProjectile"), npc.damage / 3, 5f);
                    }
                }
                else
                {
                    attackTimer = 0;
                }
            }



            if ((double)npc.ai[0] >= 650.0)
            {
                ai        = 0;
                npc.alpha = 0;
                npc.ai[2] = 0;
                fastSpeed = false;
            }
        }
 public override void tick(PlayerScript player)
 {
     if (fighter.GetCurrentWeapon() != null && fighter.GetCurrentWeapon().GetWeaponRange() > Vector2.Distance(player.transform.position, transform.position))
     {
         fighter.swing(CaptureEnemies(1), this.GetComponent <CombatTarget>());
     }
     else if (Vector2.Distance(player.transform.position, transform.position) < minChaseDistance)
     {
         navMeshAgent.SetDestination(player.transform.position);
     }
 }
Esempio n. 16
0
        /// <summary>
        /// Returns a dictionary where the keys are the structures that took damage and the values are the amount of damage taken
        /// </summary>
        public static Dictionary<Structure, float> RangedStructureDamage(Vector2 worldPosition, float worldRange, float damage, float levelWallDamage, Character attacker = null)
        {
            List<Structure> structureList = new List<Structure>();            
            float dist = 600.0f;
            foreach (MapEntity entity in MapEntity.mapEntityList)
            {
                if (!(entity is Structure structure)) { continue; }

                if (structure.HasBody &&
                    !structure.IsPlatform &&
                    Vector2.Distance(structure.WorldPosition, worldPosition) < dist * 3.0f)
                {
                    structureList.Add(structure);
                }
            }

            Dictionary<Structure, float> damagedStructures = new Dictionary<Structure, float>();
            foreach (Structure structure in structureList)
            {
                for (int i = 0; i < structure.SectionCount; i++)
                {
                    float distFactor = 1.0f - (Vector2.Distance(structure.SectionPosition(i, true), worldPosition) / worldRange);
                    if (distFactor <= 0.0f) continue;

                    structure.AddDamage(i, damage * distFactor, attacker);

                    if (damagedStructures.ContainsKey(structure))
                    {
                        damagedStructures[structure] += damage * distFactor;
                    }
                    else
                    {
                        damagedStructures.Add(structure, damage * distFactor);
                    }
                }
            }

            if (Level.Loaded != null && !MathUtils.NearlyEqual(levelWallDamage, 0.0f))
            {
                for (int i = Level.Loaded.ExtraWalls.Count - 1; i >= 0; i--)
                {
                    if (!(Level.Loaded.ExtraWalls[i] is DestructibleLevelWall destructibleWall)) { continue; }
                    foreach (var cell in destructibleWall.Cells)
                    {
                        if (cell.IsPointInside(worldPosition))
                        {
                            destructibleWall.AddDamage(levelWallDamage, worldPosition);
                            continue;
                        }
                        foreach (var edge in cell.Edges)
                        {
                            if (!MathUtils.GetLineIntersection(worldPosition, cell.Center, edge.Point1 + cell.Translation, edge.Point2 + cell.Translation, out Vector2 intersection))
                            {
                                continue;
                            }

                            float wallDist = Vector2.DistanceSquared(worldPosition, intersection);
                            if (wallDist < worldRange * worldRange)
                            {
                                destructibleWall.AddDamage(damage, worldPosition);
                                break;
                            }
                        }
                    }
                }
            }

            return damagedStructures;
        }
Esempio n. 17
0
        public static void DamageCharacters(Vector2 worldPosition, Attack attack, float force, Entity damageSource, Character attacker)
        {
            if (attack.Range <= 0.0f) { return; }

            //long range for the broad distance check, because large characters may still be in range even if their collider isn't
            float broadRange = Math.Max(attack.Range * 10.0f, 10000.0f);

            foreach (Character c in Character.CharacterList)
            {
                if (!c.Enabled || 
                    Math.Abs(c.WorldPosition.X - worldPosition.X) > broadRange ||
                    Math.Abs(c.WorldPosition.Y - worldPosition.Y) > broadRange)
                {
                    continue;
                }

                Vector2 explosionPos = worldPosition;
                if (c.Submarine != null) { explosionPos -= c.Submarine.Position; }

                Hull hull = Hull.FindHull(explosionPos, null, false);
                bool underWater = hull == null || explosionPos.Y < hull.Surface;

                explosionPos = ConvertUnits.ToSimUnits(explosionPos);

                Dictionary<Limb, float> distFactors = new Dictionary<Limb, float>();
                Dictionary<Limb, float> damages = new Dictionary<Limb, float>();
                List<Affliction> modifiedAfflictions = new List<Affliction>();
                foreach (Limb limb in c.AnimController.Limbs)
                {
                    if (limb.IsSevered || limb.IgnoreCollisions || !limb.body.Enabled) { continue; }

                    float dist = Vector2.Distance(limb.WorldPosition, worldPosition);
                    
                    //calculate distance from the "outer surface" of the physics body
                    //doesn't take the rotation of the limb into account, but should be accurate enough for this purpose
                    float limbRadius = limb.body.GetMaxExtent();
                    dist = Math.Max(0.0f, dist - ConvertUnits.ToDisplayUnits(limbRadius));

                    if (dist > attack.Range) { continue; }

                    float distFactor = 1.0f - dist / attack.Range;

                    //solid obstacles between the explosion and the limb reduce the effect of the explosion
                    distFactor *= GetObstacleDamageMultiplier(explosionPos, worldPosition, limb.SimPosition);
                    distFactors.Add(limb, distFactor);

                    modifiedAfflictions.Clear();
                    foreach (Affliction affliction in attack.Afflictions.Keys)
                    {
                        //previously the damage would be divided by the number of limbs (the intention was to prevent characters with more limbs taking more damage from explosions)
                        //that didn't work well on large characters like molochs and endworms: the explosions tend to only damage one or two of their limbs, and since the characters
                        //have lots of limbs, they tended to only take a fraction of the damage they should

                        //now we just divide by 10, which keeps the damage to normal-sized characters roughly the same as before and fixes the large characters
                        modifiedAfflictions.Add(affliction.CreateMultiplied(distFactor / 10));
                    }
                    c.LastDamageSource = damageSource;
                    if (attacker == null)
                    {
                        if (damageSource is Item item)
                        {
                            attacker = item.GetComponent<Projectile>()?.User;
                            if (attacker == null)
                            {
                                attacker = item.GetComponent<MeleeWeapon>()?.User;
                            }
                        }
                    }

                    //use a position slightly from the limb's position towards the explosion
                    //ensures that the attack hits the correct limb and that the direction of the hit can be determined correctly in the AddDamage methods
                    Vector2 dir = worldPosition - limb.WorldPosition;
                    Vector2 hitPos = limb.WorldPosition + (dir.LengthSquared() <= 0.001f ? Rand.Vector(1.0f) : Vector2.Normalize(dir)) * 0.01f;
                    AttackResult attackResult = c.AddDamage(hitPos, modifiedAfflictions, attack.Stun * distFactor, false, attacker: attacker);
                    damages.Add(limb, attackResult.Damage);
                    
                    if (attack.StatusEffects != null && attack.StatusEffects.Any())
                    {
                        attack.SetUser(attacker);
                        var statusEffectTargets = new List<ISerializableEntity>() { c, limb };
                        foreach (StatusEffect statusEffect in attack.StatusEffects)
                        {
                            statusEffect.Apply(ActionType.OnUse, 1.0f, damageSource, statusEffectTargets);
                            statusEffect.Apply(ActionType.Always, 1.0f, damageSource, statusEffectTargets);
                            statusEffect.Apply(underWater ? ActionType.InWater : ActionType.NotInWater, 1.0f, damageSource, statusEffectTargets);
                        }
                    }
                    
                    if (limb.WorldPosition != worldPosition && !MathUtils.NearlyEqual(force, 0.0f))
                    {
                        Vector2 limbDiff = Vector2.Normalize(limb.WorldPosition - worldPosition);
                        if (!MathUtils.IsValid(limbDiff)) { limbDiff = Rand.Vector(1.0f); }
                        Vector2 impulse = limbDiff * distFactor * force;
                        Vector2 impulsePoint = limb.SimPosition - limbDiff * limbRadius;
                        limb.body.ApplyLinearImpulse(impulse, impulsePoint, maxVelocity: NetConfig.MaxPhysicsBodyVelocity * 0.2f);
                    }
                }

                if (c == Character.Controlled && !c.IsDead)
                {
                    Limb head = c.AnimController.GetLimb(LimbType.Head);
                    if (damages.TryGetValue(head, out float headDamage) && headDamage > 0.0f && distFactors.TryGetValue(head, out float headFactor))
                    {
                        PlayTinnitusProjSpecific(headFactor);
                    }
                }

                //sever joints 
                if (attack.SeverLimbsProbability > 0.0f)
                {
                    foreach (Limb limb in c.AnimController.Limbs)
                    {
                        if (limb.character.Removed || limb.Removed) { continue; }
                        if (limb.IsSevered) { continue; }
                        if (!c.IsDead && !limb.CanBeSeveredAlive) { continue; }
                        if (distFactors.TryGetValue(limb, out float distFactor))
                        {
                            if (damages.TryGetValue(limb, out float damage))
                            {
                                c.TrySeverLimbJoints(limb, attack.SeverLimbsProbability * distFactor, damage, allowBeheading: true);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 18
0
    // Update is called once per frame
    void Update()
    {
        player = GameObject.FindGameObjectWithTag("Player");
        //if (Input.GetKeyDown(KeyCode.Y)) Die();

        //transform.position = new Vector3(transform.position.x, transform.position.y, transform.position.y);
        rb2d.velocity = Vector2.zero;

        if (playerInSameRoom() && !freezeMovement)
        {
            if (mySpells.hasAxe)
            {
                if (Mathf.Abs(transform.position.x - player.transform.position.x) >= 4 && Mathf.Abs(transform.localPosition.x) < 6 && Mathf.Abs(transform.localPosition.y) < 2.5)
                {
                    throwAxe();
                }
                else
                {
                    swingHammer();
                }
            }
            else
            {
                // get the closest axe in the room
                GameObject[] axes = GameObject.FindGameObjectsWithTag("AxeOnWall");
                foreach (GameObject axe in axes)
                {
                    if (axe.transform.parent == transform.parent)
                    {
                        if (closestAxe == null)
                        {
                            closestAxe = axe;
                        }
                        else
                        {
                            if (Vector2.Distance(transform.position, axe.transform.position) < Vector2.Distance(transform.position, closestAxe.transform.position))
                            {
                                closestAxe = axe;
                            }
                        }
                    }
                }

                // if he's closer to axe, pick it up. otherwise, go attack the player
                if (closestAxe == null)
                {
                    swingHammer();
                }
                else if (Vector2.Distance(transform.position, closestAxe.transform.position) > Vector2.Distance(transform.position, player.transform.position))
                {
                    swingHammer();
                }
                else
                {
                    pickUpAxe();
                }
            }
        }
    }
Esempio n. 19
0
        public static float Distance(this Vector2 point, Vector2 segmentStart, Vector2 segmentEnd, bool onlyIfOnSegment = false, bool squared = false)
        {
            var objects = point.ProjectOns(segmentStart, segmentEnd);

            if (objects.IsOnSegment || onlyIfOnSegment == false)
            {
                return(squared ? Vector2.DistanceSquared(objects.SegmentPoint, point) : Vector2.Distance(objects.SegmentPoint, point));
            }

            return(float.MaxValue);
        }
Esempio n. 20
0
        public void Update(List <Wall> walls)
        {
            compt++; // Cette petite ligne correspond à l'IA ( WAAAW Gros QI )
            distance2player = Hitbox.X - Global.Player.Hitbox.X;

            #region Mort Ennemi
            for (int i = 0; i < bullets.Count(); i++)
            {
                if (Hitbox.Intersects(new Rectangle((int)bullets[i].position.X, (int)bullets[i].position.Y, 30, 30)))
                {
                    bullets[i].isVisible = false;
                    bullets.RemoveAt(i);
                    i--;
                    if (pv > 1)
                    {
                        pv--;
                    }
                    else
                    {
                        isDead = true;
                    }
                }
            }

            if (!isDead && Keyboard.GetState().IsKeyDown(Keys.D) && Global.Player.Hitbox.Intersects(Hitbox))
            {
                isDead = true;
            }

            #endregion

            #region Animation
            if (!isDead)
            {
                if (distance2player != 0)
                {
                    if (framecolumn > 8)
                    {
                        framecolumn = 1;
                    }
                    else if (compt % 2 == 0)
                    {
                        framecolumn++;
                    }
                }
                else
                {
                    framecolumn = 9;
                }
            }
            #endregion

            #region Gravité
            if (!isDead)
            {
                bool gravity = collisions.CollisionDown(Hitbox, walls, this.fallspeed);

                if (!gravity)
                {
                    if (collisions.CollisionUp(Hitbox, walls, fallspeed))
                    {
                        speedjump = 0;
                    }
                    if (speedjump > 1)
                    {
                        this.Hitbox.Y -= speedjump;
                        speedjump     -= 1;
                    }
                    else
                    {
                        this.Hitbox.Y += this.fallspeed;
                    }
                }
                else
                if (!collisions.CollisionDown(Hitbox, walls, this.fallspeed - 4))
                {
                    if (!collisions.CollisionDown(Hitbox, walls, this.fallspeed - 2))
                    {
                        this.Hitbox.Y += 2;
                    }
                    else
                    {
                        this.Hitbox.Y++;
                    }
                }
            }
            #endregion

            #region Déplacements
            if (!isDead)
            {
                if (distance2player == 0)
                {
                    speed = 0;
                }
                else
                {
                    speed = 1;
                    if (distance2player < 0 && distance2player >= -200)
                    {
                        left  = false;
                        compt = 1;
                    }
                    else
                    if (distance2player > 0 && distance2player <= 200)
                    {
                        left  = true;
                        compt = 1;
                    }
                    else
                    if (distance2player > 200 || distance2player <= -200)
                    {
                        if (this.Hitbox.X <= origin - 200)
                        {
                            left  = false;
                            compt = 1;
                        }
                        else if (this.Hitbox.X >= origin + 200)
                        {
                            left  = true;
                            compt = 1;
                        }
                    }

                    if (left)
                    {
                        if (!collisions.CollisionLeft(Hitbox, walls, speed) && Hitbox.X > 0 && collisions.CollisionDown(new Rectangle(Hitbox.X - Hitbox.Width, Hitbox.Y, Hitbox.Width, Hitbox.Height), walls, speed))
                        {
                            this.Hitbox.X -= speed;
                            this.Direction = Direction.Left;
                        }
                        else
                        {
                            framecolumn = 1;
                            compt      += 10;
                        }
                    }

                    if (!left)
                    {
                        if (!collisions.CollisionRight(Hitbox, walls, speed) && collisions.CollisionDown(new Rectangle(Hitbox.X + Hitbox.Width, Hitbox.Y, Hitbox.Width, Hitbox.Height), walls, speed) && Hitbox.X < 4600)
                        {
                            this.Hitbox.X += speed;
                            this.Direction = Direction.Right;
                        }
                        else
                        {
                            framecolumn = 1;
                            compt      += 10;
                        }
                    }
                }
            }


            #endregion

            #region Tir

            //enemy_bullets.Capacity = 5;
            if ((distance2player >= -200 && distance2player <= -100) || (distance2player > 100 && distance2player <= 200))
            {
                a_portee = true;
            }
            else
            {
                a_portee = false;
            }

            if (!isDead && Math.Abs(Hitbox.Y - Global.Player.Hitbox.Y) < 20 && a_portee && !shot && enemy_bullets.Count == 0 && Global.Player.health > 0)
            {
                shot_sound_instance.Play();
                shot = true;
                Bullets bullet = new Bullets(Resources.bullet);
                bullet.velocity  = 2;
                bullet.isVisible = true;
                enemy_bullets.Add(bullet);
                if (Direction == Direction.Right)
                {
                    Old_Direction   = Direction.Right;
                    bullet.position = new Vector2(Hitbox.X + Hitbox.Width / 2, Hitbox.Y + Hitbox.Height / 4) + new Vector2(bullet.velocity * 5, 0);
                }
                else
                {
                    Old_Direction   = Direction.Left;
                    bullet.position = new Vector2(Hitbox.X, Hitbox.Y + Hitbox.Height / 4) + new Vector2(bullet.velocity * 5, 0);
                }
            }
            else
            {
                shot = false;
            }

            // la balle disparait si elle parcourt la distance ou rencontre un obstacle


            foreach (Bullets bullet in enemy_bullets)
            {
                if (!isDead)
                {
                    if (Old_Direction == Direction.Right)
                    {
                        bullet.position.X += bullet.velocity; // va vers la droite
                    }
                    else
                    {
                        bullet.position.X -= bullet.velocity; // va vers la gauche
                    }
                    if (Vector2.Distance(bullet.position, new Vector2(Hitbox.X, Hitbox.Y)) >= 200)
                    {
                        bullet.isVisible = false;
                    }
                    else
                    if (Global.Player.Hitbox.Intersects(new Rectangle((int)bullet.position.X, (int)bullet.position.Y, 3, 3)))
                    {
                        Global.Player.health -= 3;
                        bullet.isVisible      = false;
                    }
                }
                foreach (Wall wall in walls)
                {
                    if (wall.Hitbox.Intersects(new Rectangle((int)bullet.position.X, (int)bullet.position.Y, 5, 2)))
                    {
                        bullet.isVisible = false;
                    }
                }
            }

            for (int i = 0; i < enemy_bullets.Count; i++)
            {
                if (!enemy_bullets[i].isVisible)
                {
                    enemy_bullets.RemoveAt(i);
                    i--;
                }
            }

            #endregion

            switch (Direction)
            {
            case Direction.Right:
                effect = SpriteEffects.FlipHorizontally;
                break;

            case Direction.Left:
                effect = SpriteEffects.None;
                break;
            }
            switch (pv)
            {
            case 1:
                color.A = 100;
                break;

            case 2:
                color.A = 200;
                break;

            case 3:
                color = Color.White;
                break;
            }
        }
Esempio n. 21
0
            private void DrawFlower(SpriteBatch spriteBatch)
            {
                if (!this.active)
                {
                    return;
                }
                Vector2 vector2_1 = Main.MouseScreen;
                Vector2 position  = this.position;

                if (PlayerInput.UsingGamepad && Main.SmartCursorEnabled)
                {
                    vector2_1 = !(PlayerInput.GamepadThumbstickRight != Vector2.Zero) ? (!(PlayerInput.GamepadThumbstickLeft != Vector2.Zero) ? this.position : this.position + PlayerInput.GamepadThumbstickLeft * 40f) : this.position + PlayerInput.GamepadThumbstickRight * 40f;
                }
                Vector2 v                  = vector2_1 - position;
                double  num1               = (double)Vector2.Dot(Vector2.Normalize(v), Vector2.UnitX);
                double  num2               = (double)Vector2.Dot(Vector2.Normalize(v), Vector2.UnitY);
                float   rotation           = v.ToRotation();
                float   num3               = v.Length();
                bool    flag1              = false;
                bool    toolAllowActuators = WiresUI.Settings.DrawToolAllowActuators;
                float   num4               = (float)(4 + toolAllowActuators.ToInt());
                float   num5               = toolAllowActuators ? 11f : -0.5f;

                for (int index = 0; index < 6; ++index)
                {
                    if (toolAllowActuators || index != 5)
                    {
                        bool flag2 = WiresUI.Settings.ToolMode.HasFlag((Enum)(WiresUI.Settings.MultiToolMode)(1 << index));
                        if (index == 5)
                        {
                            flag2 = WiresUI.Settings.ToolMode.HasFlag((Enum)WiresUI.Settings.MultiToolMode.Actuator);
                        }
                        Vector2 vector2_2 = position + Vector2.UnitX * (float)(45.0 * ((double)index - 1.5));
                        switch (index)
                        {
                        case 0:
                        case 1:
                        case 2:
                        case 3:
                            float num6 = (float)index;
                            if (index == 0)
                            {
                                num6 = 3f;
                            }
                            if (index == 3)
                            {
                                num6 = 0.0f;
                            }
                            vector2_2 = position + Vector2.UnitX.RotatedBy((double)num6 * 6.28318548202515 / (double)num4 - 3.14159274101257 / (double)num5, new Vector2()) * 45f;
                            break;

                        case 4:
                            flag2     = false;
                            vector2_2 = position;
                            break;

                        case 5:
                            vector2_2 = position + Vector2.UnitX.RotatedBy((double)(index - 1) * 6.28318548202515 / (double)num4 - 3.14159274101257 / (double)num5, new Vector2()) * 45f;
                            break;
                        }
                        bool flag3 = false;
                        if (index == 4)
                        {
                            flag3 = (double)num3 < 20.0;
                        }
                        switch (index)
                        {
                        case 0:
                        case 1:
                        case 2:
                        case 3:
                        case 5:
                            float num7 = (vector2_2 - position).ToRotation().AngleTowards(rotation, (float)(6.28318548202515 / ((double)num4 * 2.0))) - rotation;
                            if ((double)num3 >= 20.0 && (double)Math.Abs(num7) < 0.00999999977648258)
                            {
                                flag3 = true;
                                break;
                            }
                            break;

                        case 4:
                            flag3 = (double)num3 < 20.0;
                            break;
                        }
                        if (!PlayerInput.UsingGamepad)
                        {
                            flag3 = (double)Vector2.Distance(vector2_2, vector2_1) < 19.0;
                        }
                        if (flag1)
                        {
                            flag3 = false;
                        }
                        if (flag3)
                        {
                            flag1 = true;
                        }
                        Texture2D texture2D1 = Main.wireUITexture[(WiresUI.Settings.ToolMode.HasFlag((Enum)WiresUI.Settings.MultiToolMode.Cutter) ? 8 : 0) + (flag3 ? 1 : 0)];
                        Texture2D texture2D2 = (Texture2D)null;
                        switch (index)
                        {
                        case 0:
                        case 1:
                        case 2:
                        case 3:
                            texture2D2 = Main.wireUITexture[2 + index];
                            break;

                        case 4:
                            texture2D2 = Main.wireUITexture[WiresUI.Settings.ToolMode.HasFlag((Enum)WiresUI.Settings.MultiToolMode.Cutter) ? 7 : 6];
                            break;

                        case 5:
                            texture2D2 = Main.wireUITexture[10];
                            break;
                        }
                        Color color1 = Color.White;
                        Color color2 = Color.White;
                        if (!flag2 && index != 4)
                        {
                            if (flag3)
                            {
                                color2 = new Color(100, 100, 100);
                                color2 = new Color(120, 120, 120);
                                color1 = new Color(200, 200, 200);
                            }
                            else
                            {
                                color2 = new Color(150, 150, 150);
                                color2 = new Color(80, 80, 80);
                                color1 = new Color(100, 100, 100);
                            }
                        }
                        Utils.CenteredRectangle(vector2_2, new Vector2(40f));
                        if (flag3)
                        {
                            if (Main.mouseLeft && Main.mouseLeftRelease)
                            {
                                switch (index)
                                {
                                case 0:
                                    WiresUI.Settings.ToolMode ^= WiresUI.Settings.MultiToolMode.Red;
                                    break;

                                case 1:
                                    WiresUI.Settings.ToolMode ^= WiresUI.Settings.MultiToolMode.Green;
                                    break;

                                case 2:
                                    WiresUI.Settings.ToolMode ^= WiresUI.Settings.MultiToolMode.Blue;
                                    break;

                                case 3:
                                    WiresUI.Settings.ToolMode ^= WiresUI.Settings.MultiToolMode.Yellow;
                                    break;

                                case 4:
                                    WiresUI.Settings.ToolMode ^= WiresUI.Settings.MultiToolMode.Cutter;
                                    break;

                                case 5:
                                    WiresUI.Settings.ToolMode ^= WiresUI.Settings.MultiToolMode.Actuator;
                                    break;
                                }
                            }
                            Main.player[Main.myPlayer].mouseInterface = true;
                            this.OnWiresMenu = true;
                        }
                        int num8 = flag3 ? 1 : 0;
                        spriteBatch.Draw(texture2D1, vector2_2, new Rectangle?(), color1, 0.0f, texture2D1.Size() / 2f, 1f, SpriteEffects.None, 0.0f);
                        spriteBatch.Draw(texture2D2, vector2_2, new Rectangle?(), color2, 0.0f, texture2D2.Size() / 2f, 1f, SpriteEffects.None, 0.0f);
                    }
                }
                if (!Main.mouseLeft || !Main.mouseLeftRelease || flag1)
                {
                    return;
                }
                this.active = false;
            }
Esempio n. 22
0
        public override void AI()
        {
            if (projectile.timeLeft < 30)
            {
                projectile.alpha += 10;
            }
            // 核心代码部分

            // 如果玩家仍然在控制弹幕
            if (Main.player[projectile.owner].channel)
            {
                // 获取弹幕持有者
                Player player = Main.player[projectile.owner];

                // 从玩家到达鼠标位置的单位向量
                Vector2 unit = Vector2.Normalize(Main.MouseWorld - player.Center);
                // 随机角度
                float rotaion = unit.ToRotation();
                // 调整玩家转向以及手持物品的转动方向
                player.direction    = Main.MouseWorld.X < player.Center.X ? -1 : 1;
                player.itemRotation = (float)Math.Atan2(rotaion.ToRotationVector2().Y *player.direction,
                                                        rotaion.ToRotationVector2().X *player.direction);
                player.itemTime      = 2;
                player.itemAnimation = 2;
                // 从弹幕到达鼠标位置的单位向量
                Vector2 unit2 = Vector2.Normalize(Main.MouseWorld - projectile.Center);
                // 让弹幕缓慢朝鼠标方向移动
                if (Vector2.Distance(projectile.Center, Main.MouseWorld) < 5)
                {
                    projectile.velocity *= 0;
                    projectile.Center    = Main.MouseWorld;
                }
                else
                {
                    projectile.velocity = unit2 * 5;
                }
            }
            else
            {
                // 如果玩家放弃吟唱就慢慢消失
                if (projectile.timeLeft > 30)
                {
                    projectile.timeLeft = 30;
                }
                // 返回函数这样就不会执行下面的攻击代码
                return;
            }

            // 累加帧计时器
            projectile.frameCounter++;
            // 当计时器经过了7帧
            if (projectile.frameCounter % 7 == 0)
            {
                // 重置计时器
                projectile.frameCounter = 0;
                // 选择下一帧动画
                // 让弹幕的帧与等于与5进行模运算,也就是除以5的余数
                projectile.frame++;
                projectile.frame %= 5;
            }

            NPC target = null;
            // 最大寻敌距离
            float distanceMax = 400f;

            foreach (NPC npc in Main.npc)
            {
                // 如果npc活着且敌对
                if (npc.active && !npc.friendly && npc.type != NPCID.TargetDummy &&
                    Collision.CanHit(projectile.Center, 1, 1, npc.position, npc.width, npc.height))
                {
                    // 计算距离
                    float currentDistance = Vector2.Distance(npc.Center, projectile.Center);
                    // 如果npc距离比当前最大距离小
                    if (currentDistance < distanceMax)
                    {
                        // 就把最大距离设置为npc和玩家的距离
                        // 并且暂时选取这个npc为距离最近npc
                        distanceMax = currentDistance;
                        target      = npc;
                    }
                }
            }
            baseRot += 0.15f;
            // 如果找到符合条件的npc, 并且符合开火间隔(一秒6次)
            if (target != null && projectile.timeLeft % 10 < 1)
            {
                Vector2 toTarget = target.Center - projectile.Center;
                toTarget.Normalize();
                toTarget *= 6f;

                toTarget = toTarget.RotatedBy(baseRot);
                for (int i = 0; i < 3; i++)
                {
                    toTarget = toTarget.RotatedBy(MathHelper.Pi / 1.5f);
                    // 我调整了一下发射位置,这样射线看起来更像从磁球中间射出来的
                    Projectile.NewProjectile(projectile.Center + projectile.velocity * 4f,
                                             toTarget, ProjectileID.LightBeam, 100, 5f, projectile.owner, target.whoAmI);
                }
            }
        }
Esempio n. 23
0
    public void UpdateNet()
    {
        float angle       = -90;
        float angleAdd    = 22.5f;
        float distance    = 3f;
        float outDistance = 0.35f;

        Vector3[]      direction        = new Vector3[numberOfSensors];
        Vector3[]      relativePosition = new Vector3[numberOfSensors];
        RaycastHit2D[] rayHit           = new RaycastHit2D[numberOfSensors];

        float redness   = 1f - (damage / 100f);
        Color lineColor = new Color(1f, redness, redness);

        for (int i = 0; i < numberOfSensors; i++)
        {
            direction[i]        = Quaternion.AngleAxis(angle, Vector3.forward) * transform.up;
            relativePosition[i] = transform.position + (outDistance * direction[i]);
            rayHit[i]           = Physics2D.Raycast(relativePosition[i], direction[i], distance);
            lines[i].SetPosition(0, relativePosition[i]);
            sightHit[i] = -1f;

            if (rayHit[i].collider != null)
            {
                sightHit[i] = Vector2.Distance(rayHit[i].point, transform.position) / (distance);
                lines[i].SetPosition(1, rayHit[i].point);
            }
            else
            {
                lines[i].SetPosition(1, relativePosition[i]);
            }

            lines[i].SetColors(lineColor, lineColor);

            angle += angleAdd;
        }

        int num = Physics2D.OverlapCircleAll(transform.position, 0.3f).Length;

        num--;

        float[] inputValues =
        {
            sightHit[0],   sightHit[1],  sightHit[2],
            sightHit[3],   sightHit[4],  sightHit[5],
            sightHit[6],   sightHit[7],  sightHit[8],
            sightHit[9],   sightHit[10], sightHit[11],
            damage / 100f, num
        };

        float[] output = net.FireNet(inputValues);

        if (output[0] > 0)
        {
            rBody.velocity = 7 * transform.up * output[0];
        }
        else
        {
            rBody.velocity = rBody.velocity.magnitude * transform.up;
        }
        rBody.angularVelocity = 200f * output[1];

        float turn = (1f - Mathf.Abs(output[1]) / 100f);
        //net.AddNetFitness(turn/2f);
    }
        /// <summary>
        /// Apply values from native containers (jobs) to meshes
        /// </summary>
        public void ApplyMesh()
        {
            Mesh blockMesh = blockMeshFilter.mesh;

            blockMesh.Clear();

            Mesh liquidMesh = liquidMeshFilter.mesh;

            liquidMesh.Clear();

            Mesh plantsMesh = plantsMeshFilter.mesh;

            plantsMesh.Clear();

            // blocks
            blockMesh.SetVertices <float3>(blockVerticles);
            blockMesh.SetTriangles(blockTriangles.ToArray(), 0, false);
            blockMesh.SetUVs <float2>(0, blockUVs);

            // liquids
            liquidMesh.SetVertices <float3>(liquidVerticles);
            liquidMesh.SetTriangles(liquidTriangles.ToArray(), 0, false);
            liquidMesh.SetUVs <float2>(0, liquidUVs);

            //plants
            plantsMesh.SetVertices <float3>(plantsVerticles);
            plantsMesh.SetTriangles(plantsTriangles.ToArray(), 0, false);
            plantsMesh.SetUVs <float2>(0, plantsUVs);

            blockMesh.RecalculateNormals((MeshUpdateFlags)int.MaxValue);
            blockMeshFilter.mesh = blockMesh;

            // bake mesh immediately if player is near
            Vector2 playerPosition = new Vector2(PlayerController.PlayerTransform.position.x, PlayerController.PlayerTransform.position.z);

            if (Vector2.Distance(new Vector2(ChunkPosition.x, ChunkPosition.y), playerPosition) < FixedChunkSizeXZ * 2)
            {
                blockMeshCollider.sharedMesh = blockMesh;
            }
            else
            {
                World.SchedulePhysicsBake(this);
            }

            liquidMesh.RecalculateNormals((MeshUpdateFlags)int.MaxValue);
            liquidMeshFilter.mesh = liquidMesh;

            plantsMesh.RecalculateNormals((MeshUpdateFlags)int.MaxValue);
            plantsMeshFilter.mesh = plantsMesh;

            // clear blocks
            blockVerticles.Clear();
            blockTriangles.Clear();
            blockUVs.Clear();

            // clear liquids
            liquidVerticles.Clear();
            liquidTriangles.Clear();
            liquidUVs.Clear();

            // clear plants
            plantsVerticles.Clear();
            plantsTriangles.Clear();
            plantsUVs.Clear();
        }
Esempio n. 25
0
    public EBlockId GetVoxel(Vector3 pPos)
    {
        int yPos = Mathf.FloorToInt(pPos.y);

        if (!IsVoxelInWorld(pPos))
        {
            return(0);
        }


        //undestructable block at the bottom
        if (yPos == 0)
        {
            return(EBlockId.Bedrock);
        }

        int terrainHeight = Mathf.FloorToInt(
            terrainAttributes.terrainHeight *
            Noise.Get2DPerlin(pPos.x, pPos.z, 0, terrainAttributes.terrainScale)) +
                            terrainAttributes.solidGroundHeight;

        //enhance terrain height difference
        Vector2   p = new Vector2(pPos.x, pPos.z);
        const int circlesCenterStep = 50;
        const int circleScaleCoeff  = 30;

        //get center of 'hill'
        float   x = (int)(pPos.x / circlesCenterStep) * circlesCenterStep + circlesCenterStep / 2;
        float   z = (int)(pPos.z / circlesCenterStep) * circlesCenterStep + circlesCenterStep / 2;
        Vector2 c = new Vector2(x, z);

        if (Vector2.Distance(p, c) < circlesCenterStep / 2 - 5)
        {
            //enhance height based on distance from hill center
            float addition = 1 + 2 * Vector2.Distance(p, c) / circleScaleCoeff;

            //hills at odd indexes are reverted
            int indexX = Mathf.FloorToInt(c.x / (circlesCenterStep * 2));
            int indexY = Mathf.FloorToInt(c.y / (circlesCenterStep * 2));
            if (indexX % 2 == 1)
            {
                addition *= -1;
            }
            if (indexY % 2 == 1)
            {
                addition *= -1;
            }

            terrainHeight = (int)(terrainHeight + addition);
        }


        if (yPos < terrainHeight + 10 && IsVoxelAtWorldBorder(pPos))
        {
            return(EBlockId.Bedrock);
        }

        EBlockId voxelValue;

        if (yPos == terrainHeight)
        {
            voxelValue = EBlockId.Grass;
        }
        else if (yPos < terrainHeight && yPos > terrainHeight - terrainAttributes.dirtThickness)
        {
            voxelValue = EBlockId.Dirt;
        }
        else if (yPos > terrainHeight)
        {
            return(EBlockId.None);
        }
        else
        {
            voxelValue = EBlockId.Stone;
        }

        return(voxelValue);
    }
Esempio n. 26
0
    Vector3 pickRandPos()
    {
        float randX;
        float randY;

        if (Random.Range(0, 2) == 1)
        {
            randX = transform.position.x + Random.Range(4.0f, 7.0f);
            if (Random.Range(0, 2) == 1)
            {
                randY = transform.position.y + Random.Range(4.0f, 7.0f);
            }
            else
            {
                randY = transform.position.y + Random.Range(-7.0f, -4.0f);
            }
        }
        else
        {
            randX = transform.position.x + Random.Range(-7.0f, -4.0f);
            if (Random.Range(0, 2) == 1)
            {
                randY = transform.position.y + Random.Range(4.0f, 7.0f);
            }
            else
            {
                randY = transform.position.y + Random.Range(-7.0f, -4.0f);
            }
        }

        Vector3 randPos = new Vector3(Mathf.Clamp(randX, Camera.main.transform.position.x - 7, Camera.main.transform.position.x + 7), Mathf.Clamp(randY, Camera.main.transform.position.y - 7, Camera.main.transform.position.y + 7), 0);

        while (Physics2D.OverlapCircle(randPos, .5f) || Vector2.Distance(randPos, transform.position) < 2)
        {
            if (Random.Range(0, 2) == 1)
            {
                randX = transform.position.x + Random.Range(4.0f, 7.0f);
                if (Random.Range(0, 2) == 1)
                {
                    randY = transform.position.y + Random.Range(4.0f, 7.0f);
                }
                else
                {
                    randY = transform.position.y + Random.Range(-7.0f, -4.0f);
                }
            }
            else
            {
                randX = transform.position.x + Random.Range(-7.0f, -4.0f);
                if (Random.Range(0, 2) == 1)
                {
                    randY = transform.position.y + Random.Range(4.0f, 7.0f);
                }
                else
                {
                    randY = transform.position.y + Random.Range(-7.0f, -4.0f);
                }
            }
            randPos = new Vector3(Mathf.Clamp(randX, Camera.main.transform.position.x - 7, Camera.main.transform.position.x + 7), Mathf.Clamp(randY, Camera.main.transform.position.y - 7, Camera.main.transform.position.y + 7), 0);
        }
        return(randPos);
    }
Esempio n. 27
0
    private void FixedUpdate()
    {
        if (gameOver || isPause)
        {
            return;
        }
        // start mouse controls
        if (Input.GetMouseButtonDown(0))
        {
            if (!isMouseDown)
            {
                mouseStartPos = Input.mousePosition;
            }
            isMouseDown   = true;
            mouseDownTime = Time.time;
        }
        if (Input.GetMouseButtonUp(0))
        {
            isMouseDown = false;
            mouseUpTime = Time.time;
        }
        // start touch controls
        int tc = Input.touchCount;

        if (tc > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
        {
            fingerStartPos = Input.GetTouch(0).position;
            touchDownTime  = Time.time;
            isTouchDown    = true;
        }
        if (tc > 0 && Input.GetTouch(0).phase == TouchPhase.Ended)
        {
            touchUpTime    = Time.time;
            isTouchDown    = false;
            fingerStartPos = Input.GetTouch(0).position;
        }
        decayDown     = Mathf.Max(decayDown - Time.deltaTime, -1);
        decaySpaceBar = Mathf.Max(decaySpaceBar - Time.deltaTime, -1);
        decayTouchHor = Mathf.Max(decayTouchHor - Time.deltaTime, -1);
        //decayHor = Mathf.Max(decayHor - Time.deltaTime, -1);
        if (shape == null)
        {
            shape     = shapeNext;
            shapeNext = null;
            RenderShape(shape);
        }
        if (shapeNext == null)
        {
            shapeNext = createPiece.CreateNewPiece();
            Destroy(next);
            createNextPiece(shapeNext);
        }
        oldPosition = position;
        // keyboard/gamepad movement logic
        float dir = Input.GetAxis("Horizontal"), downPress = Input.GetAxis("Vertical");

        // mouse movement logic
        //if(isMouseDown)
        //    Debug.Log(mouseStartPos + " " + Input.mousePosition+" "+ Vector2.Distance(mouseStartPos, Input.mousePosition));
        if (decayTouchHor <= 0 && isMouseDown && Vector2.Distance(mouseStartPos, Input.mousePosition) > 1)
        {
            Vector2 v = Input.mousePosition - mouseStartPos;
            //Debug.Log(v + " " + v.normalized + " " + v.magnitude + " " + v.normalized.magnitude);
            dir           = v.normalized.x;
            decayTouchHor = decayTouchHorStart;
            mouseStartPos = Input.mousePosition;
            if (v.y < -10)
            {
                downPress = v.y;
                dir       = 0;
            }
        }
        // touch movement logic
        if (decayTouchHor <= 0 && isTouchDown && tc > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
        {
            Vector2 v = Input.GetTouch(0).position - fingerStartPos;
            dir            = v.normalized.x;
            decayTouchHor  = decayTouchHorStart;
            fingerStartPos = Input.GetTouch(0).position;
            if (v.y < -10)
            {
                downPress = v.y;
                dir       = 0;
            }
            //float angle = Vector2.Angle(fingerStartPos, Input.GetTouch(0).position);
            //dir = Mathf.Abs(angle) > 90 && Mathf.Abs(angle) < 180 + 90 ? -1 : 1;
        }
        if (decaySpaceBar <= 0 && (Input.GetButton("Jump") ||
                                   (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Ended && Math.Abs(touchUpTime - touchDownTime) < .5) ||
                                   (Input.GetMouseButtonUp(0) && Math.Abs(mouseUpTime - mouseDownTime) < .5))) // flip piece logic                                flip controls
        {
            changeVector.x = 0;
            rotateShape();                      // TODO can clip out of bounds on rotation
            decaySpaceBar = decaySpaceBarStart; // make sure flips don't happen too fast
        }

        if (Input.GetButton("Submit"))
        {
            Debug.Log("Submit");
            holdClicked();
        }

        if (Mathf.Abs(dir) > min)  //                                                         horizontal controls
        {
            changeVector.x = Mathf.Sign(dir);
        }
        if (downPress < -min)
        {
            decayDown = Mathf.Min(decayDown, .1f);
            if (firstTimePressed && Time.time - timeOfPressed < 0.5f)
            {
                // TODO double press to make speed 0
                //decayDown = -1; // doesn't work, need to teleport to bottom somehow probably need ghost image as prerequesite
                //foreach (Vector2 v in oldShape)
                //    changeToGrid((int)v.x, (int)v.y);
                //foreach (Vector2 v in oldGhost)
                //    changeToBlock((int)v.x, (int)v.y,shape.sprite,true);
                //shape = null;
                firstTimePressed = false;
            }
            else
            {
                firstTimePressed = true;
            }
        }
        else
        {
            timeOfPressed = Time.time;
        }
        changeVector.y = -1; // minus because it starts at the top ie grid position y = 19  not y = 0

        if (shape != null)
        {
            displayGhost();
        }
        // check if you can move in position direction // if not then remove the changeVector
        bool floorChanged = false;

        if (shape != null)
        {
            foreach (Vector2 v in shape.shape)
            {
                int x = (int)(v.x + position.x + changeVector.x);
                // -1 = 0+ 0 + -1 // 0 1 -1 0
                if (x < 0 || x >= grid.Count ||
                    ((int)(v.y + position.y) < grid[x].Count && // for overhang
                     grid[x][(int)(v.y + position.y)].GetComponent <Grid>().isPlaced)) // then you can't move in the designated x direction
                {
                    changeVector.x = 0;                                                // this isn't necessarily 0 due to rotation
                }
                x = (int)(v.x + position.x + changeVector.x);
                int y = (int)(v.y + position.y + changeVector.y);
                //Debug.Log(x + "," + y + " : "+v+" -> "+position+" -> "+changeVector);
                // TODO exception here when rotating out of bounds.  While moving an object out of bounds rotate it
                if (x < 0 || x >= grid.Count)   // 10 this fixes rotation issues
                {
                    changeVector.x = x >= grid.Count ? grid.Count - 1 - x : -x;
                    x += (int)changeVector.x;
                }
                //Debug.Log(x + " " + v.x + " " + position.x + " " + changeVector.x);

                List <GameObject> val = grid[x]; // check above should make sure x isn't out of bounds so don't need to check here
                if (y >= val.Count)              // for overhang
                {
                    continue;
                }
                if (y < 0 || val[y].GetComponent <Grid>().isPlaced)  // y <= 0 because the bottom is 0 and the top is 19 so don't go below the bottom
                {
                    changeVector.y = 0;
                    isFloor        = true;
                    floorChanged   = true;
                }
                if (changeVector.magnitude == 0)
                {
                    break;
                }
            }
        }
        if (decayDown > 0)      //                                                                                 veritcal controls
        {
            changeVector.y = 0; // put decay down here and floorChanged bool to fix (floor doesn't work when it touches the bottom then moves away ie: __- if it touches the right then you move over to the left it will float)
        }
        else
        {
            decayDown = decayDownStart;  // restart the decay so it doesn't move down every tick
        }
        if (!floorChanged)
        {
            isFloor = false;
        }
        if (isFloor) // start floor decay
        {
            decayFloorDown = Mathf.Max(decayFloorDown - Time.deltaTime, -1);
        }
        else
        {
            decayFloorDown = decayFloorDownStart;
        }
        if (decayFloorDown <= 0)   // this means the piece is now stuck in place
        // TODO if below is out of range then that means game over
        {
            foreach (Vector2 v in shape.shape) // turn this piece into something another piece can't move through
            {
                if ((int)(v.y + position.y) >= grid[(int)(v.x + position.x)].Count)
                {
                    endGame();
                }
                else
                {
                    grid[(int)(v.x + position.x)][(int)(v.y + position.y)].GetComponent <Grid>().isPlaced = true;
                }
            }
            shape          = shapeNext;
            decayFloorDown = decayFloorDownStart;
            shapeNext      = null;
            isFloor        = false;
            position       = origin;
            List <int> breaks = checkForBreaks();
            if (breaks.Count > 0)
            {
                breakRows(breaks);
            }
            addPoints(4); // add 4 points because you laid a shape with 4 pieces down
            oldGhost.Clear();
            oldShape.Clear();
            canHold = true;
        }
        if (changeVector.magnitude > 0)
        {
            //Debug.Log((position + changeVector) + " " + position + " " + changeVector);
            position += changeVector;
            moveShape(shape);
        }
        changeVector = Vector2.zero;
    }
Esempio n. 28
0
        /// <summary>
        ///     Gets triggered when a unit casts a spell and the unit is visible.
        /// </summary>
        private static void ObjAiHeroOnOnProcessSpellCast(Obj_AI_Base sender, GameObjectProcessSpellCastEventArgs args)
        {
            if (sender == null || !sender.IsValid)
            {
                return;
            }

            if (Config.PrintSpellData && sender is Obj_AI_Hero)
            {
                Game.PrintChat(Utils.TickCount + " ProcessSpellCast: " + args.SData.Name);
                Console.WriteLine(Utils.TickCount + " ProcessSpellCast: " + args.SData.Name);
            }

            if (args.SData.Name == "dravenrdoublecast")
            {
                Program.DetectedSkillshots.RemoveAll(
                    s => s.Unit.NetworkId == sender.NetworkId && s.SpellData.SpellName == "DravenRCast");
            }

            if (!sender.IsValid || sender.Team == ObjectManager.Player.Team && !Config.TestOnAllies)
            {
                return;
            }
            //Get the skillshot data.
            var spellData = SpellDatabase.GetByName(args.SData.Name);

            //Skillshot not added in the database.
            if (spellData == null)
            {
                return;
            }

            var startPos = new Vector2();

            if (spellData.FromObject != "")
            {
                foreach (var o in ObjectManager.Get <GameObject>())
                {
                    if (o.Name.Contains(spellData.FromObject))
                    {
                        startPos = o.Position.To2D();
                    }
                }
            }
            else
            {
                startPos = sender.ServerPosition.To2D();
            }

            //For now only zed support.
            if (spellData.FromObjects != null && spellData.FromObjects.Length > 0)
            {
                foreach (var obj in ObjectManager.Get <GameObject>())
                {
                    if (obj.IsEnemy && spellData.FromObjects.Contains(obj.Name))
                    {
                        var start = obj.Position.To2D();
                        var end   = start + spellData.Range * (args.End.To2D() - obj.Position.To2D()).Normalized();
                        TriggerOnDetectSkillshot(
                            DetectionType.ProcessSpell, spellData, Utils.TickCount - Game.Ping / 2, start, end,
                            sender);
                    }
                }
            }

            if (!startPos.IsValid())
            {
                return;
            }

            var endPos = args.End.To2D();

            if (spellData.SpellName == "LucianQ" && args.Target != null &&
                args.Target.NetworkId == ObjectManager.Player.NetworkId)
            {
                return;
            }

            //Calculate the real end Point:
            var direction = (endPos - startPos).Normalized();

            if (startPos.Distance(endPos) > spellData.Range || spellData.FixedRange)
            {
                endPos = startPos + direction * spellData.Range;
            }

            if (spellData.ExtraRange != -1)
            {
                endPos = endPos +
                         Math.Min(spellData.ExtraRange, spellData.Range - endPos.Distance(startPos)) * direction;
            }


            //Trigger the skillshot detection callbacks.
            TriggerOnDetectSkillshot(
                DetectionType.ProcessSpell, spellData, Utils.TickCount - Game.Ping / 2, startPos, endPos, sender);
        }
Esempio n. 29
0
        public override void AI()
        {
            npc.ai[0]++;
            npc.TargetClosest(true);
            npcCenter = new Vector2(npc.position.X + npc.width / 2, npc.position.Y + npc.height / 2);

            Player player = Main.player[npc.target];

            PlayerAngle = (float)Math.Atan2(player.position.Y - npc.position.Y,
                                            player.position.X - npc.position.X);
            #region default pattern
            if (npc.ai[0] < 720)
            {
                if(npc.ai[0] == 1 || npc.ai[0]%120 == 0 || Vector2.Distance(player.position - npc.position, Vector2.Zero) > 400f)
                {
                    oldPosition = new Vector2(player.position.X + Random(), player.position.Y + Random());

                    TargetAngle = (float)Math.Atan2(oldPosition.Y - npc.position.Y,
                                                    oldPosition.X - npc.position.X);

                    npc.velocity.X = Distance(null, TargetAngle, 4f).X;
                    npc.velocity.Y = Distance(null, TargetAngle, 4f).Y;

                    npc.rotation = TargetAngle;

                    if (npc.position.Y > player.position.Y)
                        npc.velocity.Y--;
                }
            }
            #endregion
            if(npc.ai[0] > 720)
            {
                #region sweep
                if (npc.ai[0] == 780)
                {
                    choose = Main.rand.Next(1, 2);
                }
                if (choose == 1)
                {
                    Start.X = player.position.X - 256;
                    Start.Y = player.position.Y - 448;

                    End.X = player.position.X + 256;
                    End.Y = Start.Y;

                    sweep = true;
                    choose = 0;
                }
                if (Depreciate > 0 && sweep)
                {
                    Depreciate--;
                    Point = (Time - Depreciate) / Time;
                    npc.position = Vector2.Lerp(Start, End, Point);

                    npc.rotation = radians * 90;
                    if (Depreciate % 8 == 0)
                    {
                        int attack = Projectile.NewProjectile(npc.position + new Vector2(npc.width / 2, npc.height / 2 + 32), Vector2.Zero, 134, 12 + Main.rand.Next(-2, 8), 2f, player.whoAmI, 0f, 0f);
                        Projectile proj = Main.projectile[attack];
                        proj.velocity.X += Distance(null, npc.rotation, 4f).X;
                        proj.velocity.Y += Distance(null, npc.rotation, 4f).Y;
                        proj.friendly = false;
                        proj.hostile = true;
                    }
                }
                else if (Depreciate == 0)
                {
                    sweep = false;
                    npc.ai[0] = 0;
                    Depreciate = Time;

                    npc.position = new Vector2(player.position.X + Random(), player.position.Y + Random());
                }
                #endregion
                #region spin
                if (choose == 2)
                {
                    oldPosition.X = player.position.X - npc.width / 2;
                    oldPosition.Y = player.position.Y - 384;
                    spinAttack = true;
                    choose = 0;
                }
                if (spinAttack)
                {
                    npc.position = oldPosition;

                    degrees += radians * 15;
                    npc.rotation = degrees;
                    if (degrees >= radians * 360)
                        degrees = radians;
                    if (degrees >= radians * 45f && degrees <= radians * 146.25f)
                    {
                        int attack = Projectile.NewProjectile(npc.position + new Vector2(npc.width/2, npc.height/2 + 32), Vector2.Zero, 134, 20, 2f, player.whoAmI, 0f, 0f);
                        Projectile proj = Main.projectile[attack];
                        proj.velocity.X += Distance(null, npc.rotation, 4f).X;
                        proj.velocity.Y += Distance(null, npc.rotation, 4f).Y;
                        proj.friendly = false;
                        proj.hostile = true;
                    }
                    ticks++;
                    if (ticks > 300)
                    {
                        spinAttack = false;
                        degrees = radians;
                        npc.rotation = PlayerAngle;
                        ticks = 0;
                        npc.ai[0] = 0;

                        npc.position = new Vector2(player.position.X + Random(), player.position.Y + Random());
                    }
                }
                #endregion
            }
            #region magno clone sequence
            if (!pupsSpawned && Main.rand.Next(0, 1200) == 0)
            {
                for (int k = 0; k < 4; k++)
                {
                    pups = NPC.NewNPC((int)npcCenter.X + Main.rand.Next(-npc.width, npc.width), (int)npcCenter.Y, mod.NPCType("m_diggerhead"));
                    NetMessage.SendData(23, -1, -1, null, pups, 0f, 0f, 0f, 0, 0, 0);
                    pupsSpawned = true;
                }
            }
            if (pupsSpawned)
            {
                Main.npc[pups].realLife = Main.npc[pups].whoAmI;
                if (!Main.npc[pups].active)
                {
                    pupsSpawned = false;
                    magnoClone = true;
                }
            }
            if (magnoClone)
            {
                clone = NPC.NewNPC((int)npcCenter.X, (int)npcCenter.Y + 128, mod.NPCType("m_mimic"));
                Main.npc[clone].color = Color.Gold;
                Main.npc[clone].scale = 0.6f;
                timeLeft = 600;
                magnoClone = false;
            }
            if(timeLeft > 0)
                timeLeft--;
            if (timeLeft < 60)
            {
            /*  degrees += radians * 11.25f;
                Main.npc[clone].rotation = degrees;
                Main.npc[clone].scale++;
                Main.npc[clone].velocity = Vector2.Zero;
            */
                if (timeLeft == 0)
                {
                    Main.npc[clone].active = false;
                    timeLeft = 600;
                }
            }
            #endregion
        }
Esempio n. 30
0
            /// <summary>
            ///     Returns a list of Vector2 point candidates for the linear prediction.
            /// </summary>
            /// <param name="from">Vector2 from position</param>
            /// <param name="to">Vector2 to position</param>
            /// <param name="radius">The Radius</param>
            /// <param name="range">The Range</param>
            /// <returns>Vector2 list</returns>
            internal static Vector2[] GetCandidates(Vector2 from, Vector2 to, float radius, float range)
            {
                var middlePoint = (from + to) / 2;
                var intersections = @from.CircleCircleIntersection(middlePoint, radius, from.Distance(middlePoint));

                if (intersections.Length > 1)
                {
                    var c1 = intersections[0];
                    var c2 = intersections[1];

                    c1 = from + range * (to - c1).Normalized();
                    c2 = from + range * (to - c2).Normalized();

                    return new[] { c1, c2 };
                }

                return new Vector2[] { };
            }
Esempio n. 31
0
 public static float Distance(this Vector2 v, Vector2 to, bool squared = false)
 {
     return(squared ? Vector2.DistanceSquared(v, to) : Vector2.Distance(v, to));
 }
        public bool AssignTrackIfClose(EdgeCollider2D track)
        {
            if (m_CurrentPointIndex != -1)
            {
                // Already assigned to a track
                return(false);
            }

            // Get the points of the track in world position
            var points = track.points.Select(pt => pt + (Vector2)track.transform.position).ToArray();

            Assert.IsTrue(points.Length > 1);

            var pos         = gameObject.transform.position;
            var minDistance = float.MaxValue;
            var ptOnTrack   = Vector2.zero;
            var ptIndex     = -1;

            // Find closest position in the line segments passed in
            for (int i = 0; i < points.Length - 1; i++)
            {
                var A           = points[i];
                var B           = points[i + 1];
                var ptPotential = ClosestPointOnLineSegment(pos, A, B);

                var distance = Vector2.Distance(pos, ptPotential);

                if (distance < minDistance)
                {
                    minDistance = distance;
                    ptOnTrack   = ptPotential;
                    ptIndex     = i;
                }
            }

            // Are we close enough to the track to be attached to it?
            if (minDistance < MaxDistanceFromTrack)
            {
                // Use projection and initial direction to determine how we should travel from one edge to another along our track
                var nextIndex = (ptIndex + 1) % points.Length;
                var A         = points[ptIndex];
                var B         = points[nextIndex];
                if (Vector2.Dot(B - A, m_InitialDirection) < 0)
                {
                    // Reverse track direction
                    m_IndexAdvance = -1;
                    ptIndex        = nextIndex;
                }
                else
                {
                    m_IndexAdvance = 1;
                }

                m_CurrentPointIndex           = ptIndex;
                m_Points                      = points;
                gameObject.transform.position = ptOnTrack;
                return(true);
            }

            return(false);
        }
Esempio n. 33
0
 public static float Distance(this Vector2 v, Vector3 to, bool squared = false)
 {
     return(v.Distance(to.ToVector2(), squared));
 }
Esempio n. 34
0
 public static float Distance(this Vector2 v, Obj_AI_Base to, bool squared = false)
 {
     return(v.Distance(to.ServerPosition.ToVector2(), squared));
 }
        public static Vector2 GetBlinkCastPos(EvadePlus evade, Vector2 center, float maxRange)
        {
            var polygons = evade.ClippedPolygons.Where(p => p.IsInside(center)).ToArray();
            var segments = new List<Vector2[]>();

            foreach (var pol in polygons)
            {
                for (var i = 0; i < pol.Points.Count; i++)
                {
                    var start = pol.Points[i];
                    var end = i == pol.Points.Count - 1 ? pol.Points[0] : pol.Points[i + 1];

                    var intersections =
                        Utils.GetLineCircleIntersectionPoints(center, maxRange, start, end)
                            .Where(p => p.IsInLineSegment(start, end))
                            .ToList();

                    if (intersections.Count == 0)
                    {
                        if (start.Distance(center, true) < maxRange.Pow() &&
                            end.Distance(center, true) < maxRange.Pow())
                        {
                            intersections = new[] {start, end}.ToList();
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else if (intersections.Count == 1)
                    {
                        intersections.Add(center.Distance(start, true) > center.Distance(end, true)
                            ? end
                            : start);
                    }

                    segments.Add(intersections.ToArray());
                }
            }

            if (!segments.Any())
            {
                return Vector2.Zero;
            }

            const int maxdist = 2000;
            const int division = 30;
            var points = new List<Vector2>();

            foreach (var segment in segments)
            {
                var dist = segment[0].Distance(segment[1]);
                if (dist > maxdist)
                {
                    segment[0] = segment[0].Extend(segment[1], dist/2 - maxdist/2);
                    segment[1] = segment[1].Extend(segment[1], dist/2 - maxdist/2);
                    dist = maxdist;
                }

                var step = maxdist/division;
                var count = dist/step;

                for (var i = 0; i < count; i++)
                {
                    var point = segment[0].Extend(segment[1], i*step);
                    if (!point.IsWall())
                    {
                        points.Add(point);
                    }
                }
            }

            if (!points.Any())
            {
                return Vector2.Zero;
            }

            var evadePoint =
                points.OrderByDescending(p => p.Distance(evade.LastIssueOrderPos) + p.Distance(center)).Last();
            return evadePoint;
        }
Esempio n. 36
0
        public static void CaveManAI(Enemy enemy, Player player, Room room, List <Bullet> bullets, GameTime gameTime)
        {
            var move_vector = player.Centre() - enemy.Centre();
            var offset      = Vector2.Zero;

            // Attack if able, the 'swing' is a bullet
            if (enemy.attack_cooldown <= 0 && Vector2.Distance(player.Centre(), enemy.Centre()) < enemy.range)
            {
                Bullet     attack;
                bool       ranged          = false;
                Directions bulletDirection = Directions.None;

                if (enemy.enemyType == EnemyType.Caveman)
                {
                    attack                = new Bullet(BulletType.MeleeSwing, enemy.facing);
                    attack.speed          = 0;
                    enemy.attack_cooldown = 2000;
                    attack.duration       = 1000;
                    attack.damage         = 1;

                    if (enemy.facing == Directions.Up)
                    {
                        enemy.Sprite.PlayAnimation(enemy.AnimMeleeUp, 1);
                    }
                    if (enemy.facing == Directions.Down)
                    {
                        enemy.Sprite.PlayAnimation(enemy.AnimMeleeDown, 1);
                    }
                    if (enemy.facing == Directions.Left)
                    {
                        enemy.Sprite.PlayAnimation(enemy.AnimMeleeLeft, 1);
                    }
                    if (enemy.facing == Directions.Right)
                    {
                        enemy.Sprite.PlayAnimation(enemy.AnimMeleeRight, 1);
                    }
                }
                else
                {
                    attack = new Bullet(BulletType.Cyborg, enemy.facing);
                    if (enemy.enemyType == EnemyType.Cyborg)
                    {
                        enemy.attack_cooldown = 2000;
                    }
                    else
                    {
                        enemy.attack_cooldown = 2000;
                    }
                    attack.speed      = 200;
                    attack.duration   = 1000;
                    attack.damage     = 1;
                    attack.col_width  = 16;
                    attack.col_height = 16;

                    ranged = true;
                }

                var rangedOffset = new Vector2(7, 25);

                if (enemy.enemyType == EnemyType.Caveman)
                {
                    // Figure out the direction of the attack
                    offset = Vector2.Zero;
                    if (Vector2.Distance(player.Centre(), enemy.Centre()) < 20)
                    {
                        attack.col_width  = attack.draw_width = 30;
                        attack.col_height = attack.draw_height = 30;
                        attack.SetPosCentre(enemy.Centre() + new Vector2(0, 0));
                        if (ranged)
                        {
                            attack.SetPosCentre(enemy.Centre() + rangedOffset);
                        }

                        if (ranged)
                        {
                            attack.vel.X++;
                        }
                    }
                    else if (move_vector.X > Math.Abs(move_vector.Y) && move_vector.X >= 0)
                    {
                        offset = new Vector2(-5, 14);
                        if (ranged)
                        {
                            offset = Vector2.Zero;
                        }
                        attack.col_width  = attack.draw_width = 20;
                        attack.col_height = attack.draw_height = 60;
                        attack.SetPosCentre(enemy.Centre() + new Vector2(35, 0));
                        if (ranged)
                        {
                            attack.SetPosCentre(enemy.Centre() + rangedOffset);
                        }
                        attack.pos += offset;
                        attack.collision_offset = -1 * offset;

                        if (ranged)
                        {
                            attack.vel.X++;
                        }
                    }
                    else if (Math.Abs(move_vector.X) > Math.Abs(Math.Abs(move_vector.Y)) && move_vector.X <= 0)
                    {
                        offset = new Vector2(5, 14);
                        if (ranged)
                        {
                            offset = Vector2.Zero;
                        }
                        attack.col_width  = attack.draw_width = 20;
                        attack.col_height = attack.draw_height = 60;
                        attack.SetPosCentre(enemy.Centre() + new Vector2(-35, 0));
                        if (ranged)
                        {
                            attack.SetPosCentre(enemy.Centre() + rangedOffset);
                        }
                        attack.pos += offset;
                        attack.collision_offset = -1 * offset;

                        if (ranged)
                        {
                            attack.vel.X--;
                        }
                    }
                    else if (Math.Abs(move_vector.X) <= Math.Abs(move_vector.Y) && move_vector.Y <= 0)
                    {
                        offset = new Vector2(14, 5);
                        if (ranged)
                        {
                            offset = Vector2.Zero;
                        }
                        attack.col_width  = attack.draw_width = 60;
                        attack.col_height = attack.draw_height = 20;
                        attack.SetPosCentre(enemy.Centre() + new Vector2(0, -35));
                        if (ranged)
                        {
                            attack.SetPosCentre(enemy.Centre() + rangedOffset);
                        }
                        attack.pos += offset;
                        attack.collision_offset = -1 * offset;

                        if (ranged)
                        {
                            attack.vel.Y--;
                        }
                    }
                    else if (Math.Abs(move_vector.X) <= move_vector.Y && move_vector.Y > 0)
                    {
                        offset = new Vector2(14, -5);
                        if (ranged)
                        {
                            offset = Vector2.Zero;
                        }
                        attack.col_width  = attack.draw_width = 60;
                        attack.col_height = attack.draw_height = 20;
                        attack.SetPosCentre(enemy.Centre() + new Vector2(0, 35));
                        if (ranged)
                        {
                            attack.SetPosCentre(enemy.Centre() + rangedOffset);
                        }
                        attack.pos += offset;
                        attack.collision_offset = -1 * offset;

                        if (ranged)
                        {
                            attack.vel.Y++;
                        }
                    }
                }
                else
                {
                    offset = Vector2.Zero;
                    if (move_vector.X > Math.Abs(move_vector.Y) && move_vector.X >= 0) //right
                    {
                        offset = Vector2.Zero;
                        attack.SetPosCentre(enemy.Centre() + offset);
                        attack.vel.X++;
                    }
                    else if (Math.Abs(move_vector.X) > Math.Abs(Math.Abs(move_vector.Y)) && move_vector.X <= 0)//left
                    {
                        //offset = new Vector2(-5, 14);
                        offset = Vector2.Zero;
                        attack.SetPosCentre(enemy.Centre() + offset);
                        attack.vel.X--;
                    }
                    else if (Math.Abs(move_vector.X) <= Math.Abs(move_vector.Y) && move_vector.Y <= 0)//up
                    {
                        //offset = new Vector2(-5, 14);
                        offset = Vector2.Zero;
                        attack.SetPosCentre(enemy.Centre() + offset);
                        attack.vel.Y--;
                    }
                    else if (Math.Abs(move_vector.X) <= move_vector.Y && move_vector.Y > 0)//down
                    {
                        //offset = new Vector2(-5, 14);
                        offset = Vector2.Zero;
                        attack.SetPosCentre(enemy.Centre() + offset);
                        attack.vel.Y++;
                    }
                }
                if (ranged)
                {
                    enemy.ExplosionSprite.PlayAnimation(enemy.AnimLightningExplosion, 1);
                    enemy.AnimExplosionDuration = enemy.AnimLightningExplosion.Duration;
                    enemy.ExplosionPos          = attack.Centre() + offset;
                }

                bullets.Add(attack);

                if (enemy.enemyType == EnemyType.Caveman)
                {
                    ModManager.Instance.SoundManager.PlaySound("SFXMelee", (int)SoundType.SoundEffect, false);
                }
                else if (enemy.enemyType == EnemyType.Cyborg)
                {
                    ModManager.Instance.SoundManager.PlaySound("SFXLaser", (int)SoundType.SoundEffect, false);
                }
                else if (enemy.enemyType == EnemyType.CaveBorg)
                {
                    ModManager.Instance.SoundManager.PlaySound("SFXLaser", (int)SoundType.SoundEffect, false);
                }
            }

            // Move towards player, unless too close or attack is on cooldown
            //enemy.vel = new Vector2(0);

            var playerCenter = player.Centre();
            var enemyCenter  = enemy.Centre();
            int xDiff        = (int)(playerCenter.X - enemyCenter.X);
            var yDiff        = (int)(playerCenter.Y - enemyCenter.Y);

            if (Vector2.Distance(player.pos, enemy.pos) < enemy.range / 2 || enemy.attack_cooldown > 0)
            {
                enemy.vel       = new Vector2(0);
                enemy.moveup    = false;
                enemy.movedown  = false;
                enemy.moveleft  = false;
                enemy.moveright = false;
            }
            else
            {
                enemy.moveup    = false;
                enemy.movedown  = false;
                enemy.moveleft  = false;
                enemy.moveright = false;

                if (xDiff > 0)
                {
                    enemy.moveright = true;
                }
                else if (xDiff < 0)
                {
                    enemy.moveleft = true;
                }
                if (yDiff > 0)
                {
                    enemy.movedown = true;
                }
                else if (yDiff < 0)
                {
                    enemy.moveup = true;
                }
            }
        } // CaveManAI