Exemple #1
0
        private static ObjectAction GetMoveAction(
            GuidGenerator guidGenerator)
        {
            string variableName = guidGenerator.NextGuid();

            ObjectAction initializeVariable = ObjectAction.SetNumericVariable(
                variableName: variableName,
                variableValue: MathExpression.Constant(0));

            ObjectAction incrementVariable = ObjectAction.SetNumericVariable(
                variableName: variableName,
                variableValue: MathExpression.Add(MathExpression.Variable(variableName), MathExpression.ElapsedMillisecondsPerIteration()));

            ObjectAction initializeAndIncrementVariable = ObjectAction.ConditionalNextAction(
                currentAction: initializeVariable,
                condition: BooleanExpression.True(),
                nextAction: incrementVariable);

            ObjectAction teleportToInitialLocation = ObjectAction.SetPosition(
                xMillis: MathExpression.Add(50 * 1000, MathExpression.RandomInteger(900 * 1000)),
                yMillis: MathExpression.Constant(800 * 1000));

            ObjectAction faceTowardsPlayer = ObjectAction.Move(
                moveToXMillis: MathExpression.PlayerXMillis(),
                moveToYMillis: MathExpression.Min(MathExpression.PlayerYMillis(), 300 * 1000));

            ObjectAction setInitialSpeed = ObjectActionGenerator.DoOnce(
                ObjectAction.SetSpeed(
                    speedInMillipixelsPerMillisecond: MathExpression.Constant(60)));

            ObjectAction slowDownSpeed1 = ObjectAction.Condition(
                condition: BooleanExpression.GreaterThanOrEqualTo(
                    MathExpression.Variable(variableName),
                    1 * 1000),
                action: ObjectActionGenerator.DoOnce(
                    ObjectAction.SetSpeed(
                        speedInMillipixelsPerMillisecond: MathExpression.Constant(40))));

            ObjectAction slowDownSpeed2 = ObjectAction.Condition(
                condition: BooleanExpression.GreaterThanOrEqualTo(
                    MathExpression.Variable(variableName),
                    2 * 1000),
                action: ObjectActionGenerator.DoOnce(
                    ObjectAction.SetSpeed(
                        speedInMillipixelsPerMillisecond: MathExpression.Constant(20))));

            ObjectAction stopMovement = ObjectAction.Condition(
                condition: BooleanExpression.GreaterThanOrEqualTo(
                    MathExpression.Variable(variableName),
                    3 * 1000),
                action: ObjectActionGenerator.DoOnce(
                    ObjectAction.SetSpeed(
                        speedInMillipixelsPerMillisecond: MathExpression.Constant(0))));

            BooleanExpression ShouldLeave1 = BooleanExpression.GreaterThanOrEqualTo(
                MathExpression.Variable(variableName),
                10 * 1000);

            ObjectAction leave1 = ObjectAction.SetPosition(
                xMillis: MathExpression.XMillis(),
                yMillis: MathExpression.Add(MathExpression.YMillis(), MathExpression.Multiply(MathExpression.ElapsedMillisecondsPerIteration(), MathExpression.Constant(25))));

            ObjectAction leave1ConditionalAction = ObjectAction.Condition(
                condition: ShouldLeave1,
                action: leave1);

            BooleanExpression shouldLeave2 = BooleanExpression.GreaterThanOrEqualTo(
                MathExpression.Variable(variableName),
                11 * 1000);

            ObjectAction leave2 = ObjectAction.SetPosition(
                xMillis: MathExpression.XMillis(),
                yMillis: MathExpression.Add(MathExpression.YMillis(), MathExpression.Multiply(MathExpression.ElapsedMillisecondsPerIteration(), MathExpression.Constant(50))));

            ObjectAction leave2ConditionalAction = ObjectAction.ConditionalNextAction(
                currentAction: leave1ConditionalAction,
                condition: shouldLeave2,
                nextAction: leave2);

            ObjectAction shouldDestroy = ObjectAction.Condition(
                condition: BooleanExpression.And(shouldLeave2, BooleanExpression.GreaterThanOrEqualTo(MathExpression.YMillis(), 800 * 1000)),
                action: ObjectAction.Destroy());

            return(ObjectAction.ConditionalNextAction(
                       currentAction: teleportToInitialLocation,
                       condition: BooleanExpression.True(),
                       nextAction: ObjectAction.Union(faceTowardsPlayer, initializeAndIncrementVariable, setInitialSpeed, slowDownSpeed1, slowDownSpeed2, stopMovement, leave2ConditionalAction, shouldDestroy)));
        }
