soiz1's picture
Upload 811 files
30c32c8 verified
raw
history blame
16 kB
const BlockType = require('../../extension-support/block-type')
const BlockShape = require('../../extension-support/block-shape')
const ArgumentType = require('../../extension-support/argument-type')
const TargetType = require('../../extension-support/target-type')
const Cast = require('../../util/cast')
function span(text) {
let el = document.createElement('span')
el.innerHTML = text
el.style.display = 'hidden'
el.style.whiteSpace = 'nowrap'
el.style.width = '100%'
el.style.textAlign = 'center'
return el
}
class jwTargetType {
customId = "jwTargets"
targetId = ""
constructor(targetId) {
this.targetId = targetId
}
static toTarget(x) {
if (x instanceof jwTargetType) return x
if (typeof x == "string") return new jwTargetType(x)
return new jwTargetType("")
}
jwArrayHandler() {
try {
return `Target<${this.target.sprite.name}>`
} catch {
return `Target`
}
}
toString() {
return this.targetId
}
toMonitorContent = () => span(this.toString())
toReporterContent() {
try {
let target = this.target
let name = target.sprite.name
let isClone = !target.isOriginal
let costumeURI = target.getCostumes()[target.currentCostume].asset.encodeDataURI()
let root = document.createElement('div')
root.style.display = 'flex'
root.style.flexDirection = 'column'
root.style.justifyContent = 'center'
let img = document.createElement('img')
img.src = costumeURI
img.style.maxWidth = '150px'
img.style.maxHeight = '150px'
root.appendChild(img)
root.appendChild(span(`${name}${isClone ? ' (clone)' : ''}`))
return root
} catch {
return span("Unknown")
}
}
get target() {
return vm.runtime.getTargetById(this.targetId)
}
}
const Target = {
Type: jwTargetType,
Block: {
blockType: BlockType.REPORTER,
forceOutputType: "Target",
disableMonitor: true
},
Argument: {
check: ["Target"]
}
}
let jwArray = {
Type: class {},
Block: {},
Argument: {}
}
class Extension {
constructor() {
vm.jwTargets = Target
vm.runtime.registerSerializer(
"jwTargets",
v => v.targetId,
v => new Target.Type(v)
);
if (!vm.jwArray) vm.extensionManager.loadExtensionIdSync('jwArray')
jwArray = vm.jwArray
}
getInfo() {
return {
id: "jwTargets",
name: "Targets",
color1: "#4254f5",
menuIconURI: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCIgeG1sbnM6Yng9Imh0dHBzOi8vYm94eS1zdmcuY29tIj4KICA8Y2lyY2xlIHN0eWxlPSJzdHJva2Utd2lkdGg6IDJweDsgcGFpbnQtb3JkZXI6IHN0cm9rZTsgZmlsbDogcmdiKDY2LCA4NCwgMjQ1KTsgc3Ryb2tlOiByZ2IoNDAsIDU1LCAxOTkpOyIgY3g9IjEwIiBjeT0iMTAiIHI9IjkiPjwvY2lyY2xlPgogIDxwYXRoIGQ9Ik0gMTAgMy4yMjIgQyA0Ljc4MyAzLjIyMiAxLjUyMyA4Ljg3IDQuMTMgMTMuMzg5IEMgNS4zNCAxNS40ODUgNy41OCAxNi43NzggMTAgMTYuNzc4IEMgMTUuMjE4IDE2Ljc3OCAxOC40OCAxMS4xMyAxNS44NjkgNi42MTEgQyAxNC42NjEgNC41MTUgMTIuNDIyIDMuMjIyIDEwIDMuMjIyIE0gMTAgNS40ODEgQyAxMy40NzkgNS40ODEgMTUuNjUzIDkuMjQ4IDEzLjkxMyAxMi4yNTkgQyAxMy4xMDYgMTMuNjU4IDExLjYxNiAxNC41MTkgMTAgMTQuNTE5IEMgNi41MjIgMTQuNTE5IDQuMzUgMTAuNzUyIDYuMDg3IDcuNzQxIEMgNi44OTUgNi4zNDIgOC4zODUgNS40ODEgMTAgNS40ODEgTSAxMCA3Ljc0MSBDIDguMjYyIDcuNzQxIDcuMTczIDkuNjIyIDguMDQ0IDExLjEzIEMgOC40NDggMTEuODI4IDkuMTkzIDEyLjI1OSAxMCAxMi4yNTkgQyAxMS43NCAxMi4yNTkgMTIuODI3IDEwLjM3OCAxMS45NTYgOC44NyBDIDExLjU1MyA4LjE3MiAxMC44MDggNy43NDEgMTAgNy43NDEiIGZpbGw9IiNmZmYiIHN0eWxlPSIiPjwvcGF0aD4KPC9zdmc+",
blocks: [
{
opcode: 'this',
text: 'this target',
hideFromPalette: true,
...Target.Block
},
{
opcode: 'stage',
text: 'stage target',
hideFromPalette: true,
...Target.Block
},
{
opcode: 'fromName',
text: '[SPRITE] target',
arguments: {
SPRITE: {
menu: "sprite"
}
},
...Target.Block
},
{
opcode: 'cloneOrigin',
text: 'origin of [TARGET]',
arguments: {
TARGET: Target.Argument
},
...Target.Block
},
'---',
{
opcode: 'get',
text: '[TARGET] [MENU]',
blockType: BlockType.REPORTER,
arguments: {
TARGET: Target.Argument,
MENU: {
menu: "targetProperty",
defaultValue: "name"
}
}
},
{
opcode: 'set',
text: 'set [TARGET] [MENU] to [VALUE]',
blockType: BlockType.COMMAND,
arguments: {
TARGET: Target.Argument,
MENU: {
menu: "targetPropertySet",
defaultValue: "x"
},
VALUE: {
type: ArgumentType.STRING,
exemptFromNormalization: true
}
}
},
'---',
{
opcode: 'isClone',
text: 'is [TARGET] a clone',
blockType: BlockType.BOOLEAN,
arguments: {
TARGET: Target.Argument
}
},
{
opcode: 'isTouching',
text: 'is [A] touching [B]',
blockType: BlockType.BOOLEAN,
arguments: {
A: Target.Argument,
B: Target.Argument
}
},
'---',
{
opcode: 'getVar',
text: 'var [NAME] of [TARGET]',
blockType: BlockType.REPORTER,
allowDropAnywhere: true,
arguments: {
TARGET: Target.Argument,
NAME: {
type: ArgumentType.STRING
}
}
},
{
opcode: 'setVar',
text: 'set var [NAME] of [TARGET] to [VALUE]',
blockType: BlockType.COMMAND,
arguments: {
TARGET: Target.Argument,
NAME: {
type: ArgumentType.STRING
},
VALUE: {
type: ArgumentType.STRING,
exemptFromNormalization: true
}
}
},
'---',
{
opcode: 'clone',
text: 'create clone of [TARGET]',
blockType: BlockType.COMMAND,
arguments: {
TARGET: Target.Argument
}
},
{
opcode: 'cloneR',
text: 'create clone of [TARGET]',
arguments: {
TARGET: Target.Argument
},
...Target.Block
},
'---',
{
opcode: 'all',
text: 'all targets',
...jwArray.Block
},
{
opcode: 'touching',
text: 'targets touching [TARGET]',
arguments: {
TARGET: Target.Argument
},
...jwArray.Block
},
{
opcode: 'clones',
text: 'clones of [TARGET]',
arguments: {
TARGET: Target.Argument
},
...jwArray.Block
},
{
opcode: 'arrayHasTarget',
text: '[ARRAY] has clone of [TARGET]',
blockType: BlockType.BOOLEAN,
arguments: {
ARRAY: jwArray.Argument,
TARGET: Target.Argument
}
},
'---',
{
blockType: BlockType.XML,
xml: `<block type="control_run_as_sprite" />`
}
],
menus: {
sprite: {
acceptReporters: true,
items: 'getSpriteMenu'
},
targetProperty: {
acceptReporters: true,
items: [
"name",
"x",
"y",
"direction",
"size",
"stretch x",
"stretch y",
"costume #",
"costume name",
]
},
targetPropertySet: {
acceptReporters: true,
items: [
"x",
"y",
"direction",
"size",
"stretch x",
"stretch y",
"costume #",
"costume name",
]
}
}
};
}
getSpriteMenu({}) {
let sprites = ["this", "stage"]
for (let target of vm.runtime.targets.filter(v => v !== vm.runtime._stageTarget)) {
if (!sprites.includes(target.sprite.name)) sprites.push(target.sprite.name)
}
return sprites
}
this({}, util) {
return new Target.Type(util.target.id)
}
stage() {
return new Target.Type(vm.runtime._stageTarget.id)
}
fromName({SPRITE}, util) {
SPRITE = Cast.toString(SPRITE)
if (SPRITE == "this") return this.this({}, util)
if (SPRITE == "stage") return this.stage()
let target = vm.runtime.getSpriteTargetByName(SPRITE)
return new Target.Type(target ? target.id : "")
}
cloneOrigin({TARGET}, util) {
TARGET = Target.Type.toTarget(TARGET)
if (!TARGET.target) return ""
return this.fromName({SPRITE: TARGET.target.sprite.name}, util)
}
get({TARGET, MENU}) {
TARGET = Target.Type.toTarget(TARGET)
MENU = Cast.toString(MENU)
if (!TARGET.target) return ""
switch(MENU) {
case "x": return TARGET.target.x
case "y": return TARGET.target.y
case "direction": return TARGET.target.direction
case "size": return TARGET.target.size
case "name": return TARGET.target.sprite.name
case "stretch x": return TARGET.target.stretch[0]
case "stretch y": return TARGET.target.stretch[1]
case "costume #": return TARGET.target.currentCostume + 1
case "costume name": return TARGET.target.getCurrentCostume().name
}
return ""
}
set({TARGET, MENU, VALUE}) {
TARGET = Target.Type.toTarget(TARGET)
MENU = Cast.toString(MENU)
if (!TARGET.target) return
switch(MENU) {
case "x":
TARGET.target.setXY(Cast.toNumber(VALUE), TARGET.target.y)
break
case "y":
TARGET.target.setXY(TARGET.target.x, Cast.toNumber(VALUE))
break
case "direction":
TARGET.target.setDirection(Cast.toNumber(VALUE))
break
case "size":
TARGET.target.setSize(Cast.toNumber(VALUE))
break
case "stretch x":
TARGET.target.setStretch(Cast.toNumber(VALUE), TARGET.target.stretch[1])
break
case "stretch y":
TARGET.target.setStretch(TARGET.target.stretch[0], Cast.toNumber(VALUE))
break
case "costume #":
TARGET.target.setCostume(Cast.toNumber(VALUE) - 1)
break
case "costume name":
let index = TARGET.target.getCostumes().indexOf(TARGET.target.getCostumes().find(v => v.name === Cast.toString(VALUE)))
TARGET.target.setCostume(index)
break
}
}
isClone({TARGET}) {
TARGET = Target.Type.toTarget(TARGET)
if (!TARGET.target) return false
return !TARGET.target.isOriginal
}
isTouching({A, B}) {
A = Target.Type.toTarget(A)
B = Target.Type.toTarget(B)
if (!A.target) return
return A.target.isTouchingTarget(B.targetId)
}
getVar({TARGET, NAME}) {
TARGET = Target.Type.toTarget(TARGET)
NAME = Cast.toString(NAME)
if (!TARGET.target) return ""
let variable = Object.values(TARGET.target.variables).find(v => v.name == NAME)
if (!variable) return ""
return variable.value
}
setVar({TARGET, NAME, VALUE}) {
TARGET = Target.Type.toTarget(TARGET)
NAME = Cast.toString(NAME)
if (!TARGET.target) return
let variable = Object.values(TARGET.target.variables).find(v => v.name == NAME)
if (!variable) return
variable.value = VALUE
}
clone(args) {
this.cloneR(args)
}
cloneR({TARGET}) {
TARGET = Target.Type.toTarget(TARGET)
if (!TARGET.target) return
let origin = TARGET.target
let clone = origin.makeClone()
if (clone) {
vm.runtime.addTarget(clone)
clone.goBehindOther(origin) //mimick clone making from control category
}
return new Target.Type(clone ? clone.id : "")
}
all() {
return new jwArray.Type(vm.runtime.targets.map(v => new Target.Type(v.id)))
}
touching({TARGET}) {
TARGET = Target.Type.toTarget(TARGET)
if (!TARGET.target) return new jwArray.Type
let targets = vm.runtime.targets
targets = targets.filter(v => v !== TARGET && !v.isStage)
targets = targets.filter(v => v.isTouchingTarget(TARGET.targetId))
return new jwArray.Type(targets.map(v => new Target.Type(v.id)))
}
clones({TARGET}) {
TARGET = Target.Type.toTarget(TARGET)
if (TARGET.target) {
return new jwArray.Type(TARGET.target.sprite.clones.filter(v => !v.isOriginal).map(v => new Target.Type(v.id)))
}
return new jwArray.Type()
}
arrayHasTarget({ARRAY, TARGET}) {
ARRAY = jwArray.Type.toArray(ARRAY)
TARGET = Target.Type.toTarget(TARGET)
if (!TARGET.target) return false
return ARRAY.array.find(v => {
let target = Target.Type.toTarget(v)
if (!target.target) return false
return target.target.sprite == TARGET.target.sprite
}) !== undefined
}
}
module.exports = Extension