public Simulator(ConnectionState state, Server server) { server.ReloadMeshes(); collidableMaterials = new CollidableProperty <SimpleMaterial>(); this.connectionState = state; this.server = server; bufferPool = new BufferPool(); var targetThreadCount = Math.Max(1, Environment.ProcessorCount > 4 ? Environment.ProcessorCount - 2 : Environment.ProcessorCount - 1); ThreadDispatcher = new SimpleThreadDispatcher(targetThreadCount); narrowPhaseCallbacks = new QuixNarrowPhaseCallbacks() { CollidableMaterials = collidableMaterials, simulator = this }; Simulation = Simulation.Create(bufferPool, narrowPhaseCallbacks, new QuixPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper()); CreateMap(); // Server.Send(state.workSocket, "Hola desde simulator"); gameLoop = new GameLoop(); gameLoop.Load(this); //CreateNewt(); thread = new Thread(new ThreadStart(gameLoop.Start)); commandReader = new CommandReader(this); thread.Start(); }
public DebugCollisionItem(ITypeResolver resolver, Vector2 pos) : base(resolver, pos) { collidable = new CollidableProperty(this, 1); AddProperty(collidable); }
private void InitItem(Vector2 carrier1, Vector2 portable1, Vector2?carrier2, Vector2?portable2) { Item1 = new DebugCarrierItem(carrier1); Moving1 = Item1.GetProperty <WalkingProperty>(); Collidable1 = Item1.GetProperty <CollidableProperty>(); Carrier1 = Item1.GetProperty <CarrierProperty>(); Item3 = new DebugPortableItem(portable1); Moving3 = Item3.GetProperty <WalkingProperty>(); Collidable3 = Item3.GetProperty <CollidableProperty>(); Portable3 = Item3.GetProperty <PortableProperty>(); if (carrier2.HasValue) { Item2 = new DebugCarrierItem(carrier2.Value); Moving2 = Item2.GetProperty <WalkingProperty>(); Collidable2 = Item2.GetProperty <CollidableProperty>(); Carrier2 = Item2.GetProperty <CarrierProperty>(); } if (portable2.HasValue) { Item4 = new DebugPortableItem(portable2.Value); Moving4 = Item4.GetProperty <WalkingProperty>(); Collidable4 = Item4.GetProperty <CollidableProperty>(); Portable4 = Item4.GetProperty <PortableProperty>(); } }
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(20, 10, 20); camera.Yaw = MathHelper.Pi * -1f / 4; camera.Pitch = MathHelper.Pi * 0.05f; var masks = new CollidableProperty <ulong>(); characters = new CharacterControllers(BufferPool); Simulation = Simulation.Create(BufferPool, new CharacterNarrowphaseCallbacks(characters), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper()); var random = new Random(5); for (int i = 0; i < 8192; ++i) { ref var character = ref characters.AllocateCharacter( Simulation.Bodies.Add( BodyDescription.CreateDynamic( new Vector3(250 * (float)random.NextDouble() - 125, 2, 250 * (float)random.NextDouble() - 125), new BodyInertia { InverseMass = 1 }, new CollidableDescription(Simulation.Shapes.Add(new Capsule(0.5f, 1f)), 0.1f), new BodyActivityDescription(-1)))); character.CosMaximumSlope = .707f; character.LocalUp = Vector3.UnitY; character.MaximumHorizontalForce = 10; character.MaximumVerticalForce = 10; character.MinimumSupportContinuationDepth = -0.1f; character.MinimumSupportDepth = -0.01f; character.TargetVelocity = new Vector2(4, 0); character.ViewDirection = new Vector3(0, 0, -1); character.JumpVelocity = 4; }
public void CleanupEngine() { Item1 = null; Moving1 = null; Collidable1 = null; Item2 = null; Moving2 = null; Collidable2 = null; Map = null; Engine = null; }
/// <summary> /// Default Constructor for the Type Mapper. /// </summary> /// <param name="item">Related Engine Item</param> /// <param name="property">Related Engine Property</param> public CollidableState(Item item, CollidableProperty property) : base(item, property) { // Bind Fixed to Item Fixed Fixed = property.CollisionFixed; property.OnCollisionFixedChanged += (i, v) => { Fixed = v; }; // Bind Mass to Item Mass Mass = property.CollisionMass; property.OnCollisionMassChanged += (i, v) => { Mass = v; }; }
private void InitItem(Vector2 pos1, Vector2?pos2) { Item1 = new DebugCollisionItem(new Vector2(pos1.X, pos1.Y)); Moving1 = Item1.GetProperty <WalkingProperty>(); Collidable1 = Item1.GetProperty <CollidableProperty>(); if (pos2.HasValue) { Item2 = new DebugCollisionItem(new Vector2(pos2.Value.X, pos2.Value.Y)); Moving2 = Item2.GetProperty <WalkingProperty>(); Collidable2 = Item2.GetProperty <CollidableProperty>(); } }
public PhysicsUnit(Item item, Dictionary <int, PhysicsUnit> items) { this.item = item; this.items = items; moving = item.GetProperty <WalkingProperty>(); collidable = item.GetProperty <CollidableProperty>(); carrier = item.GetProperty <CarrierProperty>(); portable = item.GetProperty <PortableProperty>(); map = item.Engine.Map; mapSize = map.GetSize(); // Attach Item Stuff item.CellChanged += item_CellChanged; // Attach Moving Stuff if (moving != null) { moving.OnMaximumMoveSpeedChanged += moving_OnMaximumMoveSpeedChanged; moving.OnMoveDirectionChanged += moving_OnMoveDirectionChanged; moving.OnMoveSpeedChanged += moving_OnMoveSpeedChanged; moving.MoveMalus = 1; } // Attach Collision Stuff if (collidable != null) { collidable.OnCollisionMassChanged += collidable_OnCollisionMassChanged; collidable.OnCollisionFixedChanged += collidable_OnCollisionFixedChanged; } // Attach Carrier Stuff if (carrier != null) { carrier.OnCarrierLoadChanged += carrier_OnCarrierLoadChanged; carrier.OnCarrierStrengthChanged += carrier_OnCarrierStrengthChanged; } // Attach Portable Stuff if (portable != null) { portable.OnPortableWeightChanged += portable_OnPortableMassChanged; portable.OnNewCarrierItem += portable_OnNewCarrierItem; portable.OnLostCarrierItem += portable_OnLostCarrierItem; clusterUnits = new HashSet <PhysicsUnit>(); } Recalc(); }
public PhysicsUnit(Item item, Dictionary<int, PhysicsUnit> items) { this.item = item; this.items = items; moving = item.GetProperty<WalkingProperty>(); collidable = item.GetProperty<CollidableProperty>(); carrier = item.GetProperty<CarrierProperty>(); portable = item.GetProperty<PortableProperty>(); map = item.Engine.Map; mapSize = map.GetSize(); // Attach Item Stuff item.CellChanged += item_CellChanged; // Attach Moving Stuff if (moving != null) { moving.OnMaximumMoveSpeedChanged += moving_OnMaximumMoveSpeedChanged; moving.OnMoveDirectionChanged += moving_OnMoveDirectionChanged; moving.OnMoveSpeedChanged += moving_OnMoveSpeedChanged; moving.MoveMalus = 1; } // Attach Collision Stuff if (collidable != null) { collidable.OnCollisionMassChanged += collidable_OnCollisionMassChanged; collidable.OnCollisionFixedChanged += collidable_OnCollisionFixedChanged; } // Attach Carrier Stuff if (carrier != null) { carrier.OnCarrierLoadChanged += carrier_OnCarrierLoadChanged; carrier.OnCarrierStrengthChanged += carrier_OnCarrierStrengthChanged; } // Attach Portable Stuff if (portable != null) { portable.OnPortableWeightChanged += portable_OnPortableMassChanged; portable.OnNewCarrierItem += portable_OnNewCarrierItem; portable.OnLostCarrierItem += portable_OnLostCarrierItem; clusterUnits = new HashSet<PhysicsUnit>(); } Recalc(); }
/// <summary> /// Default Constructor for the Type Mapper. /// </summary> /// <param name="faction">Faction</param> /// <param name="item">Item</param> /// <param name="interop">UnitInterop</param> public AntMovementInterop(Faction faction, FactionItem item, UnitInterop interop) : base(faction, item, interop) { // Get Walking Property walking = Item.GetProperty <WalkingProperty>(); if (walking == null) { throw new NotSupportedException("There is no Walking Property"); } // Get Collision Property collidable = Item.GetProperty <CollidableProperty>(); if (collidable == null) { throw new NotSupportedException("There is no Collidable Property"); } // Handle Collisions with Walls and Borders. walking.OnHitBorder += (i, v) => { if (OnHitWall != null) { OnHitWall(v); } }; walking.OnHitWall += (i, v) => { if (OnHitWall != null) { OnHitWall(v); } }; // Kollisionen mit anderen Items füllt die Liste der Kollisionsitems // und prüft, ob es sich beim getroffenen Item um das Ziel handelt. collidable.OnCollision += (i, v) => { // Zur Liste der kollidierten Items hinzufügen. collidedItems.Add(v.GetItemInfo(Item)); // Prüfen, ob es sich um das aktuelle Ziel handelt. if (CurrentDestination != null && Item == Item.GetItemFromInfo(CurrentDestination)) { // Alles anhalten und Reach melden Stop(); if (OnTargetReched != null) { OnTargetReched(i.GetItemInfo(Item)); } } }; }
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 9, -40); camera.Yaw = MathHelper.Pi; camera.Pitch = 0; var filters = new CollidableProperty <SubgroupCollisionFilter>(); Simulation = Simulation.Create(BufferPool, new SubgroupFilteredCallbacks { CollisionFilters = filters }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0))); int ragdollIndex = 0; var spacing = new Vector3(1.7f, 1.8f, 0.5f); int width = 4; int height = 4; int length = 44; var origin = -0.5f * spacing * new Vector3(width - 1, 0, length - 1) + new Vector3(0, 5f, 0); for (int i = 0; i < width; ++i) { for (int j = 0; j < height; ++j) { for (int k = 0; k < length; ++k) { RagdollDemo.AddRagdoll(origin + spacing * new Vector3(i, j, k), QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), MathHelper.Pi * 0.05f), ragdollIndex++, filters, Simulation); } } } var tubeCenter = new Vector3(0, 8, 0); const int panelCount = 20; const float tubeRadius = 6; var panelShape = new Box(MathF.PI * 2 * tubeRadius / panelCount, 1, 80); var panelShapeIndex = Simulation.Shapes.Add(panelShape); var builder = new CompoundBuilder(BufferPool, Simulation.Shapes, panelCount + 1); for (int i = 0; i < panelCount; ++i) { var rotation = QuaternionEx.CreateFromAxisAngle(Vector3.UnitZ, i * MathHelper.TwoPi / panelCount); QuaternionEx.TransformUnitY(rotation, out var localUp); var position = localUp * tubeRadius; builder.AddForKinematic(panelShapeIndex, new RigidPose(position, rotation), 1); } builder.AddForKinematic(Simulation.Shapes.Add(new Box(1, 2, panelShape.Length)), new RigidPose(new Vector3(0, tubeRadius - 1, 0)), 0); builder.BuildKinematicCompound(out var children); var compound = new BigCompound(children, Simulation.Shapes, BufferPool); Simulation.Bodies.Add(BodyDescription.CreateKinematic(tubeCenter, new BodyVelocity(default, new Vector3(0, 0, .25f)), new CollidableDescription(Simulation.Shapes.Add(compound), 0.1f), new BodyActivityDescription()));
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-5f, 5.5f, 5f); camera.Yaw = MathHelper.Pi / 4; camera.Pitch = MathHelper.Pi * 0.15f; var filters = new CollidableProperty <DeformableCollisionFilter>(); Simulation = Simulation.Create(BufferPool, new DeformableCallbacks { Filters = filters }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0))); var meshContent = content.Load <MeshContent>("Content\\newt.obj"); float cellSize = 0.1f; DumbTetrahedralizer.Tetrahedralize(meshContent.Triangles, cellSize, BufferPool, out var vertices, out var vertexSpatialIndices, out var cellVertexIndices, out var tetrahedraVertexIndices); var weldSpringiness = new SpringSettings(30f, 0); var volumeSpringiness = new SpringSettings(30f, 1); for (int i = 0; i < 5; ++i) { NewtDemo.CreateDeformable(Simulation, new Vector3(i * 3, 5 + i * 1.5f, 0), QuaternionEx.CreateFromAxisAngle(new Vector3(1, 0, 0), MathF.PI * (i * 0.55f)), 1f, cellSize, weldSpringiness, volumeSpringiness, i, filters, ref vertices, ref vertexSpatialIndices, ref cellVertexIndices, ref tetrahedraVertexIndices); } BufferPool.Return(ref vertices); vertexSpatialIndices.Dispose(BufferPool); BufferPool.Return(ref cellVertexIndices); BufferPool.Return(ref tetrahedraVertexIndices); Simulation.Bodies.Add(BodyDescription.CreateConvexDynamic(new Vector3(0, 100, -.5f), 10, Simulation.Shapes, new Sphere(5))); Simulation.Statics.Add(new StaticDescription(new Vector3(0, -0.5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(1500, 1, 1500)), 0.1f))); Simulation.Statics.Add(new StaticDescription(new Vector3(0, -1.5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Sphere(3)), 0.1f))); var bulletShape = new Sphere(0.5f); bulletShape.ComputeInertia(.25f, out var bulletInertia); bulletDescription = BodyDescription.CreateDynamic(RigidPose.Identity, bulletInertia, new CollidableDescription(Simulation.Shapes.Add(bulletShape), 1f), new BodyActivityDescription(0.01f)); DemoMeshHelper.LoadModel(content, BufferPool, "Content\\newt.obj", new Vector3(20), out var mesh); Simulation.Statics.Add(new StaticDescription(new Vector3(200, 0.5f, 120), QuaternionEx.CreateFromAxisAngle(Vector3.UnitY, -3 * MathHelper.PiOver4), new CollidableDescription(Simulation.Shapes.Add(mesh), 0.1f))); }
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 40, 200); camera.Yaw = 0; camera.Pitch = 0; //This type of position-based bounciness requires feedback from position error to drive the corrective impulses that make stuff bounce. //The briefer a collision is, the more damped the bounce becomes relative to the physical ideal. //To counteract this, a substepping timestepper is used. In the demos, we update the simulation at 60hz, so a substep count of 4 means the solver and integrator will run at 240hz. //That allows higher stiffnesses to be used since collisions last longer relative to the solver timestep duration. //(Note that substepping tends to be an extremely strong simulation stabilizer, so you can usually get away with lower solver iteration counts for better performance.) var collidableMaterials = new CollidableProperty <SimpleMaterial>(); Simulation = Simulation.Create(BufferPool, new BounceCallbacks() { CollidableMaterials = collidableMaterials }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new SubsteppingTimestepper(4), solverIterationCount: 2); var shape = new Sphere(1); shape.ComputeInertia(1, out var inertia); var ballDescription = BodyDescription.CreateDynamic(RigidPose.Identity, inertia, new CollidableDescription(Simulation.Shapes.Add(shape), 20f), new BodyActivityDescription(1e-2f)); for (int i = 0; i < 100; ++i) { for (int j = 0; j < 100; ++j) { //We'll drop balls in a grid. From left to right, we increase stiffness, and from back to front (relative to the camera), we'll increase damping. //Note that higher frequency values tend to result in smaller bounces even at 0 damping. This is not physically realistic; it's a byproduct of the solver timestep being too long to properly handle extremely brief contacts. //(Try increasing the substep count above to higher values and watch how the bounce gets closer and closer to equal height across frequency values.) ballDescription.Pose.Position = new Vector3(i * 3 - 99f * 3f / 2f, 100, j * 3 - 230); collidableMaterials.Allocate(Simulation.Bodies.Add(ballDescription)) = new SimpleMaterial { FrictionCoefficient = 1, MaximumRecoveryVelocity = float.MaxValue, SpringSettings = new SpringSettings(5 + 0.25f * i, j * j / 10000f) }; } } collidableMaterials.Allocate(Simulation.Statics.Add(new StaticDescription(new Vector3(0, -15f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(2500, 30, 2500)), 0.1f)))) = new SimpleMaterial { FrictionCoefficient = 1, MaximumRecoveryVelocity = 2, SpringSettings = new SpringSettings(30, 1) }; }
public void CleanupEngine() { Item1 = null; Moving1 = null; Collidable1 = null; Carrier1 = null; Item2 = null; Moving2 = null; Collidable2 = null; Carrier2 = null; Item3 = null; Moving3 = null; Collidable3 = null; Portable3 = null; Item4 = null; Moving4 = null; Collidable4 = null; Portable4 = null; Map = null; Engine = null; }
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-32f, 20.5f, 61f); camera.Yaw = MathHelper.Pi * 0.3f; camera.Pitch = MathHelper.Pi * -0.05f; filters = new CollidableProperty <SubgroupCollisionFilter>(BufferPool); Simulation = Simulation.Create(BufferPool, new SubgroupFilteredCallbacks() { CollisionFilters = filters }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0))); Simulation.Statics.Add(new StaticDescription(new Vector3(0, -0.5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(1500, 1, 1500)), 0.1f))); Simulation.Statics.Add(new StaticDescription(new Vector3(0, 10, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(70, 20, 80)), 0.1f))); Simulation.Statics.Add(new StaticDescription(new Vector3(0, 7.5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(80, 15, 90)), 0.1f))); Simulation.Statics.Add(new StaticDescription(new Vector3(0, 5, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(90, 10, 100)), 0.1f))); Simulation.Statics.Add(new StaticDescription(new Vector3(0, 2.5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(100, 5, 110)), 0.1f))); //High fidelity simulation isn't super important on this one. Simulation.Solver.IterationCount = 2; DemoMeshHelper.LoadModel(content, BufferPool, "Content\\newt.obj", new Vector3(30), out var mesh); Simulation.Statics.Add(new StaticDescription(new Vector3(0, 20, 0), QuaternionEx.CreateFromAxisAngle(Vector3.UnitY, 0), new CollidableDescription(Simulation.Shapes.Add(mesh), 0.1f))); }
/// <summary> /// Registers Sugar /// </summary> /// <param name="typeMapper">Type Mapper</param> /// <param name="settings">Settings</param> private void RegisterSugar(ITypeMapper typeMapper, KeyValueStore settings) { // Sugar typeMapper.RegisterItem <SugarItem, SugarState, SugarInfo>(this, "Sugar"); // Collidable typeMapper.AttachItemProperty <SugarItem, CollidableProperty>(this, "Sugar Collidable", (i) => { CollidableProperty property = new CollidableProperty(i); // Define mass (Fixed) property.CollisionFixed = true; property.CollisionMass = 0f; // Bind Collision Radius to the Item Radius property.CollisionRadius = i.Radius; i.RadiusChanged += (item, v) => { property.CollisionRadius = v; }; return(property); }); // Visibility typeMapper.AttachItemProperty <SugarItem, VisibleProperty>(this, "Sugar Visible", (i) => { VisibleProperty property = new VisibleProperty(i); // Bind Visibility Radius to the Item Radius property.VisibilityRadius = i.Radius; i.RadiusChanged += (item, v) => { property.VisibilityRadius = v; }; return(property); }); // Collectable typeMapper.AttachItemProperty <SugarItem, SugarCollectableProperty>(this, "Sugar Collectable"); // TODO: Amounts (SugarMaxCapacity, Math.Min(SugarMaxCapacity, amount)) }
/// <summary> /// Registers Anthills /// </summary> /// <param name="typeMapper">Type Mapper</param> /// <param name="settings">Settings</param> private void RegisterAnthill(ITypeMapper typeMapper, KeyValueStore settings) { // Anthill typeMapper.RegisterItem <AnthillItem, AnthillState, AnthillInfo>(this, "Anthill"); // Collision typeMapper.AttachItemProperty <AnthillItem, CollidableProperty>(this, "Anthill Collidable", (i) => { CollidableProperty property = new CollidableProperty(i); // Set Collision Mass property.CollisionFixed = true; property.CollisionMass = 0f; // Bind Radius to the Item Radius property.CollisionRadius = i.Radius; i.RadiusChanged += (item, v) => { property.CollisionRadius = v; }; return(property); }); // Visibility typeMapper.AttachItemProperty <AnthillItem, VisibleProperty>(this, "Anthill Visible", (i) => { VisibleProperty property = new VisibleProperty(i); // Bind Visibility Radius to the Item Radius property.VisibilityRadius = i.Radius; i.RadiusChanged += (item, v) => { property.VisibilityRadius = v; }; return(property); }); // Attackable settings.Set <AnthillItem>("Attackable", false, "Enables the possibility to destroy Anthills"); settings.Set <AnthillItem>("MaxHealth", 1000, "Maximum Health of an Anthill"); settings.Set <AnthillItem>("Buildable", false, "Can an Anthill build by ants"); typeMapper.AttachItemProperty <AnthillItem, AttackableProperty>(this, "Anthill Attackable", (i) => { // Check Attackable Switch if (!i.Settings.GetBool <AnthillItem>("Attackable").Value) { return(null); } AttackableProperty property = new AttackableProperty(i); // Bind Attackable Radius to Item Radius property.AttackableRadius = i.Radius; i.RadiusChanged += (item, v) => { property.AttackableRadius = v; }; // Health property.AttackableMaximumHealth = settings.GetInt <AnthillItem>("MaxHealth").Value; property.AttackableHealth = settings.GetInt <AnthillItem>("MaxHealth").Value; return(property); }); // Collectable typeMapper.AttachItemProperty <AnthillItem, SugarCollectableProperty>(this, "Anthill Sugarsafe"); // TODO: Radius typeMapper.AttachItemProperty <AnthillItem, AppleCollectableProperty>(this, "Anthill Applesafe"); // TODO: Radius }
protected override void RequestDraw() { if (_level != null) { DrawPlayground(_level.Map.GetCellCount(), _level.Map.Tiles); foreach (var item in _level.Items) { float?bodySpeed = null; float?bodyDirection = null; float?bodyRadius = null; float?smellableRadius = null; float?viewRange = null; float?viewAngle = null; float?viewDirection = null; float?attackRange = null; // Movement if (item.ContainsProperty <WalkingProperty>()) { WalkingProperty prop = item.GetProperty <WalkingProperty>(); bodySpeed = prop.Speed; bodyDirection = prop.Direction; } // Kollisionsradius if (item.ContainsProperty <CollidableProperty>()) { CollidableProperty prop = item.GetProperty <CollidableProperty>(); bodyRadius = prop.CollisionRadius; } // Sicht if (item.ContainsProperty <SightingProperty>()) { SightingProperty prop = item.GetProperty <SightingProperty>(); viewRange = prop.ViewRange; viewDirection = prop.ViewDirection.Radian; viewAngle = prop.ViewAngle; } // Attack if (item.ContainsProperty <AttackerProperty>()) { AttackerProperty prop = item.GetProperty <AttackerProperty>(); attackRange = prop.AttackRange; } // Stinkender radius if (item.ContainsProperty <SmellableProperty>()) { SmellableProperty prop = item.GetProperty <SmellableProperty>(); smellableRadius = prop.SmellableRadius; } Color color = Color.Gray; Color?borderColor = null; // Farbe if (item is AnthillItem) { color = Color.Brown; } else if (item is SugarItem) { color = Color.White; } else if (item is AppleItem) { color = Color.LightGreen; } else if (item is BugItem) { color = Color.Blue; } else if (item is AntItem) { color = Color.LightGray; AntItem ant = item as AntItem; switch (ant.PlayerIndex) { case 0: borderColor = Color.Orange; break; case 1: borderColor = Color.Red; break; case 2: borderColor = Color.Yellow; break; case 3: borderColor = Color.Green; break; case 4: borderColor = Color.Blue; break; case 5: borderColor = Color.Purple; break; case 6: borderColor = Color.White; break; case 7: borderColor = Color.Black; break; } } else if (item is MarkerItem) { color = Color.LightGray; MarkerItem marker = item as MarkerItem; switch (marker.PlayerIndex) { case 0: borderColor = Color.Orange; break; case 1: borderColor = Color.Red; break; case 2: borderColor = Color.Yellow; break; case 3: borderColor = Color.Green; break; case 4: borderColor = Color.Blue; break; case 5: borderColor = Color.Purple; break; case 6: borderColor = Color.White; break; case 7: borderColor = Color.Black; break; } } // Malen DrawItem(item.Id, item.Position, bodyRadius, bodyDirection, bodySpeed, color, viewRange, viewDirection, viewAngle, attackRange, smellableRadius, borderColor); } } }
/// <summary> /// Registers classic Bugs /// </summary> /// <param name="typeMapper">Type Mapper</param> /// <param name="settings">Settings</param> private void RegisterClassicBug(ITypeMapper typeMapper, KeyValueStore settings) { // Classic Bug typeMapper.RegisterItem <ClassicBugItem, BugState, BugInfo>(this, "Classic Bug"); // Walking settings.Set <ClassicBugItem>("MaxSpeed", 2f, "Maximum Speed of a Classic Bug"); typeMapper.AttachItemProperty <ClassicBugItem, WalkingProperty>(this, "Classic Bug Walking", (i) => { WalkingProperty property = new WalkingProperty(i); // Set Walking Speed property.MaximumSpeed = i.Settings.GetFloat <ClassicBugItem>("MaxSpeed").Value; // Bind Direction to the Items Orientation property.Direction = i.Orientation; i.OrientationChanged += (item, v) => { property.Direction = v; }; return(property); }); // Collision settings.Set <ClassicBugItem>("Mass", 10f, "Collision Mass of a Classic Bug"); typeMapper.AttachItemProperty <ClassicBugItem, CollidableProperty>(this, "Classic Bug Collidable", (i) => { CollidableProperty property = new CollidableProperty(i); // Set Collision Mass property.CollisionFixed = false; property.CollisionMass = i.Settings.GetFloat <ClassicBugItem>("Mass").Value; // Bind Collision Radius to the Item Radius property.CollisionRadius = i.Radius; i.RadiusChanged += (item, v) => { property.CollisionRadius = v; }; return(property); }); // Visibility typeMapper.AttachItemProperty <ClassicBugItem, VisibleProperty>(this, "Classic Bug Visible", (i) => { VisibleProperty property = new VisibleProperty(i); // Bind Visibility Radius to the Item Radius property.VisibilityRadius = i.Radius; i.RadiusChanged += (item, v) => { property.VisibilityRadius = v; }; return(property); }); // Sighting settings.Set <ClassicBugItem>("ViewRange", 20f, "View Range of a Classic Bug"); settings.Set <ClassicBugItem>("ViewAngle", 360, "View Angle of a Classic Bug"); typeMapper.AttachItemProperty <ClassicBugItem, SightingProperty>(this, "Classic Bug Sighting", (i) => { SightingProperty property = new SightingProperty(i); // Set View Range and Angle property.ViewRange = i.Settings.GetFloat <ClassicBugItem>("ViewRange").Value; property.ViewAngle = i.Settings.GetFloat <ClassicBugItem>("ViewAngle").Value; // Bind View Direction to the Item Orientation property.ViewDirection = i.Orientation; i.OrientationChanged += (item, v) => { property.ViewDirection = v; }; return(property); }); // Sniffer typeMapper.AttachItemProperty <ClassicBugItem, SnifferProperty>(this, "Classic Bug Sniffer"); // Attackable settings.Set <ClassicBugItem>("MaxHealth", 1000, "Maximum Health of a Classic Bug"); typeMapper.AttachItemProperty <ClassicBugItem, AttackableProperty>(this, "Classic Bug Attackable", (i) => { AttackableProperty property = new AttackableProperty(i); // Bind Attackable Radius to Item Radius property.AttackableRadius = i.Radius; i.RadiusChanged += (item, v) => { property.AttackableRadius = v; }; // Health property.AttackableMaximumHealth = settings.GetInt <ClassicBugItem>("MaxHealth").Value; property.AttackableHealth = settings.GetInt <ClassicBugItem>("MaxHealth").Value; return(property); }); // Attacker settings.Set <ClassicBugItem>("AttackRange", 5f, "Attack Range for a Classic Bug"); settings.Set <ClassicBugItem>("RecoveryTime", 5, "Recovery Time in Rounds for a Classic Bug"); settings.Set <ClassicBugItem>("AttackStrength", 10, "Attach Strength for a Classic Bug"); typeMapper.AttachItemProperty <ClassicBugItem, AttackerProperty>(this, "Classic Bug Attacker", (i) => { AttackerProperty property = new AttackerProperty(i); property.AttackRange = i.Settings.GetFloat <ClassicBugItem>("AttackRange").Value; property.AttackRecoveryTime = i.Settings.GetInt <ClassicBugItem>("RecoveryTime").Value; property.AttackStrength = i.Settings.GetInt <ClassicBugItem>("AttackStrength").Value; return(property); }); }
public void CleanupEngine() { Item1 = null; Moving1 = null; Collidable1 = null; Item2 = null; Moving2 = null; Collidable2 = null; Map = null; Engine = null; }
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 5, 10); camera.Yaw = 0; camera.Pitch = 0; var properties = new CollidableProperty <CarBodyProperties>(); //The PositionFirstTimestepper is the simplest timestepping mode, but since it integrates velocity into position at the start of the frame, directly modified velocities outside of the timestep //will be integrated before collision detection or the solver has a chance to intervene. That's fine in this demo. Other built-in options include the PositionLastTimestepper and the SubsteppingTimestepper. //Note that the timestepper also has callbacks that you can use for executing logic between processing stages, like BeforeCollisionDetection. Simulation = Simulation.Create(BufferPool, new CarCallbacks() { Properties = properties }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper()); var builder = new CompoundBuilder(BufferPool, Simulation.Shapes, 2); builder.Add(new Box(1.85f, 0.7f, 4.73f), RigidPose.Identity, 10); builder.Add(new Box(1.85f, 0.6f, 2.5f), new RigidPose(new Vector3(0, 0.65f, -0.35f)), 0.5f); builder.BuildDynamicCompound(out var children, out var bodyInertia, out _); builder.Dispose(); var bodyShape = new Compound(children); var bodyShapeIndex = Simulation.Shapes.Add(bodyShape); var wheelShape = new Cylinder(0.4f, .18f); wheelShape.ComputeInertia(0.25f, out var wheelInertia); var wheelShapeIndex = Simulation.Shapes.Add(wheelShape); const float x = 0.9f; const float y = -0.1f; const float frontZ = 1.7f; const float backZ = -1.7f; playerController = new SimpleCarController(SimpleCar.Create(Simulation, properties, new RigidPose(new Vector3(0, 10, 0), Quaternion.Identity), bodyShapeIndex, bodyInertia, 0.5f, wheelShapeIndex, wheelInertia, 2f, new Vector3(-x, y, frontZ), new Vector3(x, y, frontZ), new Vector3(-x, y, backZ), new Vector3(x, y, backZ), new Vector3(0, -1, 0), 0.25f, new SpringSettings(5f, 0.7f), QuaternionEx.CreateFromAxisAngle(Vector3.UnitZ, MathF.PI * 0.5f)), forwardSpeed: 75, forwardForce: 6, zoomMultiplier: 2, backwardSpeed: 30, backwardForce: 4, idleForce: 0.25f, brakeForce: 7, steeringSpeed: 1.5f, maximumSteeringAngle: MathF.PI * 0.23f); //Create a bunch of AI cars to race against. const int aiCount = 384; BufferPool.Take(aiCount, out aiControllers); const int planeWidth = 257; const float scale = 3; Vector2 terrainPosition = new Vector2(1 - planeWidth, 1 - planeWidth) * scale * 0.5f; raceTrack = new RaceTrack { QuadrantRadius = (planeWidth - 32) * scale * 0.25f, Center = default }; var random = new Random(5); //Add some building-ish landmarks in the middle of each of the four racetrack quadrants. for (int i = 0; i < 4; ++i) { var landmarkCenter = new Vector3((i & 1) * raceTrack.QuadrantRadius * 2 - raceTrack.QuadrantRadius, -20, (i & 2) * raceTrack.QuadrantRadius - raceTrack.QuadrantRadius); var landmarkMin = landmarkCenter - new Vector3(raceTrack.QuadrantRadius * 0.5f, 0, raceTrack.QuadrantRadius * 0.5f); var landmarkSpan = new Vector3(raceTrack.QuadrantRadius, 0, raceTrack.QuadrantRadius); for (int j = 0; j < 25; ++j) { var buildingShape = new Box(10 + (float)random.NextDouble() * 10, 20 + (float)random.NextDouble() * 20, 10 + (float)random.NextDouble() * 10); Simulation.Statics.Add(new StaticDescription( new Vector3(0, buildingShape.HalfHeight, 0) + landmarkMin + landmarkSpan * new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), QuaternionEx.CreateFromAxisAngle(Vector3.UnitY, (float)random.NextDouble() * MathF.PI), new CollidableDescription(Simulation.Shapes.Add(buildingShape), 0.1f))); } } Vector3 min = new Vector3(-planeWidth * scale * 0.45f, 10, -planeWidth * scale * 0.45f); Vector3 span = new Vector3(planeWidth * scale * 0.9f, 15, planeWidth * scale * 0.9f); for (int i = 0; i < aiCount; ++i) { //The AI cars are very similar, except... we handicap them a little to make the player good about themselves. var position = min + span * new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()); var orientation = QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), (float)random.NextDouble() * MathF.PI * 2); aiControllers[i].Controller = new SimpleCarController(SimpleCar.Create(Simulation, properties, new RigidPose(position, orientation), bodyShapeIndex, bodyInertia, 0.5f, wheelShapeIndex, wheelInertia, 2f, new Vector3(-x, y, frontZ), new Vector3(x, y, frontZ), new Vector3(-x, y, backZ), new Vector3(x, y, backZ), new Vector3(0, -1, 0), 0.25f, new SpringSettings(5, 0.7f), QuaternionEx.CreateFromAxisAngle(Vector3.UnitZ, MathF.PI * 0.5f)), forwardSpeed: 50, forwardForce: 5, zoomMultiplier: 2, backwardSpeed: 10, backwardForce: 4, idleForce: 0.25f, brakeForce: 7, steeringSpeed: 1.5f, maximumSteeringAngle: MathF.PI * 0.23f); aiControllers[i].LaneOffset = (float)random.NextDouble() * 20 - 10; } DemoMeshHelper.CreateDeformedPlane(planeWidth, planeWidth, (int vX, int vY) => { var octave0 = (MathF.Sin((vX + 5f) * 0.05f) + MathF.Sin((vY + 11) * 0.05f)) * 1.8f; var octave1 = (MathF.Sin((vX + 17) * 0.15f) + MathF.Sin((vY + 19) * 0.15f)) * 0.9f; var octave2 = (MathF.Sin((vX + 37) * 0.35f) + MathF.Sin((vY + 93) * 0.35f)) * 0.4f; var octave3 = (MathF.Sin((vX + 53) * 0.65f) + MathF.Sin((vY + 47) * 0.65f)) * 0.2f; var octave4 = (MathF.Sin((vX + 67) * 1.50f) + MathF.Sin((vY + 13) * 1.5f)) * 0.125f; var distanceToEdge = planeWidth / 2 - Math.Max(Math.Abs(vX - planeWidth / 2), Math.Abs(vY - planeWidth / 2)); var edgeRamp = 25f / (distanceToEdge + 1); var terrainHeight = octave0 + octave1 + octave2 + octave3 + octave4; var vertexPosition = new Vector2(vX * scale, vY * scale) + terrainPosition; var distanceToTrack = raceTrack.GetDistance(vertexPosition); var trackWeight = MathF.Min(1f, 3f / (distanceToTrack * 0.1f + 1f)); var height = trackWeight * -10f + terrainHeight * (1 - trackWeight); return(new Vector3(vertexPosition.X, height + edgeRamp, vertexPosition.Y)); }, new Vector3(1, 1, 1), BufferPool, out var planeMesh); Simulation.Statics.Add(new StaticDescription(new Vector3(0, -15, 0), QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), MathF.PI / 2), new CollidableDescription(Simulation.Shapes.Add(planeMesh), 0.1f))); }
/// <summary> /// Registers Apples /// </summary> /// <param name="typeMapper">Type Mapper</param> /// <param name="settings">Settings</param> private void RegisterApple(ITypeMapper typeMapper, KeyValueStore settings) { // Apple typeMapper.RegisterItem <AppleItem, AppleState, AppleInfo>(this, "Apple"); // Collidable settings.Set <AppleItem>("Mass", 200f, "Mass of an Apple"); typeMapper.AttachItemProperty <AppleItem, CollidableProperty>(this, "Apple Collidable", (i) => { CollidableProperty property = new CollidableProperty(i); // Define Radius property.CollisionRadius = AppleItem.AppleInnerRadius; // Define Mass property.CollisionFixed = false; property.CollisionMass = i.Settings.GetFloat <AppleItem>("Mass").Value; return(property); }); // Visibility typeMapper.AttachItemProperty <AppleItem, VisibleProperty>(this, "Apple Visible", (i) => { VisibleProperty property = new VisibleProperty(i); // Bind Visibility Radius to the Item Radius property.VisibilityRadius = i.Radius; i.RadiusChanged += (item, v) => { property.VisibilityRadius = v; }; return(property); }); // Portable settings.Set <AppleItem>("Weight", 200f, "Weight of an Apple"); typeMapper.AttachItemProperty <AppleItem, PortableProperty>(this, "Apple Portable", (i) => { PortableProperty property = new PortableProperty(i); // Set Weight property.PortableWeight = settings.GetFloat <AppleItem>("Weight").Value; // Bind Portable Radius to the Item Radius property.PortableRadius = i.Radius; i.RadiusChanged += (item, v) => { property.PortableRadius = v; }; return(property); }); settings.Set <AppleItem>("Collectable", false, "Will an Apple be collectable"); settings.Set <AppleItem>("Amount", 250, "Amount of Apple Units"); typeMapper.AttachItemProperty <AppleItem, AppleCollectableProperty>(this, "Apple Collectable", (i) => { if (!i.Settings.GetBool <AppleItem>("Collectable").Value) { return(null); } AppleCollectableProperty property = new AppleCollectableProperty(i); property.Capacity = i.Settings.GetInt <AppleItem>("Amount").Value; property.Amount = i.Settings.GetInt <AppleItem>("Amount").Value; return(property); }); }
private void InitItem(Vector2 pos1, Vector2? pos2) { Item1 = new DebugCollisionItem(new Vector2(pos1.X, pos1.Y)); Moving1 = Item1.GetProperty<WalkingProperty>(); Collidable1 = Item1.GetProperty<CollidableProperty>(); if (pos2.HasValue) { Item2 = new DebugCollisionItem(new Vector2(pos2.Value.X, pos2.Value.Y)); Moving2 = Item2.GetProperty<WalkingProperty>(); Collidable2 = Item2.GetProperty<CollidableProperty>(); } }
public void Update(Simulation simulation, CollidableProperty <TankDemoBodyProperties> bodyProperties, Random random, long frameIndex, in Vector2 playAreaMin, in Vector2 playAreaMax, int aiIndex, ref QuickList <AITank> aiTanks, ref int projectileCount)
public CollidableInfo(Item item, ItemProperty property, Item observer) : base(item, property, observer) { this.property = property as CollidableProperty; }
protected override void RequestDraw() { if (_engine != null) { DrawPlayground(_engine.Map.GetCellCount(), _engine.Map.Tiles); foreach (var item in _engine.Items) { float?bodySpeed = null; float?bodyDirection = null; float?bodyRadius = null; float?smellableRadius = null; float?viewRange = null; float?viewAngle = null; float?viewDirection = null; float?attackRange = null; // Movement if (item.ContainsProperty <WalkingProperty>()) { WalkingProperty prop = item.GetProperty <WalkingProperty>(); bodySpeed = prop.Speed; bodyDirection = prop.Direction; } // Kollisionsradius if (item.ContainsProperty <CollidableProperty>()) { CollidableProperty prop = item.GetProperty <CollidableProperty>(); bodyRadius = prop.CollisionRadius; } // Sicht if (item.ContainsProperty <SightingProperty>()) { SightingProperty prop = item.GetProperty <SightingProperty>(); viewRange = prop.ViewRange; viewDirection = prop.ViewDirection.Radian; viewAngle = prop.ViewAngle; } // Attack if (item.ContainsProperty <AttackerProperty>()) { AttackerProperty prop = item.GetProperty <AttackerProperty>(); attackRange = prop.AttackRange; } // Stinkender radius if (item.ContainsProperty <SmellableProperty>()) { SmellableProperty prop = item.GetProperty <SmellableProperty>(); smellableRadius = prop.SmellableRadius; } DrawItem(item.Id, item.Position, bodyRadius, bodyDirection, bodySpeed, Color.White, viewRange, viewDirection, viewAngle, attackRange, smellableRadius, null); } } }
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 5, 10); camera.Yaw = 0; camera.Pitch = 0; bodyProperties = new CollidableProperty <TankDemoBodyProperties>(); //We assign velocities outside of the timestep to fire bullets, so using the PositionLastTimestepper avoids integrating those velocities into positions before the solver has a chance to intervene. //We could have also modified velocities in the PositionFirstTimestepper's BeforeCollisionDetection callback, but it's just a little simpler to do this with very little cost. Simulation = Simulation.Create(BufferPool, new TankCallbacks() { Properties = bodyProperties }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionLastTimestepper()); var builder = new CompoundBuilder(BufferPool, Simulation.Shapes, 2); builder.Add(new Box(1.85f, 0.7f, 4.73f), RigidPose.Identity, 10); builder.Add(new Box(1.85f, 0.6f, 2.5f), new RigidPose(new Vector3(0, 0.65f, -0.35f)), 0.5f); builder.BuildDynamicCompound(out var children, out var bodyInertia, out _); builder.Dispose(); var bodyShape = new Compound(children); var bodyShapeIndex = Simulation.Shapes.Add(bodyShape); var wheelShape = new Cylinder(0.4f, .18f); wheelShape.ComputeInertia(0.25f, out var wheelInertia); var wheelShapeIndex = Simulation.Shapes.Add(wheelShape); var projectileShape = new Sphere(0.1f); projectileShape.ComputeInertia(0.2f, out var projectileInertia); var tankDescription = new TankDescription { Body = TankPartDescription.Create(10, new Box(4f, 1, 5), RigidPose.Identity, 0.5f, Simulation.Shapes), Turret = TankPartDescription.Create(1, new Box(1.5f, 0.7f, 2f), new RigidPose(new Vector3(0, 0.85f, 0.4f)), 0.5f, Simulation.Shapes), Barrel = TankPartDescription.Create(0.5f, new Box(0.2f, 0.2f, 3f), new RigidPose(new Vector3(0, 0.85f, 0.4f - 1f - 1.5f)), 0.5f, Simulation.Shapes), TurretAnchor = new Vector3(0f, 0.5f, 0.4f), BarrelAnchor = new Vector3(0, 0.5f + 0.35f, 0.4f - 1f), TurretBasis = Quaternion.Identity, TurretServo = new ServoSettings(1f, 0f, 40f), TurretSpring = new SpringSettings(10f, 1f), BarrelServo = new ServoSettings(1f, 0f, 40f), BarrelSpring = new SpringSettings(10f, 1f), ProjectileShape = Simulation.Shapes.Add(projectileShape), ProjectileSpeed = 100f, BarrelLocalProjectileSpawn = new Vector3(0, 0, -1.5f), ProjectileInertia = projectileInertia, LeftTreadOffset = new Vector3(-1.9f, 0f, 0), RightTreadOffset = new Vector3(1.9f, 0f, 0), SuspensionLength = 1f, SuspensionSettings = new SpringSettings(2.5f, 1.5f), WheelShape = wheelShapeIndex, WheelInertia = wheelInertia, WheelFriction = 2f, TreadSpacing = 1f, WheelCountPerTread = 5, WheelOrientation = QuaternionEx.CreateFromAxisAngle(Vector3.UnitZ, MathF.PI * -0.5f), }; playerController = new TankController(Tank.Create(Simulation, bodyProperties, BufferPool, new RigidPose(new Vector3(0, 10, 0), Quaternion.Identity), tankDescription), 20, 5, 2, 1, 3.5f); const int planeWidth = 257; const float terrainScale = 3; const float inverseTerrainScale = 1f / terrainScale; var terrainPosition = new Vector2(1 - planeWidth, 1 - planeWidth) * terrainScale * 0.5f; random = new Random(5); //Add some building-ish landmarks. var landmarkMin = new Vector3(planeWidth * terrainScale * -0.45f, 0, planeWidth * terrainScale * -0.45f); var landmarkMax = new Vector3(planeWidth * terrainScale * 0.45f, 0, planeWidth * terrainScale * 0.45f); var landmarkSpan = landmarkMax - landmarkMin; for (int j = 0; j < 25; ++j) { var buildingShape = new Box(10 + (float)random.NextDouble() * 10, 20 + (float)random.NextDouble() * 20, 10 + (float)random.NextDouble() * 10); var position = landmarkMin + landmarkSpan * new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()); Simulation.Statics.Add(new StaticDescription( new Vector3(0, buildingShape.HalfHeight - 4f + GetHeightForPosition(position.X, position.Z, planeWidth, inverseTerrainScale, terrainPosition), 0) + position, QuaternionEx.CreateFromAxisAngle(Vector3.UnitY, (float)random.NextDouble() * MathF.PI), new CollidableDescription(Simulation.Shapes.Add(buildingShape), 0.1f))); } DemoMeshHelper.CreateDeformedPlane(planeWidth, planeWidth, (int vX, int vY) => { var position2D = new Vector2(vX, vY) * terrainScale + terrainPosition; return(new Vector3(position2D.X, GetHeightForPosition(position2D.X, position2D.Y, planeWidth, inverseTerrainScale, terrainPosition), position2D.Y)); }, new Vector3(1, 1, 1), BufferPool, out var planeMesh); Simulation.Statics.Add(new StaticDescription(new Vector3(0, 0, 0), new CollidableDescription(Simulation.Shapes.Add(planeMesh), 0.1f))); explosions = new QuickList <Explosion>(32, BufferPool); //Create the AI tanks. const int aiTankCount = 100; aiTanks = new QuickList <AITank>(aiTankCount, BufferPool); playAreaMin = new Vector2(landmarkMin.X, landmarkMin.Z); playAreaMax = new Vector2(landmarkMax.X, landmarkMax.Z); var playAreaSpan = playAreaMax - playAreaMin; for (int i = 0; i < aiTankCount; ++i) { var horizontalPosition = playAreaMin + new Vector2((float)random.NextDouble(), (float)random.NextDouble()) * playAreaSpan; aiTanks.AllocateUnsafely() = new AITank { Controller = new TankController( Tank.Create(Simulation, bodyProperties, BufferPool, new RigidPose( new Vector3(horizontalPosition.X, 10, horizontalPosition.Y), QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), (float)random.NextDouble() * 0.1f)), tankDescription), 20, 5, 2, 1, 3.5f), HitPoints = 5 }; } }
/// <summary> /// Registers Ants /// </summary> /// <param name="typeMapper">Type Mapper</param> /// <param name="settings">Settings</param> private void RegisterAnt(ITypeMapper typeMapper, KeyValueStore settings) { // Ant Item settings.Set <AntItem>("ZickZackAngle", 10, "Correction Angle after Sprint"); settings.Set <AntItem>("ZickZackRange", 30f, "Distance to go every Sprint"); settings.Set <AntItem>("RotationSpeed", 20, "Maximum Rotation Angle per Round"); settings.Set <AntItem>("DropSugar", false, "Will an Ant leave a small Sugar on Drop"); settings.Set <AntItem>("MarkerDelay", 10, "Time in Rounds between Marker-Drops"); typeMapper.RegisterItem <AntItem, AntState, AntInfo>(this, "Ant"); // Walking settings.Set <AntItem>("MaxSpeed", 1f, "Maximum Speed of an Ant"); typeMapper.AttachItemProperty <AntItem, WalkingProperty>(this, "Ant Walking", (i) => { WalkingProperty property = new WalkingProperty(i); // Set Maximum Speed based on the current Settings // TODO: Check for Castes property.MaximumSpeed = i.Settings.GetFloat <AntItem>("MaxSpeed").Value; // Bind Item Orientation to Walk-Direction property.Direction = i.Orientation; i.OrientationChanged += (item, v) => { property.Direction = v; }; return(property); }); // Collision settings.Set <AntItem>("Mass", 1f, "Collision Mass of an Ant"); typeMapper.AttachItemProperty <AntItem, CollidableProperty>(this, "Ant Collidable", (i) => { CollidableProperty property = new CollidableProperty(i); // Set Mass to Settings property.CollisionFixed = false; property.CollisionMass = i.Settings.GetFloat <AntItem>("Mass").Value; // Bind Collision Radius to Item Radius property.CollisionRadius = i.Radius; i.RadiusChanged += (item, v) => { property.CollisionRadius = v; }; return(property); }); // Visibility typeMapper.AttachItemProperty <AntItem, VisibleProperty>(this, "Ant Visible", (i) => { VisibleProperty property = new VisibleProperty(i); // Bind Visibility Radius to the Item Radius property.VisibilityRadius = i.Radius; i.RadiusChanged += (item, v) => { property.VisibilityRadius = v; }; return(property); }); // Sighting settings.Set <AntItem>("ViewRange", 20f, "View Range of an Ant"); settings.Set <AntItem>("ViewAngle", 360, "View Angle of an Ant"); typeMapper.AttachItemProperty <AntItem, SightingProperty>(this, "Ant Sighting", (i) => { SightingProperty property = new SightingProperty(i); // Set View Range and Angle property.ViewRange = i.Settings.GetFloat <AntItem>("ViewRange").Value; property.ViewAngle = i.Settings.GetFloat <AntItem>("ViewAngle").Value; // Bind View Direction to the Item Orientation property.ViewDirection = i.Orientation; i.OrientationChanged += (item, v) => { property.ViewDirection = v; }; return(property); }); // Sniffer typeMapper.AttachItemProperty <AntItem, SnifferProperty>(this, "Ant Sniffer"); // Carrier settings.Set <AntItem>("CarrierStrength", 10f, "Carrier Strength of an Ant"); typeMapper.AttachItemProperty <AntItem, CarrierProperty>(this, "Ant Carrier", (i) => { CarrierProperty property = new CarrierProperty(i); property.CarrierStrength = i.Settings.GetFloat <AntItem>("CarrierStrength").Value; return(property); }); // Attackable settings.Set <AntItem>("MaxHealth", 100f, "Maximum Health for an Ant"); typeMapper.AttachItemProperty <AntItem, AttackableProperty>(this, "Ant Attackable", (i) => { AttackableProperty property = new AttackableProperty(i); // Bind Attackable Radius to Item Radius property.AttackableRadius = i.Radius; i.RadiusChanged += (item, v) => { property.AttackableRadius = v; }; // Health property.AttackableMaximumHealth = settings.GetInt <AntItem>("MaxHealth").Value; property.AttackableHealth = settings.GetInt <AntItem>("MaxHealth").Value; return(property); }); // Attacker settings.Set <AntItem>("AttackRange", 3f, "Attack Range for a Bug"); settings.Set <AntItem>("RecoveryTime", 2, "Recovery Time in Rounds for a Bug"); settings.Set <AntItem>("AttackStrength", 5, "Attach Strength for a Bug"); typeMapper.AttachItemProperty <AntItem, AttackerProperty>(this, "Ant Attacker", (i) => { AttackerProperty property = new AttackerProperty(i); property.AttackRange = i.Settings.GetFloat <AntItem>("AttackRange").Value; property.AttackRecoveryTime = i.Settings.GetInt <AntItem>("RecoveryTime").Value; property.AttackStrength = i.Settings.GetInt <AntItem>("AttackStrength").Value; return(property); }); // Collector settings.Set <AntItem>("SugarCapacity", 5, "Maximum Capacity for Sugar"); settings.Set <AntItem>("AppleCapacity", 2, "Maximum Capacity for Apple"); typeMapper.AttachItemProperty <AntItem, SugarCollectorProperty>(this, "Ant Sugar Collectable", (i) => { SugarCollectorProperty property = new SugarCollectorProperty(i); property.Capacity = i.Settings.GetInt <AntItem>("SugarCapacity").Value; return(property); }); typeMapper.AttachItemProperty <AntItem, AppleCollectorProperty>(this, "Ant Apple Collectable", (i) => { AppleCollectorProperty property = new AppleCollectorProperty(i); property.Capacity = i.Settings.GetInt <AntItem>("AppleCapacity").Value; return(property); }); // TODO: Optional, wenn _settings.ANT_APPLECOLLECT | _settings.ANT_APPLE_CAPACITY, 0); }
public CollidableInfo(Item item, ItemProperty property, Item observer) : base(item, property, observer) { this.property = property as CollidableProperty; }