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; }
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; }
/// <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); }
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; } } } }
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); } } } }
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 } }
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))); }
private ScriptLineView FindLineNearPosition(Vector2 worldPos) { var localPos = linesContainer.WorldToLocal(worldPos); return(linesContainer.Children().OrderBy(v => Vector2.Distance(localPos, v.layout.center)).FirstOrDefault() as ScriptLineView); }
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); } }
/// <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; }
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); } } } } } }
// 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(); } } } }
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); }
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; } }
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; }
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); } } }
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(); }
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); }
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); }
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; }
/// <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); }
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 }
/// <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[] { }; }
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); }
public static float Distance(this Vector2 v, Vector3 to, bool squared = false) { return(v.Distance(to.ToVector2(), squared)); }
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; }
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