77#include < scratchcpp/input.h>
88#include < scratchcpp/field.h>
99#include < scratchcpp/sprite.h>
10+ #include < scratchcpp/stage.h>
11+ #include < scratchcpp/costume.h>
1012#include " sensingblocks.h"
1113
1214#include " ../engine/internal/clock.h"
@@ -31,16 +33,19 @@ void SensingBlocks::registerBlocks(IEngine *engine)
3133 engine->addCompileFunction (this , " sensing_setdragmode" , &compileSetDragMode);
3234 engine->addCompileFunction (this , " sensing_timer" , &compileTimer);
3335 engine->addCompileFunction (this , " sensing_resettimer" , &compileResetTimer);
36+ engine->addCompileFunction (this , " sensing_of" , &compileOf);
3437 engine->addCompileFunction (this , " sensing_current" , &compileCurrent);
3538 engine->addCompileFunction (this , " sensing_dayssince2000" , &compileDaysSince2000);
3639
3740 // Inputs
3841 engine->addInput (this , " DISTANCETOMENU" , DISTANCETOMENU);
3942 engine->addInput (this , " KEY_OPTION" , KEY_OPTION);
43+ engine->addInput (this , " OBJECT" , OBJECT);
4044
4145 // Fields
4246 engine->addField (this , " CURRENTMENU" , CURRENTMENU);
4347 engine->addField (this , " DRAG_MODE" , DRAG_MODE);
48+ engine->addField (this , " PROPERTY" , PROPERTY);
4449
4550 // Field values
4651 engine->addFieldValue (this , " YEAR" , YEAR);
@@ -52,6 +57,16 @@ void SensingBlocks::registerBlocks(IEngine *engine)
5257 engine->addFieldValue (this , " SECOND" , SECOND);
5358 engine->addFieldValue (this , " draggable" , Draggable);
5459 engine->addFieldValue (this , " not draggable" , NotDraggable);
60+ engine->addFieldValue (this , " x position" , XPosition);
61+ engine->addFieldValue (this , " y position" , YPosition);
62+ engine->addFieldValue (this , " direction" , Direction);
63+ engine->addFieldValue (this , " costume #" , CostumeNumber);
64+ engine->addFieldValue (this , " costume name" , CostumeName);
65+ engine->addFieldValue (this , " size" , Size);
66+ engine->addFieldValue (this , " volume" , Volume);
67+ engine->addFieldValue (this , " background #" , BackdropNumber); // Scratch 1.4 support
68+ engine->addFieldValue (this , " backdrop #" , BackdropNumber);
69+ engine->addFieldValue (this , " backdrop name" , BackdropName);
5570}
5671
5772void SensingBlocks::compileDistanceTo (Compiler *compiler)
@@ -124,6 +139,111 @@ void SensingBlocks::compileResetTimer(Compiler *compiler)
124139 compiler->addFunctionCall (&resetTimer);
125140}
126141
142+ void SensingBlocks::compileOf (Compiler *compiler)
143+ {
144+ int option = compiler->field (PROPERTY)->specialValueId ();
145+ Input *input = compiler->input (OBJECT);
146+ BlockFunc f = nullptr ;
147+
148+ if (input->type () != Input::Type::ObscuredShadow) {
149+ assert (input->pointsToDropdownMenu ());
150+ std::string value = input->selectedMenuItem ();
151+
152+ int index = compiler->engine ()->findTarget (value);
153+
154+ switch (option) {
155+ case XPosition:
156+ f = &xPositionOfSpriteByIndex;
157+ break ;
158+
159+ case YPosition:
160+ f = &yPositionOfSpriteByIndex;
161+ break ;
162+
163+ case Direction:
164+ f = &directionOfSpriteByIndex;
165+ break ;
166+
167+ case CostumeNumber:
168+ f = &costumeNumberOfSpriteByIndex;
169+ break ;
170+
171+ case CostumeName:
172+ f = &costumeNameOfSpriteByIndex;
173+ break ;
174+
175+ case Size:
176+ f = &sizeOfSpriteByIndex;
177+ break ;
178+
179+ case Volume:
180+ f = &volumeOfTargetByIndex;
181+ break ;
182+
183+ case BackdropNumber:
184+ f = &backdropNumberOfStageByIndex;
185+ break ;
186+
187+ case BackdropName:
188+ f = &backdropNameOfStageByIndex;
189+ break ;
190+
191+ default :
192+ break ;
193+ }
194+
195+ if (f)
196+ compiler->addConstValue (index);
197+ } else {
198+ switch (option) {
199+ case XPosition:
200+ f = &xPositionOfSprite;
201+ break ;
202+
203+ case YPosition:
204+ f = &yPositionOfSprite;
205+ break ;
206+
207+ case Direction:
208+ f = &directionOfSprite;
209+ break ;
210+
211+ case CostumeNumber:
212+ f = &costumeNumberOfSprite;
213+ break ;
214+
215+ case CostumeName:
216+ f = &costumeNameOfSprite;
217+ break ;
218+
219+ case Size:
220+ f = &sizeOfSprite;
221+ break ;
222+
223+ case Volume:
224+ f = &volumeOfTarget;
225+ break ;
226+
227+ case BackdropNumber:
228+ f = &backdropNumberOfStage;
229+ break ;
230+
231+ case BackdropName:
232+ f = &backdropNameOfStage;
233+ break ;
234+
235+ default :
236+ break ;
237+ }
238+
239+ if (f)
240+ compiler->addInput (input);
241+ }
242+
243+ if (f)
244+ compiler->addFunctionCall (f);
245+ }
246+
127247void SensingBlocks::compileCurrent (Compiler *compiler)
128248{
129249 int id = compiler->field (CURRENTMENU)->specialValueId ();
@@ -271,6 +391,238 @@ unsigned int SensingBlocks::resetTimer(VirtualMachine *vm)
271391 return 0 ;
272392}
273393
394+ unsigned int SensingBlocks::xPositionOfSprite (VirtualMachine *vm)
395+ {
396+ Target *target = vm->engine ()->targetAt (vm->engine ()->findTarget (vm->getInput (0 , 1 )->toString ()));
397+ Sprite *sprite = dynamic_cast <Sprite *>(target);
398+
399+ if (sprite)
400+ vm->replaceReturnValue (sprite->x (), 1 );
401+ else
402+ vm->replaceReturnValue (0 , 1 );
403+
404+ return 0 ;
405+ }
406+
407+ unsigned int SensingBlocks::xPositionOfSpriteByIndex (VirtualMachine *vm)
408+ {
409+ Target *target = vm->engine ()->targetAt (vm->getInput (0 , 1 )->toInt ());
410+ Sprite *sprite = dynamic_cast <Sprite *>(target);
411+
412+ if (sprite)
413+ vm->replaceReturnValue (sprite->x (), 1 );
414+ else
415+ vm->replaceReturnValue (0 , 1 );
416+
417+ return 0 ;
418+ }
419+
420+ unsigned int SensingBlocks::yPositionOfSprite (VirtualMachine *vm)
421+ {
422+ Target *target = vm->engine ()->targetAt (vm->engine ()->findTarget (vm->getInput (0 , 1 )->toString ()));
423+ Sprite *sprite = dynamic_cast <Sprite *>(target);
424+
425+ if (sprite)
426+ vm->replaceReturnValue (sprite->y (), 1 );
427+ else
428+ vm->replaceReturnValue (0 , 1 );
429+
430+ return 0 ;
431+ }
432+
433+ unsigned int SensingBlocks::yPositionOfSpriteByIndex (VirtualMachine *vm)
434+ {
435+ Target *target = vm->engine ()->targetAt (vm->getInput (0 , 1 )->toInt ());
436+ Sprite *sprite = dynamic_cast <Sprite *>(target);
437+
438+ if (sprite)
439+ vm->replaceReturnValue (sprite->y (), 1 );
440+ else
441+ vm->replaceReturnValue (0 , 1 );
442+
443+ return 0 ;
444+ }
445+
446+ unsigned int SensingBlocks::directionOfSprite (VirtualMachine *vm)
447+ {
448+ Target *target = vm->engine ()->targetAt (vm->engine ()->findTarget (vm->getInput (0 , 1 )->toString ()));
449+ Sprite *sprite = dynamic_cast <Sprite *>(target);
450+
451+ if (sprite)
452+ vm->replaceReturnValue (sprite->direction (), 1 );
453+ else
454+ vm->replaceReturnValue (0 , 1 );
455+
456+ return 0 ;
457+ }
458+
459+ unsigned int SensingBlocks::directionOfSpriteByIndex (VirtualMachine *vm)
460+ {
461+ Target *target = vm->engine ()->targetAt (vm->getInput (0 , 1 )->toInt ());
462+ Sprite *sprite = dynamic_cast <Sprite *>(target);
463+
464+ if (sprite)
465+ vm->replaceReturnValue (sprite->direction (), 1 );
466+ else
467+ vm->replaceReturnValue (0 , 1 );
468+
469+ return 0 ;
470+ }
471+
472+ unsigned int SensingBlocks::costumeNumberOfSprite (VirtualMachine *vm)
473+ {
474+ Target *target = vm->engine ()->targetAt (vm->engine ()->findTarget (vm->getInput (0 , 1 )->toString ()));
475+ Sprite *sprite = dynamic_cast <Sprite *>(target);
476+
477+ if (sprite)
478+ vm->replaceReturnValue (sprite->currentCostume (), 1 );
479+ else
480+ vm->replaceReturnValue (0 , 1 );
481+
482+ return 0 ;
483+ }
484+
485+ unsigned int SensingBlocks::costumeNumberOfSpriteByIndex (VirtualMachine *vm)
486+ {
487+ Target *target = vm->engine ()->targetAt (vm->getInput (0 , 1 )->toInt ());
488+ Sprite *sprite = dynamic_cast <Sprite *>(target);
489+
490+ if (sprite)
491+ vm->replaceReturnValue (sprite->currentCostume (), 1 );
492+ else
493+ vm->replaceReturnValue (0 , 1 );
494+
495+ return 0 ;
496+ }
497+
498+ unsigned int SensingBlocks::costumeNameOfSprite (VirtualMachine *vm)
499+ {
500+ Target *target = vm->engine ()->targetAt (vm->engine ()->findTarget (vm->getInput (0 , 1 )->toString ()));
501+ Sprite *sprite = dynamic_cast <Sprite *>(target);
502+
503+ if (sprite)
504+ vm->replaceReturnValue (sprite->costumeAt (sprite->currentCostume () - 1 )->name (), 1 );
505+ else
506+ vm->replaceReturnValue (0 , 1 );
507+
508+ return 0 ;
509+ }
510+
511+ unsigned int SensingBlocks::costumeNameOfSpriteByIndex (VirtualMachine *vm)
512+ {
513+ Target *target = vm->engine ()->targetAt (vm->getInput (0 , 1 )->toInt ());
514+ Sprite *sprite = dynamic_cast <Sprite *>(target);
515+
516+ if (sprite)
517+ vm->replaceReturnValue (sprite->costumeAt (sprite->currentCostume () - 1 )->name (), 1 );
518+ else
519+ vm->replaceReturnValue (0 , 1 );
520+
521+ return 0 ;
522+ }
523+
524+ unsigned int SensingBlocks::sizeOfSprite (VirtualMachine *vm)
525+ {
526+ Target *target = vm->engine ()->targetAt (vm->engine ()->findTarget (vm->getInput (0 , 1 )->toString ()));
527+ Sprite *sprite = dynamic_cast <Sprite *>(target);
528+
529+ if (sprite)
530+ vm->replaceReturnValue (sprite->size (), 1 );
531+ else
532+ vm->replaceReturnValue (0 , 1 );
533+
534+ return 0 ;
535+ }
536+
537+ unsigned int SensingBlocks::sizeOfSpriteByIndex (VirtualMachine *vm)
538+ {
539+ Target *target = vm->engine ()->targetAt (vm->getInput (0 , 1 )->toInt ());
540+ Sprite *sprite = dynamic_cast <Sprite *>(target);
541+
542+ if (sprite)
543+ vm->replaceReturnValue (sprite->size (), 1 );
544+ else
545+ vm->replaceReturnValue (0 , 1 );
546+
547+ return 0 ;
548+ }
549+
550+ unsigned int SensingBlocks::volumeOfTarget (VirtualMachine *vm)
551+ {
552+ Target *target = vm->engine ()->targetAt (vm->engine ()->findTarget (vm->getInput (0 , 1 )->toString ()));
553+
554+ if (target)
555+ vm->replaceReturnValue (target->volume (), 1 );
556+ else
557+ vm->replaceReturnValue (0 , 1 );
558+
559+ return 0 ;
560+ }
561+
562+ unsigned int SensingBlocks::volumeOfTargetByIndex (VirtualMachine *vm)
563+ {
564+ Target *target = vm->engine ()->targetAt (vm->getInput (0 , 1 )->toInt ());
565+
566+ if (target)
567+ vm->replaceReturnValue (target->volume (), 1 );
568+ else
569+ vm->replaceReturnValue (0 , 1 );
570+
571+ return 0 ;
572+ }
573+
574+ unsigned int SensingBlocks::backdropNumberOfStage (VirtualMachine *vm)
575+ {
576+ Target *target = vm->engine ()->targetAt (vm->engine ()->findTarget (vm->getInput (0 , 1 )->toString ()));
577+ Stage *stage = dynamic_cast <Stage *>(target);
578+
579+ if (stage)
580+ vm->replaceReturnValue (stage->currentCostume (), 1 );
581+ else
582+ vm->replaceReturnValue (0 , 1 );
583+
584+ return 0 ;
585+ }
586+
587+ unsigned int SensingBlocks::backdropNumberOfStageByIndex (VirtualMachine *vm)
588+ {
589+ Target *target = vm->engine ()->targetAt (vm->getInput (0 , 1 )->toInt ());
590+ Stage *stage = dynamic_cast <Stage *>(target);
591+
592+ if (stage)
593+ vm->replaceReturnValue (stage->currentCostume (), 1 );
594+ else
595+ vm->replaceReturnValue (0 , 1 );
596+
597+ return 0 ;
598+ }
599+
600+ unsigned int SensingBlocks::backdropNameOfStage (VirtualMachine *vm)
601+ {
602+ Target *target = vm->engine ()->targetAt (vm->engine ()->findTarget (vm->getInput (0 , 1 )->toString ()));
603+ Stage *stage = dynamic_cast <Stage *>(target);
604+
605+ if (stage)
606+ vm->replaceReturnValue (stage->costumeAt (stage->currentCostume () - 1 )->name (), 1 );
607+ else
608+ vm->replaceReturnValue (0 , 1 );
609+
610+ return 0 ;
611+ }
612+
613+ unsigned int SensingBlocks::backdropNameOfStageByIndex (VirtualMachine *vm)
614+ {
615+ Target *target = vm->engine ()->targetAt (vm->getInput (0 , 1 )->toInt ());
616+ Stage *stage = dynamic_cast <Stage *>(target);
617+
618+ if (stage)
619+ vm->replaceReturnValue (stage->costumeAt (stage->currentCostume () - 1 )->name (), 1 );
620+ else
621+ vm->replaceReturnValue (0 , 1 );
622+
623+ return 0 ;
624+ }
625+
274626unsigned int SensingBlocks::currentYear (VirtualMachine *vm)
275627{
276628 time_t now = time (0 );
0 commit comments