public void attemptRopeGrab(string levelUid, int characterId, CharacterMovementComponent characterMovementComponent, PhysicsComponent physicsComponent, RopeGrabComponent existingRopeGrabComponent)
        {
            float margin = 0.5f;
            AABB region = new AABB();
            RopeNode ropeNode = null;
            int nodeCount = 0;

            region.LowerBound = physicsComponent.body.Position - new Vector2(margin, margin);
            region.UpperBound = physicsComponent.body.Position + new Vector2(margin, margin);

            if (physicsComponent == null)
                return;

            // Query the world for a body, and check to see if it's a rope
            physicsComponent.body.World.QueryAABB((fixture) =>
                {
                    int ropeEntityId = (int)fixture.Body.UserData;
                    RopeComponent ropeComponent = (RopeComponent)_entityManager.getComponent(levelUid, ropeEntityId, ComponentType.Rope);
                    RopeGrabComponent ropeGrabComponent = null;

                    if (ropeComponent != null && !ropeComponent.doubleAnchor)
                    {
                        RopeNode current = ropeComponent.ropeNodeHead;

                        characterMovementComponent.allowRopeGrab = false;

                        while (current != null)
                        {
                            if (current.body == fixture.Body)
                            {
                                ropeNode = current;
                                break;
                            }
                            nodeCount++;
                            current = current.next;
                        }

                        if (existingRopeGrabComponent != null)
                        {
                            RopeComponent existingRopeComponent = (RopeComponent)_entityManager.getComponent(levelUid, existingRopeGrabComponent.ropeEntityId, ComponentType.Rope);

                            if (existingRopeComponent.destroyAfterRelease)
                                existingRopeComponent.timeToLive = 100;

                            _ropeSystem.releaseRope(existingRopeGrabComponent, physicsComponent.body);
                            _entityManager.removeComponent(levelUid, characterId, existingRopeGrabComponent);
                        }

                        ropeGrabComponent = new RopeGrabComponent(ropeEntityId, ropeNode, (float)nodeCount, ropeComponent.reverseClimbDirection);
                        _ropeSystem.grabRope(ropeGrabComponent, physicsComponent.body);
                        _entityManager.addComponent(levelUid, characterId, ropeGrabComponent);

                        return false;
                    }
                    return true;
                },
                ref region);
        }