Exemple #2
0
        private static Tuple <ObjectAction, BooleanExpression> MoveToSpecifiedLocations_Helper(
            long startingXMillis,
            long startingYMillis,
            long endingXMillis,
            long endingYMillis,
            long speedInPixelsPerSecond,
            bool shouldStrafe,
            GuidGenerator guidGenerator)
        {
            string variableName  = guidGenerator.NextGuid();
            string variableName2 = guidGenerator.NextGuid();

            long?direction = DTDanmakuMath.GetMovementDirectionInMillidegrees(
                currentX: startingXMillis,
                currentY: startingYMillis,
                desiredX: endingXMillis,
                desiredY: endingYMillis);

            if (direction == null)
            {
                throw new Exception();
            }

            DTDanmakuMath.Offset offset = DTDanmakuMath.GetOffset(
                speedInMillipixelsPerMillisecond: speedInPixelsPerSecond, // millipixels/millisecond is equivalent to pixels/second
                movementDirectionInMillidegrees: direction.Value,
                elapsedMillisecondsPerIteration: 1000);                   // Use the 1000 to help prevent rounding issues

            ObjectAction moveAction = ObjectAction.SetPosition(
                xMillis: MathExpression.Add(MathExpression.XMillis(), MathExpression.Divide(MathExpression.Multiply(MathExpression.Constant(offset.DeltaXInMillipixels), MathExpression.ElapsedMillisecondsPerIteration()), MathExpression.Constant(1000))),
                yMillis: MathExpression.Add(MathExpression.YMillis(), MathExpression.Divide(MathExpression.Multiply(MathExpression.Constant(offset.DeltaYInMillipixels), MathExpression.ElapsedMillisecondsPerIteration()), MathExpression.Constant(1000))));

            ObjectAction setDirectionAction = shouldStrafe
                                ? ObjectAction.SetFacingDirection(facingDirectionInMillidegrees: MathExpression.Constant(180 * 1000))
                                : ObjectAction.SetFacingDirection(facingDirectionInMillidegrees: MathExpression.Constant(direction.Value));

            IMathExpression deltaX             = MathExpression.AbsoluteValue(MathExpression.Subtract(MathExpression.XMillis(), MathExpression.Constant(endingXMillis)));
            IMathExpression deltaY             = MathExpression.AbsoluteValue(MathExpression.Subtract(MathExpression.YMillis(), MathExpression.Constant(endingYMillis)));
            IMathExpression totalDelta         = MathExpression.Add(deltaX, deltaY);
            ObjectAction    setDeltaToVariable = ObjectAction.Union(
                ObjectAction.SetNumericVariable(variableName: variableName2, variableValue: MathExpression.Variable(variableName)),
                ObjectAction.SetNumericVariable(variableName: variableName, variableValue: totalDelta));
            BooleanExpression reachedDestination = BooleanExpression.And(
                BooleanExpression.LessThanOrEqualTo(
                    MathExpression.Variable(variableName2),
                    MathExpression.Variable(variableName)),
                BooleanExpression.And(
                    BooleanExpression.GreaterThanOrEqualTo(MathExpression.Variable(variableName), MathExpression.Constant(0)),
                    BooleanExpression.GreaterThanOrEqualTo(MathExpression.Variable(variableName2), MathExpression.Constant(0))
                    ));

            ObjectAction initializeVariables = ObjectAction.Union(
                ObjectAction.SetNumericVariable(variableName: variableName, variableValue: MathExpression.Constant(-1)),
                ObjectAction.SetNumericVariable(variableName: variableName2, variableValue: MathExpression.Constant(-1)));

            return(new Tuple <ObjectAction, BooleanExpression>(
                       ObjectAction.Union(
                           moveAction,
                           setDirectionAction,
                           ObjectAction.ConditionalNextAction(
                               currentAction: initializeVariables,
                               condition: BooleanExpression.True(),
                               nextAction: setDeltaToVariable)),
                       reachedDestination));
        }
