1 using Microsoft.Xna.Framework;
2 using Microsoft.Xna.Framework.Graphics;
4 using System.Collections.Generic;
12 const int MaxCreatures = 100;
14 const float VisibilityCheckInterval = 1.0f;
16 private float checkVisibleTimer;
18 private readonly List<BackgroundCreaturePrefab> prefabs =
new List<BackgroundCreaturePrefab>();
19 private readonly List<BackgroundCreature> creatures =
new List<BackgroundCreature>();
23 foreach(var file
in files)
25 LoadConfig(file.Path);
31 DebugConsole.AddWarning($
"Couldn't find any BackgroundCreaturePrefabs files, falling back to {path}");
39 XDocument doc = XMLExtensions.TryLoadXml(configPath);
40 if (doc ==
null) {
return; }
42 if (mainElement.IsOverride())
44 mainElement = mainElement.FirstElement();
46 DebugConsole.NewMessage($
"Overriding all background creatures with '{configPath}'", Color.MediumPurple);
48 else if (prefabs.Any())
50 DebugConsole.NewMessage($
"Loading additional background creatures from file '{configPath}'");
53 foreach (var element
in mainElement.Elements())
55 prefabs.Add(
new BackgroundCreaturePrefab(element));
60 DebugConsole.ThrowError(String.Format(
"Failed to load BackgroundCreatures from {0}", configPath), e);
68 if (prefabs.Count == 0) {
return; }
70 count = Math.Min(count, MaxCreatures);
72 List<BackgroundCreaturePrefab> availablePrefabs =
new List<BackgroundCreaturePrefab>(prefabs);
74 for (
int i = 0; i < count; i++)
76 Vector2 pos = Vector2.Zero;
82 WayPoint wp = wayPoints[Rand.Int(wayPoints.Count, Rand.RandSync.ClientOnly)];
83 pos =
new Vector2(wp.
Rect.X, wp.
Rect.Y);
84 pos += Rand.Vector(200.0f, Rand.RandSync.ClientOnly);
88 pos = Rand.Vector(2000.0f, Rand.RandSync.ClientOnly);
93 pos = (Vector2)position;
96 var prefab = ToolBox.SelectWeightedRandom(availablePrefabs, availablePrefabs.Select(p => p.GetCommonness(level.
GenerationParams)).ToList(), Rand.RandSync.ClientOnly);
97 if (prefab ==
null) {
break; }
99 int amount = Rand.Range(prefab.SwarmMin, prefab.SwarmMax + 1, Rand.RandSync.ClientOnly);
100 List<BackgroundCreature> swarmMembers =
new List<BackgroundCreature>();
101 for (
int n = 0; n < amount; n++)
103 var creature =
new BackgroundCreature(prefab, pos + Rand.Vector(Rand.Range(0.0f, prefab.SwarmRadius, Rand.RandSync.ClientOnly), Rand.RandSync.ClientOnly));
104 creatures.Add(creature);
105 swarmMembers.Add(creature);
109 new Swarm(swarmMembers, prefab.SwarmRadius, prefab.SwarmCohesion);
111 if (creatures.Count(c => c.Prefab == prefab) > prefab.MaxCount)
113 availablePrefabs.Remove(prefab);
114 if (availablePrefabs.Count <= 0) {
break; }
126 if (checkVisibleTimer < 0.0f)
132 bool wasVisible = creature.
Visible;
134 extents.Right >= cam.
WorldView.X - margin &&
135 extents.X <= cam.
WorldView.Right + margin &&
140 checkVisibleTimer = VisibilityCheckInterval;
144 checkVisibleTimer -= deltaTime;
149 if (!creature.
Visible) {
continue; }
150 creature.
Update(deltaTime);
158 if (!creature.
Visible) {
continue; }
159 creature.
Draw(spriteBatch, cam);
167 if (!creature.
Visible) {
continue; }
void Update(float deltaTime)
void Draw(SpriteBatch spriteBatch, Camera cam)
void DrawLightSprite(SpriteBatch spriteBatch, Camera cam)
Rectangle GetExtents(Camera cam)
void DrawLights(SpriteBatch spriteBatch, Camera cam)
BackgroundCreatureManager(IEnumerable< BackgroundCreaturePrefabsFile > files)
void Draw(SpriteBatch spriteBatch, Camera cam)
BackgroundCreatureManager(string path)
void SpawnCreatures(Level level, int count, Vector2? position=null)
void Update(float deltaTime, Camera cam)
readonly? ContentPackage ContentPackage
static ContentPath FromRaw(string? rawValue)
LevelGenerationParams GenerationParams
static List< WayPoint > WayPointList