public override Vector3Int GetJobLocation() { var currentPos = usedNPC.Position; if (_playerState.CallToArmsEnabled && _weapon != null) { _target = MonsterTracker.Find(currentPos, _weapon.range, _weapon.shootDamage); if (_target != null) { return(currentPos); } _target = MonsterTracker.Find(currentPos, CALL_RAD, _weapon.shootDamage); if (_target != null) { var ranged = _weapon.range - 5; if (ranged < 0) { ranged = 1; } position = new Vector3Int(_target.Position).Add(ranged, 0, ranged); position = AIManager.ClosestPosition(position, currentPos); if (!AIManager.CanStandAt(position)) { _tmpVals.Set(COOLDOWN_KEY, _weapon.cooldownMissingItem); _waitingFor++; } else { return(position); } } else { _tmpVals.Set(COOLDOWN_KEY, _weapon.cooldownMissingItem); _waitingFor++; } } if (_waitingFor > 10) { var banner = BannerTracker.GetClosest(usedNPC.Colony.Owner, currentPos); if (banner != null) { return(banner.KeyLocation); } } return(currentPos); }
public static MonsterSpawner.ESpawnResult TryGetSpawnLocation(Banner primaryBanner, float maxSpawnWalkDistance, out Vector3Int positionFinal) { Vector3Int bannerPos = primaryBanner.KeyLocation; var bannerList = BannerTracker.GetBanners(); int safeRadius = primaryBanner.SafeRadius; int spawnRadius = Pipliz.Math.RoundToInt(Pipliz.Math.Min(maxSpawnWalkDistance, primaryBanner.MaxSpawnRadius)); positionFinal = Vector3Int.invalidPos; for (int spawnTry = 0; spawnTry < MAX_TRIES; spawnTry++) { Vector3Int possiblePosition; Vector3Int dif; while (true) { possiblePosition.x = bannerPos.x + Pipliz.Random.Next(-spawnRadius, spawnRadius); possiblePosition.z = bannerPos.z + Pipliz.Random.Next(-spawnRadius, spawnRadius); possiblePosition.y = Pipliz.Math.RoundToInt(TerrainGenerator.UsedGenerator.GetHeight(possiblePosition.x, possiblePosition.z)); dif = bannerPos - possiblePosition; if (dif.MaxPartAbs > safeRadius && Pipliz.Math.Abs(dif.x) + Pipliz.Math.Abs(dif.z) < spawnRadius) { break; } } for (int idxBanner = 0; idxBanner < bannerList.Count; idxBanner++) { var otherBanner = bannerList.GetValueAtIndex(idxBanner); Colony otherColony = Colony.Get(otherBanner.Owner); if (otherColony.FollowerCount > 0 && (otherBanner.KeyLocation - possiblePosition).MaxPartAbs <= otherBanner.SafeRadius) { goto NEXT_TRY; } } if (!AIManager.Loaded(possiblePosition)) { return(MonsterSpawner.ESpawnResult.NotLoaded); } for (int idxOffset = 0; idxOffset < offsets.Length; idxOffset++) { Vector3Int positionAITest = possiblePosition.Add(0, offsets[idxOffset], 0); if (AIManager.CanStandAt(positionAITest)) { positionFinal = positionAITest; return(MonsterSpawner.ESpawnResult.Success); } } NEXT_TRY: continue; } return(MonsterSpawner.ESpawnResult.Fail); }
protected override void ReconsiderDecision() { switch (decision.GoalType) { case ZombieGoal.Banner: if ((!decision.IsValid || decision.PathDistance > MinDistanceToReconsiderBanner) && (ConsiderPlayerTarget(ref decision) || ConsiderNPCTarget(ref decision))) { return; } if (!BannerTracker.Contains(decision.GoalLocation)) { var closest = BannerTracker.GetClosest(originalGoal, position); if (closest != null && AIManager.ZombiePathFinder.TryFindPath(position, closest.KeyLocation, out var path, 2000000000) == EPathFindingResult.Success) { decision.Clear(); decision = new ZombieDecision(this, path); return; } SetCooldown(3.0); } break; case ZombieGoal.NPC: if (!decision.IsValid || decision.PathDistance > MinDistanceToReconsiderNPC) { if (ConsiderPlayerTarget(ref decision)) { return; } NPCBase nPCBase; if (NPCTracker.TryGetNear(position.Vector, MaxRadiusToNPCToConsider, out nPCBase)) { if (decision.IsGoingTo(nPCBase) && IsMovingTargetPathOkay(nPCBase.Position)) { decision.Reconsidered(); return; } if (AIManager.ZombiePathFinder.TryFindPath(position, nPCBase.Position, out var path2, decision.PathDistance / 2) == EPathFindingResult.Success) { decision.Clear(); decision = new ZombieDecision(this, nPCBase, path2); } } if (ConsiderBannerTarget(ref decision)) { return; } } break; case ZombieGoal.Player: if (Players.FindClosestAlive(position.Vector, out var player, out var num)) { if (decision.IsGoingTo(player) && IsMovingTargetPathOkay(player.VoxelPosition)) { decision.Reconsidered(); return; } if (num < MaxSqrdRadiusToPlayerToConsider && AIManager.CanStandAt(player.VoxelPosition) && AIManager.ZombiePathFinder.TryFindPath(position, player.VoxelPosition, out var path3, 2000000000) == EPathFindingResult.Success) { decision.Clear(); decision = new ZombieDecision(this, player, path3); } } if (ConsiderNPCTarget(ref decision) || ConsiderBannerTarget(ref decision)) { return; } break; default: if (ConsiderPlayerTarget(ref decision) || ConsiderNPCTarget(ref decision) || ConsiderBannerTarget(ref decision)) { return; } break; } decision.Reconsidered(); }