Skip to content

Commit c833386

Browse files
committed
Implement looks_switchbackdropto block
1 parent 1fddc53 commit c833386

File tree

3 files changed

+644
-1
lines changed

3 files changed

+644
-1
lines changed

src/blocks/looksblocks.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@
33
#include <scratchcpp/iengine.h>
44
#include <scratchcpp/compiler.h>
55
#include <scratchcpp/sprite.h>
6+
#include <scratchcpp/stage.h>
67
#include <scratchcpp/input.h>
78
#include <scratchcpp/field.h>
89
#include <scratchcpp/costume.h>
910

1011
#include "looksblocks.h"
12+
#include "../engine/internal/randomgenerator.h"
1113

1214
using namespace libscratchcpp;
1315

16+
IRandomGenerator *LooksBlocks::rng = nullptr;
17+
1418
std::string LooksBlocks::name() const
1519
{
1620
return "Looks";
@@ -26,12 +30,14 @@ void LooksBlocks::registerBlocks(IEngine *engine)
2630
engine->addCompileFunction(this, "looks_size", &compileSize);
2731
engine->addCompileFunction(this, "looks_switchcostumeto", &compileSwitchCostumeTo);
2832
engine->addCompileFunction(this, "looks_nextcostume", &compileNextCostume);
33+
engine->addCompileFunction(this, "looks_switchbackdropto", &compileSwitchBackdropTo);
2934
engine->addCompileFunction(this, "looks_costumenumbername", &compileCostumeNumberName);
3035

3136
// Inputs
3237
engine->addInput(this, "CHANGE", CHANGE);
3338
engine->addInput(this, "SIZE", SIZE);
3439
engine->addInput(this, "COSTUME", COSTUME);
40+
engine->addInput(this, "BACKDROP", BACKDROP);
3541

3642
// Fields
3743
engine->addField(this, "NUMBER_NAME", NUMBER_NAME);
@@ -110,6 +116,45 @@ void LooksBlocks::compileNextCostume(Compiler *compiler)
110116
compiler->addFunctionCall(&nextCostume);
111117
}
112118

119+
void LooksBlocks::compileSwitchBackdropTo(Compiler *compiler)
120+
{
121+
Stage *stage = compiler->engine()->stage();
122+
123+
if (!stage)
124+
return;
125+
126+
Input *input = compiler->input(BACKDROP);
127+
128+
if (input->type() != Input::Type::ObscuredShadow) {
129+
assert(input->pointsToDropdownMenu());
130+
std::string value = input->selectedMenuItem();
131+
int index = stage->findCostume(value);
132+
133+
if (index == -1) {
134+
if (value == "next backdrop")
135+
compiler->addFunctionCall(&nextBackdrop);
136+
else if (value == "previous backdrop")
137+
compiler->addFunctionCall(&previousBackdrop);
138+
else if (value == "random backdrop")
139+
compiler->addFunctionCall(&randomBackdrop);
140+
else {
141+
Value v(value);
142+
143+
if (v.type() == Value::Type::Integer) {
144+
compiler->addConstValue(v.toLong() - 1);
145+
compiler->addFunctionCall(&switchBackdropToByIndex);
146+
}
147+
}
148+
} else {
149+
compiler->addConstValue(index);
150+
compiler->addFunctionCall(&switchBackdropToByIndex);
151+
}
152+
} else {
153+
compiler->addInput(input);
154+
compiler->addFunctionCall(&switchBackdropTo);
155+
}
156+
}
157+
113158
void LooksBlocks::compileCostumeNumberName(Compiler *compiler)
114159
{
115160
int option = compiler->field(NUMBER_NAME)->specialValueId();
@@ -241,6 +286,73 @@ unsigned int LooksBlocks::previousCostume(VirtualMachine *vm)
241286
return 0;
242287
}
243288

