2017-04-17 15:10:04 -04:00
|
|
|
const Cast = require('../util/cast');
|
2016-09-08 09:40:27 -04:00
|
|
|
|
2017-04-17 15:10:04 -04:00
|
|
|
const Scratch3LooksBlocks = function (runtime) {
|
2016-06-30 00:11:47 -04:00
|
|
|
/**
|
|
|
|
* The runtime instantiating this block package.
|
|
|
|
* @type {Runtime}
|
|
|
|
*/
|
|
|
|
this.runtime = runtime;
|
2016-10-23 17:55:31 -04:00
|
|
|
};
|
2016-06-30 00:11:47 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve the block primitives implemented by this package.
|
2017-02-01 15:59:50 -05:00
|
|
|
* @return {object.<string, Function>} Mapping of opcode to Function.
|
2016-06-30 00:11:47 -04:00
|
|
|
*/
|
2016-10-23 12:41:45 -04:00
|
|
|
Scratch3LooksBlocks.prototype.getPrimitives = function () {
|
2016-06-30 00:11:47 -04:00
|
|
|
return {
|
2016-10-24 11:02:19 -04:00
|
|
|
looks_say: this.say,
|
|
|
|
looks_sayforsecs: this.sayforsecs,
|
|
|
|
looks_think: this.think,
|
|
|
|
looks_thinkforsecs: this.sayforsecs,
|
|
|
|
looks_show: this.show,
|
|
|
|
looks_hide: this.hide,
|
|
|
|
looks_switchcostumeto: this.switchCostume,
|
|
|
|
looks_switchbackdropto: this.switchBackdrop,
|
|
|
|
looks_switchbackdroptoandwait: this.switchBackdropAndWait,
|
|
|
|
looks_nextcostume: this.nextCostume,
|
|
|
|
looks_nextbackdrop: this.nextBackdrop,
|
|
|
|
looks_changeeffectby: this.changeEffect,
|
|
|
|
looks_seteffectto: this.setEffect,
|
|
|
|
looks_cleargraphiceffects: this.clearEffects,
|
|
|
|
looks_changesizeby: this.changeSize,
|
|
|
|
looks_setsizeto: this.setSize,
|
|
|
|
looks_gotofront: this.goToFront,
|
|
|
|
looks_gobacklayers: this.goBackLayers,
|
|
|
|
looks_size: this.getSize,
|
|
|
|
looks_costumeorder: this.getCostumeIndex,
|
|
|
|
looks_backdroporder: this.getBackdropIndex,
|
|
|
|
looks_backdropname: this.getBackdropName
|
2016-06-30 00:11:47 -04:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2016-07-06 13:47:32 -04:00
|
|
|
Scratch3LooksBlocks.prototype.say = function (args, util) {
|
|
|
|
util.target.setSay('say', args.MESSAGE);
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.sayforsecs = function (args, util) {
|
|
|
|
util.target.setSay('say', args.MESSAGE);
|
2017-04-17 15:10:04 -04:00
|
|
|
return new Promise(resolve => {
|
|
|
|
setTimeout(() => {
|
2016-07-06 13:47:32 -04:00
|
|
|
// Clear say bubble and proceed.
|
|
|
|
util.target.setSay();
|
|
|
|
resolve();
|
|
|
|
}, 1000 * args.SECS);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.think = function (args, util) {
|
|
|
|
util.target.setSay('think', args.MESSAGE);
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.thinkforsecs = function (args, util) {
|
|
|
|
util.target.setSay('think', args.MESSAGE);
|
2017-04-17 15:10:04 -04:00
|
|
|
return new Promise(resolve => {
|
|
|
|
setTimeout(() => {
|
2016-07-06 13:47:32 -04:00
|
|
|
// Clear say bubble and proceed.
|
|
|
|
util.target.setSay();
|
|
|
|
resolve();
|
|
|
|
}, 1000 * args.SECS);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2016-07-01 12:56:59 -04:00
|
|
|
Scratch3LooksBlocks.prototype.show = function (args, util) {
|
|
|
|
util.target.setVisible(true);
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.hide = function (args, util) {
|
|
|
|
util.target.setVisible(false);
|
|
|
|
};
|
|
|
|
|
2016-09-08 09:40:27 -04:00
|
|
|
/**
|
|
|
|
* Utility function to set the costume or backdrop of a target.
|
|
|
|
* Matches the behavior of Scratch 2.0 for different types of arguments.
|
|
|
|
* @param {!Target} target Target to set costume/backdrop to.
|
|
|
|
* @param {Any} requestedCostume Costume requested, e.g., 0, 'name', etc.
|
2016-10-23 17:55:31 -04:00
|
|
|
* @param {boolean=} optZeroIndex Set to zero-index the requestedCostume.
|
2016-09-08 09:40:27 -04:00
|
|
|
* @return {Array.<!Thread>} Any threads started by this switch.
|
|
|
|
*/
|
|
|
|
Scratch3LooksBlocks.prototype._setCostumeOrBackdrop = function (target,
|
2016-10-23 17:55:31 -04:00
|
|
|
requestedCostume, optZeroIndex) {
|
2016-09-08 09:40:27 -04:00
|
|
|
if (typeof requestedCostume === 'number') {
|
2016-10-23 17:55:31 -04:00
|
|
|
target.setCostume(optZeroIndex ?
|
2016-09-08 09:40:27 -04:00
|
|
|
requestedCostume : requestedCostume - 1);
|
|
|
|
} else {
|
2017-04-17 15:10:04 -04:00
|
|
|
const costumeIndex = target.getCostumeIndexByName(requestedCostume);
|
2016-09-08 09:40:27 -04:00
|
|
|
if (costumeIndex > -1) {
|
|
|
|
target.setCostume(costumeIndex);
|
2016-11-09 11:22:17 -05:00
|
|
|
} else if (requestedCostume === 'previous costume' ||
|
|
|
|
requestedCostume === 'previous backdrop') {
|
2016-09-08 09:40:27 -04:00
|
|
|
target.setCostume(target.currentCostume - 1);
|
2016-11-09 11:22:17 -05:00
|
|
|
} else if (requestedCostume === 'next costume' ||
|
|
|
|
requestedCostume === 'next backdrop') {
|
2016-09-08 09:40:27 -04:00
|
|
|
target.setCostume(target.currentCostume + 1);
|
|
|
|
} else {
|
2017-04-17 15:10:04 -04:00
|
|
|
const forcedNumber = Number(requestedCostume);
|
2016-09-08 09:40:27 -04:00
|
|
|
if (!isNaN(forcedNumber)) {
|
2016-10-23 17:55:31 -04:00
|
|
|
target.setCostume(optZeroIndex ?
|
2016-09-08 09:40:27 -04:00
|
|
|
forcedNumber : forcedNumber - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-10-23 17:55:31 -04:00
|
|
|
if (target === this.runtime.getTargetForStage()) {
|
2016-09-08 09:40:27 -04:00
|
|
|
// Target is the stage - start hats.
|
2017-04-17 15:10:04 -04:00
|
|
|
const newName = target.sprite.costumes[target.currentCostume].name;
|
2016-09-08 09:40:27 -04:00
|
|
|
return this.runtime.startHats('event_whenbackdropswitchesto', {
|
2016-10-24 11:02:19 -04:00
|
|
|
BACKDROP: newName
|
2016-09-08 09:40:27 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
return [];
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.switchCostume = function (args, util) {
|
|
|
|
this._setCostumeOrBackdrop(util.target, args.COSTUME);
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.nextCostume = function (args, util) {
|
|
|
|
this._setCostumeOrBackdrop(
|
|
|
|
util.target, util.target.currentCostume + 1, true
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.switchBackdrop = function (args) {
|
|
|
|
this._setCostumeOrBackdrop(this.runtime.getTargetForStage(), args.BACKDROP);
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.switchBackdropAndWait = function (args, util) {
|
|
|
|
// Have we run before, starting threads?
|
|
|
|
if (!util.stackFrame.startedThreads) {
|
|
|
|
// No - switch the backdrop.
|
|
|
|
util.stackFrame.startedThreads = (
|
|
|
|
this._setCostumeOrBackdrop(
|
|
|
|
this.runtime.getTargetForStage(),
|
|
|
|
args.BACKDROP
|
|
|
|
)
|
|
|
|
);
|
2016-10-23 17:55:31 -04:00
|
|
|
if (util.stackFrame.startedThreads.length === 0) {
|
2016-09-08 09:40:27 -04:00
|
|
|
// Nothing was started.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// We've run before; check if the wait is still going on.
|
2017-04-17 15:10:04 -04:00
|
|
|
const instance = this;
|
|
|
|
const waiting = util.stackFrame.startedThreads.some(thread => instance.runtime.isActiveThread(thread));
|
2016-09-08 09:40:27 -04:00
|
|
|
if (waiting) {
|
2016-10-17 23:23:16 -04:00
|
|
|
util.yield();
|
2016-09-08 09:40:27 -04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.nextBackdrop = function () {
|
2017-04-17 15:10:04 -04:00
|
|
|
const stage = this.runtime.getTargetForStage();
|
2016-09-08 09:40:27 -04:00
|
|
|
this._setCostumeOrBackdrop(
|
|
|
|
stage, stage.currentCostume + 1, true
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2016-06-30 00:11:47 -04:00
|
|
|
Scratch3LooksBlocks.prototype.changeEffect = function (args, util) {
|
2017-04-17 15:10:04 -04:00
|
|
|
const effect = Cast.toString(args.EFFECT).toLowerCase();
|
|
|
|
const change = Cast.toNumber(args.CHANGE);
|
2016-09-12 13:14:16 -04:00
|
|
|
if (!util.target.effects.hasOwnProperty(effect)) return;
|
2017-04-17 15:10:04 -04:00
|
|
|
const newValue = change + util.target.effects[effect];
|
2016-09-12 13:14:16 -04:00
|
|
|
util.target.setEffect(effect, newValue);
|
2016-06-30 00:11:47 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.setEffect = function (args, util) {
|
2017-04-17 15:10:04 -04:00
|
|
|
const effect = Cast.toString(args.EFFECT).toLowerCase();
|
|
|
|
const value = Cast.toNumber(args.VALUE);
|
2016-09-12 13:14:16 -04:00
|
|
|
util.target.setEffect(effect, value);
|
2016-06-30 00:11:47 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.clearEffects = function (args, util) {
|
|
|
|
util.target.clearEffects();
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.changeSize = function (args, util) {
|
2017-04-17 15:10:04 -04:00
|
|
|
const change = Cast.toNumber(args.CHANGE);
|
2016-09-12 13:14:16 -04:00
|
|
|
util.target.setSize(util.target.size + change);
|
2016-06-30 00:11:47 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.setSize = function (args, util) {
|
2017-04-17 15:10:04 -04:00
|
|
|
const size = Cast.toNumber(args.SIZE);
|
2016-09-12 13:14:16 -04:00
|
|
|
util.target.setSize(size);
|
2016-06-30 00:11:47 -04:00
|
|
|
};
|
|
|
|
|
2016-10-17 23:17:55 -04:00
|
|
|
Scratch3LooksBlocks.prototype.goToFront = function (args, util) {
|
|
|
|
util.target.goToFront();
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.goBackLayers = function (args, util) {
|
|
|
|
util.target.goBackLayers(args.NUM);
|
|
|
|
};
|
|
|
|
|
2016-06-30 00:11:47 -04:00
|
|
|
Scratch3LooksBlocks.prototype.getSize = function (args, util) {
|
2017-04-08 13:35:29 -04:00
|
|
|
return Math.round(util.target.size);
|
2016-06-30 00:11:47 -04:00
|
|
|
};
|
|
|
|
|
2016-09-08 09:40:27 -04:00
|
|
|
Scratch3LooksBlocks.prototype.getBackdropIndex = function () {
|
2017-04-17 15:10:04 -04:00
|
|
|
const stage = this.runtime.getTargetForStage();
|
2016-09-08 09:40:27 -04:00
|
|
|
return stage.currentCostume + 1;
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.getBackdropName = function () {
|
2017-04-17 15:10:04 -04:00
|
|
|
const stage = this.runtime.getTargetForStage();
|
2016-09-08 09:40:27 -04:00
|
|
|
return stage.sprite.costumes[stage.currentCostume].name;
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3LooksBlocks.prototype.getCostumeIndex = function (args, util) {
|
|
|
|
return util.target.currentCostume + 1;
|
|
|
|
};
|
|
|
|
|
2016-06-30 00:11:47 -04:00
|
|
|
module.exports = Scratch3LooksBlocks;
|