public void SetRootComponent(GameComponent Component) { RootComponent = Component; }
public ParticleTrigger(string emitter, ComponentManager manager, string name, GameComponent parent, Matrix localTransform, Vector3 boundingBoxExtents, Vector3 boundingBoxPos) : base(name, parent, localTransform, boundingBoxExtents, boundingBoxPos, false) { SoundToPlay = ContentPaths.Audio.explode; EmitterName = emitter; TriggerOnDeath = true; TriggerAmount = 2; BoxTriggerTimes = 10; TriggerInBox = true; }
public static void GenerateCaveVegetation(VoxelChunk chunk, int x, int y, int z, int caveHeight, BiomeData biome, Vector3 vec, WorldManager world, Perlin NoiseGenerator) { var vUnder = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y - 1, z)); var wayUnder = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y - caveHeight, z)); wayUnder.RawSetType(VoxelLibrary.GetVoxelType(biome.SoilLayer.VoxelType)); wayUnder.RawSetGrass(GrassLibrary.GetGrassType(biome.GrassDecal).ID); foreach (VegetationData veg in biome.Vegetation) { if (!MathFunctions.RandEvent(veg.SpawnProbability)) { continue; } if (NoiseGenerator.Noise(vec.X / veg.ClumpSize, veg.NoiseOffset, vec.Y / veg.ClumpSize) < veg.ClumpThreshold) { continue; } if (!vUnder.IsEmpty && vUnder.Type.Name == biome.SoilLayer.VoxelType) { vUnder.RawSetType(VoxelLibrary.GetVoxelType(biome.SoilLayer.VoxelType)); vUnder.RawSetGrass(0); float treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize; WorldManager.DoLazy(() => { if (!GameSettings.Default.FogofWar) { GameComponent entity = EntityFactory.CreateEntity <GameComponent>(veg.Name, vUnder.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f), Blackboard.Create("Scale", treeSize)); } else { world.ComponentManager.RootComponent.AddChild(new ExploredListener( world.ComponentManager, vUnder) { EntityToSpawn = veg.Name, SpawnLocation = vUnder.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f), BlackboardData = Blackboard.Create("Scale", treeSize) }); } }); } } foreach (FaunaData animal in biome.Fauna) { if (y <= 0 || !(MathFunctions.Random.NextDouble() < animal.SpawnProbability)) { continue; } FaunaData animal1 = animal; WorldManager.DoLazy(() => { if (!GameSettings.Default.FogofWar) { var entity = EntityFactory.CreateEntity <GameComponent>(animal1.Name, wayUnder.WorldPosition + Vector3.Up * 1.5f); } else { world.ComponentManager.RootComponent.AddChild(new ExploredListener (world.ComponentManager, new VoxelHandle(chunk, wayUnder.Coordinate.GetLocalVoxelCoordinate())) { EntityToSpawn = animal1.Name, SpawnLocation = wayUnder.WorldPosition + Vector3.Up * 1.5f }); } }); break; } }
public bool CanMove(GameComponent entity) { return(entity.Tags.Contains("Moveable") && !entity.IsReserved); }
public GreedyPathAct(CreatureAI creature, GameComponent target, float threshold) : base(creature) { Target = target; Threshold = threshold; }
public void body_onDestroyed(GameComponent body) { ZoneBodies.Remove(body); }
public TradeEnvoy SendTradeEnvoy() { if (!World.EnumerateZones().Any(room => room is BalloonPort && room.IsBuilt)) { World.MakeAnnouncement(String.Format("Trade envoy from {0} left: No balloon port!", ParentFaction.Name)); SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_negative_generic, 0.15f); return(null); } if (Race.HasValue(out var race)) { TradeEnvoy envoy = null; var creatures = World.MonsterSpawner.Spawn(World.MonsterSpawner.GenerateSpawnEvent(this, World.PlayerFaction, MathFunctions.Random.Next(4) + 1, false)); envoy = new TradeEnvoy(World.Time.CurrentDate) { Creatures = creatures, OtherFaction = World.PlayerFaction, ShouldRemove = false, OwnerFaction = this, TradeGoods = ParentFaction.IsCorporate ? new ResourceSet() : (Race.HasValue(out var _race) ? _race.GenerateTradeItems(World) : new ResourceSet()), TradeMoney = new DwarfBux((decimal)MathFunctions.Rand(race.MinCash, race.MaxCash)) }; if (race.IsNative) { if (Economy == null) { Economy = new Company(this, 1000.0m, new CompanyInformation() { Name = ParentFaction.Name }); } foreach (CreatureAI creature in envoy.Creatures) { creature.Physics.AddChild(new ResourcePack(World.ComponentManager)); creature.Physics.AddChild(new Flag(World.ComponentManager, Vector3.Up * 0.5f + Vector3.Backward * 0.25f, Economy.Information, new Resource("Flag"))); } } else { GameComponent balloon = null; var rooms = World.EnumerateZones().Where(room => room.Type.Name == "Balloon Port").ToList(); if (rooms.Count != 0) { var pos = rooms.First().GetBoundingBox().Center(); balloon = Balloon.CreateBalloon(pos + new Vector3(0, 1000, 0), pos + Vector3.UnitY * 15, World.ComponentManager, this); } if (balloon != null) { foreach (CreatureAI creature in creatures) { var tf = creature.Physics.LocalTransform; tf.Translation = balloon.LocalTransform.Translation; creature.Physics.LocalTransform = tf; } } else { if (Economy == null) { Economy = new Company(this, 1000.0m, new CompanyInformation() { Name = ParentFaction.Name }); } foreach (CreatureAI creature in envoy.Creatures) { creature.Physics.AddChild(new ResourcePack(World.ComponentManager)); creature.Physics.AddChild(new Flag(World.ComponentManager, Vector3.Up * 0.5f + Vector3.Backward * 0.25f, Economy.Information, new Resource("Flag"))); } } } foreach (CreatureAI creature in envoy.Creatures) { creature.Physics.AddChild(new ResourcePack(World.ComponentManager)); } envoy.DistributeGoods(); TradeEnvoys.Add(envoy); World.MakeAnnouncement(new DwarfCorp.Gui.Widgets.QueuedAnnouncement { Text = String.Format("Trade envoy from {0} has arrived!", ParentFaction.Name), ClickAction = (gui, sender) => { if (envoy.Creatures.Count > 0) { envoy.Creatures.First().ZoomToMe(); World.UserInterface.MakeWorldPopup(String.Format("Traders from {0} ({1}) have entered our territory.\nThey will try to get to our balloon port to trade with us.", ParentFaction.Name, race.Name), envoy.Creatures.First().Physics, -10); } }, ShouldKeep = () => envoy.ExpiditionState == Expedition.State.Arriving }); SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_positive_generic, 0.15f); World.Tutorial("trade"); if (!String.IsNullOrEmpty(race.TradeMusic)) { SoundManager.PlayMusic(race.TradeMusic); } return(envoy); } else { return(null); } }
public FireballProjectile(ComponentManager manager, Vector3 position, Vector3 initialVelocity, GameComponent target) : base(manager, position, initialVelocity, new Health.DamageAmount() { Amount = 15.0f, DamageType = Health.DamageType.Fire }, 0.25f, ContentPaths.Particles.fireball, "flame", ContentPaths.Audio.Oscar.sfx_ic_demon_fire_hit_1, target) { Sprite.LightsWithVoxels = false; Sprite2.LightsWithVoxels = false; HitAnimation = Library.CreateSimpleAnimation(ContentPaths.Effects.pierce); }
public override IEnumerable <Act.Status> Run() { List <ResourceAmount> foods = Agent.Creature.Inventory.GetResources(new Quantitiy <Resource.ResourceTags>(Resource.ResourceTags.Edible), Inventory.RestockType.Any); if (foods.Count == 0 && Agent.Creature.Faction == Agent.World.PlayerFaction) { Agent.SetMessage("Failed to eat. No food in inventory."); yield return(Act.Status.Fail); yield break; } FoodBody = null; Timer eatTimer = new Timer(3.0f, true); foreach (ResourceAmount resourceAmount in foods) { if (resourceAmount.Count > 0) { List <GameComponent> bodies = Agent.Creature.Inventory.RemoveAndCreate(new ResourceAmount(resourceAmount.Type, 1), Inventory.RestockType.Any); var resource = Library.GetResourceType(resourceAmount.Type); Agent.Creature.NoiseMaker.MakeNoise("Chew", Agent.Creature.AI.Position); if (bodies.Count == 0) { Agent.SetMessage("Failed to eat. No food in inventory."); yield return(Act.Status.Fail); } else { FoodBody = bodies[0]; while (!eatTimer.HasTriggered) { eatTimer.Update(DwarfTime.LastTime); Matrix rot = Agent.Creature.Physics.LocalTransform; rot.Translation = Vector3.Zero; FoodBody.LocalTransform = Agent.Creature.Physics.LocalTransform; Vector3 foodPosition = Agent.Creature.Physics.Position + Vector3.Up * 0.05f + Vector3.Transform(Vector3.Forward, rot) * 0.5f; FoodBody.LocalPosition = foodPosition; FoodBody.PropogateTransforms(); FoodBody.Active = false; Agent.Creature.Physics.Velocity = Vector3.Zero; Agent.Creature.CurrentCharacterMode = CharacterMode.Sitting; if (MathFunctions.RandEvent(0.05f)) { Agent.Creature.World.ParticleManager.Trigger("crumbs", foodPosition, Color.White, 3); } yield return(Act.Status.Running); } Agent.Creature.Stats.Hunger.CurrentValue += resource.FoodContent; if (resource.Tags.Contains(Resource.ResourceTags.Alcohol)) { Agent.Creature.AddThought("I had good ale recently.", new TimeSpan(0, 8, 0, 0), 10.0f); } else { Agent.Creature.AddThought("I ate good food recently.", new TimeSpan(0, 8, 0, 0), 5.0f); } FoodBody.GetRoot().Delete(); if (MustPay) { var depositAct = new DepositMoney(Agent, resource.MoneyValue); foreach (var result in depositAct.Run()) { if (result == Status.Running) { yield return(result); } } } yield return(Act.Status.Success); } yield break; } } }
public IEnumerable <Status> TrackMovingTarget() { while (true) { // This is to support the case of going from one entity to another. if (_entity != null) { Entity = _entity; } Creature.AI.Blackboard.Erase("EntityVoxel"); Act.Status status = SetTargetVoxelFromEntityAct.SetTarget("EntityVoxel", EntityName, Creature); GameComponent entity = Agent.Blackboard.GetData <GameComponent>(EntityName); if (entity == null || entity.IsDead) { yield return(Status.Success); yield break; } if (status != Status.Success) { yield return(Act.Status.Running); } List <MoveAction> existingPath = Creature.AI.Blackboard.GetData <List <MoveAction> >("PathToEntity"); Creature.AI.Blackboard.Erase("PathToEntity"); PlanWithGreedyFallbackAct planAct = new PlanWithGreedyFallbackAct() { Agent = Creature.AI, PathName = "PathToEntity", VoxelName = "EntityVoxel", PlanType = PlanType, Radius = Radius, MaxTimeouts = 1 }; planAct.Initialize(); bool planSucceeded = false; while (true) { Act.Status planStatus = planAct.Tick(); LastTickedChild = planAct; if (planStatus == Status.Fail) { yield return(Act.Status.Running); break; } else if (planStatus == Status.Running) { yield return(Act.Status.Running); } else if (planStatus == Status.Success) { planSucceeded = true; break; } } if (!planSucceeded) { Agent.SetMessage("Failed to reach entity. Path planning failed."); yield return(Act.Status.Fail); yield break; } FollowPathAct followPath = new FollowPathAct(Creature.AI, "PathToEntity") { //BlendEnd = true, //BlendStart = existingPath == null }; followPath.Initialize(); while (true) { if (PlanType == PlanAct.PlanType.Radius && (Creature.Physics.Position - entity.Position).Length() < Radius) { yield return(Act.Status.Success); } Act.Status pathStatus = followPath.Tick(); LastTickedChild = followPath; if (pathStatus == Status.Fail) { break; } else if (pathStatus == Status.Running) { yield return(Act.Status.Running); List <MoveAction> path = Agent.Blackboard.GetData <List <MoveAction> >("PathToEntity"); if (path == null || path.Count == 0) { Agent.SetMessage("Failed to find path to entity."); yield return(Act.Status.Fail); yield break; } var under = VoxelHelpers.FindFirstVoxelBelowIncludingWater(new VoxelHandle(entity.World.ChunkManager, GlobalVoxelCoordinate.FromVector3(entity.Position))); bool targetMoved = under == VoxelHandle.InvalidHandle || (path.Last().DestinationVoxel.WorldPosition - under.WorldPosition).Length() > Math.Max(Radius, 2) * 2; if (MovingTarget && (path.Count > 0 && targetMoved)) { break; } if (MovingTarget && (Creature.Physics.Position - entity.Position).Length() < 2) { yield return(Status.Success); yield break; } continue; } else if (pathStatus == Status.Success) { yield return(Act.Status.Success); yield break; } } yield return(Act.Status.Running); } }
public LightEmitter(string name, GameComponent parent, Matrix localTransform, Vector3 boundingBoxExtents, Vector3 boundingBoxPos, float intensity, float range) : base(parent.Manager, name, parent, localTransform, boundingBoxExtents, boundingBoxPos) { Light = new DynamicLight(intensity, range); }
public override void Construct() { Border = "border-one"; Font = "font10"; OnConstruct = (sender) => { sender.Root.RegisterForUpdate(sender); AddChild(new Widget { AutoLayout = AutoLayout.DockBottom, MinimumSize = new Point(0, 32), Text = "CLOSE", ChangeColorOnHover = true, OnClick = (sender1, args) => sender.Close() }); ComponentProperties = AddChild(new Widget { AutoLayout = AutoLayout.DockBottom, MinimumSize = new Point(0, 128), }); ListView = AddChild(new WidgetListView { AutoLayout = AutoLayout.DockFill, SelectedItemForegroundColor = new Vector4(0, 0, 0, 1), ChangeColorOnSelected = false, Border = null, ItemHeight = 24 }) as WidgetListView; ListView.Border = null; // Can't make WidgetListView stop defaulting its border without breaking everywhere else its used. }; OnUpdate = (sender, time) => { if (sender.Hidden) { return; } if (SelectedEntity == null) { SelectedComponent = null; ListView.ClearItems(); return; } var components = SelectedEntity.EnumerateAll(); int i = 0; ListView.ClearItems(); foreach (var component in components) { i++; var tag = component.GuiTag as Widget; var lambdaCopy = component; if (tag != null) { ListView.AddItem(tag); } else { #region Create gui row tag = Root.ConstructWidget(new Widget { Text = component.GetType().Name, MinimumSize = new Point(0, 16), Padding = new Margin(0, 0, 4, 4), TextVerticalAlign = VerticalAlign.Center, Tag = lambdaCopy }); tag.OnClick = (sender1, args) => { if (tag.IsAnyParentHidden()) { return; } SelectedComponent = lambdaCopy; }; #endregion component.GuiTag = tag; ListView.AddItem(tag); } } ListView.Invalidate(); if (SelectedComponent != null) { Drawer3D.DrawBox(SelectedComponent.GetBoundingBox(), Color.White, 0.1f, true); ComponentProperties.Text = SelectedComponent.GetType().Name + "\n" + SelectedComponent.Position.ToString() + "\nBB Extents: " + SelectedComponent.BoundingBoxSize.ToString() + "\nBB Offset: " + SelectedComponent.LocalBoundingBoxOffset.ToString(); } else { ComponentProperties.Text = ""; } }; base.Construct(); }
public static bool IsValidPlacement( VoxelHandle Location, CraftItem CraftType, WorldManager World, GameComponent PreviewBody, String Verb, String PastParticple) { if (CraftType == null) { return(false); } if (!String.IsNullOrEmpty(CraftType.CraftLocation) && World.PlayerFaction.FindNearestItemWithTags(CraftType.CraftLocation, Location.WorldPosition, false, null) == null) { World.UserInterface.ShowTooltip("Can't " + Verb + ", need " + CraftType.CraftLocation); return(false); } foreach (var req in CraftType.Prerequisites) { switch (req) { case CraftItem.CraftPrereq.NearWall: { var neighborFound = VoxelHelpers.EnumerateManhattanNeighbors2D(Location.Coordinate) .Select(c => new VoxelHandle(World.ChunkManager, c)) .Any(v => v.IsValid && !v.IsEmpty); if (!neighborFound) { World.UserInterface.ShowTooltip("Must be " + PastParticple + " next to wall!"); return(false); } break; } case CraftItem.CraftPrereq.OnGround: { var below = VoxelHelpers.GetNeighbor(Location, new GlobalVoxelOffset(0, -1, 0)); if (!below.IsValid || below.IsEmpty) { World.UserInterface.ShowTooltip("Must be " + PastParticple + " on solid ground!"); return(false); } break; } } } if (PreviewBody != null) { // Just check for any intersecting body in octtree. var previewBox = PreviewBody.GetRotatedBoundingBox(); var sensorBox = previewBox; var sensor = PreviewBody.GetComponent <GenericVoxelListener>(); if (sensor != null) { sensorBox = sensor.GetRotatedBoundingBox(); } if (Debugger.Switches.DrawToolDebugInfo) { Drawer3D.DrawBox(sensorBox, Color.Yellow, 0.1f, false); } foreach (var intersectingObject in World.EnumerateIntersectingObjects(sensorBox, CollisionType.Static)) { if (Object.ReferenceEquals(intersectingObject, sensor)) { continue; } var objectRoot = intersectingObject.GetRoot() as GameComponent; if (objectRoot is WorkPile) { continue; } if (objectRoot == PreviewBody) { continue; } if (objectRoot != null && objectRoot.GetRotatedBoundingBox().Intersects(previewBox)) { World.UserInterface.ShowTooltip("Can't " + Verb + " here: intersects " + objectRoot.Name); return(false); } } bool intersectsWall = VoxelHelpers.EnumerateCoordinatesInBoundingBox (PreviewBody.GetRotatedBoundingBox().Expand(-0.1f)).Any( v => { var tvh = new VoxelHandle(World.ChunkManager, v); return(tvh.IsValid && !tvh.IsEmpty); }); var current = new VoxelHandle(World.ChunkManager, GlobalVoxelCoordinate.FromVector3(PreviewBody.Position)); bool underwater = current.IsValid && current.LiquidType != LiquidType.None; if (underwater) { World.UserInterface.ShowTooltip("Can't " + Verb + " here: underwater or in lava."); return(false); } if (intersectsWall && !CraftType.Prerequisites.Contains(CraftItem.CraftPrereq.NearWall)) { World.UserInterface.ShowTooltip("Can't " + Verb + " here: intersects wall."); return(false); } } World.UserInterface.ShowTooltip(""); return(true); }
public Projectile(ComponentManager manager, Vector3 position, Vector3 initialVelocity, Health.DamageAmount damage, float size, string asset, string hitParticles, string hitNoise, GameComponent target, bool animated = false, bool singleSprite = false) : base(manager, "Projectile", Matrix.CreateTranslation(position), new Vector3(size, size, size), Vector3.One, 1.0f, 1.0f, 1.0f, 1.0f, new Vector3(0, -10, 0), OrientMode.Fixed) { this.AllowPhysicsSleep = false; Target = target; HitAnimation = null; IsSleeping = false; Velocity = initialVelocity; Orientation = OrientMode.LookAt; CollideMode = Physics.CollisionMode.None; var spriteSheet = new SpriteSheet(asset); if (animated) { spriteSheet.FrameWidth = Math.Min(spriteSheet.FrameWidth, spriteSheet.FrameHeight); spriteSheet.FrameHeight = spriteSheet.FrameWidth; } // Todo: Needs the cosmetic children treatement. if (animated) { Sprite = AddChild(new AnimatedSprite(Manager, "Sprite", Matrix.CreateRotationY((float)Math.PI * 0.5f)) { OrientationType = AnimatedSprite.OrientMode.Fixed }) as AnimatedSprite; var anim = Library.CreateSimpleAnimation(asset); anim.Loops = true; (Sprite as AnimatedSprite).AddAnimation(anim); if (singleSprite) { (Sprite as AnimatedSprite).OrientationType = AnimatedSprite.OrientMode.Spherical; } } else { Sprite = AddChild(new SimpleSprite(Manager, "Sprite", Matrix.CreateRotationY((float)Math.PI * 0.5f), spriteSheet, new Point(0, 0)) { OrientationType = SimpleSprite.OrientMode.Fixed }) as SimpleSprite; (Sprite as SimpleSprite).AutoSetWorldSize(); if (singleSprite) { (Sprite as SimpleSprite).OrientationType = SimpleSprite.OrientMode.Spherical; } } Sprite.SetFlag(Flag.ShouldSerialize, false); if (!singleSprite) { if (animated) { Sprite2 = Sprite.AddChild(new AnimatedSprite(Manager, "Sprite2", Matrix.CreateRotationY((float)Math.PI * 0.5f) * Matrix.CreateRotationZ((float)Math.PI * 0.5f)) { OrientationType = AnimatedSprite.OrientMode.Fixed }) as AnimatedSprite; var anim = Library.CreateSimpleAnimation(asset); anim.Loops = true; (Sprite2 as AnimatedSprite).AddAnimation(anim); } else { Sprite2 = AddChild(new SimpleSprite(Manager, "Sprite", Matrix.CreateRotationY((float)Math.PI * 0.5f) * Matrix.CreateRotationZ((float)Math.PI * 0.5f), spriteSheet, new Point(0, 0)) { OrientationType = SimpleSprite.OrientMode.Fixed }) as SimpleSprite; (Sprite2 as SimpleSprite).AutoSetWorldSize(); } Sprite2.SetFlag(Flag.ShouldSerialize, false); } Damage = damage; HitParticles = AddChild(new ParticleTrigger(hitParticles, manager, "Hit Particles", Matrix.Identity, new Vector3(size * 0.5f, size * 0.5f, size * 0.5f), Vector3.Zero) { TriggerOnDeath = true, SoundToPlay = hitNoise, BoxTriggerTimes = 2 }) as ParticleTrigger; DamageRadius = (float)Math.Pow(size * 4, 2); }
public virtual void ComponentDestroyed(GameComponent C) { }
public virtual bool AddItem(GameComponent component) { return(Resources.AddItem(component)); }
public void AddBody(GameComponent body) { ZoneBodies.Add(body); body.OnDestroyed += () => body_onDestroyed(body); }
public Grabber(string name, GameComponent parent, Matrix localTrans, Vector3 boundingboxExtents, Vector3 boundingBoxCenter) : base(name, parent, localTrans, boundingboxExtents, boundingBoxCenter, false) { GrabbedComponents = new List <GrabbedItem>(); MaxGrabs = 1; }
public void CheckSurroundings(GameComponent Body, DwarfTime gameTime, ChunkManager chunks) { if (Heat > Flashpoint) { var insideBodies = World.EnumerateIntersectingObjects(Body.GetBoundingBox()); foreach (var body in insideBodies.Where(b => b != Parent && b.Active && b.Parent == Manager.RootComponent)) { if (body.GetComponent <Flammable>().HasValue(out var flames)) { flames.Heat += 100; } } SoundManager.PlaySound(ContentPaths.Audio.fire, Body.Position, true); } float expansion = Heat > Flashpoint ? 1.0f : 0.0f; foreach (var coordinate in VoxelHelpers.EnumerateCoordinatesInBoundingBox(Body.BoundingBox.Expand(expansion))) { var voxel = new VoxelHandle(chunks, coordinate); if (!voxel.IsValid) { continue; } if (Heat > Flashpoint && MathFunctions.RandEvent(0.5f)) { if (voxel.Type.IsFlammable) { if (MathFunctions.RandEvent(0.1f)) { var existingItems = World.EnumerateIntersectingObjects(voxel.GetBoundingBox().Expand(-0.1f)); if (!existingItems.Any(e => e is Fire)) { EntityFactory.CreateEntity <Fire>("Fire", voxel.GetBoundingBox().Center()); } SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_env_lava_spread, voxel.GetBoundingBox().Center(), true, 1.0f); VoxelHelpers.KillVoxel(World, voxel); } } if (voxel.GrassType != 0x0) { if (MathFunctions.RandEvent(0.1f)) { var box = voxel.GetBoundingBox().Expand(-0.1f); box.Min += Vector3.One; // Todo: Why shifting one on every axis? box.Max += Vector3.One; if (!World.EnumerateIntersectingObjects(box).Any(e => e is Fire)) { EntityFactory.CreateEntity <Fire>("Fire", box.Center()); } } if (MathFunctions.RandEvent(0.5f)) { SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_env_lava_spread, voxel.GetBoundingBox().Center(), true, 1.0f); voxel.GrassType = 0x0; } } } if (voxel.LiquidLevel <= 0) { continue; } if (voxel.LiquidType == LiquidType.Lava) { Heat += 100.0f; } else if (voxel.LiquidType == LiquidType.Water) { Heat = Heat * 0.25f; } } }
public void SetTarget(GameComponent targt) { Agent.Blackboard.SetData(TargetName, targt); }
public Box(ComponentManager manager, string name, GameComponent parent, Matrix localTransform, Vector3 boundingBoxExtents, Vector3 boundingBoxPos, string primitive, Texture2D tex) : base(name, parent, localTransform, boundingBoxExtents, boundingBoxPos, false) { Primitive = primitive; Texture = tex; }
public void GenerateCaves(VoxelChunk chunk) { Vector3 origin = chunk.Origin; int chunkSizeX = chunk.SizeX; int chunkSizeY = chunk.SizeY; int chunkSizeZ = chunk.SizeZ; BiomeData biome = BiomeLibrary.Biomes[Overworld.Biome.Cave]; List <Voxel> neighbors = new List <Voxel>(); Voxel vUnder = chunk.MakeVoxel(0, 0, 0); for (int x = 0; x < chunkSizeX; x++) { for (int z = 0; z < chunkSizeZ; z++) { int h = chunk.GetFilledVoxelGridHeightAt(x, chunk.SizeY - 1, z); for (int i = 0; i < CaveLevels.Count; i++) { int y = CaveLevels[i]; if (y <= 0 || y >= h - 1) { continue; } Vector3 vec = new Vector3(x, y, z) + chunk.Origin; double caveNoise = CaveNoise.GetValue((x + origin.X) * CaveNoiseScale * CaveFrequencies[i], (y + origin.Y) * CaveNoiseScale * 3.0f, (z + origin.Z) * CaveNoiseScale * CaveFrequencies[i]); double heightnoise = NoiseGenerator.Noise((x + origin.X) * NoiseScale * CaveFrequencies[i], (y + origin.Y) * NoiseScale * 3.0f, (z + origin.Z) * NoiseScale * CaveFrequencies[i]); int caveHeight = Math.Min(Math.Max((int)(heightnoise * 5), 1), 3); if (caveNoise > CaveSize) { bool waterFound = false; for (int dy = 0; dy < caveHeight; dy++) { int index = chunk.Data.IndexAt(x, y - dy, z); chunk.GetNeighborsManhattan(x, y - dy, z, neighbors); if (neighbors.Any(v => v.WaterLevel > 0)) { waterFound = true; } if (waterFound) { break; } chunk.Data.Types[index] = 0; } if (!waterFound && caveNoise > CaveSize * 1.8f && y - caveHeight > 0) { int indexunder = chunk.Data.IndexAt(x, y - caveHeight, z); chunk.Data.Types[indexunder] = (byte)VoxelLibrary.GetVoxelType(biome.GrassVoxel).ID; chunk.Data.Health[indexunder] = (byte)VoxelLibrary.GetVoxelType(biome.GrassVoxel).StartingHealth; chunk.Data.IsExplored[indexunder] = false; foreach (VegetationData veg in biome.Vegetation) { if (!MathFunctions.RandEvent(veg.SpawnProbability)) { continue; } if (NoiseGenerator.Noise(vec.X / veg.ClumpSize, veg.NoiseOffset, vec.Y / veg.ClumpSize) < veg.ClumpThreshold) { continue; } vUnder.GridPosition = new Vector3(x, y - 1, z); if (!vUnder.IsEmpty && vUnder.TypeName == biome.GrassVoxel) { vUnder.Type = VoxelLibrary.GetVoxelType(biome.SoilVoxel); float offset = veg.VerticalOffset; if (vUnder.RampType != RampType.None) { offset -= 0.25f; } float treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize; GameComponent entity = EntityFactory.CreateEntity <GameComponent>(veg.Name, chunk.Origin + new Vector3(x, y, z) + new Vector3(0, treeSize * offset, 0), Blackboard.Create("Scale", treeSize)); entity.GetRootComponent().SetActiveRecursive(false); entity.GetRootComponent().SetVisibleRecursive(false); if (GameSettings.Default.FogofWar) { ExploredListener listener = new ExploredListener( PlayState.ComponentManager, entity, PlayState.ChunkManager, vUnder); } } } } foreach (FaunaData animal in biome.Fauna) { if (y <= 0 || !(PlayState.Random.NextDouble() < animal.SpawnProbability)) { continue; } var entity = EntityFactory.CreateEntity <GameComponent>(animal.Name, chunk.Origin + new Vector3(x, y, z) + Vector3.Up * 1.0f); entity.GetRootComponent().SetActiveRecursive(false); entity.GetRootComponent().SetVisibleRecursive(false); if (GameSettings.Default.FogofWar) { ExploredListener listener = new ExploredListener(PlayState.ComponentManager, entity, PlayState.ChunkManager, chunk.MakeVoxel(x, y, z)); } break; } } } } } }
public override IEnumerable <Status> Run() { Creature.IsCloaked = false; if (CurrentAttack == null) { yield return(Status.Fail); yield break; } Timeout.Reset(); FailTimer.Reset(); if (Target == null && TargetName != null) { Target = Agent.Blackboard.GetData <GameComponent>(TargetName); if (Target == null) { yield return(Status.Fail); yield break; } } if (Agent.Faction.Race.IsIntelligent) { var targetInventory = Target.GetRoot().GetComponent <Inventory>(); if (targetInventory != null) { targetInventory.SetLastAttacker(Agent); } } CharacterMode defaultCharachterMode = Creature.AI.Movement.CanFly ? CharacterMode.Flying : CharacterMode.Walking; bool avoided = false; while (true) { Timeout.Update(DwarfTime.LastTime); FailTimer.Update(DwarfTime.LastTime); if (FailTimer.HasTriggered) { Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Fail); yield break; } if (Timeout.HasTriggered) { if (Training) { Agent.AddXP(1); Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Success); yield break; } else { Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Fail); yield break; } } if (Target == null || Target.IsDead) { Creature.CurrentCharacterMode = defaultCharachterMode; Creature.Physics.Orientation = Physics.OrientMode.RotateY; yield return(Status.Success); } // Find the location of the melee target Vector3 targetPos = new Vector3(Target.GlobalTransform.Translation.X, Target.GetBoundingBox().Min.Y, Target.GlobalTransform.Translation.Z); Vector2 diff = new Vector2(targetPos.X, targetPos.Z) - new Vector2(Creature.AI.Position.X, Creature.AI.Position.Z); Creature.Physics.Face(targetPos); bool intersectsbounds = Creature.Physics.BoundingBox.Intersects(Target.BoundingBox); float dist = diff.Length(); // If we are really far from the target, something must have gone wrong. if (DefensiveStructure == null && !intersectsbounds && dist > CurrentAttack.Weapon.Range * 4) { Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Fail); yield break; } if (DefensiveStructure != null) { if (Creature.Hp < LastHp) { float damage = LastHp - Creature.Hp; Creature.Heal(Math.Min(5.0f, damage)); var health = DefensiveStructure.GetRoot().GetComponent <Health>(); if (health != null) { health.Damage(damage); Drawer2D.DrawLoadBar(health.World.Renderer.Camera, DefensiveStructure.Position, Color.White, Color.Black, 32, 1, health.Hp / health.MaxHealth, 0.1f); } LastHp = Creature.Hp; } if (dist > CurrentAttack.Weapon.Range) { float sqrDist = dist * dist; foreach (var threat in Creature.AI.Faction.Threats) { float threatDist = (threat.AI.Position - Creature.AI.Position).LengthSquared(); if (threatDist < sqrDist) { sqrDist = threatDist; Target = threat.Physics; break; } } dist = (float)Math.Sqrt(sqrDist); } if (dist > CurrentAttack.Weapon.Range * 4) { yield return(Status.Fail); yield break; } if (DefensiveStructure.IsDead) { DefensiveStructure = null; } } LastHp = Creature.Hp; // If we're out of attack range, run toward the target. if (DefensiveStructure == null && !Creature.AI.Movement.IsSessile && !intersectsbounds && diff.Length() > CurrentAttack.Weapon.Range) { Creature.CurrentCharacterMode = defaultCharachterMode; var greedyPath = new GreedyPathAct(Creature.AI, Target, CurrentAttack.Weapon.Range * 0.75f) { PathLength = 5 }; greedyPath.Initialize(); foreach (Act.Status stat in greedyPath.Run()) { if (stat == Act.Status.Running) { yield return(Status.Running); } else { break; } } } // If we have a ranged weapon, try avoiding the target for a few seconds to get within range. else if (DefensiveStructure == null && !Creature.AI.Movement.IsSessile && !intersectsbounds && !avoided && (CurrentAttack.Weapon.Mode == Weapon.AttackMode.Ranged && dist < CurrentAttack.Weapon.Range * 0.15f)) { FailTimer.Reset(); foreach (Act.Status stat in AvoidTarget(CurrentAttack.Weapon.Range, 3.0f)) { yield return(Status.Running); } avoided = true; } // Else, stop and attack else if ((DefensiveStructure == null && dist < CurrentAttack.Weapon.Range) || (DefensiveStructure != null && dist < CurrentAttack.Weapon.Range * 2.0)) { if (CurrentAttack.Weapon.Mode == Weapon.AttackMode.Ranged && VoxelHelpers.DoesRayHitSolidVoxel(Creature.World.ChunkManager, Creature.AI.Position, Target.Position)) { yield return(Status.Fail); yield break; } FailTimer.Reset(); avoided = false; Creature.Physics.Orientation = Physics.OrientMode.Fixed; Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f); CurrentAttack.RechargeTimer.Reset(CurrentAttack.Weapon.RechargeRate); Creature.Sprite.ResetAnimations(Creature.Stats.CurrentClass.AttackMode); Creature.Sprite.PlayAnimations(Creature.Stats.CurrentClass.AttackMode); Creature.CurrentCharacterMode = Creature.Stats.CurrentClass.AttackMode; Creature.OverrideCharacterMode = true; Timer timeout = new Timer(10.0f, true); while (!CurrentAttack.Perform(Creature, Target, DwarfTime.LastTime, Creature.Stats.Strength + Creature.Stats.Size, Creature.AI.Position, Creature.Faction.ParentFaction.Name)) { timeout.Update(DwarfTime.LastTime); if (timeout.HasTriggered) { break; } Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f); if (Creature.AI.Movement.CanFly) { Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt); } yield return(Status.Running); } timeout.Reset(); while (!Agent.Creature.Sprite.AnimPlayer.IsDone()) { timeout.Update(DwarfTime.LastTime); if (timeout.HasTriggered) { break; } if (Creature.AI.Movement.CanFly) { Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt); } yield return(Status.Running); } var targetCreature = Target.GetRoot().GetComponent <CreatureAI>(); if (targetCreature != null && Creature.AI.FightOrFlight(targetCreature) == CreatureAI.FightOrFlightResponse.Flee) { yield return(Act.Status.Fail); yield break; } Creature.CurrentCharacterMode = CharacterMode.Attacking; Vector3 dogfightTarget = Vector3.Zero; while (!CurrentAttack.RechargeTimer.HasTriggered && !Target.IsDead) { CurrentAttack.RechargeTimer.Update(DwarfTime.LastTime); if (CurrentAttack.Weapon.Mode == Weapon.AttackMode.Dogfight) { dogfightTarget += MathFunctions.RandVector3Cube() * 0.1f; Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, dogfightTarget + Target.Position, Creature.Physics.GlobalTransform.Translation) * 0.9f; Creature.Physics.ApplyForce(output - Creature.Physics.Gravity, DwarfTime.Dt); } else { Creature.Physics.Velocity = Vector3.Zero; if (Creature.AI.Movement.CanFly) { Creature.Physics.ApplyForce(-Creature.Physics.Gravity, DwarfTime.Dt); } } yield return(Status.Running); } Creature.CurrentCharacterMode = defaultCharachterMode; Creature.Physics.Orientation = Physics.OrientMode.RotateY; if (Target.IsDead) { Target = null; Agent.AddXP(10); Creature.Physics.Face(Creature.Physics.Velocity + Creature.Physics.GlobalTransform.Translation); Creature.Stats.NumThingsKilled++; Creature.AddThought("I killed somehing!", new TimeSpan(0, 8, 0, 0), 1.0f); Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Success); break; } } yield return(Status.Running); } }
public void DoDamage(Creature performer, GameComponent other, float bonus) { if (!String.IsNullOrEmpty(Weapon.DiseaseToSpread)) { if (other.GetRoot().GetComponent <Creature>().HasValue(out var otherCreature)) { var disease = DiseaseLibrary.GetDisease(Weapon.DiseaseToSpread); if (disease != null) { if (MathFunctions.RandEvent(disease.LikelihoodOfSpread)) { otherCreature.Stats.AcquireDisease(disease); } } } } var health = other.GetRoot().EnumerateAll().OfType <Health>().FirstOrDefault(); if (health != null) { health.Damage(Weapon.DamageAmount + bonus); var injury = DiseaseLibrary.GetRandomInjury(); if (MathFunctions.RandEvent(injury.LikelihoodOfSpread)) { if (other.GetRoot().GetComponent <Creature>().HasValue(out var creature)) { creature.Stats.AcquireDisease(injury); } } Vector3 knock = other.Position - performer.Physics.Position; knock.Normalize(); knock *= 0.2f; if (other.AnimationQueue.Count == 0) { other.AnimationQueue.Add(new KnockbackAnimation(0.15f, other.LocalTransform, knock)); } } else { other.GetRoot().Die(); } PlayNoise(other.GlobalTransform.Translation); if (Weapon.HitParticles != "") { performer.Manager.World.ParticleManager.Trigger(Weapon.HitParticles, other.LocalTransform.Translation, Color.White, 5); if (Weapon.ShootLaser) { performer.Manager.World.ParticleManager.TriggerRay(Weapon.HitParticles, performer.AI.Position, other.LocalTransform.Translation); } } if (Weapon.HitAnimation != null) { IndicatorManager.DrawIndicator(Weapon.HitAnimation, other.BoundingBox.Center(), 10.0f, 1.0f, MathFunctions.RandVector2Circle(), Color.White, MathFunctions.Rand() > 0.5f); } Physics physics = other as Physics; if (physics != null) { Vector3 force = other.Position - performer.AI.Position; if (force.LengthSquared() > 0.01f) { force.Normalize(); physics.ApplyForce(force * Weapon.Knockback, 1.0f); } } }
public override Feasibility IsFeasible(Creature agent) { GameComponent closestItem = agent.Faction.FindNearestItemWithTags("Bed", agent.AI.Position, true, agent.AI); return((closestItem != null && !agent.AI.Stats.Health.IsSatisfied()) || agent.AI.Stats.Health.IsCritical() ? Feasibility.Feasible : Feasibility.Infeasible); }
public bool Perform(Creature performer, GameComponent other, DwarfTime time, float bonus, Vector3 pos, string faction) { if (!performer.Sprite.AnimPlayer.HasValidAnimation() || performer.Sprite.AnimPlayer.CurrentFrame != Weapon.TriggerFrame) { HasTriggered = false; return(false); } if (HasTriggered) { return(true); } HasTriggered = true; switch (Weapon.Mode) { case Weapon.AttackMode.Melee: case Weapon.AttackMode.Dogfight: { DoDamage(performer, other, bonus); break; } case Weapon.AttackMode.Area: { var box = new BoundingBox(performer.AI.Position - Vector3.One * Weapon.Range, performer.AI.Position + Vector3.One * Weapon.Range); foreach (var body in performer.World.EnumerateIntersectingObjects(box, CollisionType.Both).Where(b => b.IsRoot())) { if (body.GetRoot().GetComponent <CreatureAI>().HasValue(out var creature)) { if (creature.Faction == performer.Faction) { continue; } if (performer.World.Overworld.GetPolitics(creature.Faction.ParentFaction, performer.Faction.ParentFaction).GetCurrentRelationship() != Relationship.Hateful) { continue; } DoDamage(performer, body, bonus); } else { if (body.GetRoot().GetComponent <Health>().HasValue(out var health)) { DoDamage(performer, body, bonus); } continue; } } break; } case Weapon.AttackMode.Ranged: { PlayNoise(other.GlobalTransform.Translation); LaunchProjectile(pos, other.Position, other); var injury = DiseaseLibrary.GetRandomInjury(); if (MathFunctions.RandEvent(injury.LikelihoodOfSpread)) { if (other.GetRoot().GetComponent <Creature>().HasValue(out var creature)) { creature.Stats.AcquireDisease(injury); } } break; } } return(true); }
public Body FindNearestItemWithTags(string tag, Vector3 location, bool filterReserved, GameComponent queryObject) { Body closestItem = null; float closestDist = float.MaxValue; foreach (Body i in OwnedObjects) { if (i == null || i.IsDead || (i.IsReserved && filterReserved && i.ReservedFor != queryObject) || !(i.Tags.Any(t => tag == t))) { continue; } float d = (i.GlobalTransform.Translation - location).LengthSquared(); if (!(d < closestDist)) { continue; } closestDist = d; closestItem = i; } return(closestItem); }
public virtual void ComponentCreated(GameComponent C) { }
public KillEntityAct(GameComponent entity, CreatureAI creature) : base(creature) { Entity = entity; Name = "Kill Entity"; // Get the closest structure that we might defend from. closestDefensiveStructure = creature.Faction.OwnedObjects.Where(b => !b.IsReserved && b.Tags.Contains("Defensive")).OrderBy(b => (b.Position - Entity.Position).LengthSquared()).FirstOrDefault(); // Do not attempt to defend from faraway structures if (closestDefensiveStructure != null) { float distToStructure = (closestDefensiveStructure.Position - creature.Position).Length(); float distToEntity = (Entity.Position - creature.Position).Length(); if (distToStructure > 1.5f * distToEntity || distToStructure > 12.0f) { closestDefensiveStructure = null; } } PlanAct.PlanType planType = PlanAct.PlanType.Adjacent; float radius = 0.0f; if (creature.Creature.Attacks[0].Weapon.Mode == Weapon.AttackMode.Ranged) { planType = PlanAct.PlanType.Radius; radius = creature.Creature.Attacks[0].Weapon.Range; } if (creature.Movement.IsSessile) { Tree = new Domain(() => Verify(creature), new Sequence ( new AttackAct(Agent, entity) ) | new Wrap(() => OnAttackEnd(creature)) ); } else { if (creature.Creature.Attacks[0].Weapon.Mode != Weapon.AttackMode.Ranged || closestDefensiveStructure == null || (closestDefensiveStructure.Position - creature.Position).Length() > 20.0f) { Tree = new Domain(() => Verify(creature), new Sequence ( new GoToEntityAct(entity, creature) { MovingTarget = true, PlanType = planType, Radius = radius } | new Wrap(() => OnAttackEnd(creature)), new AttackAct(Agent, entity), new Wrap(() => OnAttackEnd(creature)) )); } else { closestDefensiveStructure.ReservedFor = creature; Tree = new Domain(() => Verify(creature), new Sequence ( new GoToEntityAct(closestDefensiveStructure, creature) { PlanType = PlanAct.PlanType.Into, } | new Wrap(() => OnAttackEnd(creature)), new TeleportAct(Creature.AI) { Location = closestDefensiveStructure.GetRotatedBoundingBox().Center(), Type = TeleportAct.TeleportType.Lerp }, new AttackAct(Agent, entity) { DefensiveStructure = closestDefensiveStructure }, new Wrap(() => OnAttackEnd(creature)) )); } } }
public void RemoveComponent(GameComponent component) { RemovalMutex.WaitOne(); Removals.Add(component); RemovalMutex.ReleaseMutex(); }