// Grab a rope public void grabRope(int entityId, RopeComponent ropeComponent, Body ropeBody) { RopeGrabExclusionComponent ropeGrabExclusionComponent = EntityManager.getRopeGrabExclusionComponent(entityId); if (ropeGrabExclusionComponent == null || !ropeGrabExclusionComponent.excludedRopeComponents.Contains(ropeComponent)) { GroupComponent groupComponent = SystemManager.groupSystem.getGroupComponentContaining(entityId); CharacterComponent characterComponent = EntityManager.getCharacterComponent(entityId); int index = ropeComponent.bodies.IndexOf(ropeBody); RevoluteJoint joint = JointFactory.CreateRevoluteJoint(SystemManager.physicsSystem.world, ropeBody, characterComponent.body, Vector2.Zero, Vector2.Zero); RopeGrabComponent ropeGrabComponent = new RopeGrabComponent(entityId, ropeComponent, joint, (float)index); EntityManager.addComponent(entityId, ropeGrabComponent); if (groupComponent != null) { Formation activeFormation = groupComponent.activeFormation; float maxPosition = ropeComponent.anchorBody.Position.X + 2f * groupComponent.entities.Count; LimitedRangeFormation newFormation = new LimitedRangeFormation(groupComponent.entities, activeFormation.position, activeFormation.speed, float.MinValue, maxPosition); ropeGrabComponent.formationToRemove = newFormation; activeFormation.position = (ropeComponent.anchorBody.Position.X + maxPosition) * 0.5f; groupComponent.addFormation(newFormation); } } }
// Release a rope public void releaseRope(int entityId, RopeGrabComponent ropeGrabComponent) { RopeGrabExclusionComponent ropeGrabExclusionComponent = EntityManager.getRopeGrabExclusionComponent(entityId); GroupComponent groupComponent = SystemManager.groupSystem.getGroupComponentContaining(entityId); if (ropeGrabExclusionComponent == null) { ropeGrabExclusionComponent = new RopeGrabExclusionComponent(entityId); EntityManager.addComponent(entityId, ropeGrabExclusionComponent); } ropeGrabExclusionComponent.excludedRopeComponents.Add(ropeGrabComponent.ropeComponent); EntityManager.removeComponent(entityId, ComponentType.RopeGrab); if (groupComponent != null) { groupComponent.removeFormation(ropeGrabComponent.formationToRemove); } }
// Move along a grabbed rope private void updateGrab(int entityId, RopeGrabComponent ropeGrabComponent, CharacterComponent characterBodyComponent) { Vector2 localAnchor; Body body; int oldIndex = (int)Math.Floor(ropeGrabComponent.progress); int newIndex; float fraction; float segmentLength = 1.2f; float progress = SystemManager.physicsSystem.isSlowMotion ? 0.025f : 0.05f; SystemManager.physicsSystem.world.RemoveJoint(ropeGrabComponent.joint); ropeGrabComponent.progress += progress; newIndex = (int)Math.Floor(ropeGrabComponent.progress); if (newIndex < 0 || newIndex > ropeGrabComponent.ropeComponent.bodies.Count - 1) { releaseRope(entityId, ropeGrabComponent); } else { fraction = ropeGrabComponent.progress - newIndex; body = ropeGrabComponent.ropeComponent.bodies[newIndex]; localAnchor = new Vector2((fraction - 0.5f) * segmentLength, 0f); ropeGrabComponent.joint = JointFactory.CreateRevoluteJoint(SystemManager.physicsSystem.world, body, characterBodyComponent.body, localAnchor, Vector2.Zero); } }