@@ -835,26 +835,41 @@ void LooksBlocks::setCostumeByIndex(Target *target, long index)
835835
836836unsigned int LooksBlocks::switchCostumeTo (VirtualMachine *vm)
837837{
838+ // https://github.com/scratchfoundation/scratch-vm/blob/8dbcc1fc8f8d8c4f1e40629fe8a388149d6dfd1c/src/blocks/scratch3_looks.js#L389-L413
838839 Target *target = vm->target ();
839840
840841 if (!target)
841842 return 1 ;
842843
843844 const Value *name = vm->getInput (0 , 1 );
844- std::string nameStr = name->toString ();
845- int index = target->findCostume (nameStr);
846845
847- if (index == -1 ) {
848- if (nameStr == " next costume" )
846+ if (!name->isString ()) {
847+ // Numbers should be treated as costume indices, always
848+ if (name->isNaN () || name->isInfinity () || name->isNegativeInfinity ())
849+ target->setCostumeIndex (0 );
850+ else
851+ setCostumeByIndex (target, name->toLong () - 1 );
852+ } else {
853+ // Strings should be treated as costume names, where possible
854+ const int costumeIndex = target->findCostume (name->toString ());
855+ std::string nameStr = name->toString ();
856+
857+ auto it = std::find_if (nameStr.begin (), nameStr.end (), [](char c) { return !std::isspace (c); });
858+ bool isWhiteSpace = (it == nameStr.end ());
859+
860+ if (costumeIndex != -1 ) {
861+ setCostumeByIndex (target, costumeIndex);
862+ } else if (nameStr == " next costume" ) {
849863 nextCostume (vm);
850- else if (nameStr == " previous costume" )
864+ } else if (nameStr == " previous costume" ) {
851865 previousCostume (vm);
852- else {
853- if (name->isValidNumber ())
854- setCostumeByIndex (target, name->toLong () - 1 );
866+ // Try to cast the string to a number (and treat it as a costume index)
867+ // Pure whitespace should not be treated as a number
868+ // Note: isNaN will cast the string to a number before checking if it's NaN
869+ } else if (!(name->isNaN () || isWhiteSpace)) {
870+ target->setCostumeIndex (name->toInt () - 1 );
855871 }
856- } else
857- setCostumeByIndex (target, index);
872+ }
858873
859874 return 1 ;
860875}
@@ -885,28 +900,43 @@ void LooksBlocks::startBackdropScripts(VirtualMachine *vm, bool wait)
885900
886901void LooksBlocks::switchBackdropToImpl (VirtualMachine *vm)
887902{
903+ // https://github.com/scratchfoundation/scratch-vm/blob/8dbcc1fc8f8d8c4f1e40629fe8a388149d6dfd1c/src/blocks/scratch3_looks.js#L423-L462
888904 Stage *stage = vm->engine ()->stage ();
889905
890906 if (!stage)
891907 return ;
892908
893909 const Value *name = vm->getInput (0 , 1 );
894- std::string nameStr = name->toString ();
895- int index = stage->findCostume (nameStr);
896910
897- if (index == -1 ) {
898- if (nameStr == " next backdrop" )
911+ if (!name->isString ()) {
912+ // Numbers should be treated as costume indices, always
913+ if (name->isNaN () || name->isInfinity () || name->isNegativeInfinity ())
914+ stage->setCostumeIndex (0 );
915+ else
916+ setCostumeByIndex (stage, name->toLong () - 1 );
917+ } else {
918+ // Strings should be treated as costume names, where possible
919+ const int costumeIndex = stage->findCostume (name->toString ());
920+ std::string nameStr = name->toString ();
921+
922+ auto it = std::find_if (nameStr.begin (), nameStr.end (), [](char c) { return !std::isspace (c); });
923+ bool isWhiteSpace = (it == nameStr.end ());
924+
925+ if (costumeIndex != -1 ) {
926+ setCostumeByIndex (stage, costumeIndex);
927+ } else if (nameStr == " next backdrop" ) {
899928 nextBackdropImpl (vm);
900- else if (nameStr == " previous backdrop" )
929+ } else if (nameStr == " previous backdrop" ) {
901930 previousBackdropImpl (vm);
902- else if (nameStr == " random backdrop" ) {
931+ } else if (nameStr == " random backdrop" ) {
903932 randomBackdropImpl (vm);
904- } else {
905- if (name->isValidNumber ())
906- setCostumeByIndex (stage, name->toLong () - 1 );
933+ // Try to cast the string to a number (and treat it as a costume index)
934+ // Pure whitespace should not be treated as a number
935+ // Note: isNaN will cast the string to a number before checking if it's NaN
936+ } else if (!(name->isNaN () || isWhiteSpace)) {
937+ stage->setCostumeIndex (name->toInt () - 1 );
907938 }
908- } else
909- setCostumeByIndex (stage, index);
939+ }
910940}
911941
912942void LooksBlocks::nextBackdropImpl (VirtualMachine *vm)
0 commit comments