289+
unsigned int LooksBlocks::switchBackdropToByIndex(VirtualMachine *vm)
290+
{
291+
if (Stage *stage = vm->engine()->stage())
292+
setCostumeByIndex(stage, vm->getInput(0, 1)->toLong());
293+
294+
return 1;
295+
}
296+
297+
unsigned int LooksBlocks::switchBackdropTo(VirtualMachine *vm)
298+
{
299+
Stage *stage = vm->engine()->stage();
300+
301+
if (!stage)
302+
return 1;
303+
304+
const Value *name = vm->getInput(0, 1);
305+
std::string nameStr = name->toString();
306+
int index = stage->findCostume(nameStr);
307+
308+
if (index == -1) {
309+
if (nameStr == "next backdrop")
310+
nextBackdrop(vm);
311+
else if (nameStr == "previous backdrop")
312+
previousBackdrop(vm);
313+
else if (nameStr == "random backdrop") {
314+
randomBackdrop(vm);
315+
} else {
316+
if (name->type() == Value::Type::Integer)
317+
setCostumeByIndex(stage, name->toLong() - 1);
318+
}
319+
} else
320+
setCostumeByIndex(stage, index);
321+
322+
return 1;
323+
}
324+
325+
unsigned int LooksBlocks::nextBackdrop(VirtualMachine *vm)
326+
{
327+
if (Stage *stage = vm->engine()->stage())
328+
setCostumeByIndex(stage, stage->currentCostume());
329+
330+
return 0;
331+
}
332+
333+
unsigned int LooksBlocks::previousBackdrop(VirtualMachine *vm)
334+
{
335+
if (Stage *stage = vm->engine()->stage())
336+
setCostumeByIndex(stage, stage->currentCostume() - 2);
337+
338+
return 0;
339+
}
340+
341+
unsigned int LooksBlocks::randomBackdrop(VirtualMachine *vm)
342+
{
343+
if (!rng)
344+
rng = RandomGenerator::instance().get();
345+
346+
if (Stage *stage = vm->engine()->stage()) {
347+
std::size_t count = stage->costumes().size();
348+
349+
if (count > 0)
350+
stage->setCurrentCostume(rng->randint(1, count));
351+
}
352+
353+
return 0;
354+
}
355+
244356
unsigned int LooksBlocks::costumeNumber(VirtualMachine *vm)
245357
{
246358
if (Target *target = vm->target())

src/blocks/looksblocks.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace libscratchcpp
88
{
99

1010
class Target;
11+
class IRandomGenerator;
1112

1213
/*! \brief The LooksBlocks class contains the implementation of looks blocks. */
1314
class LooksBlocks : public IBlockSection
@@ -17,7 +18,8 @@ class LooksBlocks : public IBlockSection
1718
{
1819
CHANGE,
1920
SIZE,
20-
COSTUME
21+
COSTUME,
22+
BACKDROP
2123
};
2224

2325
enum Fields
@@ -42,6 +44,7 @@ class LooksBlocks : public IBlockSection
4244
static void compileSize(Compiler *compiler);
4345
static void compileSwitchCostumeTo(Compiler *compiler);
4446
static void compileNextCostume(Compiler *compiler);
47+
static void compileSwitchBackdropTo(Compiler *compiler);
4548
static void compileCostumeNumberName(Compiler *compiler);
4649

4750
static unsigned int show(VirtualMachine *vm);
@@ -56,8 +59,16 @@ class LooksBlocks : public IBlockSection
5659
static unsigned int nextCostume(VirtualMachine *vm);
5760
static unsigned int previousCostume(VirtualMachine *vm);
5861

62+
static unsigned int switchBackdropToByIndex(VirtualMachine *vm);
63+
static unsigned int switchBackdropTo(VirtualMachine *vm);
64+
static unsigned int nextBackdrop(VirtualMachine *vm);
65+
static unsigned int previousBackdrop(VirtualMachine *vm);
66+
static unsigned int randomBackdrop(VirtualMachine *vm);
67+
5968
static unsigned int costumeNumber(VirtualMachine *vm);
6069
static unsigned int costumeName(VirtualMachine *vm);
70+
71+
static IRandomGenerator *rng;
6172
};
6273

6374
} // namespace libscratchcpp

0 commit comments

Comments
 (0)