@@ -100,6 +100,7 @@ TEST_F(MotionBlocksTest, RegisterBlocks)
100100 EXPECT_CALL (m_engineMock, addCompileFunction (m_section.get (), " motion_pointindirection" , &MotionBlocks::compilePointInDirection));
101101 EXPECT_CALL (m_engineMock, addCompileFunction (m_section.get (), " motion_pointtowards" , &MotionBlocks::compilePointTowards));
102102 EXPECT_CALL (m_engineMock, addCompileFunction (m_section.get (), " motion_gotoxy" , &MotionBlocks::compileGoToXY));
103+ EXPECT_CALL (m_engineMock, addCompileFunction (m_section.get (), " motion_goto" , &MotionBlocks::compileGoTo));
103104
104105 // Inputs
105106 EXPECT_CALL (m_engineMock, addInput (m_section.get (), " STEPS" , MotionBlocks::STEPS));
@@ -108,6 +109,7 @@ TEST_F(MotionBlocksTest, RegisterBlocks)
108109 EXPECT_CALL (m_engineMock, addInput (m_section.get (), " TOWARDS" , MotionBlocks::TOWARDS));
109110 EXPECT_CALL (m_engineMock, addInput (m_section.get (), " X" , MotionBlocks::X));
110111 EXPECT_CALL (m_engineMock, addInput (m_section.get (), " Y" , MotionBlocks::Y));
112+ EXPECT_CALL (m_engineMock, addInput (m_section.get (), " TO" , MotionBlocks::TO));
111113
112114 m_section->registerBlocks (&m_engineMock);
113115}
@@ -478,3 +480,145 @@ TEST_F(MotionBlocksTest, GoToXYImpl)
478480 ASSERT_EQ (sprite.x (), 95.2 );
479481 ASSERT_EQ (sprite.y (), -175.9 );
480482}
483+
484+ TEST_F (MotionBlocksTest, GoTo)
485+ {
486+ Compiler compiler (&m_engineMock);
487+
488+ // go to (mouse-pointer)
489+ auto block1 = std::make_shared<Block>(" a" , " motion_goto" );
490+ addDropdownInput (block1, " TO" , MotionBlocks::TO, " _mouse_" );
491+
492+ // go to (random position)
493+ auto block2 = std::make_shared<Block>(" b" , " motion_goto" );
494+ addDropdownInput (block2, " TO" , MotionBlocks::TO, " _random_" );
495+
496+ // go to (Sprite2)
497+ auto block3 = std::make_shared<Block>(" c" , " motion_goto" );
498+ addDropdownInput (block3, " TO" , MotionBlocks::TO, " Sprite2" );
499+
500+ // go to (join "" "")
501+ auto joinBlock = std::make_shared<Block>(" e" , " operator_join" );
502+ joinBlock->setCompileFunction (&OperatorBlocks::compileJoin);
503+ auto block4 = std::make_shared<Block>(" d" , " motion_goto" );
504+ addDropdownInput (block4, " TO" , MotionBlocks::TO, " " , joinBlock);
505+
506+ compiler.init ();
507+
508+ EXPECT_CALL (m_engineMock, functionIndex (&MotionBlocks::goToMousePointer)).WillOnce (Return (0 ));
509+ compiler.setBlock (block1);
510+ MotionBlocks::compileGoTo (&compiler);
511+
512+ EXPECT_CALL (m_engineMock, functionIndex (&MotionBlocks::goToRandomPosition)).WillOnce (Return (1 ));
513+ compiler.setBlock (block2);
514+ MotionBlocks::compileGoTo (&compiler);
515+
516+ EXPECT_CALL (m_engineMock, findTarget (" Sprite2" )).WillOnce (Return (5 ));
517+ EXPECT_CALL (m_engineMock, functionIndex (&MotionBlocks::goToByIndex)).WillOnce (Return (2 ));
518+ compiler.setBlock (block3);
519+ MotionBlocks::compileGoTo (&compiler);
520+
521+ EXPECT_CALL (m_engineMock, functionIndex (&MotionBlocks::goTo)).WillOnce (Return (3 ));
522+ compiler.setBlock (block4);
523+ MotionBlocks::compileGoTo (&compiler);
524+
525+ compiler.end ();
526+
527+ ASSERT_EQ (
528+ compiler.bytecode (),
529+ std::vector<unsigned int >({ vm::OP_START, vm::OP_EXEC, 0 , vm::OP_EXEC, 1 , vm::OP_CONST, 0 , vm::OP_EXEC, 2 , vm::OP_NULL, vm::OP_NULL, vm::OP_STR_CONCAT, vm::OP_EXEC, 3 , vm::OP_HALT }));
530+ ASSERT_EQ (compiler.constValues ().size (), 1 );
531+ ASSERT_EQ (compiler.constValues ()[0 ].toDouble (), 5 );
532+ }
533+
534+ TEST_F (MotionBlocksTest, GoToImpl)
535+ {
536+ static unsigned int bytecode1[] = { vm::OP_START, vm::OP_CONST, 0 , vm::OP_EXEC, 0 , vm::OP_HALT };
537+ static unsigned int bytecode2[] = { vm::OP_START, vm::OP_CONST, 1 , vm::OP_EXEC, 0 , vm::OP_HALT };
538+ static unsigned int bytecode3[] = { vm::OP_START, vm::OP_CONST, 2 , vm::OP_EXEC, 0 , vm::OP_HALT };
539+ static unsigned int bytecode4[] = { vm::OP_START, vm::OP_CONST, 3 , vm::OP_EXEC, 1 , vm::OP_HALT };
540+ static unsigned int bytecode5[] = { vm::OP_START, vm::OP_EXEC, 2 , vm::OP_HALT };
541+ static unsigned int bytecode6[] = { vm::OP_START, vm::OP_EXEC, 3 , vm::OP_HALT };
542+ static BlockFunc functions[] = { &MotionBlocks::goTo, &MotionBlocks::goToByIndex, &MotionBlocks::goToMousePointer, &MotionBlocks::goToRandomPosition };
543+ static Value constValues[] = { " _mouse_" , " _random_" , " Sprite2" , 3 };
544+
545+ Sprite sprite;
546+ sprite.setX (70.1 );
547+ sprite.setY (-100.025 );
548+
549+ Sprite anotherSprite;
550+ anotherSprite.setX (-195.25 );
551+ anotherSprite.setY (148.02 );
552+
553+ VirtualMachine vm (&sprite, &m_engineMock, nullptr );
554+ vm.setFunctions (functions);
555+ vm.setConstValues (constValues);
556+
557+ RandomGeneratorMock rng;
558+ MotionBlocks::rng = &rng;
559+
560+ // go to (join "_mouse_" "")
561+ EXPECT_CALL (m_engineMock, mouseX ()).WillOnce (Return (70.56 ));
562+ EXPECT_CALL (m_engineMock, mouseY ()).WillOnce (Return (45.2 ));
563+
564+ vm.setBytecode (bytecode1);
565+ vm.run ();
566+
567+ ASSERT_EQ (vm.registerCount (), 0 );
568+ ASSERT_EQ (sprite.x (), 70.56 );
569+ ASSERT_EQ (sprite.y (), 45.2 );
570+
571+ // go to (join "_random_" "")
572+ EXPECT_CALL (rng, randint (-240 , 240 )).WillOnce (Return (-158 ));
573+ EXPECT_CALL (rng, randint (-180 , 180 )).WillOnce (Return (65 ));
574+
575+ vm.setBytecode (bytecode2);
576+ vm.run ();
577+
578+ ASSERT_EQ (vm.registerCount (), 0 );
579+ ASSERT_EQ (sprite.x (), -158 );
580+ ASSERT_EQ (sprite.y (), 65 );
581+
582+ // go to (join "Sprite2" "")
583+ EXPECT_CALL (m_engineMock, findTarget (" Sprite2" )).WillOnce (Return (3 ));
584+ EXPECT_CALL (m_engineMock, targetAt (3 )).WillOnce (Return (&anotherSprite));
585+
586+ vm.setBytecode (bytecode3);
587+ vm.run ();
588+
589+ ASSERT_EQ (vm.registerCount (), 0 );
590+ ASSERT_EQ (sprite.x (), anotherSprite.x ());
591+ ASSERT_EQ (sprite.y (), anotherSprite.y ());
592+
593+ // go to (Sprite2)
594+ EXPECT_CALL (m_engineMock, targetAt (3 )).WillOnce (Return (&anotherSprite));
595+
596+ vm.setBytecode (bytecode4);
597+ vm.run ();
598+
599+ ASSERT_EQ (vm.registerCount (), 0 );
600+ ASSERT_EQ (sprite.x (), anotherSprite.x ());
601+ ASSERT_EQ (sprite.y (), anotherSprite.y ());
602+
603+ // go to (mouse-pointer)
604+ EXPECT_CALL (m_engineMock, mouseX ()).WillOnce (Return (-239.92 ));
605+ EXPECT_CALL (m_engineMock, mouseY ()).WillOnce (Return (-170.6 ));
606+
607+ vm.setBytecode (bytecode5);
608+ vm.run ();
609+
610+ ASSERT_EQ (vm.registerCount (), 0 );
611+ ASSERT_EQ (sprite.x (), -239.92 );
612+ ASSERT_EQ (sprite.y (), -170.6 );
613+
614+ // go to (random position)
615+ EXPECT_CALL (rng, randint (-240 , 240 )).WillOnce (Return (220 ));
616+ EXPECT_CALL (rng, randint (-180 , 180 )).WillOnce (Return (-16 ));
617+
618+ vm.setBytecode (bytecode6);
619+ vm.run ();
620+
621+ ASSERT_EQ (vm.registerCount (), 0 );
622+ ASSERT_EQ (sprite.x (), 220 );
623+ ASSERT_EQ (sprite.y (), -16 );
624+ }
0 commit comments