public static void MakeAttachable(Entity entity, Main main) { Transform transform = entity.Get<Transform>(); Property<float> attachOffset = entity.GetOrMakeProperty<float>("AttachmentOffset", true); Property<Entity.Handle> map = entity.GetOrMakeProperty<Entity.Handle>("AttachedMap"); Property<Map.Coordinate> coord = entity.GetOrMakeProperty<Map.Coordinate>("AttachedCoordinate"); if (main.EditorEnabled) return; Binding<Matrix> attachmentBinding = null; CommandBinding deleteBinding = null; CommandBinding<IEnumerable<Map.Coordinate>, Map> cellEmptiedBinding = null; entity.Add(new NotifyBinding(delegate() { if (attachmentBinding != null) { entity.Remove(attachmentBinding); entity.Remove(deleteBinding); entity.Remove(cellEmptiedBinding); } Map m = map.Value.Target.Get<Map>(); coord.Value = m.GetCoordinate(Vector3.Transform(new Vector3(0, 0, attachOffset), transform.Matrix)); Matrix offset = transform.Matrix * Matrix.Invert(Matrix.CreateTranslation(m.Offset) * m.Transform); attachmentBinding = new Binding<Matrix>(transform.Matrix, () => offset * Matrix.CreateTranslation(m.Offset) * m.Transform, m.Transform, m.Offset); entity.Add(attachmentBinding); deleteBinding = new CommandBinding(m.Delete, entity.Delete); entity.Add(deleteBinding); cellEmptiedBinding = new CommandBinding<IEnumerable<Map.Coordinate>, Map>(m.CellsEmptied, delegate(IEnumerable<Map.Coordinate> coords, Map newMap) { foreach (Map.Coordinate c in coords) { if (c.Equivalent(coord)) { if (newMap == null) entity.Delete.Execute(); else map.Value = newMap.Entity; break; } } }); entity.Add(cellEmptiedBinding); }, map)); entity.Add(new PostInitialization { delegate() { if (map.Value.Target == null) { Map closestMap = null; int closestDistance = 3; float closestFloatDistance = 3.0f; Vector3 target = Vector3.Transform(new Vector3(0, 0, attachOffset), transform.Matrix); foreach (Map m in Map.Maps) { Map.Coordinate targetCoord = m.GetCoordinate(target); Map.Coordinate? c = m.FindClosestFilledCell(targetCoord, closestDistance); if (c.HasValue) { float distance = (m.GetRelativePosition(c.Value) - m.GetRelativePosition(targetCoord)).Length(); if (distance < closestFloatDistance) { closestFloatDistance = distance; closestDistance = (int)Math.Floor(distance); closestMap = m; } } } if (closestMap == null) entity.Delete.Execute(); else map.Value = closestMap.Entity; } else map.Reset(); } }); }
public override void InitializeProperties() { this.Add(new Binding<Vector3>(this.Position, () => Vector3.Transform(new Vector3(0.0f, 0.0f, this.Offset), this.Transform), this.Offset, this.Transform)); if (!this.main.EditorEnabled) { Action setupMap = delegate() { Entity entity = this.Map.Value.Target; if (entity == null || !entity.Active) { this.Delete.Execute(); return; } else { if (this.cellEmptiedBinding != null) this.Remove(this.cellEmptiedBinding); this.cellEmptiedBinding = new CommandBinding<IEnumerable<Map.Coordinate>, Map>(entity.Get<Map>().CellsEmptied, delegate(IEnumerable<Map.Coordinate> coords, Map newMap) { if (!this.IsValid) this.Delete.Execute(); }); this.Add(this.cellEmptiedBinding); } }; this.Add(new NotifyBinding(setupMap, this.Map)); if (this.Map.Value.Target != null) setupMap(); this.infectedID = WorldFactory.StatesByName["InfectedCritical"].ID; this.main.AddComponent(new PostInitialization { delegate() { if (this.Map.Value.Target == null || !this.Map.Value.Target.Active) { this.BaseBoxes.Clear(); bool found = false; foreach (Map m in Lemma.Components.Map.Maps) { Map.Box box = m.GetBox(this.Position); if (box != null && box.Type.ID == this.infectedID) { foreach (Map.Box b in m.GetContiguousByType(new[] { box })) this.BaseBoxes.Add(b); this.Map.Value = m.Entity; found = true; break; } } if (!found) this.Delete.Execute(); } } }); } }
public static void Bind(Entity result, Main main, Func<BEPUphysics.Entities.Entity, BEPUphysics.Entities.Entity, Vector3, Vector3, Vector3, ISpaceObject> createJoint, bool allowRotation, bool creating = false) { Transform mapTransform = result.GetOrCreate<Transform>("MapTransform"); Transform transform = result.GetOrCreate<Transform>("Transform"); Factory.Get<DynamicMapFactory>().InternalBind(result, main, creating, mapTransform); DynamicMap map = result.Get<DynamicMap>(); Property<Entity.Handle> parentMap = result.GetOrMakeProperty<Entity.Handle>("Parent"); Property<Map.Coordinate> coord = result.GetOrMakeProperty<Map.Coordinate>("Coord"); Property<Direction> dir = result.GetOrMakeProperty<Direction>("Direction", true); Action refreshMapTransform = delegate() { Entity parent = parentMap.Value.Target; if (parent != null) { if (!parent.Active) parent = null; else { Map staticMap = parent.Get<Map>(); coord.Value = staticMap.GetCoordinate(transform.Position); mapTransform.Position.Value = staticMap.GetAbsolutePosition(staticMap.GetRelativePosition(coord) - new Vector3(0.5f) + staticMap.Offset + map.Offset); if (!allowRotation) mapTransform.Orientation.Value = parent.Get<Transform>().Orientation; } } else mapTransform.Matrix.Value = transform.Matrix; }; if (main.EditorEnabled) result.Add(new NotifyBinding(refreshMapTransform, transform.Matrix, map.Offset)); ISpaceObject joint = null; CommandBinding jointDeleteBinding = null, physicsUpdateBinding = null; Action rebuildJoint = null; rebuildJoint = delegate() { if (joint != null) { if (joint.Space != null) main.Space.Remove(joint); result.Remove(jointDeleteBinding); if (physicsUpdateBinding != null) result.Remove(physicsUpdateBinding); physicsUpdateBinding = null; joint = null; jointDeleteBinding = null; } Entity parent = parentMap.Value.Target; if (main.EditorEnabled) { refreshMapTransform(); return; } if (parent != null) { if (!parent.Active) parent = null; else { Map staticMap = parent.Get<Map>(); map.PhysicsEntity.Position = mapTransform.Position; if (!allowRotation) map.PhysicsEntity.Orientation = mapTransform.Quaternion; if (dir != Direction.None && !main.EditorEnabled) { Vector3 relativeLineAnchor = staticMap.GetRelativePosition(coord) - new Vector3(0.5f) + staticMap.Offset + map.Offset; Vector3 lineAnchor = staticMap.GetAbsolutePosition(relativeLineAnchor); DynamicMap dynamicMap = parent.Get<DynamicMap>(); joint = createJoint(map.PhysicsEntity, dynamicMap == null ? null : dynamicMap.PhysicsEntity, map.PhysicsEntity.Position, staticMap.GetAbsoluteVector(dir.Value.GetVector()), lineAnchor); main.Space.Add(joint); map.PhysicsEntity.ActivityInformation.Activate(); if (dynamicMap != null) { physicsUpdateBinding = new CommandBinding(dynamicMap.PhysicsUpdated, rebuildJoint); result.Add(physicsUpdateBinding); } jointDeleteBinding = new CommandBinding(parent.Delete, delegate() { parentMap.Value = null; }); result.Add(jointDeleteBinding); } } } }; result.Add(new NotifyBinding(rebuildJoint, parentMap)); result.Add(new CommandBinding(result.Delete, delegate() { if (joint != null && joint.Space != null) { main.Space.Remove(joint); joint = null; } })); result.Add(new CommandBinding(map.OnSuspended, delegate() { if (joint != null && joint.Space != null) main.Space.Remove(joint); })); result.Add(new CommandBinding(map.OnResumed, delegate() { if (joint != null && joint.Space == null) main.Space.Add(joint); })); rebuildJoint(); Command rebuildJointCommand = new Command(); result.Add(new CommandBinding(rebuildJointCommand, rebuildJoint)); result.Add("RebuildJoint", rebuildJointCommand); if (main.EditorEnabled) JointFactory.attachEditorComponents(result, main); }
public void Bind(Property<PCInput.PCInputBinding> inputBinding, InputState state, Action action) { CommandBinding commandBinding = null; Action rebindCommand = delegate() { if (commandBinding != null) this.Remove(commandBinding); PCInput.PCInputBinding ib = inputBinding; if (ib.Key == Keys.None && ib.MouseButton == PCInput.MouseButton.None) commandBinding = null; else { commandBinding = new CommandBinding(state == InputState.Up ? this.GetInputUp(inputBinding) : this.GetInputDown(inputBinding), action); this.Add(commandBinding); } }; this.Add(new NotifyBinding(rebindCommand, inputBinding)); rebindCommand(); }