private NPC getTarget() { float lowestD = 1100; NPC closest = null; for (int i = 0; i < 200; i++) { NPC npc = Main.npc[i]; float distance = (float)Math.Sqrt((npc.Center.X - projectile.Center.X) * (npc.Center.X - projectile.Center.X) + (npc.Center.Y - projectile.Center.Y) * (npc.Center.Y - projectile.Center.Y)); if (npc.townNPC || npc.catchItem > 0) { } else if (lowestD > distance && npc.CanBeChasedBy() && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.Center, 1, 1)) { closest = npc; lowestD = distance; } } target = closest; return(closest); }
public override void AI() { if (Main.rand.Next(200) == 0) { Main.dust[Dust.NewDust(projectile.Center + new Vector2(6, 6).RotatedBy(projectile.rotation), 0, 0, 204, 0f, 0f, 0, new Color(255, 255, 255), 1f)].velocity *= 0.2f; } if (projectile.damage == 1) { Vector2 center = projectile.Center; // - new Vector2(0, 4).RotatedBy(projectile.rotation); double rot = Math.Round(projectile.rotation / MathHelper.PiOver4); Vector2 offset = new Vector2(0, 8).RotatedBy(rot * MathHelper.PiOver4); //new Vector2(4, 0).RotatedBy(projectile.rotation); //Main.dust[Dust.NewDust(center-offset, 0, 0, 204, 0f, 0f, 0, new Color(255,255,255), 1f)].velocity*=0f; //Main.dust[Dust.NewDust(center+offset, 0, 0, 204, 0f, 0f, 0, new Color(255,255,255), 1f)].velocity*=0f; if (Collision.CanHitLine(center - offset, 0, 0, center + offset, 0, 0)) { //Main.dust[Dust.NewDust(center, 0, 0, 27, 0f, 0f, 0, new Color(255,0,0), 1f)].velocity*=0.2f; Item.NewItem(projectile.Center, ModContent.ItemType <Fiberglass_Shard>()); projectile.Kill(); } } }
public override Vector2 IdleBehavior() { animationFrame++; gHelper.SetIsOnGround(); // the ground-based slime can sometimes bounce its way around // a corner, but the flying version can't noLOSPursuitTime = gHelper.isFlying ? 15 : 300; List <Projectile> minions = GetActiveMinions(); int order = minions.IndexOf(projectile); Vector2 idlePosition = player.Center; idlePosition.X += (40 + order * 38) * -player.direction; if (!Collision.CanHitLine(idlePosition, 1, 1, player.Center, 1, 1)) { idlePosition = player.Center; } Vector2 vectorToIdlePosition = idlePosition - projectile.Center; TeleportToPlayer(ref vectorToIdlePosition, 2000f); return(vectorToIdlePosition); }
private void TargetEnemies() { float maxDistance = 1000f; int possibleTarget = -1; for (int i = 0; i < Main.maxPlayers; i++) { Player player = Main.player[i]; if (player.active && Collision.CanHitLine(projectile.Center, 0, 0, player.Center, 0, 0)) { float Distance = projectile.Distance(player.Center); if (Distance < maxDistance) { maxDistance = Distance; possibleTarget = i; } } } projectile.localAI[1] = possibleTarget; projectile.netUpdate = true; }
public override void AI() { npc.TargetClosest(true); Player target = Main.player[npc.target]; if (Collision.CanHitLine(npc.position, npc.width, npc.height, target.position, target.width, target.height)) { npc.ai[3]++; } if (npc.ai[3] > 120 && Main.netMode != NetmodeID.MultiplayerClient) { float speedX = target.MountedCenter.X - npc.Center.X; float speedY = target.MountedCenter.Y - npc.Center.Y; Vector2 spd = new Vector2(speedX, speedY); spd.Normalize(); spd *= 14; Projectile.NewProjectile(npc.Center, spd, ModContent.ProjectileType <Projectiles.Smokedevil>(), npc.damage / 4, 0f); npc.ai[3] = Main.rand.Next(0, 30); npc.netUpdate = true; } }
public Vector2?ClosestEnemyInRange(float maxRange, Vector2?centeredOn = null, float noLOSRange = 0, bool maxRangeFromPlayer = true, Vector2?losCenter = null) { Vector2 center = centeredOn ?? projectile.Center; Vector2 targetCenter = projectile.position; Vector2 losCenterVector = losCenter ?? projectile.Center; bool foundTarget = false; for (int i = 0; i < Main.maxNPCs; i++) { NPC npc = Main.npc[i]; if (!npc.CanBeChasedBy()) { continue; } float between = Vector2.Distance(npc.Center, center); bool closest = Vector2.Distance(center, targetCenter) > between; // don't let a minion infinitely chain attacks off progressively further enemies bool inRange = Vector2.Distance(npc.Center, maxRangeFromPlayer ? player.Center : projectile.Center) < maxRange; bool inNoLOSRange = Vector2.Distance(npc.Center, player.Center) < noLOSRange; bool lineOfSight = inNoLOSRange || Collision.CanHitLine(losCenterVector, 1, 1, npc.position, npc.width, npc.height); if ((inNoLOSRange || (lineOfSight && inRange)) && (closest || !foundTarget)) { targetNPCIndex = i; targetCenter = npc.Center; foundTarget = true; } } if (foundTarget) { return(targetCenter); } else if (useBeacon) { return(BeaconPosition(center, maxRange, noLOSRange)); } else { return(null); } }
public override Vector2 IdleBehavior() { // hover behind the player Vector2 idlePosition = player.Top; idlePosition.X += 24 * -player.direction; idlePosition.Y += -8; // not sure what side effects changing this each frame might have if (attackSpeedCanBeModified) { projectile.localNPCHitCooldown = (int)(baseLocalIFrames * player.GetModPlayer <SquireModPlayer>().squireAttackSpeedMultiplier); } if (!Collision.CanHitLine(idlePosition, 1, 1, player.Center, 1, 1)) { idlePosition.X = player.Center.X; idlePosition.Y = player.Center.Y - 24; } Vector2 vectorToIdlePosition = idlePosition - projectile.Center; TeleportToPlayer(ref vectorToIdlePosition, 2000f); return(vectorToIdlePosition); }
public override void AI() { Player P = Main.player[npc.target]; npc.netUpdate = true; if (Vector2.Distance(npc.Center, P.Center) > 1500 || npc.target < 0 || npc.target == 255 || Main.player[npc.target].dead || !Main.player[npc.target].active) { npc.TargetClosest(true); P = Main.player[npc.target]; if (!P.active || P.dead || Vector2.Distance(npc.Center, P.Center) > 1500) { regen = true; } } if (!regen) { npc.life = npc.life < npc.lifeMax ? npc.life + 1 + (int)((float)npc.lifeMax * 0.001f) : npc.lifeMax; if (Collision.CanHitLine(new Vector2(npc.Center.X, npc.Center.Y), 1, 1, new Vector2(P.Center.X, P.Center.Y), 1, 1) || Vector2.Distance(npc.Center, P.Center) < 400) { regen = true; } } if (npc.velocity.Y == 0) { if (chance != 0) { chance = Main.rand.Next(150); } else { if (Collision.CanHitLine(new Vector2(npc.Center.X, npc.Center.Y), 1, 1, new Vector2(P.Center.X, P.Center.Y), 1, 1)) { npc.velocity.Y = -(float)Math.Sqrt(2 * 0.3f * Math.Abs((P.position.Y - 100) - npc.Center.Y)); npc.velocity.X = (P.Center.X + P.velocity.X - npc.Center.X) / 90; chance = 1; } } } }
public override bool?Colliding(Rectangle projHitbox, Rectangle targetHitbox) { // use a computed weapon hitbox instead of the projectile's natural hitbox if (!IsAttacking()) { return(false); } Vector2 unitAngle = UnitVectorFromWeaponAngle(); for (int i = WeaponHitboxStart(); i < WeaponHitboxEnd(); i += 8) { Vector2 tipCenter = projectile.Center + WeaponCenterOfRotation + i * unitAngle; Rectangle tipHitbox = new Rectangle((int)tipCenter.X - 8, (int)tipCenter.Y - 8, 16, 16); if (tipHitbox.Intersects(targetHitbox)) { return(Collision.CanHitLine( tipHitbox.Center.ToVector2(), 1, 1, projectile.Center, 1, 1)); } } return(false); }
public Vector2?AnyEnemyInRange(float maxRange, Vector2?centeredOn = null, bool noLOS = false) { Vector2 center = centeredOn ?? projectile.Center; for (int i = 0; i < Main.maxNPCs; i++) { NPC npc = Main.npc[i]; if (!npc.CanBeChasedBy()) { continue; } // bool inRange = Vector2.Distance(center, npc.Center) < maxRange; bool lineOfSight = noLOS || (inRange && Collision.CanHitLine(center, 1, 1, npc.Center, 1, 1)); if (lineOfSight && inRange) { targetNPCIndex = npc.whoAmI; return(npc.Center); } } return(null); }
public static NPC FindNearestNPC(Vector2 position, float maxDist, bool ignoreLineOfSight = true, bool ignoreFriendlies = true, bool ignoreDontTakeDamage = false, bool ignoreChaseable = false) { NPC nearest = null; float distNearest = maxDist * maxDist; for (int i = 0; i < 200; i++) { NPC npc = Main.npc[i]; Vector2 npcCenter = npc.Center; if (npc.active && (ignoreChaseable || npc.chaseable && npc.lifeMax > 5) && (ignoreDontTakeDamage || !npc.dontTakeDamage) && (!ignoreFriendlies || !npc.friendly) && !npc.immortal) { float distCurrent = Vector2.DistanceSquared(position, npcCenter); if (distCurrent < distNearest && (ignoreLineOfSight || Collision.CanHitLine(position, 0, 0, npcCenter, 0, 0))) { nearest = npc; distNearest = distCurrent; } } } return(nearest); }
public override void AI(NPC npc) { base.AI(npc); if (npc.velocity.Y < 0f) { CanDoLavaJump = true; } else if (npc.velocity.Y > 0f) //coming down { //when below target, in hell, with line of sight if (CanDoLavaJump && Main.netMode != NetmodeID.MultiplayerClient && npc.HasValidTarget && npc.Bottom.Y > Main.player[npc.target].Bottom.Y && npc.Center.ToTileCoordinates().Y > Main.maxTilesY - 200 && Collision.CanHitLine(npc.Center, 0, 0, Main.player[npc.target].Center, 0, 0)) { CanDoLavaJump = false; //Projectile.NewProjectile(npc.Center, Vector2.Zero, ProjectileID.DD2ExplosiveTrapT1Explosion, 0, 0, Main.myPlayer); int tileX = (int)(npc.Center.X + npc.velocity.X) / 16; int tileY = (int)(npc.Center.Y + npc.velocity.Y) / 16; Tile tile = Framing.GetTileSafely(tileX, tileY); if (tile != null && !tile.HasTile && tile.LiquidAmount == 0) { tile.LiquidType = LiquidID.Lava; //does this still spawn the liquid properly?? if (Main.netMode == NetmodeID.Server) { NetMessage.SendTileSquare(-1, tileX, tileY, 1); } WorldGen.SquareTileFrame(tileX, tileY, true); npc.velocity.Y = 0; npc.netUpdate = true; } } } else //npc vel y = 0 { CanDoLavaJump = false; } }
/// <summary> /// The AI of the projectile /// </summary> public override void AI() { Vector2 start = projectile.Center; Vector2 unit = velocity; unit.Normalize(); Vector2 samplingPoint = projectile.Center; // Overriding that, if the player shoves the Prism into or through a wall, the interpolation starts at the player's center. // This last part prevents the player from projecting beams through walls under any circumstances. Player player = Main.player[projectile.owner]; if (projectile.timeLeft == 32) { velocity = Vector2.Normalize(Main.MouseWorld - player.MountedCenter); projectile.position += velocity * 16; if (!Collision.CanHitLine(player.Center, 0, 0, projectile.Center, 0, 0)) { samplingPoint = projectile.Center = player.Center; } } float[] laserScanResults = new float[sample_points]; Collision.LaserScan(samplingPoint, unit, collision_size * projectile.scale, 1200f, laserScanResults); float averageLengthSample = 0f; for (int i = 0; i < laserScanResults.Length; ++i) { averageLengthSample += laserScanResults[i]; } averageLengthSample /= sample_points; _targetPos = projectile.Center + (unit * averageLengthSample); if (++projectile.frameCounter > 5) { projectile.frame = (projectile.frame + 1) % 4; projectile.frameCounter = 0; } }
public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack) { Vector2 speed = new Vector2(speedX, speedY); int projectiles = 6; for (int i = 0; i < projectiles; i++) { float roTATe = (int)((360f / projectiles * i) + circleCounter); float maxCursorReach = 192f; float distance = Math.Abs((player.MountedCenter - Main.MouseWorld).Length()); float positionOffset = -MathHelper.Clamp(distance, 0f, maxCursorReach); Vector2 spawnPosition = new Vector2(0f, positionOffset).RotatedBy(MathHelper.ToRadians(roTATe)); Vector2 shootSpeed = new Vector2(0f, -speed.Length()).RotatedBy(MathHelper.ToRadians(roTATe)) * MathHelper.Clamp((rotationIncrement / minMax[1]), 0.05f, (rotationIncrement / minMax[1])); if (Collision.CanHitLine(position, 0, 0, position + spawnPosition, 0, 0)) { Projectile projectile = Projectile.NewProjectileDirect(position + spawnPosition, shootSpeed, type, (int)(damage * (rotationIncrement / minMax[1])), knockBack * (rotationIncrement / minMax[1]), player.whoAmI); projectile.timeLeft = 45; projectile.scale = 1.1f; projectile.frame = Main.rand.Next(14); //projectile.timeLeft = 600; int rings = 16; for (int j = 0; j < rings; j++) { for (int k = 0; k < 10; k++) { Vector2 dustVelocity = (new Vector2(0f, rings).RotatedBy(j * (MathHelper.ToRadians(360f) / rings)) * new Vector2(2f, 4f)).RotatedBy(MathHelper.ToRadians(360f / projectiles * i + circleCounter)); Dust dust1 = Dust.NewDustPerfect(projectile.Center + dustVelocity, dustType, Vector2.Zero, 0, dustColor, 0.5f); dust1.noGravity = true; } } } } return(false); }
public static void DoAwarenessChecks(int distance, bool checkwalls, bool sound = false, Vector2 soundLoc = default) { if (watchers.Count < 1) { return; } if (!Main.gameMenu && sound == false && SGAPocketDim.WhereAmI != null) { if (SLWorld.currentSubworld is SGAPocketDim sub && sub.GetType() == typeof(LimboDim)) { distance *= 2; } } foreach (NullWatcher watcher in watchers) { if (!sound) { List <Player> players = Main.player.Where(playercheck => playercheck != null && playercheck.active && !playercheck.dead && (((!playercheck.invis || playercheck.itemTime > 0) && !playercheck.SGAPly().magatsuSet) || playercheck.SGAPly().watcherDebuff >= 500) && playercheck.Distance(watcher.npc.Center) < (distance + playercheck.SGAPly().watcherDebuff) && (!checkwalls || Collision.CanHitLine(playercheck.Center, 1, 1, watcher.npc.Center, 1, 1))).ToList(); players = players.OrderBy(playercheck2 => playercheck2.Distance(watcher.npc.Center)).ToList(); if (players != null && players.Count > 0) { Player them = players[0]; int add = them.SGAPly().watcherDebuff > 0 ? 2 : 1; watcher.GrowAwareness(soundLoc, add, distance, true, them); } } if (sound && (soundLoc - watcher.npc.Center).Length() < distance) { watcher.GrowAwareness(soundLoc, 30, distance, false); } } }
// A simpler version of SelectedEnemyInRange that doesn't require any tactics/teams stuff public NPC GetClosestEnemyToPosition(Vector2 position, float searchRange, bool requireLOS = true) { float minDist = float.MaxValue; NPC closest = null; for (int i = 0; i < Main.maxNPCs; i++) { NPC npc = Main.npc[i]; if (ShouldIgnoreNPC(npc)) { continue; } float distanceSq = Vector2.DistanceSquared(npc.Center, position); bool inRange = distanceSq < searchRange * searchRange; bool lineOfSight = (!requireLOS) || (inRange && Collision.CanHitLine(position, 1, 1, npc.position, npc.width, npc.height)); if (lineOfSight && inRange && distanceSq < minDist) { minDist = distanceSq; closest = npc; } } return(closest); }
public override Vector2 IdleBehavior() { base.IdleBehavior(); noLOSPursuitTime = gHelper.isFlying ? 15 : 300; Vector2 idlePosition = gHelper.isFlying ? player.Top : player.Bottom; Vector2 idleHitLine = player.Center; idlePosition.X += -player.direction * IdleLocationSets.GetXOffsetInSet(IdleLocationSets.trailingOnGround, projectile); if (!Collision.CanHitLine(idleHitLine, 1, 1, player.Center, 1, 1)) { idlePosition = player.Bottom; } Vector2 vectorToIdlePosition = idlePosition - projectile.Center; TeleportToPlayer(ref vectorToIdlePosition, 2000f); gHelper.SetIsOnGround(); if (gHelper.offTheGroundFrames == 20 || (gHelper.offTheGroundFrames > 60 && Main.rand.Next(120) == 0) || (gHelper.isOnGround && gHelper.offTheGroundFrames > 20)) { DrawPlatformDust(); } Lighting.AddLight(projectile.Center, Color.PaleGreen.ToVector3() * 0.75f); return(vectorToIdlePosition); }
public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack) { if (player == Main.player[Main.myPlayer]) { Vector2 speed = new Vector2(speedX, speedY); int rings = 8; for (int i = 0; i < rings; i++) { float distance = MathHelper.Clamp(Vector2.Distance(Main.MouseWorld, player.MountedCenter), 0f, 128f); position = new Vector2(0f, -distance).RotatedBy(MathHelper.ToRadians(360f / rings * i)); position *= new Vector2((float)Math.Abs(Vector2.Normalize(position).X), (float)Math.Abs(Vector2.Normalize(position).Y)).RotatedBy(MathHelper.ToRadians(0f)); position = position.RotatedBy(MathHelper.ToRadians(45f) + speed.ToRotation()); Vector2 velocity = Vector2.Normalize(position) * speed.Length(); position += player.MountedCenter; if (Collision.CanHitLine(player.MountedCenter, 0, 0, position, 0, 0)) { Projectile projectile = Projectile.NewProjectileDirect(position, velocity, type, damage, knockBack, player.whoAmI); } } } return(false); }
public override void HitEffect(int hitDirection, double damage) { npc.ai[2]++; for (int n = 0; n < 200; n++) { NPC N = Main.npc[n]; if (N.active && N.Distance(npc.Center) < 400 && Collision.CanHitLine(npc.Center, 1, 1, N.Center, 1, 1) && (N.type == mod.NPCType("Cactite") || N.type == mod.NPCType("Cactoid"))) { N.target = npc.target; N.ai[2]++; N.netUpdate = true; } } if (npc.life <= 0) { Gore.NewGore(npc.position, npc.velocity, mod.GetGoreSlot("Gores/Cactite1"), 1f); Gore.NewGore(npc.position, npc.velocity, mod.GetGoreSlot("Gores/Cactite2"), 1f); Gore.NewGore(npc.position, npc.velocity, mod.GetGoreSlot("Gores/Cactite2"), 1f); } if (npc.friendly) { npc.ai[3] = 45; } }
public override void OnKill(NPC npc) { base.OnKill(npc); if (npc.type == NPCID.Shark) { if (Main.hardMode && Main.rand.NextBool(4) && Collision.CanHitLine(npc.Top, 0, 0, npc.Top - 30 * 16f * Vector2.UnitY, 0, 0)) { if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, Vector2.Zero, ProjectileID.Sharknado, FargoSoulsUtil.ScaledProjectileDamage(npc.defDamage, 0.5f), 0f, Main.myPlayer, 15, 15); } } if (!Main.dedServ && Main.rand.NextBool(1000)) { SoundEngine.PlaySound(new SoundStyle("FargowiltasSouls/Sounds/a"), npc.Center); CombatText.NewText(npc.Hitbox, Color.Blue, "a", true); for (int i = 0; i < 100; i++) { int d = Dust.NewDust(npc.position, npc.width, npc.height, Main.rand.Next(new int[] { DustID.Confetti, DustID.Confetti_Blue, DustID.Confetti_Green, DustID.Confetti_Pink, DustID.Confetti_Yellow }), 0f, 0f, 0, default(Color), 2.5f); Main.dust[d].noGravity = Main.rand.NextBool(3); Main.dust[d].velocity *= 6f; } } } }
public override void AI() { bool flag64 = projectile.type == mod.ProjectileType("SoccMinion"); Player player = Main.player[projectile.owner]; AAPlayer modPlayer = player.GetModPlayer <AAPlayer>(); player.AddBuff(mod.BuffType("Socc"), 3600); if (flag64) { if (player.dead) { modPlayer.Socc = false; } if (modPlayer.Socc) { projectile.timeLeft = 2; } } float num633 = 700f; float num634 = 800f; for (int num638 = 0; num638 < 1000; num638++) { bool flag23 = Main.projectile[num638].type == mod.ProjectileType("SoccMinion"); if (num638 != projectile.whoAmI && Main.projectile[num638].active && Main.projectile[num638].owner == projectile.owner && flag23 && Math.Abs(projectile.position.X - Main.projectile[num638].position.X) + Math.Abs(projectile.position.Y - Main.projectile[num638].position.Y) < projectile.width) { if (projectile.position.X < Main.projectile[num638].position.X) { projectile.velocity.X = projectile.velocity.X - 0.02f; } else { projectile.velocity.X = projectile.velocity.X + 0.02f; } if (projectile.position.Y < Main.projectile[num638].position.Y) { projectile.velocity.Y = projectile.velocity.Y - 0.02f; } else { projectile.velocity.Y = projectile.velocity.Y + 0.02f; } } } bool flag24 = false; if (flag24) { return; } Vector2 vector46 = projectile.position; bool flag25 = false; if (projectile.ai[0] != 1f) { projectile.tileCollide = false; } if (projectile.tileCollide && WorldGen.SolidTile(Framing.GetTileSafely((int)projectile.Center.X / 16, (int)projectile.Center.Y / 16))) { projectile.tileCollide = false; } bool AttackFrame = false; if (player.HasMinionAttackTargetNPC) { NPC npc = Main.npc[player.MinionAttackTargetNPC]; AttackFrame = true; if (Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height)) { num633 = Vector2.Distance(projectile.Center, vector46); vector46 = npc.Center; flag25 = true; } } else { for (int k = 0; k < 200; k++) { NPC npc = Main.npc[k]; if (npc.CanBeChasedBy(this, false)) { AttackFrame = true; float num646 = Vector2.Distance(npc.Center, projectile.Center); if ((num646 < num633 || !flag25) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height)) { num633 = num646; vector46 = npc.Center; flag25 = true; } } } } float num647 = num634; if (flag25) { num647 = 1200f; } if (Vector2.Distance(player.Center, projectile.Center) > num647) { projectile.ai[0] = 1f; projectile.tileCollide = false; projectile.netUpdate = true; } if (flag25 && projectile.ai[0] == 0f) { Vector2 vector47 = vector46 - projectile.Center; float num648 = vector47.Length(); vector47.Normalize(); if (num648 > 200f) { float scaleFactor2 = 6f; vector47 *= scaleFactor2; projectile.velocity = (projectile.velocity * 40f + vector47) / 41f; } else { float num649 = 4f; vector47 *= -num649; projectile.velocity = (projectile.velocity * 40f + vector47) / 41f; } } else { bool flag26 = false; if (!flag26) { flag26 = projectile.ai[0] == 1f; } float num650 = 6f; if (flag26) { num650 = 15f; } Vector2 center2 = projectile.Center; Vector2 vector48 = player.Center - center2 + new Vector2(0f, -60f); float num651 = vector48.Length(); if (num651 > 200f && num650 < 8f) { num650 = 8f; } if (num651 < 150f && flag26 && !Collision.SolidCollision(projectile.position, projectile.width, projectile.height)) { projectile.ai[0] = 0f; projectile.netUpdate = true; } if (num651 > 2000f) { projectile.position.X = Main.player[projectile.owner].Center.X - projectile.width / 2; projectile.position.Y = Main.player[projectile.owner].Center.Y - projectile.height / 2; projectile.netUpdate = true; } if (num651 > 70f) { vector48.Normalize(); vector48 *= num650; projectile.velocity = (projectile.velocity * 40f + vector48) / 41f; } else if (projectile.velocity.X == 0f && projectile.velocity.Y == 0f) { projectile.velocity.X = -0.15f; projectile.velocity.Y = -0.05f; } } projectile.rotation = projectile.velocity.X * 0.04f; if (Math.Abs(projectile.velocity.X) > 0.2) { projectile.spriteDirection = projectile.direction; } if (projectile.ai[1] > 0f) { projectile.ai[1] += Main.rand.Next(1, 4); } if (projectile.ai[1] > 20) { projectile.ai[1] = 0f; projectile.netUpdate = true; } if (projectile.ai[0] == 0f) { if (flag25 && projectile.ai[1] == 0f) { projectile.ai[1] += 1f; if (Main.myPlayer == projectile.owner && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, vector46, 0, 0)) { Vector2 value19 = vector46 - projectile.Center; value19.Normalize(); value19 *= 9f; int proj = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, value19.X, value19.Y, 449, projectile.damage, projectile.knockBack, Main.myPlayer, 0f, 0f); Main.projectile[proj].extraUpdates = 1; Main.projectile[proj].hostile = false; Main.projectile[proj].friendly = true; Main.projectile[proj].magic = false; Main.projectile[proj].minion = true; Main.projectile[proj].netUpdate = true; projectile.netUpdate = true; } } } if (!AttackFrame) { if (projectile.frameCounter++ >= 10) { projectile.frameCounter = 0; if (++projectile.frame > 5) { projectile.frame = 0; } } } else { if (projectile.frameCounter++ >= 5) { projectile.frameCounter = 0; if (projectile.frame < 6 || projectile.frame > 10) { projectile.frame = 6; } } } }
public override void AI() { if (++projectile.frameCounter >= 3) { projectile.frame++; projectile.frameCounter = 0; if (projectile.frame >= 4) { projectile.frame = 0; } } projectile.velocity *= 0.5f; if (projectile.ai[1] == 0f) { projectile.ai[1] = 1f; Main.PlaySound(SoundID.Item34, projectile.position); } Lighting.AddLight(projectile.Center, 1.1f, 0.9f, 0.4f); for (int i = 0; i < 1000; i++) { if (Main.projectile[i].Hitbox.Intersects(projectile.Hitbox)) { if (combineCount < combineCap) { projectile.width *= 2; projectile.height *= 2; projectile.scale += 2f; projectile.damage += 10; combineCount += 1; projectile.timeLeft += 25; } } } if (projectile.timeLeft == 1) { for (int i = 0; i < 1000; i++) { NPC target = Main.npc[i]; float distanceX = target.position.X - projectile.Center.X; float distanceY = target.position.Y - projectile.Center.Y; float distance = (float)System.Math.Sqrt((double)(distanceX * distanceX + distanceY * distanceY)); float growthVar = 0f; float rotation = MathHelper.ToRadians(25); if (!target.friendly && target.active && target.type != 488 && !target.dontTakeDamage && Collision.CanHitLine(projectile.Center, 1, 1, target.Center, 1, 1)) { if (combineCount == 1) { if (!target.friendly && target.active && target.type != 488 && !target.dontTakeDamage && Collision.CanHitLine(projectile.Center, 1, 1, target.Center, 1, 1)) { distance = 3f / distance; distanceX *= distance * 3; distanceY *= distance * 3; Vector2 perturbedSpeed = new Vector2(distanceX, distanceY).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (growthVar - 1))) * .2f; Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("FriendlyLightning"), (int)(projectile.damage * 1f), 0, projectile.owner, 0f, 0f); } } if (combineCount == 2) { growthVar = 2f; distance = 3f / distance; distanceX *= distance * 3; distanceY *= distance * 3; for (int k = 0; k < growthVar; k++) { Vector2 perturbedSpeed = new Vector2(distanceX, distanceY).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (growthVar - 1))) * .2f; Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("FriendlyLightning"), (int)(projectile.damage * 1f), 0, projectile.owner, 0f, 0f); } } if (combineCount == 3) { growthVar = 3f; distance = 3f / distance; distanceX *= distance * 3; distanceY *= distance * 3; for (int k = 0; k < growthVar; k++) { Vector2 perturbedSpeed = new Vector2(distanceX, distanceY).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (growthVar - 1))) * .2f; Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("FriendlyLightning"), (int)(projectile.damage * 1f), 0, projectile.owner, 0f, 0f); } } if (combineCount == 4) { growthVar = 4f; distance = 3f / distance; distanceX *= distance * 3; distanceY *= distance * 3; for (int k = 0; k < growthVar; k++) { Vector2 perturbedSpeed = new Vector2(distanceX, distanceY).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (growthVar - 1))) * .2f; Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("FriendlyLightning"), (int)(projectile.damage * 1f), 0, projectile.owner, 0f, 0f); } } if (combineCount == 5) { growthVar = 5f; distance = 3f / distance; distanceX *= distance * 3; distanceY *= distance * 3; for (int k = 0; k < growthVar; k++) { Vector2 perturbedSpeed = new Vector2(distanceX, distanceY).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (growthVar - 1))) * .2f; Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("FriendlyLightning"), (int)(projectile.damage * 1f), 0, projectile.owner, 0f, 0f); } } } } } }
private int HomeOnTarget() { const bool homingCanAimAtWetEnemies = true; const float homingMaximumRangeInPixels = 1000; int selectedTarget = -1; for (int i = 0; i < Main.maxNPCs; i++) { NPC n = Main.npc[i]; if (n.CanBeChasedBy(projectile) && (!n.wet || homingCanAimAtWetEnemies) && Collision.CanHitLine(projectile.Center, 0, 0, n.Center, 0, 0)) { float distance = projectile.Distance(n.Center); if (distance <= homingMaximumRangeInPixels && ( selectedTarget == -1 || //there is no selected target projectile.Distance(Main.npc[selectedTarget].Center) > distance) //or we are closer to this target than the already selected target ) { selectedTarget = i; } } } return(selectedTarget); }
public override void Behavior() { Player player = Main.player[projectile.owner]; float spacing = (float)projectile.width * spacingMult; for (int k = 0; k < 1000; k++) { Projectile otherProj = Main.projectile[k]; if (k != projectile.whoAmI && otherProj.active && otherProj.owner == projectile.owner && otherProj.Name.Contains("Elemental Spirit") && System.Math.Abs(projectile.position.X - otherProj.position.X) + System.Math.Abs(projectile.position.Y - otherProj.position.Y) < spacing) { if (projectile.position.X < Main.projectile[k].position.X) { projectile.velocity.X -= idleAccel; } else { projectile.velocity.X += idleAccel; } if (projectile.position.Y < Main.projectile[k].position.Y) { projectile.velocity.Y -= idleAccel; } else { projectile.velocity.Y += idleAccel; } } } Vector2 targetPos = projectile.position; float targetDist = viewDist; bool target = false; projectile.tileCollide = true; for (int k = 0; k < 200; k++) { NPC npc = Main.npc[k]; if (npc.CanBeChasedBy(this, false)) { float distance = Vector2.Distance(npc.Center, projectile.Center); if ((distance < targetDist || !target) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height)) { targetDist = distance; targetPos = npc.Center; target = true; } } } if (Vector2.Distance(player.Center, projectile.Center) > (target ? 1000f : 500f)) { projectile.ai[0] = 1f; projectile.netUpdate = true; } if (projectile.ai[0] == 1f) { projectile.tileCollide = false; } if (target && projectile.ai[0] == 0f) { Vector2 direction = targetPos - projectile.Center; if (direction.Length() > chaseDist) { direction.Normalize(); projectile.velocity = (projectile.velocity * inertia + direction * chaseAccel) / (inertia + 1); } else { projectile.velocity *= (float)Math.Pow(0.97, 40.0 / inertia); } } else { if (!Collision.CanHitLine(projectile.Center, 1, 1, player.Center, 1, 1)) { projectile.ai[0] = 1f; } float speed = 6f; if (projectile.ai[0] == 1f) { speed = 15f; } Vector2 center = projectile.Center; Vector2 direction = player.Center - center; projectile.ai[1] = 3600f; projectile.netUpdate = true; int num = 1; for (int k = 0; k < projectile.whoAmI; k++) { if (Main.projectile[k].active && Main.projectile[k].owner == projectile.owner && Main.projectile[k].type == projectile.type) { num++; } } direction.X -= (float)((10 + num * 40) * player.direction); direction.Y -= 70f; float distanceTo = direction.Length(); if (distanceTo > 200f && speed < 9f) { speed = 9f; } if (distanceTo < 100f && projectile.ai[0] == 1f && !Collision.SolidCollision(projectile.position, projectile.width, projectile.height)) { projectile.ai[0] = 0f; projectile.netUpdate = true; } if (distanceTo > 2000f) { projectile.Center = player.Center; } if (distanceTo > 48f) { direction.Normalize(); direction *= speed; float temp = inertia / 2f; projectile.velocity = (projectile.velocity * temp + direction) / (temp + 1); } else { projectile.direction = Main.player[projectile.owner].direction; projectile.velocity *= (float)Math.Pow(0.9, 40.0 / inertia); } } projectile.rotation = projectile.velocity.X * 0.05f; SelectFrame(); CreateDust(); if (projectile.velocity.X > 0f) { projectile.spriteDirection = (projectile.direction = -1); } else if (projectile.velocity.X < 0f) { projectile.spriteDirection = (projectile.direction = 1); } if (projectile.ai[1] > 0f) { projectile.ai[1] += 1f; } if (projectile.ai[1] > shootCool) { projectile.ai[1] = 0f; projectile.netUpdate = true; } if (projectile.ai[0] == 0f) { if (target) { if ((targetPos - projectile.Center).X > 0f) { projectile.spriteDirection = (projectile.direction = -1); } else if ((targetPos - projectile.Center).X < 0f) { projectile.spriteDirection = (projectile.direction = 1); } if (projectile.ai[1] == 0f) { projectile.ai[1] = 1f; if (Main.myPlayer == projectile.owner) { Vector2 shootVel = targetPos - projectile.Center; if (shootVel == Vector2.Zero) { shootVel = new Vector2(0f, 1f); } shootVel.Normalize(); shootVel *= shootSpeed; int proj = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, shootVel.X, shootVel.Y, shoot, projectile.damage, projectile.knockBack, Main.myPlayer, 0f, 0f); Main.projectile[proj].timeLeft = 300; Main.projectile[proj].netUpdate = true; projectile.netUpdate = true; } } } } }
public override void AI() { bool flag64 = projectile.type == mod.ProjectileType("CrimeraMinion"); Player player = Main.player[projectile.owner]; AAPlayer modPlayer = player.GetModPlayer <AAPlayer>(); player.AddBuff(mod.BuffType("CrimeraMinion"), 3600); if (flag64) { if (player.dead) { modPlayer.CrimeraMinion = false; } if (modPlayer.CrimeraMinion) { projectile.timeLeft = 2; } } float num633 = 700f; float num634 = 800f; float num635 = 1200f; float num636 = 150f; float num637 = 0.05f; for (int num638 = 0; num638 < 1000; num638++) { bool flag23 = Main.projectile[num638].type == mod.ProjectileType("CrimeraMinion"); if (num638 != projectile.whoAmI && Main.projectile[num638].active && Main.projectile[num638].owner == projectile.owner && flag23 && Math.Abs(projectile.position.X - Main.projectile[num638].position.X) + Math.Abs(projectile.position.Y - Main.projectile[num638].position.Y) < projectile.width) { if (projectile.position.X < Main.projectile[num638].position.X) { projectile.velocity.X = projectile.velocity.X - num637; } else { projectile.velocity.X = projectile.velocity.X + num637; } if (projectile.position.Y < Main.projectile[num638].position.Y) { projectile.velocity.Y = projectile.velocity.Y - num637; } else { projectile.velocity.Y = projectile.velocity.Y + num637; } } } bool flag24 = false; if (projectile.ai[0] == 2f) { projectile.ai[1] += 1f; projectile.extraUpdates = 1; projectile.rotation = projectile.velocity.ToRotation() + 3.14159274f; if (projectile.ai[1] > 40f) { projectile.ai[1] = 1f; projectile.ai[0] = 0f; projectile.extraUpdates = 0; projectile.numUpdates = 0; projectile.netUpdate = true; } else { flag24 = true; } } if (flag24) { return; } Vector2 vector46 = projectile.position; bool flag25 = false; if (projectile.ai[0] != 1f) { projectile.tileCollide = false; } if (projectile.tileCollide && WorldGen.SolidTile(Framing.GetTileSafely((int)projectile.Center.X / 16, (int)projectile.Center.Y / 16))) { projectile.tileCollide = false; } for (int num645 = 0; num645 < 200; num645++) { NPC nPC2 = Main.npc[num645]; if (nPC2.CanBeChasedBy(projectile, false)) { float num646 = Vector2.Distance(nPC2.Center, projectile.Center); if (((Vector2.Distance(projectile.Center, vector46) > num646 && num646 < num633) || !flag25) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, nPC2.position, nPC2.width, nPC2.height)) { num633 = num646; vector46 = nPC2.Center; flag25 = true; } } } float num647 = num634; if (flag25) { num647 = num635; } if (Vector2.Distance(player.Center, projectile.Center) > num647) { projectile.ai[0] = 1f; projectile.tileCollide = false; projectile.netUpdate = true; } if (flag25 && projectile.ai[0] == 0f) { Vector2 vector47 = vector46 - projectile.Center; float num648 = vector47.Length(); vector47.Normalize(); if (num648 > 200f) { float scaleFactor2 = 8f; vector47 *= scaleFactor2; projectile.velocity = (projectile.velocity * 40f + vector47) / 41f; } else { float num649 = 4f; vector47 *= -num649; projectile.velocity = (projectile.velocity * 40f + vector47) / 41f; } } else { bool flag26 = false; if (!flag26) { flag26 = projectile.ai[0] == 1f; } float num650 = 6f; if (flag26) { num650 = 15f; } Vector2 center2 = projectile.Center; Vector2 vector48 = player.Center - center2 + new Vector2(0f, -60f); float num651 = vector48.Length(); if (num651 > 200f && num650 < 8f) { num650 = 8f; } if (num651 < num636 && flag26 && !Collision.SolidCollision(projectile.position, projectile.width, projectile.height)) { projectile.ai[0] = 0f; projectile.netUpdate = true; } if (num651 > 2000f) { projectile.position.X = Main.player[projectile.owner].Center.X - projectile.width / 2; projectile.position.Y = Main.player[projectile.owner].Center.Y - projectile.height / 2; projectile.netUpdate = true; } if (num651 > 70f) { vector48.Normalize(); vector48 *= num650; projectile.velocity = (projectile.velocity * 40f + vector48) / 41f; } else if (projectile.velocity.X == 0f && projectile.velocity.Y == 0f) { projectile.velocity.X = -0.15f; projectile.velocity.Y = -0.05f; } } projectile.rotation = projectile.velocity.ToRotation() + 3.14159274f; if (projectile.ai[1] > 0f) { projectile.ai[1] += Main.rand.Next(1, 4); } if (projectile.ai[1] > 40f) { projectile.ai[1] = 0f; projectile.netUpdate = true; } if (projectile.ai[0] == 0f) { if (projectile.ai[1] == 0f && flag25 && num633 < 500f) { projectile.ai[1] += 1f; if (Main.myPlayer == projectile.owner) { projectile.ai[0] = 2f; Vector2 value20 = vector46 - projectile.Center; value20.Normalize(); projectile.velocity = value20 * 8f; projectile.netUpdate = true; return; } } } }
public override void AI() { npc.reflectingProjectiles = false; npc.takenDamageMultiplier = 1f; int num27 = 6; int num28 = 10; float scaleFactor3 = 16f; if (npc.ai[2] > 0f) { npc.ai[2] -= 1f; } if (npc.ai[2] == 0f) { if (((Main.player[npc.target].Center.X < npc.Center.X && npc.direction < 0) || (Main.player[npc.target].Center.X > npc.Center.X && npc.direction > 0)) && Collision.CanHit(npc.Center, 1, 1, Main.player[npc.target].Center, 1, 1)) { npc.ai[2] = -1f; npc.netUpdate = true; npc.TargetClosest(true); } } else { if (npc.ai[2] < 0f && npc.ai[2] > -num27) { npc.ai[2] -= 1f; npc.velocity.X = npc.velocity.X * 0.9f; return; } if (npc.ai[2] == -num27) { npc.ai[2] -= 1f; npc.TargetClosest(true); Vector2 vec = npc.DirectionTo(Main.player[npc.target].Top + new Vector2(0f, -30f)); if (vec.HasNaNs()) { vec = Vector2.Normalize(new Vector2(npc.spriteDirection, -1f)); } npc.velocity = vec * scaleFactor3; npc.netUpdate = true; return; } if (npc.ai[2] < -num27) { npc.ai[2] -= 1f; if (npc.velocity.Y == 0f) { npc.ai[2] = 60f; } else if (npc.ai[2] < -(float)num27 - num28) { npc.velocity.Y = npc.velocity.Y + 0.15f; if (npc.velocity.Y > 24f) { npc.velocity.Y = 24f; } } npc.reflectingProjectiles = true; npc.takenDamageMultiplier = 3f; if (npc.justHit) { npc.ai[2] = 60f; npc.netUpdate = true; } return; } } int num36 = 60; bool flag5 = false; bool flag6 = true; bool flag7 = false; bool flag8 = true; if (npc.ai[2] > 0f) { flag8 = false; } if (!flag7 && flag8) { if (npc.velocity.Y == 0f && ((npc.velocity.X > 0f && npc.direction < 0) || (npc.velocity.X < 0f && npc.direction > 0))) { flag5 = true; } if (npc.position.X == npc.oldPosition.X || npc.ai[3] >= num36 || flag5) { npc.ai[3] += 1f; } else if (Math.Abs(npc.velocity.X) > 0.9 && npc.ai[3] > 0f) { npc.ai[3] -= 1f; } if (npc.ai[3] > num36 * 10) { npc.ai[3] = 0f; } if (npc.justHit) { npc.ai[3] = 0f; } if (npc.ai[3] == num36) { npc.netUpdate = true; } } if (npc.ai[3] < num36) { npc.TargetClosest(true); } float num75 = 5f; float num76 = 0.25f; float scaleFactor5 = 0.7f; num75 = 6f; num76 = 0.15f; scaleFactor5 = 0.85f; if (npc.velocity.X < -num75 || npc.velocity.X > num75) { if (npc.velocity.Y == 0f) { npc.velocity *= scaleFactor5; } } else if (npc.velocity.X < num75 && npc.direction == 1) { npc.velocity.X = npc.velocity.X + num76; if (npc.velocity.X > num75) { npc.velocity.X = num75; } } else if (npc.velocity.X > -num75 && npc.direction == -1) { npc.velocity.X = npc.velocity.X - num76; if (npc.velocity.X < -num75) { npc.velocity.X = -num75; } } if (Main.player[npc.target].Center.Y + 100f < npc.position.Y && Collision.CanHit(npc.position, npc.width, npc.height, Main.player[npc.target].position, Main.player[npc.target].width, Main.player[npc.target].height)) { { npc.velocity.Y = -5f; npc.ai[2] = 1f; } if (Main.netMode != 1) { npc.localAI[2] += 1f; if (npc.localAI[2] >= 360 + Main.rand.Next(360) && npc.Distance(Main.player[npc.target].Center) < 400f && Math.Abs(npc.DirectionTo(Main.player[npc.target].Center).Y) < 0.5f && Collision.CanHitLine(npc.Center, 0, 0, Main.player[npc.target].Center, 0, 0)) { npc.localAI[2] = 0f; Vector2 vector13 = npc.Center + new Vector2(npc.direction * 30, 2f); Vector2 vector14 = npc.DirectionTo(Main.player[npc.target].Center) * 7f; if (vector14.HasNaNs()) { vector14 = new Vector2(npc.direction * 8, 0f); } int num85 = Main.expertMode ? 50 : 75; for (int num86 = 0; num86 < 4; num86++) { Vector2 vector15 = vector14 + Utils.RandomVector2(Main.rand, -0.8f, 0.8f); Projectile.NewProjectile(vector13.X, vector13.Y, vector15.X, vector15.Y, 577, num85, 1f, Main.myPlayer, 0f, 0f); } } } } bool flag23 = false; if (npc.velocity.Y == 0f) { int num167 = (int)(npc.position.Y + npc.height + 7f) / 16; int num168 = (int)npc.position.X / 16; int num169 = (int)(npc.position.X + npc.width) / 16; for (int num170 = num168; num170 <= num169; num170++) { if (Main.tile[num170, num167] == null) { return; } if (Main.tile[num170, num167].nactive() && Main.tileSolid[Main.tile[num170, num167].type]) { flag23 = true; break; } } } if (npc.velocity.Y >= 0f) { int num171 = 0; if (npc.velocity.X < 0f) { num171 = -1; } if (npc.velocity.X > 0f) { num171 = 1; } Vector2 position2 = npc.position; position2.X += npc.velocity.X; int num172 = (int)((position2.X + npc.width / 2 + (npc.width / 2 + 1) * num171) / 16f); int num173 = (int)((position2.Y + npc.height - 1f) / 16f); if (Main.tile[num172, num173] == null) { Main.tile[num172, num173] = new Tile(); } if (Main.tile[num172, num173 - 1] == null) { Main.tile[num172, num173 - 1] = new Tile(); } if (Main.tile[num172, num173 - 2] == null) { Main.tile[num172, num173 - 2] = new Tile(); } if (Main.tile[num172, num173 - 3] == null) { Main.tile[num172, num173 - 3] = new Tile(); } if (Main.tile[num172, num173 + 1] == null) { Main.tile[num172, num173 + 1] = new Tile(); } if (Main.tile[num172 - num171, num173 - 3] == null) { Main.tile[num172 - num171, num173 - 3] = new Tile(); } if (num172 * 16 < position2.X + npc.width && num172 * 16 + 16 > position2.X && ((Main.tile[num172, num173].nactive() && !Main.tile[num172, num173].topSlope() && !Main.tile[num172, num173 - 1].topSlope() && Main.tileSolid[Main.tile[num172, num173].type] && !Main.tileSolidTop[Main.tile[num172, num173].type]) || (Main.tile[num172, num173 - 1].halfBrick() && Main.tile[num172, num173 - 1].nactive())) && (!Main.tile[num172, num173 - 1].nactive() || !Main.tileSolid[Main.tile[num172, num173 - 1].type] || Main.tileSolidTop[Main.tile[num172, num173 - 1].type] || (Main.tile[num172, num173 - 1].halfBrick() && (!Main.tile[num172, num173 - 4].nactive() || !Main.tileSolid[Main.tile[num172, num173 - 4].type] || Main.tileSolidTop[Main.tile[num172, num173 - 4].type]))) && (!Main.tile[num172, num173 - 2].nactive() || !Main.tileSolid[Main.tile[num172, num173 - 2].type] || Main.tileSolidTop[Main.tile[num172, num173 - 2].type]) && (!Main.tile[num172, num173 - 3].nactive() || !Main.tileSolid[Main.tile[num172, num173 - 3].type] || Main.tileSolidTop[Main.tile[num172, num173 - 3].type]) && (!Main.tile[num172 - num171, num173 - 3].nactive() || !Main.tileSolid[Main.tile[num172 - num171, num173 - 3].type])) { float num174 = num173 * 16; if (Main.tile[num172, num173].halfBrick()) { num174 += 8f; } if (Main.tile[num172, num173 - 1].halfBrick()) { num174 -= 8f; } if (num174 < position2.Y + npc.height) { float num175 = position2.Y + npc.height - num174; float num176 = 16.1f; if (num175 <= num176) { npc.gfxOffY += npc.position.Y + npc.height - num174; npc.position.Y = num174 - npc.height; if (num175 < 9f) { npc.stepSpeed = 1f; } else { npc.stepSpeed = 2f; } } } } } if (flag23) { int num177 = (int)((npc.position.X + npc.width / 2 + 15 * npc.direction) / 16f); int num178 = (int)((npc.position.Y + npc.height - 15f) / 16f); if (Main.tile[num177, num178] == null) { Main.tile[num177, num178] = new Tile(); } if (Main.tile[num177, num178 - 1] == null) { Main.tile[num177, num178 - 1] = new Tile(); } if (Main.tile[num177, num178 - 2] == null) { Main.tile[num177, num178 - 2] = new Tile(); } if (Main.tile[num177, num178 - 3] == null) { Main.tile[num177, num178 - 3] = new Tile(); } if (Main.tile[num177, num178 + 1] == null) { Main.tile[num177, num178 + 1] = new Tile(); } if (Main.tile[num177 + npc.direction, num178 - 1] == null) { Main.tile[num177 + npc.direction, num178 - 1] = new Tile(); } if (Main.tile[num177 + npc.direction, num178 + 1] == null) { Main.tile[num177 + npc.direction, num178 + 1] = new Tile(); } if (Main.tile[num177 - npc.direction, num178 + 1] == null) { Main.tile[num177 - npc.direction, num178 + 1] = new Tile(); } Main.tile[num177, num178 + 1].halfBrick(); } else if (flag6) { npc.ai[1] = 0f; npc.ai[2] = 0f; } }
public override void AI() { if (++projectile.frameCounter >= 5) { projectile.frameCounter = 0; if (++projectile.frame >= 4) { projectile.frame = 0; } } projectile.timeLeft = 10; Player player = Main.player[projectile.owner]; if (!player.HasBuff(ModContent.BuffType<Spawned>())) { projectile.timeLeft = 0; } if (player.dead || !player.active) { player.ClearBuff(ModContent.BuffType<Spawned>()); } if (player.HasBuff(ModContent.BuffType<Spawned>())) { projectile.timeLeft = 2; } Vector2 idlePosition = player.Center; idlePosition.Y -= 48f; float minionPositionOffsetX = (10 + projectile.minionPos * 40) * -player.direction; idlePosition.X += minionPositionOffsetX; Vector2 vectorToIdlePosition = idlePosition - projectile.Center; float distanceToIdlePosition = vectorToIdlePosition.Length(); // Starting search distance float distanceFromTarget = 700f; Vector2 targetCenter = projectile.position; bool foundTarget = false; if (player.HasMinionAttackTargetNPC) { NPC npc = Main.npc[player.MinionAttackTargetNPC]; float between = Vector2.Distance(npc.Center, projectile.Center); // Reasonable distance away so it doesn't target across multiple screens if (between < 2000f) { distanceFromTarget = between; targetCenter = npc.Center; foundTarget = true; if (timer > 50) { Vector2 noscope = npc.Center - projectile.Center; noscope.Normalize(); Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, noscope.X * 10f, noscope.Y * 10f, ModContent.ProjectileType<NightmareProjectile>(), projectile.damage, 5, Main.myPlayer); timer = 0; } } } if (timer < 500) { timer++; } if (!foundTarget) { for (int i = 0; i < Main.maxNPCs; i++) { NPC npc = Main.npc[i]; if (npc.CanBeChasedBy()) { float between = Vector2.Distance(npc.Center, projectile.Center); bool closest = Vector2.Distance(projectile.Center, npc.Center) > between; bool inRange = between < distanceFromTarget; bool lineOfSight = Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height); if (((closest && inRange) || !foundTarget) && lineOfSight) { if (timer > 50) { Vector2 noscope = npc.Center - projectile.Center; noscope.Normalize(); Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, noscope.X * 10f, noscope.Y * 10f, ModContent.ProjectileType<NightmareProjectile>(), projectile.damage, 5, Main.myPlayer); timer = 0; } } } } } float speed = 8f; float inertia = 60f; Vector2 direction = idlePosition - projectile.Center; direction.Normalize(); direction *= speed; projectile.velocity = (projectile.velocity * (inertia - 1) + direction) / inertia; }
public override void AI() { projectile.ai[1]++; if (projectile.ai[1] % 10 == 0) { for (int i = 0; i < 200; i++) { NPC target = Main.npc[i]; if (!target.friendly && target.type != 488 && !target.dontTakeDamage) { float shootToX = target.position.X + (float)target.width * 0.5f - projectile.Center.X; float shootToY = target.position.Y - projectile.Center.Y; float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY)); //If the distance between the live targeted npc and the projectile is less than 480 pixels if (distance < 200f && target.CanBeChasedBy(this, false) && !target.friendly && target.active && distance > 50f && Collision.CanHitLine(projectile.Center, 1, 1, target.Center, 1, 1)) { //Divide the factor, 3f, which is the desired velocity distance = 3f / distance; //Multiply the distance by a multiplier if you wish the projectile to have go faster shootToX *= distance * 5; shootToY *= distance * 5; //Set the velocities to the shoot values projectile.velocity.X = shootToX; projectile.velocity.Y = shootToY; } } } } }
public override void AI() { Player player = Main.player[projectile.owner]; #region Active check // This is the "active check", makes sure the minion is alive while the player is alive, and despawns if not if (player.dead || !player.active) { player.ClearBuff(BuffType <HallowedCross>()); } if (player.HasBuff(BuffType <HallowedCross>())) { projectile.timeLeft = 2; } #endregion Active check #region General behavior Vector2 idlePosition = player.Center; idlePosition.Y -= 48f; // Go up 48 coordinates (three tiles from the center of the player) // If your minion doesn't aimlessly move around when it's idle, you need to "put" it into the line of other summoned minions // The index is projectile.minionPos float minionPositionOffsetX = (10 + projectile.minionPos * 40) * -player.direction; idlePosition.X += minionPositionOffsetX; // Go behind the player // All of this code below this line is adapted from Spazmamini code (ID 388, aiStyle 66) // Teleport to player if distance is too big Vector2 vectorToIdlePosition = idlePosition - projectile.Center; float distanceToIdlePosition = vectorToIdlePosition.Length(); if (Main.myPlayer == player.whoAmI && distanceToIdlePosition > 2000f) { // Whenever you deal with non-regular events that change the behavior or position drastically, make sure to only run the code on the owner of the projectile, // and then set netUpdate to true projectile.position = idlePosition; projectile.velocity *= 0.1f; projectile.netUpdate = true; } // If your minion is flying, you want to do this independently of any conditions float overlapVelocity = 0.04f; for (int i = 0; i < Main.maxProjectiles; i++) { // Fix overlap with other minions Projectile other = Main.projectile[i]; if (i != projectile.whoAmI && other.active && other.owner == projectile.owner && Math.Abs(projectile.position.X - other.position.X) + Math.Abs(projectile.position.Y - other.position.Y) < projectile.width) { if (projectile.position.X < other.position.X) { projectile.velocity.X -= overlapVelocity; } else { projectile.velocity.X += overlapVelocity; } if (projectile.position.Y < other.position.Y) { projectile.velocity.Y -= overlapVelocity; } else { projectile.velocity.Y += overlapVelocity; } } } #endregion General behavior #region Find target // Starting search distance float distanceFromTarget = 700f; Vector2 targetCenter = projectile.position; bool foundTarget = false; // This code is required if your minion weapon has the targeting feature if (player.HasMinionAttackTargetNPC) { NPC npc = Main.npc[player.MinionAttackTargetNPC]; float between = Vector2.Distance(npc.Center, projectile.Center); // Reasonable distance away so it doesn't target across multiple screens if (between < 2000f) { distanceFromTarget = between; targetCenter = npc.Center; foundTarget = true; } } if (!foundTarget) { // This code is required either way, used for finding a target for (int i = 0; i < Main.maxNPCs; i++) { NPC npc = Main.npc[i]; if (npc.CanBeChasedBy()) { float between = Vector2.Distance(npc.Center, projectile.Center); bool closest = Vector2.Distance(projectile.Center, targetCenter) > between; bool inRange = between < distanceFromTarget; bool lineOfSight = Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height); // Additional check for this specific minion behavior, otherwise it will stop attacking once it dashed through an enemy while flying though tiles afterwards // The number depends on various parameters seen in the movement code below. Test different ones out until it works alright bool closeThroughWall = between < 100f; if (((closest && inRange) || !foundTarget) && (lineOfSight || closeThroughWall)) { distanceFromTarget = between; targetCenter = npc.Center; foundTarget = true; } } } } // friendly needs to be set to true so the minion can deal contact damage // friendly needs to be set to false so it doesn't damage things like target dummies while idling // Both things depend on if it has a target or not, so it's just one assignment here // You don't need this assignment if your minion is shooting things instead of dealing contact damage projectile.friendly = foundTarget; #endregion Find target #region Movement // Default movement parameters (here for attacking) float speed = 12f; float inertia = 20f; if (foundTarget) { // Minion has a target: attack (here, fly towards the enemy) if (distanceFromTarget > 40f) { // The immediate range around the target (so it doesn't latch onto it when close) Vector2 direction = targetCenter - projectile.Center; direction.Normalize(); direction *= speed; projectile.velocity = (projectile.velocity * (inertia - 1) + direction) / inertia; } } else { // Minion doesn't have a target: return to player and idle if (distanceToIdlePosition > 600f) { // Speed up the minion if it's away from the player speed = 14f; inertia = 60f; } else { // Slow down the minion if closer to the player speed = 8f; inertia = 80f; } if (distanceToIdlePosition > 20f) { // The immediate range around the player (when it passively floats about) // This is a simple movement formula using the two parameters and its desired direction to create a "homing" movement vectorToIdlePosition.Normalize(); vectorToIdlePosition *= speed; projectile.velocity = (projectile.velocity * (inertia - 1) + vectorToIdlePosition) / inertia; } else if (projectile.velocity == Vector2.Zero) { // If there is a case where it's not moving at all, give it a little "poke" projectile.velocity.X = -0.15f; projectile.velocity.Y = -0.05f; } } #endregion Movement #region Animation and visuals // So it will lean slightly towards the direction it's moving projectile.rotation = projectile.velocity.X * 0.05f; // This is a simple "loop through all frames from top to bottom" animation int frameSpeed = 5; projectile.frameCounter++; if (projectile.frameCounter >= frameSpeed) { projectile.frameCounter = 0; projectile.frame++; if (projectile.frame >= Main.projFrames[projectile.type]) { projectile.frame = 0; } } // Some visuals here Lighting.AddLight(projectile.Center, Color.White.ToVector3() * 0.78f); #endregion Animation and visuals }
public override void AI() { SelectAnimation(); UpdateStandInfo(); if (shootCount > 0) { shootCount--; } Player player = Main.player[projectile.owner]; MyPlayer modPlayer = player.GetModPlayer <MyPlayer>(); Lighting.AddLight((int)(projectile.Center.X / 16f), (int)(projectile.Center.Y / 16f), 0.6f, 0.9f, 0.3f); Dust.NewDust(projectile.position + projectile.velocity, projectile.width, projectile.height, 35, projectile.velocity.X * -0.5f, projectile.velocity.Y * -0.5f); projectile.scale = ((50 - player.ownedProjectileCounts[mod.ProjectileType("EmeraldStringPoint2")]) * 2f) / 100f; Vector2 vector131 = player.Center; if (!attackFrames) { vector131.X -= (float)((15 + player.width / 2) * player.direction); } if (attackFrames) { vector131.X -= (float)((15 + player.width / 2) * (player.direction * -1)); } vector131.Y -= 5f; projectile.Center = Vector2.Lerp(projectile.Center, vector131, 0.2f); projectile.velocity *= 0.8f; projectile.direction = (projectile.spriteDirection = player.direction); if (modPlayer.StandOut) { projectile.timeLeft = 2; } if (!modPlayer.StandAutoMode) { if (Main.mouseLeft && projectile.owner == Main.myPlayer) { attackFrames = true; normalFrames = false; Main.mouseRight = false; //so that the player can't just stop time while punching projectile.netUpdate = true; if (shootCount <= 0) { Main.PlaySound(SoundID.Item21, projectile.position); shootCount += newShootTime; Vector2 shootVel = Main.MouseWorld - projectile.Center; if (shootVel == Vector2.Zero) { shootVel = new Vector2(0f, 1f); } shootVel.Normalize(); shootVel *= shootSpeed; float numberProjectiles = 4; //incraeses by 1 each tier float rotation = MathHelper.ToRadians(20); //increases by 3 every tier float random = Main.rand.NextFloat(-6f, 6f); for (int i = 0; i < numberProjectiles; i++) { Vector2 perturbedSpeed = new Vector2(shootVel.X + random, shootVel.Y).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (numberProjectiles - 1))) * .2f; int proj = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("Emerald"), newProjectileDamage, 2f, player.whoAmI); Main.projectile[proj].netUpdate = true; } projectile.netUpdate = true; } } else { if (player.whoAmI == Main.myPlayer) { normalFrames = true; attackFrames = false; } } if (Main.mouseRight && shootCount <= 0 && !linkShot && projectile.scale >= 0.5f && projectile.owner == Main.myPlayer) { Main.mouseLeft = false; linkShot = true; Main.PlaySound(SoundID.Item21, projectile.position); shootCount += 15; Vector2 shootVel = Main.MouseWorld - projectile.Center; if (shootVel == Vector2.Zero) { shootVel = new Vector2(0f, 1f); } shootVel.Normalize(); shootVel *= shootSpeed; Vector2 perturbedSpeed = new Vector2(shootVel.X + Main.rand.NextFloat(-3f, 3f), shootVel.Y); int proj = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("EmeraldStringPoint"), 0, 3f, player.whoAmI); Main.projectile[proj].netUpdate = true; } if (Main.mouseRight && shootCount <= 0 && linkShot && projectile.scale >= 0.5f && projectile.owner == Main.myPlayer) { Main.mouseLeft = false; linkShot = false; Main.PlaySound(SoundID.Item21, projectile.position); shootCount += 15; Vector2 shootVel = Main.MouseWorld - projectile.Center; if (shootVel == Vector2.Zero) { shootVel = new Vector2(0f, 1f); } shootVel.Normalize(); shootVel *= shootSpeed; Vector2 perturbedSpeed = new Vector2(shootVel.X + Main.rand.NextFloat(-3f, 3f), shootVel.Y); int proj = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("EmeraldStringPoint2"), 0, 3f, player.whoAmI); Main.projectile[proj].netUpdate = true; } } if (modPlayer.StandAutoMode) { NPC target = null; Vector2 targetPos = projectile.position; float targetDist = 350f; if (target == null) { for (int k = 0; k < 200; k++) //the targeting system { NPC npc = Main.npc[k]; if (npc.CanBeChasedBy(this, false)) { float distance = Vector2.Distance(npc.Center, player.Center); if (distance < targetDist && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height)) { if (npc.boss) //is gonna try to detect bosses over anything { targetDist = distance; targetPos = npc.Center; target = npc; } else //if it fails to detect a boss, it'll detect the next best thing { targetDist = distance; targetPos = npc.Center; target = npc; } } } } } if (target != null) { attackFrames = true; normalFrames = false; if ((targetPos - projectile.Center).X > 0f) { projectile.spriteDirection = projectile.direction = 1; } else if ((targetPos - projectile.Center).X < 0f) { projectile.spriteDirection = projectile.direction = -1; } if (shootCount <= 0) { shootCount += newShootTime; Main.PlaySound(SoundID.Item21, projectile.position); if (Main.myPlayer == projectile.owner) { Vector2 shootVel = targetPos - projectile.Center; if (shootVel == Vector2.Zero) { shootVel = new Vector2(0f, 1f); } shootVel.Normalize(); shootVel *= shootSpeed; float numberProjectiles = 4; float rotation = MathHelper.ToRadians(20); float random = Main.rand.NextFloat(-6f, 6f); for (int i = 0; i < numberProjectiles; i++) { Vector2 perturbedSpeed = new Vector2(shootVel.X + random, shootVel.Y).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (numberProjectiles - 1))) * .2f; int proj = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("Emerald"), (int)((projectileDamage * modPlayer.standDamageBoosts) * 0.9f), 2f, player.whoAmI); Main.projectile[proj].netUpdate = true; } projectile.netUpdate = true; } } } else { normalFrames = true; attackFrames = false; } } }