Beispiel #2
0
        // update
        public void update(GameTime gameTime)
        {
            if (_singleStep || !_paused)
            {
                string levelUid = LevelSystem.currentLevelUid;
                LevelSystem levelSystem = _systemManager.getSystem(SystemType.Level) as LevelSystem;

                if (levelSystem.finalized)
                {
                    PlayerSystem playerSystem = _systemManager.getSystem(SystemType.Player) as PlayerSystem;
                    RopeSystem ropeSystem = _systemManager.getSystem(SystemType.Rope) as RopeSystem;
                    PhysicsComponent playerPhysicsComponent = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.Physics) as PhysicsComponent;
                    List<int> toolbarEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.Toolbar);

                    // Player equipment
                    if (playerSystem != null)
                    {
                        ToolbarComponent playerToolbar = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.Toolbar) as ToolbarComponent;
                        WorldPositionComponent playerPositionComponent = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.WorldPosition) as WorldPositionComponent;
                        ItemComponent selectedItem = playerToolbar.selectedItem;

                        if (selectedItem != null)
                        {
                            selectedItem.primaryContinuousAction = InputSystem.newMouseState.LeftButton == ButtonState.Pressed;
                            selectedItem.primarySingleAction = selectedItem.primaryContinuousAction && InputSystem.oldMouseState.LeftButton == ButtonState.Released;
                            selectedItem.secondaryContinuousAction = InputSystem.newMouseState.RightButton == ButtonState.Pressed;
                            selectedItem.secondarySingleAction = selectedItem.secondaryContinuousAction && InputSystem.oldMouseState.RightButton == ButtonState.Released;
                            //bool leftTriggerDown = InputSystem.usingGamepad && InputSystem.newGamepadState.Triggers.Left > 0.5f && InputSystem.oldGamepadState.Triggers.Left <= 0.5f;
                            //bool rightTriggerDown = InputSystem.usingGamepad && InputSystem.newGamepadState.Triggers.Right > 0.5f && InputSystem.oldGamepadState.Triggers.Right <= 0.5f;
                            AimComponent aimComponent = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.Aim) as AimComponent;

                            if (selectedItem.definition.hasAimingComponent && aimComponent != null)
                            {
                                WorldPositionComponent worldPositionComponent = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.WorldPosition) as WorldPositionComponent;

                                if (worldPositionComponent != null)
                                {
                                    Vector2 worldPosition = worldPositionComponent.position;
                                    if (InputSystem.usingGamepad)
                                    {
                                        Vector2 vector = InputSystem.newGamepadState.ThumbSticks.Left * selectedItem.state.currentRangeLimit;
                                        vector.Y *= -1;
                                        aimComponent.angle = (float)Math.Atan2(vector.Y, vector.X);
                                        aimComponent.length = vector.Length();
                                        aimComponent.vector = vector;
                                    }
                                    else
                                    {
                                        Vector2 relative = (InputSystem.worldMouse - worldPosition);
                                        aimComponent.angle = (float)Math.Atan2(relative.Y, relative.X);
                                        aimComponent.length = Math.Min(relative.Length(), selectedItem.state.currentRangeLimit);
                                        aimComponent.vector = relative;
                                    }
                                }
                            }
                        }
                    }

                    // All toolbars
                    for (int i = 0; i < toolbarEntities.Count; i++)
                    {
                        ToolbarComponent toolbarComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Toolbar) as ToolbarComponent;
                        ItemComponent selectedItem = toolbarComponent.selectedItem;

                        if (selectedItem != null)
                        {
                            if (selectedItem.secondarySingleAction)
                                Console.WriteLine("secondary action");

                            switch (selectedItem.definition.uid)
                            {
                                // RopeGun
                                case "ropegun":
                                    if (selectedItem.primarySingleAction)
                                    {
                                        AimComponent aimComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Aim) as AimComponent;
                                        Vector2 initialPointA = (_entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.WorldPosition) as WorldPositionComponent).position;
                                        Vector2 initialPointB = initialPointA + new Vector2((float)Math.Cos(aimComponent.angle), (float)Math.Sin(aimComponent.angle)) * aimComponent.length;
                                        int ropeEntityId = _entityManager.factory.createSingleAnchorRope(levelUid, initialPointA, initialPointB, _defaultRopeMaterial, true);

                                        if (ropeEntityId != -1)
                                        {
                                            RopeGrabComponent ropeGrabComponent = _entityManager.getComponent(levelUid, toolbarComponent.entityId, ComponentType.RopeGrab) as RopeGrabComponent;
                                            RopeComponent ropeComponent = _entityManager.getComponent(levelUid, ropeEntityId, ComponentType.Rope) as RopeComponent;
                                            PhysicsComponent physicsComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Physics) as PhysicsComponent;
                                            RopeGrabComponent newRopeGrabComponent = null;
                                            Vector2 initialVelocity = physicsComponent.body.LinearVelocity;
                                            RopeNode currentNode = null;
                                            int ropeSegmentCount;

                                            if (physicsComponent == null)
                                                break;

                                            // Handle initial velocity
                                            currentNode = ropeComponent.ropeNodeHead;
                                            ropeSegmentCount = currentNode.count;
                                            System.Diagnostics.Debug.Assert(ropeSegmentCount != 0);
                                            int count = ropeSegmentCount;
                                            while (currentNode != null)
                                            {
                                                float weight = (float)count / (float)ropeSegmentCount;

                                                currentNode.body.LinearVelocity = currentNode.body.LinearVelocity + initialVelocity * weight;

                                                count--;
                                                currentNode = currentNode.next;
                                            }

                                            // Handle previous grabs
                                            if (ropeGrabComponent != null)
                                            {
                                                RopeComponent previouslyGrabbedRope = _entityManager.getComponent(levelUid, ropeGrabComponent.ropeEntityId, ComponentType.Rope) as RopeComponent;
                                                ropeSystem.releaseRope(ropeGrabComponent, physicsComponent.body);

                                                if (previouslyGrabbedRope.destroyAfterRelease)
                                                    previouslyGrabbedRope.timeToLive = 100;
                                                _entityManager.removeComponent(levelUid, toolbarComponent.entityId, ropeGrabComponent);
                                                ropeGrabComponent = null;
                                            }

                                            newRopeGrabComponent = new RopeGrabComponent(ropeEntityId, ropeComponent.ropeNodeHead, 0f, ropeComponent.reverseClimbDirection);
                                            ropeSystem.grabRope(newRopeGrabComponent, physicsComponent.body);
                                            _entityManager.addComponent(levelUid, toolbarComponent.entityId, newRopeGrabComponent);
                                        }
                                    }
                                    break;

                                // Dynamite
                                case "dynamite":
                                    if (selectedItem.primarySingleAction)
                                    {
                                        AimComponent aimComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Aim) as AimComponent;

                                        _entityManager.factory.createDynamite(levelUid, playerPhysicsComponent.body.Position, aimComponent.vector * 80f);
                                    }
                                    break;

                                // Water gun
                                case "watergun":
                                    if (selectedItem.primaryContinuousAction)
                                    {
                                        FluidSystem fluidSystem = _systemManager.getSystem(SystemType.Fluid) as FluidSystem;
                                        AimComponent aimComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Aim) as AimComponent;
                                        Vector2 aimUnitVector = Vector2.Normalize(aimComponent.vector);
                                        Vector2 particlePosition =
                                            playerPhysicsComponent.body.Position +
                                            aimUnitVector +
                                            new Vector2(StasisMathHelper.floatBetween(-0.1f, 0.1f, _rng), StasisMathHelper.floatBetween(-0.1f, 0.1f, _rng));
                                        Vector2 particleVelocity = aimUnitVector * 0.4f;

                                        fluidSystem.createParticle(particlePosition, particleVelocity);
                                    }
                                    break;
                            }

                            selectedItem.primarySingleAction = false;
                            selectedItem.secondarySingleAction = false;
                            selectedItem.primaryContinuousAction = false;
                            selectedItem.secondaryContinuousAction = false;
                        }
                    }
                }
            }
            _singleStep = false;
        }