22
33#include < scratchcpp/iengine.h>
44#include < scratchcpp/compiler.h>
5+ #include < scratchcpp/sprite.h>
6+ #include < scratchcpp/input.h>
57#include < scratchcpp/field.h>
8+ #include < scratchcpp/block.h>
69#include < cassert>
710
811#include " controlblocks.h"
@@ -27,6 +30,9 @@ void ControlBlocks::registerBlocks(IEngine *engine)
2730 engine->addCompileFunction (this , " control_stop" , &compileStop);
2831 engine->addCompileFunction (this , " control_wait" , &compileWait);
2932 engine->addCompileFunction (this , " control_wait_until" , &compileWaitUntil);
33+ engine->addCompileFunction (this , " control_start_as_clone" , &compileStartAsClone);
34+ engine->addCompileFunction (this , " control_create_clone_of" , &compileCreateClone);
35+ engine->addCompileFunction (this , " control_delete_this_clone" , &compileDeleteThisClone);
3036
3137 // Inputs
3238 engine->addInput (this , " SUBSTACK" , SUBSTACK);
@@ -35,6 +41,7 @@ void ControlBlocks::registerBlocks(IEngine *engine)
3541 engine->addInput (this , " CONDITION" , CONDITION);
3642 engine->addInput (this , " DURATION" , DURATION);
3743 engine->addInput (this , " VALUE" , VALUE);
44+ engine->addInput (this , " CLONE_OPTION" , CLONE_OPTION);
3845
3946 // Fields
4047 engine->addField (this , " STOP_OPTION" , STOP_OPTION);
@@ -155,6 +162,37 @@ void ControlBlocks::compileWaitUntil(Compiler *compiler)
155162 compiler->addFunctionCall (&waitUntil);
156163}
157164
165+ void ControlBlocks::compileStartAsClone (Compiler *compiler)
166+ {
167+ compiler->engine ()->addCloneInitScript (compiler->block ());
168+ }
169+
170+ void ControlBlocks::compileCreateClone (Compiler *compiler)
171+ {
172+ Input *input = compiler->input (CLONE_OPTION);
173+
174+ if (input->type () != Input::Type::ObscuredShadow) {
175+ assert (input->pointsToDropdownMenu ());
176+ std::string spriteName = input->selectedMenuItem ();
177+
178+ if (spriteName == " _myself_" )
179+ compiler->addFunctionCall (&createCloneOfMyself);
180+ else {
181+ int index = compiler->engine ()->findTarget (spriteName);
182+ compiler->addConstValue (index);
183+ compiler->addFunctionCall (&createCloneByIndex);
184+ }
185+ } else {
186+ compiler->addInput (input);
187+ compiler->addFunctionCall (&createClone);
188+ }
189+ }
190+
191+ void ControlBlocks::compileDeleteThisClone (Compiler *compiler)
192+ {
193+ compiler->addFunctionCall (&deleteThisClone);
194+ }
195+
158196unsigned int ControlBlocks::stopAll (VirtualMachine *vm)
159197{
160198 vm->engine ()->stop ();
@@ -196,3 +234,54 @@ unsigned int ControlBlocks::waitUntil(VirtualMachine *vm)
196234 }
197235 return 1 ;
198236}
237+
238+ unsigned int ControlBlocks::createClone (VirtualMachine *vm)
239+ {
240+ std::string spriteName = vm->getInput (0 , 1 )->toString ();
241+ Target *target;
242+
243+ if (spriteName == " _myself_" )
244+ target = vm->target ();
245+ else
246+ target = vm->engine ()->targetAt (vm->engine ()->findTarget (spriteName));
247+
248+ Sprite *sprite = dynamic_cast <Sprite *>(target);
249+
250+ if (sprite)
251+ sprite->clone ();
252+
253+ return 1 ;
254+ }
255+
256+ unsigned int ControlBlocks::createCloneByIndex (VirtualMachine *vm)
257+ {
258+ Target *target = vm->engine ()->targetAt (vm->getInput (0 , 1 )->toInt ());
259+ Sprite *sprite = dynamic_cast <Sprite *>(target);
260+
261+ if (sprite)
262+ sprite->clone ();
263+
264+ return 1 ;
265+ }
266+
267+ unsigned int ControlBlocks::createCloneOfMyself (VirtualMachine *vm)
268+ {
269+ Sprite *sprite = dynamic_cast <Sprite *>(vm->target ());
270+
271+ if (sprite)
272+ sprite->clone ();
273+
274+ return 0 ;
275+ }
276+
277+ unsigned int ControlBlocks::deleteThisClone (VirtualMachine *vm)
278+ {
279+ Target *target = vm->target ();
280+
281+ if (target) {
282+ vm->engine ()->stopTarget (target, nullptr );
283+ target->~Target ();
284+ }
285+
286+ return 0 ;
287+ }
0 commit comments