Exemple #3
0
        /*
         *      If (currentX, currentY) == (desiredX, desiredY), then
         *      the resulting movement direction is arbitrary.
         */
        public static ObjectAction MoveTowardsLocation(
            IMathExpression currentX,
            IMathExpression currentY,
            IMathExpression desiredX,
            IMathExpression desiredY,

            /*
             *      Note that movement speed is not affected by shouldSnapshot
             */
            IMathExpression movementSpeedInPixelsPerSecond,

            /*
             *      When true, will decide movement direction on the first frame, and keep that direction.
             *      When false, will continuously move towards (desiredX, desiredY)
             */
            bool shouldSnapshot,
            GuidGenerator guidGenerator)
        {
            string deltaXVariable = guidGenerator.NextGuid();
            string deltaYVariable = guidGenerator.NextGuid();

            ObjectAction setDeltaX = ObjectAction.SetNumericVariable(deltaXVariable, MathExpression.Subtract(desiredX, currentX));
            ObjectAction setDeltaY = ObjectAction.SetNumericVariable(deltaYVariable, MathExpression.Subtract(desiredY, currentY));

            BooleanExpression areDeltasBothZero = BooleanExpression.And(
                BooleanExpression.Equal(MathExpression.Variable(deltaXVariable), MathExpression.Constant(0)),
                BooleanExpression.Equal(MathExpression.Variable(deltaYVariable), MathExpression.Constant(0)));

            string angleInMillidegreesVariable = guidGenerator.NextGuid();

            ObjectAction setAngle = ObjectAction.Union(
                shouldSnapshot ? ObjectActionGenerator.DoOnce(setDeltaX) : setDeltaX,
                shouldSnapshot ? ObjectActionGenerator.DoOnce(setDeltaY) : setDeltaY,
                ObjectAction.Condition(
                    condition: areDeltasBothZero,
                    action: ObjectAction.SetNumericVariable(angleInMillidegreesVariable, MathExpression.Constant(0))),
                ObjectAction.Condition(
                    condition: BooleanExpression.Not(areDeltasBothZero),
                    action: ObjectAction.SetNumericVariable(angleInMillidegreesVariable, MathExpression.ArcTangentScaled(MathExpression.Variable(deltaXVariable), MathExpression.Variable(deltaYVariable), false))),
                ObjectAction.SetNumericVariable(angleInMillidegreesVariable, MathExpression.Multiply(MathExpression.Variable(angleInMillidegreesVariable), MathExpression.Constant(-1))),
                ObjectAction.SetNumericVariable(angleInMillidegreesVariable, MathExpression.Add(MathExpression.Variable(angleInMillidegreesVariable), 90 * 1000)));

            IMathExpression xMillis =
                MathExpression.Divide(
                    MathExpression.Multiply(
                        movementSpeedInPixelsPerSecond,
                        MathExpression.ElapsedMillisecondsPerIteration(),
                        MathExpression.SineScaled(MathExpression.Variable(angleInMillidegreesVariable))),
                    MathExpression.Constant(1000));
            IMathExpression yMillis =
                MathExpression.Divide(
                    MathExpression.Multiply(
                        movementSpeedInPixelsPerSecond,
                        MathExpression.ElapsedMillisecondsPerIteration(),
                        MathExpression.CosineScaled(MathExpression.Variable(angleInMillidegreesVariable))),
                    MathExpression.Constant(1000));

            string       xMillisVariable    = guidGenerator.NextGuid();
            string       yMillisVariable    = guidGenerator.NextGuid();
            ObjectAction setXMillisVariable = shouldSnapshot
                                ? ObjectActionGenerator.DoOnce(ObjectAction.SetNumericVariable(xMillisVariable, xMillis))
                                : ObjectAction.SetNumericVariable(xMillisVariable, xMillis);
            ObjectAction setYMillisVariable = shouldSnapshot
                                ? ObjectActionGenerator.DoOnce(ObjectAction.SetNumericVariable(yMillisVariable, yMillis))
                                : ObjectAction.SetNumericVariable(yMillisVariable, yMillis);

            return(ObjectAction.Union(
                       setAngle,
                       setXMillisVariable,
                       setYMillisVariable,
                       ObjectAction.SetPosition(
                           xMillis: MathExpression.Add(MathExpression.XMillis(), MathExpression.Variable(xMillisVariable)),
                           yMillis: MathExpression.Add(MathExpression.YMillis(), MathExpression.Variable(yMillisVariable)))));
        }
