Skip to content

Commit 4cd26f7

Browse files
authored
Merge pull request #270 from scratchcpp/implement_sensing_of_block
Implement "of" sensing block
2 parents 4b2d8ec + aa74f4a commit 4cd26f7

File tree

3 files changed

+980
-3
lines changed

3 files changed

+980
-3
lines changed

src/blocks/sensingblocks.cpp

Lines changed: 352 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
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

5772
void 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+
127247
void 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+
274626
unsigned int SensingBlocks::currentYear(VirtualMachine *vm)
275627
{
276628
time_t now = time(0);

0 commit comments

Comments
 (0)