public override void behaviorAtGameTick(GameTime time) { invincibleCountdown = 1000; if (timeBeforeAIMovementAgain > 0f) { timeBeforeAIMovementAgain -= (float)time.ElapsedGameTime.Milliseconds; } if (yJumpOffset == 0) { if (Game1.random.NextDouble() < DestroyRockChance()) { ModEntry.SHelper.Reflection.GetField <Multiplayer>(typeof(Game1), "multiplayer").GetValue().broadcastSprites(base.currentLocation, new TemporaryAnimatedSprite[] { new TemporaryAnimatedSprite("TileSheets\\animations", new Rectangle(0, 128, 64, 64), 40f, 4, 0, base.getStandingPosition(), false, false) }); foreach (Vector2 v in Utility.getAdjacentTileLocations(base.getTileLocation())) { if (currentLocation is MineShaft && currentLocation.objects.ContainsKey(v) && base.currentLocation.objects[v].Name.Equals("Stone")) { AddExp(1); currentLocation.destroyObject(v, null); } } yJumpVelocity *= 2f; } if (!chargingFarmer && !chargingMonster) { xVelocity = (float)Game1.random.Next(-20, 21) / 5f; } } if (lastHitCounter >= 0) { lastHitCounter.Value -= time.ElapsedGameTime.Milliseconds; } chargingMonster = false; if (lastHitCounter < 0) { foreach (NPC npc in currentLocation.characters) { if (npc is Familiar) { continue; } if (npc is Monster && FamiliarsUtils.monstersColliding(this, (Monster)npc) && Game1.random.NextDouble() < StealChance()) { ModEntry.SMonitor.Log("Stealing loot"); FamiliarsUtils.monsterDrop(this, (Monster)npc, GetOwner()); lastHitCounter.Value = StealInterval(); chargingMonster = false; AddExp(1); break; } else if (npc is Monster && FamiliarsUtils.withinMonsterThreshold(this, (Monster)npc, 5)) { chargingMonster = true; if (currentTarget == null || Vector2.Distance(npc.position, position) < Vector2.Distance(currentTarget.position, position)) { currentTarget = (Monster)npc; } } } } if (chargingMonster && currentTarget != null) { base.Slipperiness = 10; Vector2 v2 = FamiliarsUtils.getAwayFromNPCTrajectory(GetBoundingBox(), currentTarget); xVelocity += -v2.X / 150f + ((Game1.random.NextDouble() < 0.01) ? ((float)Game1.random.Next(-50, 50) / 10f) : 0f); if (Math.Abs(xVelocity) > 5f) { xVelocity = (float)(Math.Sign(xVelocity) * 5); } yVelocity += -v2.Y / 150f + ((Game1.random.NextDouble() < 0.01) ? ((float)Game1.random.Next(-50, 50) / 10f) : 0f); if (Math.Abs(yVelocity) > 5f) { yVelocity = (float)(Math.Sign(yVelocity) * 5); } return; } chargingFarmer = false; if (!followingOwner) { return; } if (!seenFarmer && withinPlayerThreshold()) { seenFarmer = true; return; } if (seenFarmer && controller == null && !runningAwayFromFarmer) { base.addedSpeed = 2; controller = new PathFindController(this, base.currentLocation, new PathFindController.isAtEnd(Utility.isOffScreenEndFunction), -1, false, new PathFindController.endBehavior(offScreenBehavior), 350, Point.Zero, true); runningAwayFromFarmer = true; return; } if (controller == null && runningAwayFromFarmer) { chargingFarmer = true; } if (chargingFarmer) { base.Slipperiness = 10; Vector2 v2 = Utility.getAwayFromPlayerTrajectory(GetBoundingBox(), GetOwner()); xVelocity += -v2.X / 150f + ((Game1.random.NextDouble() < 0.01) ? ((float)Game1.random.Next(-50, 50) / 10f) : 0f); if (Math.Abs(xVelocity) > 5f) { xVelocity = (float)(Math.Sign(xVelocity) * 5); } yVelocity += -v2.Y / 150f + ((Game1.random.NextDouble() < 0.01) ? ((float)Game1.random.Next(-50, 50) / 10f) : 0f); if (Math.Abs(yVelocity) > 5f) { yVelocity = (float)(Math.Sign(yVelocity) * 5); } if (Game1.random.NextDouble() < 0.0001) { controller = new PathFindController(this, base.currentLocation, new Point((int)GetOwner().getTileLocation().X, (int)GetOwner().getTileLocation().Y), Game1.random.Next(4), null, 300); chargingFarmer = false; return; } } }
public override void behaviorAtGameTick(GameTime time) { invincibleCountdown = 1000; if (this.timeBeforeAIMovementAgain > 0f) { this.timeBeforeAIMovementAgain -= (float)time.ElapsedGameTime.Milliseconds; } if (lastHitCounter >= 0) { lastHitCounter.Value -= time.ElapsedGameTime.Milliseconds; } if (lastScreechCounter >= 0) { lastScreechCounter.Value -= time.ElapsedGameTime.Milliseconds; } if (lastScreechCounter < 0 && GetBoundingBox().Intersects(GetOwner().GetBoundingBox())) { if (ModEntry.Config.BatSoundEffects) { currentLocation.playSound("batScreech", NetAudio.SoundContext.Default); } lastScreechCounter.Value = 10000; } chargingMonster = false; if (lastHitCounter < 0) { foreach (NPC npc in currentLocation.characters) { if (npc is Familiar) { continue; } if (npc is Monster && FamiliarsUtils.monstersColliding(this, (Monster)npc)) { if (BaseDamage() >= 0) { int damageAmount = Game1.random.Next(BaseDamage(), BaseDamage() * 2 + 1); damageAmount = (npc as Monster).takeDamage(damageAmount, 0, 0, false, 0, GetOwner()); if ((npc as Monster).Health <= 0) { AddExp(10); } else { AddExp(1); } } lastHitCounter.Value = AttackInterval(); chargingMonster = false; break; } else if (npc is Monster && FamiliarsUtils.withinMonsterThreshold(this, (Monster)npc, 2)) { chargingMonster = true; if (currentTarget == null || Vector2.Distance(npc.position, position) < Vector2.Distance(currentTarget.position, position)) { currentTarget = (Monster)npc; } } } } if (this.wasHitCounter >= 0) { this.wasHitCounter.Value -= time.ElapsedGameTime.Milliseconds; } if (chargingMonster || followingOwner) { this.seenPlayer.Value = true; Vector2 center = Position + new Vector2(8, 8); Vector2 playerCenter = GetOwner().position + new Vector2(64, 92); if (Vector2.Distance(playerCenter, center) > 256) { Position = Vector2.Distance(playerCenter, center) * 0.03f * Vector2.Normalize(playerCenter - center) + center - new Vector2(8, 8); } float xSlope = (float)(-(float)(playerCenter.X - center.X)); float ySlope = (float)(playerCenter.Y - center.Y); float t = Math.Max(1f, Math.Abs(xSlope) + Math.Abs(ySlope)); if (t < (float)((this.extraVelocity > 0f) ? 192 : 64)) { this.xVelocity = Math.Max(-this.maxSpeed, Math.Min(this.maxSpeed, this.xVelocity * 1.05f)); this.yVelocity = Math.Max(-this.maxSpeed, Math.Min(this.maxSpeed, this.yVelocity * 1.05f)); } xSlope /= t; ySlope /= t; if (this.wasHitCounter <= 0) { this.targetRotation = (float)Math.Atan2((double)(-(double)ySlope), (double)xSlope) - 1.57079637f; if ((double)(Math.Abs(this.targetRotation) - Math.Abs(this.rotation)) > 2.748893571891069 && Game1.random.NextDouble() < 0.5) { this.turningRight.Value = true; } else if ((double)(Math.Abs(this.targetRotation) - Math.Abs(this.rotation)) < 0.39269908169872414) { this.turningRight.Value = false; } if (this.turningRight) { this.rotation -= (float)Math.Sign(this.targetRotation - this.rotation) * 0.0490873866f; } else { this.rotation += (float)Math.Sign(this.targetRotation - this.rotation) * 0.0490873866f; } this.rotation %= 6.28318548f; this.wasHitCounter.Value = 0; } float maxAccel = Math.Min(5f, Math.Max(1f, 5f - t / 64f / 2f)) + this.extraVelocity; xSlope = (float)Math.Cos((double)this.rotation + 1.5707963267948966); ySlope = -(float)Math.Sin((double)this.rotation + 1.5707963267948966); this.xVelocity += -xSlope * maxAccel / 6f + (float)Game1.random.Next(-10, 10) / 100f; this.yVelocity += -ySlope * maxAccel / 6f + (float)Game1.random.Next(-10, 10) / 100f; if (Math.Abs(this.xVelocity) > Math.Abs(-xSlope * this.maxSpeed)) { this.xVelocity -= -xSlope * maxAccel / 6f; } if (Math.Abs(this.yVelocity) > Math.Abs(-ySlope * this.maxSpeed)) { this.yVelocity -= -ySlope * maxAccel / 6f; } } }