/// <summary>Creates a new, AI controlled ship.</summary> /// <param name="manager">The manager.</param> /// <param name="blueprint">The blueprint.</param> /// <param name="faction">The faction the ship will belong to.</param> /// <param name="position">The position.</param> /// <param name="random">The random.</param> /// <param name="configuration">The configuration.</param> /// <returns>The new ship.</returns> public static int CreateAIShip( IManager manager, string blueprint, Factions faction, FarPosition position, IUniformRandom random, ArtificialIntelligence.AIConfiguration configuration = null) { var entity = FactoryLibrary.SampleShip(manager, blueprint, faction, position, random); var input = (ShipControl)manager.GetComponent(entity, ShipControl.TypeId); input.Stabilizing = true; manager.AddComponent <ArtificialIntelligence>(entity). Initialize(random != null ? random.NextUInt32() : 0, configuration).Enabled = false; // Add to the index from which entities will automatically removed // on cell death and mark it (for translation checks into empty space). manager.AddComponent <Indexable>(entity).Initialize(CellSystem.CellDeathAutoRemoveIndexId); manager.AddComponent <CellDeath>(entity).Initialize(true); // Add to AI index, to allow putting the AI to sleep. manager.AddComponent <Indexable>(entity).Initialize(SleepSystem.IndexId); return(entity); }
/// <summary>Samples a new orbiter of this type.</summary> /// <param name="manager">The manager.</param> /// <param name="center">The center.</param> /// <param name="dominantAngle">The dominant angle.</param> /// <param name="random">The random.</param> /// <returns></returns> internal void Sample(IManager manager, int center, float dominantAngle, IUniformRandom random) { if (random != null && ChanceToExist <= random.NextDouble()) { return; } var radius = UnitConversion.ToSimulationUnits(SampleOrbitRadius(random)); var eccentricity = SampleEccentricity(random); var angleOffset = SampleAngleOffset(random); var travelSpeed = UnitConversion.ToSimulationUnits(SampleTravelSpeed(random)); var periodOffset = random == null ? 0f : (float)random.NextDouble(); // Compute minor and major radius. float a, b; ComputeRadii(radius, eccentricity, out a, out b); // Get period. Figure out circumference using Ramanujan's approximation. var circumference = MathHelper.Pi * (3 * (a + b) - (float)Math.Sqrt((3 * a + b) * (a + 3 * b))); var period = circumference / travelSpeed * Settings.TicksPerSecond; var entity = FactoryLibrary.SamplePlanet(manager, Name, random); // Make it move around its center. manager.AddComponent <EllipsePath>(entity) .Initialize(center, a, b, dominantAngle + angleOffset, period, MathHelper.TwoPi * periodOffset); // Recurse. if (Moons != null) { Moons.Sample(manager, entity, random); } }
/// <summary>Performs the actual drop sampling.</summary> /// <param name="poolName">The name of the item pool to sample from.</param> /// <param name="position">The position at which to drop the items.</param> private void SampleDrop(string poolName, FarPosition position) { // Get the actual item pool to pull items from. var pool = FactoryLibrary.GetItemPool(poolName); // Get the list of possible drops. var dropInfo = new List <ItemPool.DropInfo>(pool.Items); // Randomizer used for sampling of items. Seed it based on the item // pool and the drop position, to get a deterministic result for // each drop, regardless in which order they happen. var hasher = new Hasher(); hasher.Write(poolName); hasher.Write(position); var random = new MersenneTwister(hasher.Value); // And shuffle it. This is important, to give each entry an equal // chance to be picked. Otherwise the first few entries have a much // better chance, because we stop after reaching a certain number // of items. for (var i = dropInfo.Count; i > 1; i--) { // Pick random element to swap. var j = random.NextInt32(i); // 0 <= j <= i - 1 // Swap. var tmp = dropInfo[j]; dropInfo[j] = dropInfo[i - 1]; dropInfo[i - 1] = tmp; } var dropCount = 0; for (int i = 0, j = dropInfo.Count; i < j; i++) { var item = dropInfo[i]; // Give the item a chance to be dropped. if (item.Probability > random.NextDouble()) { // Random roll succeeded, drop the item. var entity = FactoryLibrary.SampleItem(Manager, item.ItemName, position, random); // Make the item visible (per default items are hidden). foreach (IDrawable drawable in Manager.GetComponents(entity, DrawableTypeId)) { drawable.Enabled = true; } // Did a drop, check if we're done. dropCount++; if (dropCount == pool.MaxDrops) { break; } } } }
public void Depacketize(IReadablePacket packet) { Factory = FactoryLibrary.GetFactory(packet.ReadString()) as PlanetFactory; Albedo = null; Normals = null; Specular = null; Lights = null; Clouds = null; }
/// <summary>Creates a new, player controlled ship.</summary> /// <param name="manager">The manager.</param> /// <param name="playerClass">The player's class, which determines the blueprint.</param> /// <param name="playerNumber">The player for whom to create the ship.</param> /// <param name="position">The position at which to spawn and respawn the ship.</param> /// <returns>The new ship.</returns> public static int CreatePlayerShip( IManager manager, PlayerClassType playerClass, int playerNumber, FarPosition position) { // Player ships must be 'static', i.e. not have random attributes, so we don't need a randomizer. var entity = FactoryLibrary.SampleShip( manager, playerClass.GetShipFactoryName(), playerNumber.ToFaction(), position, null); // Remember the class. manager.AddComponent <PlayerClass>(entity).Initialize(playerClass); // Mark it as the player's avatar. manager.AddComponent <Avatar>(entity).Initialize(playerNumber); // Make it respawn (after 5 seconds). manager.AddComponent <Respawn>(entity).Initialize( (int)(5 * Settings.TicksPerSecond), new HashSet <Type> { // Make ship uncontrollable. typeof(ShipControl), typeof(WeaponControl), // Disable collisions. typeof(Body), // And movement. typeof(Gravitation), // Hide it. typeof(ShipDrawable), typeof(ParticleEffects), // And don't regenerate. typeof(Health), typeof(Energy) }, position); // Allow leveling up. manager.AddComponent <Experience>(entity).Initialize(100, 100f, 2.15f); // Make player ships collide more precisely. We don't much care for NPC ships tunneling // through stuff (unlikely as that may be anyways), but we really don't want it to happen // for a player ship. var body = (Body)manager.GetComponent(entity, Body.TypeId); body.IsBullet = true; return(entity); }
/// <summary>LoadContent will be called once per game and is the place to load all of your content.</summary> protected override void LoadContent() { base.LoadContent(); // Create a new SpriteBatch, which can be used to draw textures. _spriteBatch = new SpriteBatch(GraphicsDevice); Services.AddService(typeof(SpriteBatch), _spriteBatch); // Tell the console how to render itself. LoadConsole(); // Load generator constraints. FactoryLibrary.LoadContent(Content); // Create the profile implementation. Settings.Instance.CurrentProfile = new Profile(); // Load / create profile. if (Settings.Instance.CurrentProfile.Profiles.Contains(Settings.Instance.CurrentProfileName)) { Settings.Instance.CurrentProfile.Load(Settings.Instance.CurrentProfileName); } else { // TODO: create profile selection screen, show it if no or an invalid profile is active. Settings.Instance.CurrentProfile.Create("Default", Data.PlayerClassType.Default); Settings.Instance.CurrentProfileName = "Default"; Settings.Instance.CurrentProfile.Save(); } // Set up audio data (load wave/sound bank). LoadAudio(); // Set up graphical user interface. LoadGui(); // Set up graphs. LoadGraphs(); }
protected override void Initialize() { if (_content == null) { _content = new PlainContentManager(Services); } if (_batch == null) { _batch = new SpriteBatch(GraphicsDeviceManager.GraphicsDevice); } if (_grid == null) { _grid = new Grid(_content, GraphicsDeviceManager); _grid.LoadContent(); } FactoryLibrary.LoadContent(_content); _manager.AddSystems(new AbstractSystem[] { new AvatarSystem(), new ShipInfoSystem(), new CharacterSystem <AttributeType>(), new VelocitySystem(), new TranslationSystem(), new IndexSystem(16, 1), new ExpirationSystem(), new InventorySystem(), new ItemSlotSystem(), new ItemEffectSystem(), new RegeneratingValueSystem(), new PhysicsSystem(1f / Settings.TicksPerSecond), new GraphicsDeviceSystem(GraphicsDeviceManager), new ContentSystem(_content), new ShipShapeSystem(), new CameraCenteredInterpolationSystem { Enabled = true }, new LocalPlayerSystem(null), new CameraSystem(GraphicsDeviceManager.GraphicsDevice, null), new PlanetMaxBoundsRenderer(_content, GraphicsDeviceManager) { Enabled = true }, new PlanetRenderSystem { Enabled = true }, new SunRenderSystem { Enabled = true }, new CameraCenteredTextureRenderSystem { Enabled = true }, new CameraCenteredParticleEffectSystem(() => 1f) { Enabled = true }, new ShieldRenderSystem { Enabled = true }, new DebugSlotRenderSystem { Enabled = true } }); // Fix position to avoid querying unavailable services. ((CameraSystem)_manager.GetSystem(CameraSystem.TypeId)).CameraPosition = FarPosition.Zero; // Enable debug render systems. _slots = (DebugSlotRenderSystem)_manager.GetSystem(DebugSlotRenderSystem.TypeId); _maxBounds = (PlanetMaxBoundsRenderer)Manager.GetSystem(PlanetMaxBoundsRenderer.TypeId); _shields = (ShieldRenderSystem)Manager.GetSystem(ShieldRenderSystem.TypeId); Clear(); _updateTimer.Enabled = true; _drawTimer.Enabled = true; GraphicsDeviceOnDeviceReset(null, null); GraphicsDeviceManager.GraphicsDevice.DeviceReset += GraphicsDeviceOnDeviceReset; }
public void Depacketize(IReadablePacket packet) { Factory = (ShieldFactory)FactoryLibrary.GetFactory(packet.ReadString()); Structure = null; }
private void PopulateCell(CellStateChanged message, IUniformRandom random) { // Check if we have a changed cell info. if (!_cellInfo.ContainsKey(message.Id)) { // No, generate the default one. Get an independent // randomizer to avoid different results in other // sampling operations from when we have an existing // cell info. var hasher = new Hasher(); hasher.Write(message.Id).Write(WorldSeed); var independentRandom = new MersenneTwister(hasher.Value); // Figure out which faction should own this cell. Factions faction; switch (independentRandom.NextInt32(3)) { case 0: faction = Factions.NPCFactionA; break; case 1: faction = Factions.NPCFactionB; break; default: faction = Factions.NPCFactionC; break; } // Figure out our tech level. // TODO make dependent on distance to center / start system. var techLevel = independentRandom.NextInt32(3); // Create the cell and push it. _cellInfo.Add(message.Id, new CellInfo(faction, techLevel)); } // Get center of our cell. const int cellSize = CellSystem.CellSize; var center = new FarPosition( cellSize * message.X + (cellSize >> 1), cellSize * message.Y + (cellSize >> 1)); // Check if it's the start system or not. if (message.X == 0 && message.Y == 0) { // It is, use a predefined number of planets and moons, // and make sure it's a solar system. FactoryLibrary.SampleSunSystem(Manager, "solar_system", center, random); } else { // It isn't, randomize. FactoryLibrary.SampleSunSystem(Manager, "sunsystem_1", center, random); } // Find nearby active cells and the stations in them, mark // them as possible targets for all station sin this cell, // and let them know about our existence, as well. var cellSystem = (CellSystem)Manager.GetSystem(CellSystem.TypeId); var stations = _cellInfo[message.Id].Stations; for (var ny = message.Y - 1; ny <= message.Y + 1; ny++) { for (var nx = message.X - 1; nx <= message.X + 1; nx++) { // Don't fly to cells that are diagonal to // ourselves, which we do by checking if the // sum of the coordinates is uneven. // This becomes more obvious when considering this: // +-+-+-+-+ // |0|1|0|1| // +-+-+-+-+ // |1|0|1|0| // +-+-+-+-+ // |0|1|0|1| // +-+-+-+-+ // |1|0|1|0| // +-+-+-+-+ // Where 0 means the sum of the own coordinate is // even, 1 means it is odd. Then we can see that // the sum of diagonal pairs of cells is always // even, and the one of straight neighbors is // always odd. if (((message.X + message.Y + ny + nx) & 1) == 0) { // Get the id, only mark the station if we have // info on it and it's an enemy cell. var id = BitwiseMagic.Pack(nx, ny); if (cellSystem.IsCellActive(id) && _cellInfo.ContainsKey(id) && (_cellInfo[id].Faction.IsAlliedTo(_cellInfo[message.Id].Faction))) { // Tell the other stations. foreach (var stationId in _cellInfo[id].Stations) { var spawn = ((ShipSpawner)Manager.GetComponent(stationId, ShipSpawner.TypeId)); foreach (var otherStationId in stations) { spawn.Targets.Add(otherStationId); } } // Tell our own stations. foreach (var stationId in stations) { var spawner = ((ShipSpawner)Manager.GetComponent(stationId, ShipSpawner.TypeId)); foreach (var otherStationId in _cellInfo[id].Stations) { spawner.Targets.Add(otherStationId); } } } } } } }