Exemple #4
0
        private static ObjectAction GetMoveAction(
            GuidGenerator guidGenerator)
        {
            string movementCooldownVariable = guidGenerator.NextGuid();

            ObjectAction setMovementCooldownAction = ObjectAction.SetNumericVariable(
                movementCooldownVariable,
                MathExpression.Add(MathExpression.Constant(500), MathExpression.RandomInteger(5000)));

            ObjectAction decrementMovementCooldownAction = ObjectAction.SetNumericVariable(
                movementCooldownVariable,
                MathExpression.Subtract(MathExpression.Variable(movementCooldownVariable), MathExpression.ElapsedMillisecondsPerIteration()));

            BooleanExpression shouldChangeMovement = BooleanExpression.LessThanOrEqualTo(
                MathExpression.Variable(movementCooldownVariable),
                MathExpression.Constant(0));

            IMathExpression randomMilliAngle = MathExpression.RandomInteger(MathExpression.Constant(360 * 1000));

            string       angleVariable           = guidGenerator.NextGuid();
            ObjectAction writeNewAngleToVariable = ObjectAction.SetNumericVariable(
                angleVariable,
                randomMilliAngle);

            ObjectAction normalizeAngleVariable = ObjectAction.Union(
                ObjectAction.Condition(
                    condition: BooleanExpression.LessThan(MathExpression.Variable(angleVariable), MathExpression.Constant(0)),
                    action: ObjectAction.SetNumericVariable(angleVariable, MathExpression.Add(MathExpression.Variable(angleVariable), MathExpression.Constant(360 * 1000)))),
                ObjectAction.Condition(
                    condition: BooleanExpression.GreaterThanOrEqualTo(MathExpression.Variable(angleVariable), MathExpression.Constant(360 * 1000)),
                    action: ObjectAction.SetNumericVariable(angleVariable, MathExpression.Subtract(MathExpression.Variable(angleVariable), MathExpression.Constant(360 * 1000)))));

            BooleanExpression tooCloseToLeftEdge = BooleanExpression.LessThanOrEqualTo(
                MathExpression.XMillis(),
                MathExpression.Constant(200 * 1000));

            ObjectAction updateAngleVariableLeft = ObjectAction.Condition(
                condition: BooleanExpression.And(tooCloseToLeftEdge, BooleanExpression.And(
                                                     BooleanExpression.GreaterThanOrEqualTo(MathExpression.Variable(angleVariable), MathExpression.Constant(180 * 1000)),
                                                     BooleanExpression.LessThanOrEqualTo(MathExpression.Variable(angleVariable), MathExpression.Constant(360 * 1000)))),
                action: ObjectAction.SetNumericVariable(
                    angleVariable,
                    MathExpression.Multiply(MathExpression.Variable(angleVariable), MathExpression.Constant(-1))));

            BooleanExpression tooCloseToRightEdge = BooleanExpression.GreaterThanOrEqualTo(
                MathExpression.XMillis(),
                MathExpression.Constant(800 * 1000));

            ObjectAction updateAngleVariableRight = ObjectAction.Condition(
                condition: BooleanExpression.And(tooCloseToRightEdge, BooleanExpression.And(
                                                     BooleanExpression.GreaterThanOrEqualTo(MathExpression.Variable(angleVariable), MathExpression.Constant(0 * 1000)),
                                                     BooleanExpression.LessThanOrEqualTo(MathExpression.Variable(angleVariable), MathExpression.Constant(180 * 1000)))),
                action: ObjectAction.SetNumericVariable(
                    angleVariable,
                    MathExpression.Multiply(MathExpression.Variable(angleVariable), MathExpression.Constant(-1))));

            BooleanExpression tooCloseToTopEdge = BooleanExpression.GreaterThanOrEqualTo(
                MathExpression.YMillis(),
                MathExpression.Constant(600 * 1000));

            ObjectAction updateAngleVariableTop = ObjectAction.Condition(
                condition: BooleanExpression.And(tooCloseToTopEdge, BooleanExpression.Or(
                                                     BooleanExpression.GreaterThanOrEqualTo(MathExpression.Variable(angleVariable), MathExpression.Constant(270 * 1000)),
                                                     BooleanExpression.LessThanOrEqualTo(MathExpression.Variable(angleVariable), MathExpression.Constant(90 * 1000)))),
                action: ObjectAction.SetNumericVariable(
                    angleVariable,
                    MathExpression.Subtract(
                        MathExpression.Multiply(MathExpression.Add(MathExpression.Variable(angleVariable), MathExpression.Constant(90 * 1000)), MathExpression.Constant(-1)),
                        MathExpression.Constant(90 * 1000))));

            BooleanExpression tooCloseToBottomEdge = BooleanExpression.LessThanOrEqualTo(
                MathExpression.YMillis(),
                MathExpression.Constant(400 * 1000));

            ObjectAction updateAngleVariableBottom = ObjectAction.Condition(
                condition: BooleanExpression.And(tooCloseToBottomEdge, BooleanExpression.And(
                                                     BooleanExpression.GreaterThanOrEqualTo(MathExpression.Variable(angleVariable), MathExpression.Constant(90 * 1000)),
                                                     BooleanExpression.LessThanOrEqualTo(MathExpression.Variable(angleVariable), MathExpression.Constant(270 * 1000)))),
                action: ObjectAction.SetNumericVariable(
                    angleVariable,
                    MathExpression.Subtract(
                        MathExpression.Multiply(MathExpression.Add(MathExpression.Variable(angleVariable), MathExpression.Constant(90 * 1000)), MathExpression.Constant(-1)),
                        MathExpression.Constant(90 * 1000))));

            string angleSnapshotVariable = guidGenerator.NextGuid();

            ObjectAction initializeAngleSnapshotVariable = ObjectActionGenerator.DoOnce(
                ObjectAction.SetNumericVariable(angleSnapshotVariable, MathExpression.RandomInteger(360 * 1000)));

            DTDanmakuMath.MathExpressionOffset offset = DTDanmakuMath.GetOffset(
                millipixels: MathExpression.Multiply(MathExpression.Constant(80), MathExpression.ElapsedMillisecondsPerIteration()),
                movementDirectionInMillidegrees: MathExpression.Variable(angleSnapshotVariable));

            ObjectAction updatePositionAction = ObjectAction.SetPosition(
                xMillis: MathExpression.Add(MathExpression.XMillis(), offset.DeltaXInMillipixels),
                yMillis: MathExpression.Add(MathExpression.YMillis(), offset.DeltaYInMillipixels));

            ObjectAction updatePositionWhenCooldownIsZero = ObjectAction.Condition(
                condition: shouldChangeMovement,
                action: ObjectAction.Union(
                    ObjectAction.SetNumericVariable(angleSnapshotVariable, MathExpression.Variable(angleVariable)),
                    setMovementCooldownAction));

            ObjectAction immediateMoveWhenTooClose = ObjectAction.Condition(
                condition: BooleanExpression.Or(tooCloseToLeftEdge, tooCloseToRightEdge, tooCloseToTopEdge, tooCloseToBottomEdge),
                action: ObjectAction.SetNumericVariable(movementCooldownVariable, MathExpression.Constant(0)));

            List <ObjectAction> actionList = new List <ObjectAction>();

            actionList.Add(initializeAngleSnapshotVariable);
            actionList.Add(ObjectActionGenerator.DoOnce(setMovementCooldownAction));
            actionList.Add(decrementMovementCooldownAction);
            actionList.Add(writeNewAngleToVariable);
            actionList.Add(updateAngleVariableLeft);
            actionList.Add(normalizeAngleVariable);
            actionList.Add(updateAngleVariableRight);
            actionList.Add(normalizeAngleVariable);
            actionList.Add(updateAngleVariableTop);
            actionList.Add(normalizeAngleVariable);
            actionList.Add(normalizeAngleVariable);
            actionList.Add(updateAngleVariableBottom);
            actionList.Add(normalizeAngleVariable);
            actionList.Add(normalizeAngleVariable);
            actionList.Add(updatePositionWhenCooldownIsZero);
            actionList.Add(updatePositionAction);
            actionList.Add(immediateMoveWhenTooClose);

            return(ObjectAction.Union(actionList));
        }