33#include < scratchcpp/iengine.h>
44#include < scratchcpp/compiler.h>
55#include < scratchcpp/sprite.h>
6+ #include < scratchcpp/input.h>
67#include < scratchcpp/field.h>
78#include < scratchcpp/costume.h>
89
@@ -23,11 +24,13 @@ void LooksBlocks::registerBlocks(IEngine *engine)
2324 engine->addCompileFunction (this , " looks_changesizeby" , &compileChangeSizeBy);
2425 engine->addCompileFunction (this , " looks_setsizeto" , &compileSetSizeTo);
2526 engine->addCompileFunction (this , " looks_size" , &compileSize);
27+ engine->addCompileFunction (this , " looks_switchcostumeto" , &compileSwitchCostumeTo);
2628 engine->addCompileFunction (this , " looks_costumenumbername" , &compileCostumeNumberName);
2729
2830 // Inputs
2931 engine->addInput (this , " CHANGE" , CHANGE);
3032 engine->addInput (this , " SIZE" , SIZE);
33+ engine->addInput (this , " COSTUME" , COSTUME);
3134
3235 // Fields
3336 engine->addField (this , " NUMBER_NAME" , NUMBER_NAME);
@@ -64,6 +67,43 @@ void LooksBlocks::compileSize(Compiler *compiler)
6467 compiler->addFunctionCall (&size);
6568}
6669
70+ void LooksBlocks::compileSwitchCostumeTo (Compiler *compiler)
71+ {
72+ Target *target = compiler->target ();
73+
74+ if (!target)
75+ return ;
76+
77+ Input *input = compiler->input (COSTUME);
78+
79+ if (input->type () != Input::Type::ObscuredShadow) {
80+ assert (input->pointsToDropdownMenu ());
81+ std::string value = input->selectedMenuItem ();
82+ int index = target->findCostume (value);
83+
84+ if (index == -1 ) {
85+ if (value == " next costume" )
86+ compiler->addFunctionCall (&nextCostume);
87+ else if (value == " previous costume" )
88+ compiler->addFunctionCall (&previousCostume);
89+ else {
90+ Value v (value);
91+
92+ if (v.type () == Value::Type::Integer) {
93+ compiler->addConstValue (v.toLong () - 1 );
94+ compiler->addFunctionCall (&switchCostumeToByIndex);
95+ }
96+ }
97+ } else {
98+ compiler->addConstValue (index);
99+ compiler->addFunctionCall (&switchCostumeToByIndex);
100+ }
101+ } else {
102+ compiler->addInput (input);
103+ compiler->addFunctionCall (&switchCostumeTo);
104+ }
105+ }
106+
67107void LooksBlocks::compileCostumeNumberName (Compiler *compiler)
68108{
69109 int option = compiler->field (NUMBER_NAME)->specialValueId ();
@@ -131,6 +171,70 @@ unsigned int LooksBlocks::size(VirtualMachine *vm)
131171 return 0 ;
132172}
133173
174+ void LooksBlocks::setCostumeByIndex (Target *target, long index)
175+ {
176+ // TODO: Remove this (#248)
177+ std::size_t costumeCount = target->costumes ().size ();
178+ if (index < 0 || index >= costumeCount) {
179+ if (index < 0 )
180+ index = std::fmod (costumeCount + std::fmod (index, -costumeCount), costumeCount);
181+ else
182+ index = std::fmod (index, costumeCount);
183+ }
184+
185+ target->setCurrentCostume (index + 1 );
186+ }
187+
188+ unsigned int LooksBlocks::switchCostumeToByIndex (VirtualMachine *vm)
189+ {
190+ if (Target *target = vm->target ())
191+ setCostumeByIndex (target, vm->getInput (0 , 1 )->toLong ());
192+
193+ return 1 ;
194+ }
195+
196+ unsigned int LooksBlocks::switchCostumeTo (VirtualMachine *vm)
197+ {
198+ Target *target = vm->target ();
199+
200+ if (!target)
201+ return 1 ;
202+
203+ const Value *name = vm->getInput (0 , 1 );
204+ std::string nameStr = name->toString ();
205+ int index = target->findCostume (nameStr);
206+
207+ if (index == -1 ) {
208+ if (nameStr == " next costume" )
209+ nextCostume (vm);
210+ else if (nameStr == " previous costume" )
211+ previousCostume (vm);
212+ else {
213+ if (name->type () == Value::Type::Integer)
214+ setCostumeByIndex (target, name->toLong () - 1 );
215+ }
216+ } else
217+ setCostumeByIndex (target, index);
218+
219+ return 1 ;
220+ }
221+
222+ unsigned int LooksBlocks::nextCostume (VirtualMachine *vm)
223+ {
224+ if (Target *target = vm->target ())
225+ setCostumeByIndex (target, target->currentCostume ());
226+
227+ return 0 ;
228+ }
229+
230+ unsigned int LooksBlocks::previousCostume (VirtualMachine *vm)
231+ {
232+ if (Target *target = vm->target ())
233+ setCostumeByIndex (target, target->currentCostume () - 2 );
234+
235+ return 0 ;
236+ }
237+
134238unsigned int LooksBlocks::costumeNumber (VirtualMachine *vm)
135239{
136240 if (Target *target = vm->target ())
0 commit comments