From 110f44294123a5624c2ef3dfc8dbc94e3e008913 Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 21:18:45 +0100 Subject: [PATCH 01/21] edit: assert xtoken equality refactor: comments --- scratchattach/site/session.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/scratchattach/site/session.py b/scratchattach/site/session.py index 464d4f58..0a496706 100644 --- a/scratchattach/site/session.py +++ b/scratchattach/site/session.py @@ -16,9 +16,6 @@ from contextlib import contextmanager from threading import local -# import secrets -# import zipfile -# from typing import Type Type = type if TYPE_CHECKING: @@ -910,6 +907,7 @@ def connect_user_by_id(self, user_id: int) -> user.User: Returns: scratchattach.user.User: An object that represents the requested user and allows you to perform actions on the user (like user.follow) """ + # noinspection PyDeprecation return self._make_linked_object("username", self.find_username_from_id(user_id), user.User, exceptions.UserNotFound) @@ -1131,6 +1129,7 @@ def login_by_id(session_id: str, *, username: Optional[str] = None, password: Op scratchattach.session.Session: An object that represents the created login / session """ # Generate session_string (a scratchattach-specific authentication method) + # should this be changed to a @property? issue_login_warning() if password is not None: session_data = dict(id=session_id, username=username, password=password) @@ -1138,14 +1137,10 @@ def login_by_id(session_id: str, *, username: Optional[str] = None, password: Op else: session_string = None - if xtoken is not None: - # todo: consider removing the xtoken parameter? - warnings.warn("xtoken is redundant because it is retrieved by decoding the session id.") - _session = Session(id=session_id, username=username, session_string=session_string) - - # xtoken is decoded from sessid, so don't use sess.update - # but this will cause incompatibilities, warranting a change in the 2nd (semver) version number + if xtoken is not None: + # xtoken is retrievable from session id, so the most we can do is assert equality + assert xtoken == _session.xtoken return _session @@ -1176,7 +1171,6 @@ def login(username, password, *, timeout=10) -> Session: with requests.no_error_handling(): request = requests.post( "https://scratch.mit.edu/login/", json={"username": username, "password": password}, headers=_headers, - timeout=timeout ) try: From aecb2779784f76c0e6980400c1cdafd8b50c5c55 Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 21:34:11 +0100 Subject: [PATCH 02/21] doc: asset.py --- scratchattach/editor/asset.py | 52 ++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/scratchattach/editor/asset.py b/scratchattach/editor/asset.py index 4c2988c4..9d26ab1c 100644 --- a/scratchattach/editor/asset.py +++ b/scratchattach/editor/asset.py @@ -10,12 +10,19 @@ @dataclass(init=True, repr=True) class AssetFile: + """ + Represents the file information for an asset + - stores the filename, data, and md5 hash + """ filename: str _data: bytes = field(repr=False, default=None) _md5: str = field(repr=False, default=None) @property def data(self): + """ + Return the contents of the asset file, as bytes + """ if self._data is None: # Download and cache rq = requests.get(f"https://assets.scratch.mit.edu/internalapi/asset/{self.filename}/get/") @@ -28,6 +35,9 @@ def data(self): @property def md5(self): + """ + Compute/retrieve the md5 hash value of the asset file data + """ if self._md5 is None: self._md5 = md5(self.data).hexdigest() @@ -60,22 +70,40 @@ def __repr__(self): @property def folder(self): + """ + Get the folder name of this asset, based on the asset name. Uses the turbowarp syntax + """ return commons.get_folder_name(self.name) @property def name_nfldr(self): + """ + Get the asset name after removing the folder name + """ return commons.get_name_nofldr(self.name) @property def file_name(self): + """ + Get the exact file name, as it would be within an sb3 file + equivalent to the md5ext value using in scratch project JSON + """ return f"{self.id}.{self.data_format}" @property def md5ext(self): + """ + Get the exact file name, as it would be within an sb3 file + equivalent to the md5ext value using in scratch project JSON + """ return self.file_name @property def parent(self): + """ + Return the project that this asset is attached to. If there is no attached project, + try returning the attached sprite + """ if self.project is None: return self.sprite else: @@ -83,6 +111,9 @@ def parent(self): @property def asset_file(self) -> AssetFile: + """ + Get the associated asset file object for this asset object + """ for asset_file in self.parent.asset_data: if asset_file.filename == self.file_name: return asset_file @@ -94,6 +125,9 @@ def asset_file(self) -> AssetFile: @staticmethod def from_json(data: dict): + """ + Load asset data from project.json + """ _name = data.get("name") _file_name = data.get("md5ext") if _file_name is None: @@ -105,6 +139,9 @@ def from_json(data: dict): return Asset(_name, _file_name) def to_json(self) -> dict: + """ + Convert asset data to project.json format + """ return { "name": self.name, @@ -113,6 +150,7 @@ def to_json(self) -> dict: "dataFormat": self.data_format, } + # todo: implement below: """ @staticmethod def from_file(fp: str, name: str = None): @@ -134,7 +172,7 @@ def __init__(self, rotation_center_y: int | float = 50, _sprite: sprite.Sprite = build_defaulting.SPRITE_DEFAULT): """ - A costume. An asset with additional properties + A costume (image). An asset with additional properties https://en.scratch-wiki.info/wiki/Scratch_File_Format#Costumes """ super().__init__(name, file_name, _sprite) @@ -145,6 +183,9 @@ def __init__(self, @staticmethod def from_json(data): + """ + Load costume data from project.json + """ _asset_load = Asset.from_json(data) bitmap_resolution = data.get("bitmapResolution") @@ -156,6 +197,9 @@ def from_json(data): bitmap_resolution, rotation_center_x, rotation_center_y) def to_json(self) -> dict: + """ + Convert costume to project.json format + """ _json = super().to_json() _json.update({ "bitmapResolution": self.bitmap_resolution, @@ -184,6 +228,9 @@ def __init__(self, @staticmethod def from_json(data): + """ + Load sound from project.json + """ _asset_load = Asset.from_json(data) rate = data.get("rate") @@ -191,6 +238,9 @@ def from_json(data): return Sound(_asset_load.name, _asset_load.file_name, rate, sample_count) def to_json(self) -> dict: + """ + Convert Sound to project.json format + """ _json = super().to_json() commons.noneless_update(_json, { "rate": self.rate, From 854dc5740b8cce2ce61235c4f9c4ebb0233b094b Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 21:46:20 +0100 Subject: [PATCH 03/21] doc: base.py --- scratchattach/editor/base.py | 60 ++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/scratchattach/editor/base.py b/scratchattach/editor/base.py index aebbbca8..997c2995 100644 --- a/scratchattach/editor/base.py +++ b/scratchattach/editor/base.py @@ -17,6 +17,9 @@ class Base(ABC): + """ + Abstract base class for most sa.editor classes. Implements copy functions + """ def dcopy(self): """ :return: A **deep** copy of self @@ -31,6 +34,10 @@ def copy(self): class JSONSerializable(Base, ABC): + """ + 'Interface' for to_json() and from_json() methods + Also implements save_json() using to_json() + """ @staticmethod @abstractmethod def from_json(data: dict | list | Any): @@ -41,12 +48,19 @@ def to_json(self) -> dict | list | Any: pass def save_json(self, name: str = ''): + """ + Save a json file + """ data = self.to_json() with open(f"{self.__class__.__name__.lower()}{name}.json", "w") as f: json.dump(data, f) class JSONExtractable(JSONSerializable, ABC): + """ + Interface for objects that can be loaded from zip archives containing json files (sprite/project) + Only has one method - load_json + """ @staticmethod @abstractmethod def load_json(data: str | bytes | TextIOWrapper | BinaryIO, load_assets: bool = True, _name: Optional[str] = None) -> tuple[ @@ -62,35 +76,35 @@ def load_json(data: str | bytes | TextIOWrapper | BinaryIO, load_assets: bool = class ProjectSubcomponent(JSONSerializable, ABC): + """ + Base class for any class with an associated project + """ def __init__(self, _project: Optional[project.Project] = None): self.project = _project class SpriteSubComponent(JSONSerializable, ABC): + """ + Base class for any class with an associated sprite + """ def __init__(self, _sprite: sprite.Sprite = build_defaulting.SPRITE_DEFAULT): if _sprite is build_defaulting.SPRITE_DEFAULT: _sprite = build_defaulting.current_sprite() self.sprite = _sprite - # @property - # def sprite(self): - # if self._sprite is None: - # print("ok, ", build_defaulting.current_sprite()) - # return build_defaulting.current_sprite() - # else: - # return self._sprite - - # @sprite.setter - # def sprite(self, value): - # self._sprite = value - @property def project(self) -> project.Project: + """ + Get associated project by proxy of the associated sprite + """ return self.sprite.project class IDComponent(SpriteSubComponent, ABC): + """ + Base class for classes with an id attribute + """ def __init__(self, _id: str, _sprite: sprite.Sprite = build_defaulting.SPRITE_DEFAULT): self.id = _id super().__init__(_sprite) @@ -103,7 +117,6 @@ class NamedIDComponent(IDComponent, ABC): """ Base class for Variables, Lists and Broadcasts (Name + ID + sprite) """ - def __init__(self, _id: str, name: str, _sprite: sprite.Sprite = build_defaulting.SPRITE_DEFAULT): self.name = name super().__init__(_id, _sprite) @@ -113,30 +126,51 @@ def __repr__(self): class BlockSubComponent(JSONSerializable, ABC): + """ + Base class for classes with associated blocks + """ def __init__(self, _block: Optional[block.Block] = None): self.block = _block @property def sprite(self) -> sprite.Sprite: + """ + Fetch sprite by proxy of the block + """ return self.block.sprite @property def project(self) -> project.Project: + """ + Fetch project by proxy of the sprite (by proxy of the block) + """ return self.sprite.project class MutationSubComponent(JSONSerializable, ABC): + """ + Base class for classes with associated mutations + """ def __init__(self, _mutation: Optional[mutation.Mutation] = None): self.mutation = _mutation @property def block(self) -> block.Block: + """ + Fetch block by proxy of mutation + """ return self.mutation.block @property def sprite(self) -> sprite.Sprite: + """ + Fetch sprite by proxy of block (by proxy of mutation) + """ return self.block.sprite @property def project(self) -> project.Project: + """ + Fetch project by proxy of sprite (by proxy of block (by proxy of mutation)) + """ return self.sprite.project From ae40c8deca34e614c25c7fefbef8fc4f84eaf302 Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:09:12 +0100 Subject: [PATCH 04/21] doc: block.py --- scratchattach/editor/block.py | 79 +++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 9 deletions(-) diff --git a/scratchattach/editor/block.py b/scratchattach/editor/block.py index b812080c..4597ac22 100644 --- a/scratchattach/editor/block.py +++ b/scratchattach/editor/block.py @@ -9,6 +9,9 @@ class Block(base.SpriteSubComponent): + """ + Represents a block in the scratch editor, as a subcomponent of a sprite. + """ def __init__(self, _opcode: str, _shadow: bool = False, _top_level: Optional[bool] = None, _mutation: Optional[mutation.Mutation] = None, _fields: Optional[dict[str, field.Field]] = None, _inputs: Optional[dict[str, inputs.Input]] = None, x: int = 0, y: int = 0, pos: Optional[tuple[int, int]] = None, @@ -34,14 +37,11 @@ def __init__(self, _opcode: str, _shadow: bool = False, _top_level: Optional[boo self.fields = _fields self.inputs = _inputs + # Temporarily stores id of next block. Will be used later during project instantiation to find the next block object self._next_id = _next_id - """ - Temporarily stores id of next block. Will be used later during project instantiation to find the next block object - """ + + # Temporarily stores id of parent block. Will be used later during project instantiation to find the parent block object self._parent_id = _parent_id - """ - Temporarily stores id of parent block. Will be used later during project instantiation to find the parent block object - """ self.next = _next self.parent = _parent @@ -55,6 +55,9 @@ def __repr__(self): return f"Block<{self.opcode!r}>" def link_subcomponents(self): + """ + Iterate through subcomponents and assign the 'block' attribute + """ if self.mutation: self.mutation.block = self @@ -63,6 +66,9 @@ def link_subcomponents(self): subcomponent.block = self def add_input(self, name: str, _input: inputs.Input) -> Self: + """ + Add an input to the block. + """ # not sure what else to say self.inputs[name] = _input for val in (_input.value, _input.obscurer): if isinstance(val, Block): @@ -70,22 +76,34 @@ def add_input(self, name: str, _input: inputs.Input) -> Self: return self def add_field(self, name: str, _field: field.Field) -> Self: + """ + Add a field to the block. + """ # not sure what else to sa self.fields[name] = _field return self def set_mutation(self, _mutation: mutation.Mutation) -> Self: + """ + Attach a mutation object and call mutation.link_arguments() + """ # this comment explains *what* this does, not *why* self.mutation = _mutation _mutation.block = self _mutation.link_arguments() return self def set_comment(self, _comment: comment.Comment) -> Self: + """ + Attach a comment and add it to the sprite. + """ _comment.block = self self.sprite.add_comment(_comment) return self def check_toplevel(self): + """ + Edit the toplevel, x, and y attributes based on whether the parent attribute is None + """ self.is_top_level = self.parent is None if not self.is_top_level: @@ -95,7 +113,7 @@ def check_toplevel(self): def target(self): """ Alias for sprite - """ + """ # remove this? return self.sprite @property @@ -142,6 +160,9 @@ def id(self) -> str | None: @property def parent_id(self): + """ + Get the id of the parent block, if applicable + """ if self.parent is not None: return self.parent.id else: @@ -149,6 +170,9 @@ def parent_id(self): @property def next_id(self): + """ + Get the id of the next block, if applicable + """ if self.next is not None: return self.next.id else: @@ -186,13 +210,19 @@ def children(self) -> list[Block | prim.Prim]: @property def previous_chain(self): - if self.parent is None: + """ + Recursive getter method to get all previous blocks in the blockchain (until hitting a top-level block) + """ + if self.parent is None: # todo: use is_top_level? return [self] return [self] + self.parent.previous_chain @property def attached_chain(self): + """ + Recursive getter method to get all next blocks in the blockchain (until hitting a bottom-levell block) + """ if self.next is None: return [self] @@ -200,23 +230,30 @@ def attached_chain(self): @property def complete_chain(self): - # Both previous and attached chains start with self + """ + Attach previous and attached chains from this block + """ return self.previous_chain[:1:-1] + self.attached_chain @property def top_level_block(self): """ + Get the first block in the block stack that this block is part of same as the old stack_parent property from sbedtior v1 """ return self.previous_chain[-1] @property def bottom_level_block(self): + """ + Get the last block in the block stack that this block is part of + """ return self.attached_chain[-1] @property def stack_tree(self): """ + Useful for showing a block stack in the console, using pprint :return: A tree-like nested list structure representing the stack of blocks, including inputs, starting at this block """ _tree = [self] @@ -254,6 +291,9 @@ def is_next_block(self): @property def parent_input(self): + """ + Fetch an input that this block is placed inside of (if applicable) + """ if not self.parent: return None @@ -268,6 +308,9 @@ def new_id(self): @property def comment(self) -> comment.Comment | None: + """ + Fetch an associated comment (if applicable) by searching the associated sprite + """ for _comment in self.sprite.comments: if _comment.block is self: return _comment @@ -320,6 +363,9 @@ def turbowarp_block_opcode(self): @property def is_turbowarp_block(self): + """ + Return whether this block is actually a turbowarp debugger/boolean block, based on mutation + """ return self.turbowarp_block_opcode is not None @staticmethod @@ -356,6 +402,9 @@ def from_json(data: dict) -> Block: _parent_id=_parent_id) def to_json(self) -> dict: + """ + Convert a block to the project.json format + """ self.check_toplevel() _json = { @@ -387,6 +436,9 @@ def to_json(self) -> dict: return _json def link_using_sprite(self, link_subs: bool = True): + """ + Link this block to various other blocks once the sprite has been assigned + """ if link_subs: self.link_subcomponents() @@ -443,6 +495,9 @@ def link_using_sprite(self, link_subs: bool = True): # Adding/removing block def attach_block(self, new: Block) -> Block: + """ + Connect another block onto the boottom of this block (not necessarily bottom of chain) + """ if not self.can_next: raise exceptions.BadBlockShape(f"{self.block_shape} cannot be stacked onto") elif new.block_shape.is_hat or not new.block_shape.is_stack: @@ -474,6 +529,9 @@ def duplicate_chain(self) -> Block: ) def slot_above(self, new: Block) -> Block: + """ + Place a single block directly above this block + """ if not new.can_next: raise exceptions.BadBlockShape(f"{new.block_shape} cannot be stacked onto") @@ -503,6 +561,9 @@ def delete_single_block(self): self.sprite.remove_block(self) def delete_chain(self): + """ + Delete all blocks in the attached blockchain (and self) + """ for _block in self.attached_chain: _block.delete_single_block() From bfc390fe38a33e62c5a880097758b62912f4b2f0 Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:10:23 +0100 Subject: [PATCH 05/21] delete sbuild.py --- scratchattach/editor/sbuild.py | 2837 -------------------------------- 1 file changed, 2837 deletions(-) delete mode 100644 scratchattach/editor/sbuild.py diff --git a/scratchattach/editor/sbuild.py b/scratchattach/editor/sbuild.py deleted file mode 100644 index ac807796..00000000 --- a/scratchattach/editor/sbuild.py +++ /dev/null @@ -1,2837 +0,0 @@ -from __future__ import annotations - -from .. import editor -from typing import Optional - -# Copied from sbuild so we have to make a few wrappers ;-; -# May need to recreate this from scratch. In which case, it is to be done in palette.py -class Block(editor.Block): - ... - -class Input(editor.Input): - ... -class Field(editor.Field): - ... -class Variable(editor.Variable): - ... -class List(editor.List): - ... -class Broadcast(editor.Broadcast): - ... -class Mutation(editor.Mutation): - ... - - -class Motion: - class MoveSteps(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_movesteps", _shadow=shadow, pos=pos) - - def set_steps(self, value, input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("STEPS", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class TurnRight(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_turnright", _shadow=shadow, pos=pos) - - def set_degrees(self, value, input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("DEGREES", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class TurnLeft(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_turnleft", _shadow=shadow, pos=pos) - - def set_degrees(self, value, input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("DEGREES", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class GoTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_goto", _shadow=shadow, pos=pos) - - def set_to(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input(Input("TO", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class GoToMenu(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_goto_menu", _shadow=shadow, pos=pos) - - def set_to(self, value: str = "_random_", value_id: Optional[str] = None): - return self.add_field(Field("TO", value, value_id)) - - class GoToXY(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_gotoxy", _shadow=shadow, pos=pos) - - def set_x(self, value, input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input(Input("X", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_y(self, value, input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input(Input("Y", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class GlideTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_glideto", _shadow=shadow, pos=pos) - - def set_secs(self, value, input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input(Input("SECS", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_to(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input(Input("TO", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class GlideToMenu(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_glideto_menu", _shadow=shadow, pos=pos) - - def set_to(self, value: str = "_random_", value_id: Optional[str] = None): - return self.add_field(Field("TO", value, value_id)) - - class GlideSecsToXY(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_glidesecstoxy", _shadow=shadow, pos=pos) - - def set_x(self, value, input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input(Input("X", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_y(self, value, input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input(Input("Y", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_secs(self, value, input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input(Input("SECS", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class PointInDirection(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_pointindirection", _shadow=shadow, pos=pos) - - def set_direction(self, value, input_type: str | int = "angle", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("DIRECTION", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class PointTowards(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_pointtowards", _shadow=shadow, pos=pos) - - def set_towards(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("TOWARDS", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class PointTowardsMenu(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_pointtowards_menu", _shadow=shadow, pos=pos) - - def set_towards(self, value: str = "_mouse_", value_id: Optional[str] = None): - return self.add_field(Field("TOWARDS", value, value_id)) - - class ChangeXBy(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_changexby", _shadow=shadow, pos=pos) - - def set_dx(self, value, input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input(Input("DX", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class ChangeYBy(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_changeyby", _shadow=shadow, pos=pos) - - def set_dy(self, value, input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input(Input("DY", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class SetX(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_setx", _shadow=shadow, pos=pos) - - def set_x(self, value, input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input(Input("X", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class SetY(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_sety", _shadow=shadow, pos=pos) - - def set_y(self, value, input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input(Input("Y", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class IfOnEdgeBounce(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_ifonedgebounce", _shadow=shadow, pos=pos) - - class SetRotationStyle(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_setrotationstyle", _shadow=shadow, pos=pos) - - def set_style(self, value: str = "all around", value_id: Optional[str] = None): - return self.add_field(Field("STYLE", value, value_id)) - - class XPosition(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_xposition", _shadow=shadow, pos=pos) - - class YPosition(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_yposition", _shadow=shadow, pos=pos) - - class Direction(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_direction", _shadow=shadow, pos=pos) - - class ScrollRight(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_scroll_right", _shadow=shadow, pos=pos) - - def set_distance(self, value, input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("DISTANCE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class ScrollUp(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_scroll_up", _shadow=shadow, pos=pos) - - def set_distance(self, value, input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("DISTANCE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class AlignScene(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_align_scene", _shadow=shadow, pos=pos) - - def set_alignment(self, value: str = "bottom-left", value_id: Optional[str] = None): - return self.add_field(Field("ALIGNMENT", value, value_id)) - - class XScroll(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_xscroll", _shadow=shadow, pos=pos) - - class YScroll(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "motion_yscroll", _shadow=shadow, pos=pos) - - -class Looks: - class SayForSecs(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_sayforsecs", _shadow=shadow, pos=pos) - - def set_message(self, value="Hello!", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("MESSAGE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer) - ) - - def set_secs(self, value=2, input_type: str | int = "positive integer", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("SECS", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer) - ) - - class Say(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_say", _shadow=shadow, pos=pos) - - def set_message(self, value="Hello!", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("MESSAGE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer) - ) - - class ThinkForSecs(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_thinkforsecs", _shadow=shadow, pos=pos) - - def set_message(self, value="Hmm...", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("MESSAGE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer) - ) - - def set_secs(self, value=2, input_type: str | int = "positive integer", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("SECS", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer) - ) - - class Think(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_think", _shadow=shadow, pos=pos) - - def set_message(self, value="Hmm...", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("MESSAGE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer) - ) - - class SwitchCostumeTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_switchcostumeto", _shadow=shadow, pos=pos) - - def set_costume(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("COSTUME", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Costume(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_costume", _shadow=shadow, pos=pos) - - def set_costume(self, value: str = "costume1", value_id: Optional[str] = None): - return self.add_field(Field("COSTUME", value, value_id)) - - class NextCostume(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_nextcostume", _shadow=shadow, pos=pos) - - class SwitchBackdropTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_switchbackdropto", _shadow=shadow, pos=pos) - - def set_backdrop(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("BACKDROP", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Backdrops(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_backdrops", _shadow=shadow, pos=pos) - - def set_backdrop(self, value: str = "costume1", value_id: Optional[str] = None): - return self.add_field(Field("BACKDROP", value, value_id)) - - class SwitchBackdropToAndWait(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_switchbackdroptoandwait", _shadow=shadow, pos=pos) - - def set_backdrop(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("BACKDROP", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class NextBackdrop(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_nextbackdrop", _shadow=shadow, pos=pos) - - class ChangeSizeBy(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_changesizeby", _shadow=shadow, pos=pos) - - def set_change(self, value="10", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("CHANGE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class SetSizeTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_setsizeto", _shadow=shadow, pos=pos) - - def set_size(self, value="100", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("SIZE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class ChangeEffectBy(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_changeeffectby", _shadow=shadow, pos=pos) - - def set_change(self, value="100", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("CHANGE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_effect(self, value: str = "COLOR", value_id: Optional[str] = None): - return self.add_field(Field("EFFECT", value, value_id)) - - class SetEffectTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_seteffectto", _shadow=shadow, pos=pos) - - def set_value(self, value="0", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("VALUE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_effect(self, value: str = "COLOR", value_id: Optional[str] = None): - return self.add_field(Field("EFFECT", value, value_id)) - - class ClearGraphicEffects(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_cleargraphiceffects", _shadow=shadow, pos=pos) - - class Hide(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_hide", _shadow=shadow, pos=pos) - - class Show(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_show", _shadow=shadow, pos=pos) - - class GoToFrontBack(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_gotofrontback", _shadow=shadow, pos=pos) - - def set_front_back(self, value: str = "front", value_id: Optional[str] = None): - return self.add_field(Field("FRONT_BACK", value, value_id)) - - class GoForwardBackwardLayers(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_goforwardbackwardlayers", _shadow=shadow, pos=pos) - - def set_num(self, value="1", input_type: str | int = "positive integer", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NUM", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_fowrward_backward(self, value: str = "forward", value_id: Optional[str] = None): - return self.add_field(Field("FORWARD_BACKWARD", value, value_id)) - - class CostumeNumberName(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_costumenumbername", _shadow=shadow, pos=pos) - - def set_number_name(self, value: str = "string", value_id: Optional[str] = None): - return self.add_field(Field("NUMBER_NAME", value, value_id)) - - class BackdropNumberName(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_backdropnumbername", _shadow=shadow, pos=pos) - - def set_number_name(self, value: str = "number", value_id: Optional[str] = None): - return self.add_field(Field("NUMBER_NAME", value, value_id)) - - class Size(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_size", _shadow=shadow, pos=pos) - - class HideAllSprites(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_hideallsprites", _shadow=shadow, pos=pos) - - class SetStretchTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_setstretchto", _shadow=shadow, pos=pos) - - def set_stretch(self, value="100", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("STRETCH", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class ChangeStretchBy(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "looks_changestretchby", _shadow=shadow, pos=pos) - - def set_change(self, value="10", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("CHANGE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - -class Sounds: - class Play(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sound_play", _shadow=shadow, pos=pos) - - def set_sound_menu(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("SOUND_MENU", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class SoundsMenu(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sound_sounds_menu", _shadow=shadow, pos=pos) - - def set_sound_menu(self, value: str = "pop", value_id: Optional[str] = None): - return self.add_field(Field("SOUND_MENU", value, value_id)) - - class PlayUntilDone(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sound_playuntildone", _shadow=shadow, pos=pos) - - def set_sound_menu(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("SOUND_MENU", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class StopAllSounds(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sound_stopallsounds", _shadow=shadow, pos=pos) - - class ChangeEffectBy(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sound_changeeffectby", _shadow=shadow, pos=pos) - - def set_value(self, value="10", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("VALUE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_effect(self, value: str = "PITCH", value_id: Optional[str] = None): - return self.add_field(Field("EFFECT", value, value_id)) - - class SetEffectTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sound_seteffectto", _shadow=shadow, pos=pos) - - def set_value(self, value="100", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("VALUE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_effect(self, value: str = "PITCH", value_id: Optional[str] = None): - return self.add_field(Field("EFFECT", value, value_id)) - - class ClearEffects(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sound_cleareffects", _shadow=shadow, pos=pos) - - class ChangeVolumeBy(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sound_changevolumeby", _shadow=shadow, pos=pos) - - def set_volume(self, value="-10", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("VOLUME", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class SetVolumeTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sound_setvolumeto", _shadow=shadow, pos=pos) - - def set_volume(self, value="100", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("VOLUME", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Volume(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sound_volume", _shadow=shadow, pos=pos) - - -class Events: - class WhenFlagClicked(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "event_whenflagclicked", _shadow=shadow, pos=pos) - - class WhenKeyPressed(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "event_whenkeypressed", _shadow=shadow, pos=pos) - - def set_key_option(self, value: str = "space", value_id: Optional[str] = None): - return self.add_field(Field("KEY_OPTION", value, value_id)) - - class WhenThisSpriteClicked(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "event_whenthisspriteclicked", _shadow=shadow, pos=pos) - - class WhenStageClicked(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "event_whenstageclicked", _shadow=shadow, pos=pos) - - class WhenBackdropSwitchesTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "event_whenbackdropswitchesto", _shadow=shadow, pos=pos) - - def set_backdrop(self, value: str = "backdrop1", value_id: Optional[str] = None): - return self.add_field(Field("BACKDROP", value, value_id)) - - class WhenGreaterThan(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "event_whengreaterthan", _shadow=shadow, pos=pos) - - def set_value(self, value="10", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("VALUE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_when_greater_than_menu(self, value: str = "LOUDNESS", value_id: Optional[str] = None): - return self.add_field(Field("WHENGREATERTHANMENU", value, value_id)) - - class WhenBroadcastReceived(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "event_whenbroadcastreceived", _shadow=shadow, pos=pos) - - def set_broadcast_option(self, value="message1", value_id: str = "I didn't get an id..."): - return self.add_field(Field("BROADCAST_OPTION", value, value_id)) - - class Broadcast(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "event_broadcast", _shadow=shadow, pos=pos) - - def set_broadcast_input(self, value="message1", input_type: str | int = "broadcast", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("BROADCAST_INPUT", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class BroadcastAndWait(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "event_broadcastandwait", _shadow=shadow, pos=pos) - - def set_broadcast_input(self, value="message1", input_type: str | int = "broadcast", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("BROADCAST_INPUT", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class WhenTouchingObject(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "event_whentouchingobject", _shadow=shadow, pos=pos) - - def set_touching_object_menu(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("TOUCHINGOBJECTMENU", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class TouchingObjectMenu(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "event_touchingobjectmenu", _shadow=shadow, pos=pos) - - def set_touching_object_menu(self, value: str = "_mouse_", value_id: Optional[str] = None): - return self.add_field(Field("TOUCHINGOBJECTMENU", value, value_id)) - - -class Control: - class Wait(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_wait", _shadow=shadow, pos=pos) - - def set_duration(self, value="1", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("DURATION", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Forever(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_forever", _shadow=shadow, pos=pos, can_next=False) - - def set_substack(self, value, input_type: str | int = "block", shadow_status: int = 2, *, - input_id: Optional[str] = None): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input("SUBSTACK", value, input_type, shadow_status, input_id=input_id) - return self.add_input(inp) - - class If(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_if", _shadow=shadow, pos=pos) - - def set_substack(self, value, input_type: str | int = "block", shadow_status: int = 2, *, - input_id: Optional[str] = None): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input("SUBSTACK", value, input_type, shadow_status, input_id=input_id) - return self.add_input(inp) - - def set_condition(self, value, input_type: str | int = "block", shadow_status: int = 2, *, - input_id: Optional[str] = None): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input("CONDITION", value, input_type, shadow_status, input_id=input_id) - return self.add_input(inp) - - class IfElse(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_if_else", _shadow=shadow, pos=pos) - - def set_substack1(self, value, input_type: str | int = "block", shadow_status: int = 2, *, - input_id: Optional[str] = None): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input("SUBSTACK", value, input_type, shadow_status, input_id=input_id) - return self.add_input(inp) - - def set_substack2(self, value, input_type: str | int = "block", shadow_status: int = 2, *, - input_id: Optional[str] = None): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input("SUBSTACK2", value, input_type, shadow_status, input_id=input_id) - return self.add_input(inp) - - def set_condition(self, value, input_type: str | int = "block", shadow_status: int = 2, *, - input_id: Optional[str] = None): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input("CONDITION", value, input_type, shadow_status, input_id=input_id) - return self.add_input(inp) - - class WaitUntil(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_wait_until", _shadow=shadow, pos=pos) - - def set_condition(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("CONDITION", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class RepeatUntil(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_repeat_until", _shadow=shadow, pos=pos) - - def set_substack(self, value, input_type: str | int = "block", shadow_status: int = 2, *, - input_id: Optional[str] = None): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input("SUBSTACK", value, input_type, shadow_status, input_id=input_id) - return self.add_input(inp) - - def set_condition(self, value, input_type: str | int = "block", shadow_status: int = 2, *, - input_id: Optional[str] = None): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input("CONDITION", value, input_type, shadow_status, input_id=input_id) - return self.add_input(inp) - - class While(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_while", _shadow=shadow, pos=pos) - - def set_substack(self, value, input_type: str | int = "block", shadow_status: int = 2, *, - input_id: Optional[str] = None): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input("SUBSTACK", value, input_type, shadow_status, input_id=input_id) - return self.add_input(inp) - - def set_condition(self, value, input_type: str | int = "block", shadow_status: int = 2, *, - input_id: Optional[str] = None): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input("CONDITION", value, input_type, shadow_status, input_id=input_id) - return self.add_input(inp) - - class Stop(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_stop", _shadow=shadow, pos=pos, mutation=Mutation()) - - def set_stop_option(self, value: str = "all", value_id: Optional[str] = None): - return self.add_field(Field("STOP_OPTION", value, value_id)) - - def set_hasnext(self, has_next: bool = True): - self.mutation.has_next = has_next - return self - - class StartAsClone(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_start_as_clone", _shadow=shadow, pos=pos) - - class CreateCloneOf(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_create_clone_of", _shadow=shadow, pos=pos) - - def set_clone_option(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("CLONE_OPTION", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class CreateCloneOfMenu(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_create_clone_of_menu", _shadow=shadow, pos=pos) - - def set_clone_option(self, value: str = "_myself_", value_id: Optional[str] = None): - return self.add_field(Field("CLONE_OPTION", value, value_id)) - - class DeleteThisClone(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_delete_this_clone", _shadow=shadow, pos=pos, can_next=False) - - class ForEach(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_for_each", _shadow=shadow, pos=pos) - - def set_substack(self, value, input_type: str | int = "block", shadow_status: int = 2, *, - input_id: Optional[str] = None): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input("SUBSTACK", value, input_type, shadow_status, input_id=input_id) - return self.add_input(inp) - - def set_value(self, value="5", input_type: str | int = "positive integer", shadow_status: int = 1, *, - input_id: Optional[str] = None): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input("VALUE", value, input_type, shadow_status, input_id=input_id) - return self.add_input(inp) - - def set_variable(self, value: str = "i", value_id: Optional[str] = None): - return self.add_field(Field("VARIABLE", value, value_id)) - - class GetCounter(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_get_counter", _shadow=shadow, pos=pos) - - class IncrCounter(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_incr_counter", _shadow=shadow, pos=pos) - - class ClearCounter(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_clear_counter", _shadow=shadow, pos=pos) - - class AllAtOnce(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "control_all_at_once", _shadow=shadow, pos=pos) - - def set_substack(self, value, input_type: str | int = "block", shadow_status: int = 2, *, - input_id: Optional[str] = None): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input("SUBSTACK", value, input_type, shadow_status, input_id=input_id) - return self.add_input(inp) - - -class Sensing: - class TouchingObject(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_touchingobject", _shadow=shadow, pos=pos) - - def set_touching_object_menu(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("TOUCHINGOBJECTMENU", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class TouchingObjectMenu(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_touchingobjectmenu", _shadow=shadow, pos=pos) - - def set_touching_object_menu(self, value: str = "_mouse_", value_id: Optional[str] = None): - return self.add_field(Field("TOUCHINGOBJECTMENU", value, value_id)) - - class TouchingColor(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_touchingcolor", _shadow=shadow, pos=pos) - - def set_color(self, value="#0000FF", input_type: str | int = "color", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("COLOR", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class ColorIsTouchingColor(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_coloristouchingcolor", _shadow=shadow, pos=pos) - - def set_color1(self, value="#0000FF", input_type: str | int = "color", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("COLOR", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_color2(self, value="#00FF00", input_type: str | int = "color", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("COLOR2", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class DistanceTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_distanceto", _shadow=shadow, pos=pos) - - def set_distance_to_menu(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("DISTANCETOMENU", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class DistanceToMenu(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_distancetomenu", _shadow=shadow, pos=pos) - - def set_distance_to_menu(self, value: str = "_mouse_", value_id: Optional[str] = None): - return self.add_field(Field("DISTANCETOMENU", value, value_id)) - - class Loud(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_loud", _shadow=shadow, pos=pos) - - class AskAndWait(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_askandwait", _shadow=shadow, pos=pos) - - def set_question(self, value="What's your name?", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("QUESTION", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer) - ) - - class Answer(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_answer", _shadow=shadow, pos=pos) - - class KeyPressed(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_keypressed", _shadow=shadow, pos=pos) - - def set_key_option(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("KEY_OPTION", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class KeyOptions(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_keyoptions", _shadow=shadow, pos=pos) - - def set_key_option(self, value: str = "space", value_id: Optional[str] = None): - return self.add_field(Field("KEY_OPTION", value, value_id)) - - class MouseDown(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_mousedown", _shadow=shadow, pos=pos) - - class MouseX(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_mousex", _shadow=shadow, pos=pos) - - class MouseY(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_mousey", _shadow=shadow, pos=pos) - - class SetDragMode(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_setdragmode", _shadow=shadow, pos=pos) - - def set_drag_mode(self, value: str = "draggable", value_id: Optional[str] = None): - return self.add_field(Field("DRAG_MODE", value, value_id)) - - class Loudness(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_loudness", _shadow=shadow, pos=pos) - - class Timer(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_timer", _shadow=shadow, pos=pos) - - class ResetTimer(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_resettimer", _shadow=shadow, pos=pos) - - class Of(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_of", _shadow=shadow, pos=pos) - - def set_object(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("OBJECT", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_property(self, value: str = "backdrop #", value_id: Optional[str] = None): - return self.add_field(Field("PROPERTY", value, value_id)) - - class OfObjectMenu(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_of_object_menu", _shadow=shadow, pos=pos) - - def set_object(self, value: str = "_stage_", value_id: Optional[str] = None): - return self.add_field(Field("OBJECT", value, value_id)) - - class Current(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_current", _shadow=shadow, pos=pos) - - def set_current_menu(self, value: str = "YEAR", value_id: Optional[str] = None): - return self.add_field(Field("CURRENTMENU", value, value_id)) - - class DaysSince2000(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_dayssince2000", _shadow=shadow, pos=pos) - - class Username(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_username", _shadow=shadow, pos=pos) - - class UserID(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "sensing_userid", _shadow=shadow, pos=pos) - - -class Operators: - class Add(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_add", _shadow=shadow, pos=pos) - - def set_num1(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NUM1", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_num2(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NUM2", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Subtract(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_subtract", _shadow=shadow, pos=pos) - - def set_num1(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NUM1", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_num2(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NUM2", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Multiply(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_multiply", _shadow=shadow, pos=pos) - - def set_num1(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NUM1", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_num2(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NUM2", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Divide(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_divide", _shadow=shadow, pos=pos) - - def set_num1(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NUM1", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_num2(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NUM2", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Random(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_random", _shadow=shadow, pos=pos) - - def set_from(self, value="1", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("FROM", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_to(self, value="10", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("TO", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class GT(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_gt", _shadow=shadow, pos=pos) - - def set_operand1(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("OPERAND1", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_operand2(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("OPERAND2", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class LT(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_lt", _shadow=shadow, pos=pos) - - def set_operand1(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("OPERAND1", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_operand2(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("OPERAND2", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Equals(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_equals", _shadow=shadow, pos=pos) - - def set_operand1(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("OPERAND1", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_operand2(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("OPERAND2", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class And(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_and", _shadow=shadow, pos=pos) - - def set_operand1(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("OPERAND1", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_operand2(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("OPERAND2", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Or(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_or", _shadow=shadow, pos=pos) - - def set_operand1(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("OPERAND1", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_operand2(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("OPERAND2", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Not(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_not", _shadow=shadow, pos=pos) - - def set_operand(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("OPERAND", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Join(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_join", _shadow=shadow, pos=pos) - - def set_string1(self, value="apple ", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("STRING1", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_string2(self, value="banana", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("STRING2", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class LetterOf(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_letter_of", _shadow=shadow, pos=pos) - - def set_letter(self, value="1", input_type: str | int = "positive integer", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("LETTER", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_string(self, value="apple", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("STRING", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Length(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_length", _shadow=shadow, pos=pos) - - def set_string(self, value="apple", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("STRING", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Contains(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_contains", _shadow=shadow, pos=pos) - - def set_string1(self, value="apple", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("STRING1", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_string2(self, value="a", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("STRING2", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Mod(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_mod", _shadow=shadow, pos=pos) - - def set_num1(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NUM1", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_num2(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NUM2", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Round(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_round", _shadow=shadow, pos=pos) - - def set_num(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NUM", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class MathOp(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "operator_mathop", _shadow=shadow, pos=pos) - - def set_num(self, value='', input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NUM", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_operator(self, value: str = "abs", value_id: Optional[str] = None): - return self.add_field(Field("OPERATOR", value, value_id)) - - -class Data: - class VariableArr(Block): - def __init__(self, value, input_type: str | int = "variable", shadow_status: Optional[int] = None, *, - pos: tuple[int | float, int | float] = (0, 0)): - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - inp = Input(None, value, input_type, shadow_status) - if inp.type_str == "block": - arr = inp.json[0] - else: - arr = inp.json[1][-1] - - super().__init__(array=arr, pos=pos) - - class Variable(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_variable", _shadow=shadow, pos=pos) - - def set_variable(self, value: str | Variable = "variable", value_id: Optional[str] = None): - return self.add_field(Field("VARIABLE", value, value_id)) - - class SetVariableTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_setvariableto", _shadow=shadow, pos=pos) - - def set_value(self, value="0", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("VALUE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_variable(self, value: str | Variable = "variable", value_id: Optional[str] = None): - return self.add_field(Field("VARIABLE", value, value_id)) - - class ChangeVariableBy(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_changevariableby", _shadow=shadow, pos=pos) - - def set_value(self, value="1", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("VALUE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_variable(self, value: str | Variable = "variable", value_id: Optional[str] = None): - return self.add_field(Field("VARIABLE", value, value_id)) - - class ShowVariable(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_showvariable", _shadow=shadow, pos=pos) - - def set_variable(self, value: str | Variable = "variable", value_id: Optional[str] = None): - return self.add_field(Field("VARIABLE", value, value_id)) - - class HideVariable(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_hidevariable", _shadow=shadow, pos=pos) - - def set_variable(self, value: str | Variable = "variable", value_id: Optional[str] = None): - return self.add_field(Field("VARIABLE", value, value_id)) - - class ListArr(Block): - def __init__(self, value, input_type: str | int = "list", shadow_status: Optional[int] = None, *, - pos: tuple[int | float, int | float] = (0, 0)): - inp = Input(None, value, input_type, shadow_status) - if inp.type_str == "block": - arr = inp.json[0] - else: - arr = inp.json[1][-1] - - super().__init__(array=arr, pos=pos) - - class ListContents(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_listcontents", _shadow=shadow, pos=pos) - - def set_list(self, value: str | List = "my list", value_id: Optional[str] = None): - return self.add_field(Field("LIST", value, value_id)) - - class AddToList(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_addtolist", _shadow=shadow, pos=pos) - - def set_item(self, value="thing", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("ITEM", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_list(self, value: str | List = "list", value_id: Optional[str] = None): - return self.add_field(Field("LIST", value, value_id)) - - class DeleteOfList(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_deleteoflist", _shadow=shadow, pos=pos) - - def set_index(self, value="random", input_type: str | int = "positive integer", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("INDEX", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_list(self, value: str | List = "list", value_id: Optional[str] = None): - return self.add_field(Field("LIST", value, value_id)) - - class InsertAtList(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_insertatlist", _shadow=shadow, pos=pos) - - def set_item(self, value="thing", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("ITEM", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_index(self, value="random", input_type: str | int = "positive integer", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("INDEX", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_list(self, value: str | List = "list", value_id: Optional[str] = None): - return self.add_field(Field("LIST", value, value_id)) - - class DeleteAllOfList(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_deletealloflist", _shadow=shadow, pos=pos) - - def set_list(self, value: str | List = "list", value_id: Optional[str] = None): - return self.add_field(Field("LIST", value, value_id)) - - class ReplaceItemOfList(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_replaceitemoflist", _shadow=shadow, pos=pos) - - def set_item(self, value="thing", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("ITEM", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_index(self, value="random", input_type: str | int = "positive integer", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("INDEX", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_list(self, value: str | List = "list", value_id: Optional[str] = None): - return self.add_field(Field("LIST", value, value_id)) - - class ItemOfList(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_itemoflist", _shadow=shadow, pos=pos) - - def set_index(self, value="random", input_type: str | int = "positive integer", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("INDEX", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_list(self, value: str | List = "list", value_id: Optional[str] = None): - return self.add_field(Field("LIST", value, value_id)) - - class ItemNumOfList(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_itemnumoflist", _shadow=shadow, pos=pos) - - def set_item(self, value="thing", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("ITEM", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_list(self, value: str | List = "list", value_id: Optional[str] = None): - return self.add_field(Field("LIST", value, value_id)) - - class LengthOfList(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_lengthoflist", _shadow=shadow, pos=pos) - - def set_list(self, value: str | List = "list", value_id: Optional[str] = None): - return self.add_field(Field("LIST", value, value_id)) - - class ListContainsItem(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_listcontainsitem", _shadow=shadow, pos=pos) - - def set_item(self, value="thing", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("ITEM", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_list(self, value: str | List = "list", value_id: Optional[str] = None): - return self.add_field(Field("LIST", value, value_id)) - - class ShowList(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_showlist", _shadow=shadow, pos=pos) - - def set_list(self, value: str | List = "list", value_id: Optional[str] = None): - return self.add_field(Field("LIST", value, value_id)) - - class HideList(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_hidelist", _shadow=shadow, pos=pos) - - def set_list(self, value: str | List = "list", value_id: Optional[str] = None): - return self.add_field(Field("LIST", value, value_id)) - - class ListIndexAll(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_listindexall", _shadow=shadow, pos=pos) - - class ListIndexRandom(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "data_listindexrandom", _shadow=shadow, pos=pos) - - -class Proc: - class Definition(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "procedures_definition", _shadow=shadow, pos=pos) - - def set_custom_block(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("custom_block", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Call(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "procedures_call", _shadow=shadow, pos=pos, mutation=Mutation()) - - def set_proc_code(self, proc_code: str = ''): - self.mutation.proc_code = proc_code - return self - - def set_argument_ids(self, *argument_ids: list[str]): - self.mutation.argument_ids = argument_ids - return self - - def set_warp(self, warp: bool = True): - self.mutation.warp = warp - return self - - def set_arg(self, arg, value='', input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input(arg, value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class Declaration(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "procedures_declaration", _shadow=shadow, pos=pos, mutation=Mutation()) - - def set_proc_code(self, proc_code: str = ''): - self.mutation.proc_code = proc_code - return self - - class Prototype(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "procedures_prototype", _shadow=shadow, pos=pos, mutation=Mutation()) - - def set_proc_code(self, proc_code: str = ''): - self.mutation.proc_code = proc_code - return self - - def set_argument_ids(self, *argument_ids: list[str]): - self.mutation.argument_ids = argument_ids - return self - - def set_argument_names(self, *argument_names: list[str]): - self.mutation.argument_names = list(argument_names) - return self - - def set_argument_defaults(self, *argument_defaults: list[str]): - self.mutation.argument_defaults = argument_defaults - return self - - def set_warp(self, warp: bool = True): - self.mutation.warp = warp - return self - - def set_arg(self, arg, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input(arg, value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - -class Args: - class EditorBoolean(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "argument_editor_boolean", _shadow=shadow, pos=pos, mutation=Mutation()) - - def set_text(self, value: str = "foo", value_id: Optional[str] = None): - return self.add_field(Field("TEXT", value, value_id)) - - class EditorStringNumber(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "argument_editor_string_number", _shadow=shadow, pos=pos, mutation=Mutation()) - - def set_text(self, value: str = "foo", value_id: Optional[str] = None): - return self.add_field(Field("TEXT", value, value_id)) - - class ReporterBoolean(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "argument_reporter_boolean", _shadow=shadow, pos=pos, mutation=Mutation()) - - def set_value(self, value: str = "boolean", value_id: Optional[str] = None): - return self.add_field(Field("VALUE", value, value_id)) - - class ReporterStringNumber(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "argument_reporter_string_number", _shadow=shadow, pos=pos, mutation=Mutation()) - - def set_value(self, value: str = "boolean", value_id: Optional[str] = None): - return self.add_field(Field("VALUE", value, value_id)) - - -class Addons: - class IsTurbowarp(Args.ReporterBoolean): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(_shadow=shadow, pos=pos) - self.set_value("is turbowarp?") - - class IsCompiled(Args.ReporterBoolean): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(_shadow=shadow, pos=pos) - self.set_value("is compiled?") - - class IsForkphorus(Args.ReporterBoolean): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(_shadow=shadow, pos=pos) - self.set_value("is forkphorus?") - - class Breakpoint(Proc.Call): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(_shadow=shadow, pos=pos) - self.set_proc_code("​​breakpoint​​") - - class Log(Proc.Call): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(_shadow=shadow, pos=pos) - self.set_proc_code("​​log​​ %s") - self.set_argument_ids("arg0") - - def set_message(self, value='', input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - return self.set_arg("arg0", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer) - - class Warn(Proc.Call): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(_shadow=shadow, pos=pos) - self.set_proc_code("​​warn​​ %s") - self.set_argument_ids("arg0") - - def set_message(self, value='', input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - return self.set_arg("arg0", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer) - - class Error(Proc.Call): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(_shadow=shadow, pos=pos) - self.set_proc_code("​​error​​ %s") - self.set_argument_ids("arg0") - - def set_message(self, value='', input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - return self.set_arg("arg0", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer) - - -class Pen: - class Clear(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_clear", _shadow=shadow, pos=pos) - - class Stamp(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_stamp", _shadow=shadow, pos=pos) - - class PenDown(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_penDown", _shadow=shadow, pos=pos) - - class PenUp(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_penUp", _shadow=shadow, pos=pos) - - class SetPenColorToColor(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_setPenColorToColor", _shadow=shadow, pos=pos) - - def set_color(self, value="#FF0000", input_type: str | int = "color", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("COLOR", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class ChangePenParamBy(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_changePenColorParamBy", _shadow=shadow, pos=pos) - - def set_param(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("COLOR_PARAM", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_value(self, value="10", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("VALUE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class SetPenParamTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_setPenColorParamTo", _shadow=shadow, pos=pos) - - def set_param(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("COLOR_PARAM", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_value(self, value="10", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("VALUE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class ChangePenSizeBy(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_changePenSizeBy", _shadow=shadow, pos=pos) - - def set_size(self, value="1", input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("SIZE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class SetPenSizeTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_setPenSizeTo", _shadow=shadow, pos=pos) - - def set_size(self, value="1", input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("SIZE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class SetPenHueTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_setPenHueToNumber", _shadow=shadow, pos=pos) - - def set_hue(self, value="1", input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("HUE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class ChangePenHueBy(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_changePenHueBy", _shadow=shadow, pos=pos) - - def set_hue(self, value="1", input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("HUE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class SetPenShadeTo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_setPenShadeToNumber", _shadow=shadow, pos=pos) - - def set_shade(self, value="1", input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("SHADE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class ChangePenShadeBy(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_changePenShadeBy", _shadow=shadow, pos=pos) - - def set_shade(self, value="1", input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("SHADE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class ColorParamMenu(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "pen_menu_colorParam", _shadow=shadow, pos=pos) - - def set_color_param(self, value: str = "color", value_id: Optional[str] = None): - return self.add_field(Field("colorParam", value, value_id)) - - -class Music: - class PlayDrumForBeats(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "music_playDrumForBeats", _shadow=shadow, pos=pos) - - def set_drum(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("DRUM", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_beats(self, value="0.25", input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("BEATS", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class PlayNoteForBeats(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "music_playDrumForBeats", _shadow=shadow, pos=pos) - - def set_note(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("NOTE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_beats(self, value="0.25", input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("BEATS", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class RestForBeats(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "music_restForBeats", _shadow=shadow, pos=pos) - - def set_beats(self, value="0.25", input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("BEATS", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class SetTempo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "music_setTempo", _shadow=shadow, pos=pos) - - def set_beats(self, value="60", input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("TEMPO", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class ChangeTempo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "music_changeTempo", _shadow=shadow, pos=pos) - - def set_beats(self, value="60", input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("TEMPO", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class GetTempo(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "music_getTempo", _shadow=shadow, pos=pos) - - class SetInstrument(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "music_setInstrument", _shadow=shadow, pos=pos) - - def set_instrument(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("INSTRUMENT", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class MidiPlayDrumForBeats(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "music_midiPlayDrumForBeats", _shadow=shadow, pos=pos) - - def set_drum(self, value="123", input_type: str | int = "positive integer", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("DRUM", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_beats(self, value="1", input_type: str | int = "positive number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("BEATS", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class MidiSetInstrument(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "music_midiSetInstrument", _shadow=shadow, pos=pos) - - def set_instrument(self, value="6", input_type: str | int = "positive integer", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("INSTRUMENT", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class MenuDrum(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "music_menu_DRUM", _shadow=shadow, pos=pos) - - def set_drum(self, value: str = "1", value_id: Optional[str] = None): - return self.add_field(Field("DRUM", value, value_id)) - - class MenuInstrument(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "music_menu_INSTRUMENT", _shadow=shadow, pos=pos) - - def set_instrument(self, value: str = "1", value_id: Optional[str] = None): - return self.add_field(Field("INSTRUMENT", value, value_id)) - - -class VideoSensing: - class WhenMotionGreaterThan(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "videoSensing_whenMotionGreaterThan", _shadow=shadow, pos=pos) - - def set_reference(self, value="10", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("REFERENCE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class VideoOn(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "videoSensing_videoOn", _shadow=shadow, pos=pos) - - def set_attribute(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("ATTRIBUTE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_subject(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("SUBJECT", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class MenuAttribute(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "videoSensing_menu_ATTRIBUTE", _shadow=shadow, pos=pos) - - def set_attribute(self, value: str = "motion", value_id: Optional[str] = None): - return self.add_field(Field("ATTRIBUTE", value, value_id)) - - class MenuSubject(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "videoSensing_menu_SUBJECT", _shadow=shadow, pos=pos) - - def set_subject(self, value: str = "this sprite", value_id: Optional[str] = None): - return self.add_field(Field("SUBJECT", value, value_id)) - - class VideoToggle(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "videoSensing_videoToggle", _shadow=shadow, pos=pos) - - def set_video_state(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("VIDEO_STATE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class MenuVideoState(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "videoSensing_menu_VIDEO_STATE", _shadow=shadow, pos=pos) - - def set_video_state(self, value: str = "on", value_id: Optional[str] = None): - return self.add_field(Field("VIDEO_STATE", value, value_id)) - - class SetVideoTransparency(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "videoSensing_setVideoTransparency", _shadow=shadow, pos=pos) - - def set_transparency(self, value: str = "50", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("TRANSPARENCY", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - -class Text2Speech: - class SpeakAndWait(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "text2speech_speakAndWait", _shadow=shadow, pos=pos) - - def set_words(self, value: str = "50", input_type: str | int = "number", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("WORDS", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class SetVoice(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "text2speech_setVoice", _shadow=shadow, pos=pos) - - def set_voice(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("VOICE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class MenuVoices(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "text2speech_menu_voices", _shadow=shadow, pos=pos) - - def set_voices(self, value: str = "ALTO", value_id: Optional[str] = None): - return self.add_field(Field("voices", value, value_id)) - - class SetLanguage(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "text2speech_setLanguage", _shadow=shadow, pos=pos) - - def set_language(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("LANGUAGE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class MenuLanguages(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "text2speech_menu_languages", _shadow=shadow, pos=pos) - - def set_languages(self, value: str = "en", value_id: Optional[str] = None): - return self.add_field(Field("languages", value, value_id)) - - -class Translate: - class GetTranslate(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "translate_getTranslate", _shadow=shadow, pos=pos) - - def set_words(self, value="hello!", input_type: str | int = "string", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("WORDS", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - def set_language(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("LANGUAGE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class MenuLanguages(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "translate_menu_languages", _shadow=shadow, pos=pos) - - def set_languages(self, value: str = "sv", value_id: Optional[str] = None): - return self.add_field(Field("languages", value, value_id)) - - class GetViewerLanguage(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "translate_getViewerLanguage", _shadow=shadow, pos=pos) - - -class MakeyMakey: - class WhenMakeyKeyPressed(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "makeymakey_whenMakeyKeyPressed", _shadow=shadow, pos=pos) - - def set_key(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("KEY", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class MenuKey(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "makeymakey_menu_KEY", _shadow=shadow, pos=pos) - - def set_key(self, value: str = "SPACE", value_id: Optional[str] = None): - return self.add_field(Field("KEY", value, value_id)) - - class WhenCodePressed(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "makeymakey_whenCodePressed", _shadow=shadow, pos=pos) - - def set_sequence(self, value, input_type: str | int = "block", shadow_status: int = 1, *, - input_id: Optional[str] = None, obscurer: Optional[str | Block] = None): - - if isinstance(value, Block): - value = self.target.add_block(value) - elif isinstance(value, list) or isinstance(value, tuple): - if isinstance(value[0], Block): - value = self.target.link_chain(value) - return self.add_input( - Input("SEQUENCE", value, input_type, shadow_status, input_id=input_id, obscurer=obscurer)) - - class MenuSequence(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "makeymakey_menu_SEQUENCE", _shadow=shadow, pos=pos) - - def set_key(self, value: str = "LEFT UP RIGHT", value_id: Optional[str] = None): - return self.add_field(Field("SEQUENCE", value, value_id)) - - -class CoreExample: - class ExampleOpcode(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "coreExample_exampleOpcode", _shadow=shadow, pos=pos) - - class ExampleWithInlineImage(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "coreExample_exampleWithInlineImage", _shadow=shadow, pos=pos) - - -class OtherBlocks: - class Note(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "note", _shadow=shadow, pos=pos) - - def set_note(self, value: str = "60", value_id: Optional[str] = None): - return self.add_field(Field("NOTE", value, value_id)) - - class Matrix(Block): - def __init__(self, *, shadow: bool = True, pos: tuple[int | float, int | float] = (0, 0)): - super().__init__(None, "matrix", _shadow=shadow, pos=pos) - - def set_note(self, value: str = "0101010101100010101000100", value_id: Optional[str] = None): - return self.add_field(Field("MATRIX", value, value_id)) - - class RedHatBlock(Block): - def __init__(self, *, shadow: bool = False, pos: tuple[int | float, int | float] = (0, 0)): - # Note: There is no single opcode for the red hat block as the block is simply the result of an error - # The opcode here has been set to 'redhatblock' to make it obvious what is going on - - # (It's not called red_hat_block because then TurboWarp thinks that it's supposed to find an extension - # called red) - - # Appendix: You **CAN** actually add comments to this block, however it will make the block misbehave in the - # editor. The link between the comment and the block will not be visible, but will be visible with the - # corresponding TurboWarp addon - super().__init__(None, "redhatblock", _shadow=shadow, pos=pos, can_next=False) From 5be6b1583c4ed187db7481e8c4bb971fc90f26e1 Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:11:55 +0100 Subject: [PATCH 06/21] doc: blockshape.py --- scratchattach/editor/blockshape.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scratchattach/editor/blockshape.py b/scratchattach/editor/blockshape.py index ebfa6614..49cfb407 100644 --- a/scratchattach/editor/blockshape.py +++ b/scratchattach/editor/blockshape.py @@ -3,7 +3,7 @@ """ from __future__ import annotations -# Perhaps this should be merged with pallet.py +# Perhaps this should be merged with pallete.py from dataclasses import dataclass from typing import Final @@ -12,6 +12,9 @@ class _MutationDependent(commons.Singleton): + """ + Singleton value that represents the uncertainty of a vablue because it depends on block mutation data. + """ def __bool__(self): raise TypeError("Need mutation data to work out attribute value.") @@ -23,7 +26,7 @@ def __bool__(self): @dataclass(init=True, repr=True) class BlockShape: """ - A class that describes the shape of a block; e.g. is it a stack, c-mouth, cap, hat reporter, boolean or menu block? + The shape of a block; e.g. is it a stack, c-mouth, cap, hat reporter, boolean or menu block? """ is_stack: bool | _MutationDependent = False # Most blocks - e.g. move [10] steps is_c_mouth: bool | _MutationDependent = False # Has substack - e.g. repeat @@ -262,7 +265,7 @@ class BlockShapes(_EnumWrapper): MAKEYMAKEY_MENU_KEY = BlockShape(is_reporter=True, is_menu=True, opcode="makeymakey_menu_KEY") MAKEYMAKEY_MENU_SEQUENCE = BlockShape(is_reporter=True, is_menu=True, opcode="makeymakey_menu_SEQUENCE") - MICROBIT_WHENBUTTONPRESSED = BlockShape(opcode="microbit_whenButtonPressed") + MICROBIT_WHENBUTTONPRESSED = BlockShape(opcode="microbit_whenButtonPressed") # todo: finish this MICROBIT_ISBUTTONPRESSED = BlockShape(opcode="microbit_isButtonPressed") MICROBIT_WHENGESTURE = BlockShape(opcode="microbit_whenGesture") MICROBIT_DISPLAYSYMBOL = BlockShape(opcode="microbit_displaySymbol") From 46ac0d09d970577539f4827d77fd3d7b84858fab Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:13:30 +0100 Subject: [PATCH 07/21] doc: build_defaulting.py --- scratchattach/editor/build_defaulting.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scratchattach/editor/build_defaulting.py b/scratchattach/editor/build_defaulting.py index b7d22f7d..48adf4a2 100644 --- a/scratchattach/editor/build_defaulting.py +++ b/scratchattach/editor/build_defaulting.py @@ -25,6 +25,9 @@ def stack_add_sprite(_sprite: sprite.Sprite): def current_sprite() -> sprite.Sprite | None: + """ + Retrieve the default sprite from the top of the sprite stack + """ if len(_sprite_stack) == 0: return None return _sprite_stack[-1] From e8b0eb31d0bb3ad8b7bcce01fcbf420a1c3635eb Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:14:22 +0100 Subject: [PATCH 08/21] doc: comment.py --- scratchattach/editor/comment.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scratchattach/editor/comment.py b/scratchattach/editor/comment.py index 82babd80..932c1075 100644 --- a/scratchattach/editor/comment.py +++ b/scratchattach/editor/comment.py @@ -5,6 +5,9 @@ class Comment(base.IDComponent): + """ + Represents a comment in the scratch editor. + """ def __init__(self, _id: Optional[str] = None, _block: Optional[block.Block] = None, x: int = 0, y: int = 0, width: int = 200, height: int = 200, minimized: bool = False, text: str = '', *, _block_id: Optional[str] = None, _sprite: sprite.Sprite = build_defaulting.SPRITE_DEFAULT, pos: Optional[tuple[int, int]] = None): @@ -32,6 +35,9 @@ def __repr__(self): @property def block_id(self): + """ + Retrieve the id of the associateed block (if applicable) + """ if self.block is not None: return self.block.id elif self._block_id is not None: From 4207f9b4f39ec52e2e5db2341e7c773799ce9a15 Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:19:00 +0100 Subject: [PATCH 09/21] doc: commons.py --- scratchattach/editor/commons.py | 35 ++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/scratchattach/editor/commons.py b/scratchattach/editor/commons.py index 110c9c9e..04e8d5b6 100644 --- a/scratchattach/editor/commons.py +++ b/scratchattach/editor/commons.py @@ -72,7 +72,8 @@ def read_exponent(sub: str): return json.loads(ret) - +# todo: consider if this should be moved to util.commons instead of editor.commons +# note: this is currently unused code def consume_json(_str: str, i: int = 0) -> str | float | int | dict | list | bool | None: """ *'gobble up some JSON until we hit something not quite so tasty'* @@ -134,16 +135,20 @@ def is_partial_json(_str: str, i: int = 0) -> bool: def is_valid_json(_str: Any) -> bool: + """ + Try to load a json string, if it fails, return False, else return true. + """ try: json.loads(_str) return True - except ValueError: - return False - except TypeError: + except (ValueError, TypeError): return False def noneless_update(obj: dict, update: dict) -> None: + """ + equivalent to dict.update, except and values of None are not assigned + """ for key, value in update.items(): if value is not None: obj[key] = value @@ -163,6 +168,9 @@ def remove_nones(obj: dict) -> None: def safe_get(lst: list | tuple, _i: int, default: Optional[Any] = None) -> Any: + """ + Like dict.get() but for lists + """ if len(lst) <= _i: return default else: @@ -183,6 +191,9 @@ def trim_final_nones(lst: list) -> list: def dumps_ifnn(obj: Any) -> str: + """ + Return json.dumps(obj) if the object is not None + """ if obj is None: return None else: @@ -190,9 +201,13 @@ def dumps_ifnn(obj: Any) -> str: def gen_id() -> str: - # The old 'naïve' method but that chances of a repeat are so miniscule - # Have to check if whitespace chars break it - # May later add checking within sprites so that we don't need such long ids (we can save space this way) + """ + Generate an id for scratch blocks/variables/lists/broadcasts + + The old 'naïve' method but that chances of a repeat are so miniscule + Have to check if whitespace chars break it + May later add checking within sprites so that we don't need such long ids (we can save space this way) + """ return ''.join(random.choices(ID_CHARS, k=20)) @@ -212,6 +227,9 @@ def sanitize_fn(filename: str): def get_folder_name(name: str) -> str | None: + """ + Get the name of the folder if this is a turbowarp-style costume name + """ if name.startswith('//'): return None @@ -233,6 +251,9 @@ def get_name_nofldr(name: str) -> str: class Singleton(object): + """ + Singleton base class + """ _instance: Singleton def __new__(cls, *args, **kwargs): From 8a72de4420e47d9aeb253d52a8c8fc63648c8a79 Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:22:21 +0100 Subject: [PATCH 10/21] doc: extension.py --- scratchattach/editor/extension.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scratchattach/editor/extension.py b/scratchattach/editor/extension.py index 81bfed06..baa4e06c 100644 --- a/scratchattach/editor/extension.py +++ b/scratchattach/editor/extension.py @@ -1,3 +1,7 @@ +""" +Enum & dataclass representing extension categories +""" + from __future__ import annotations @@ -7,8 +11,11 @@ from ..utils import enums -@dataclass(init=True, repr=True) +@dataclass class Extension(base.JSONSerializable): + """ + Represents an extension in the Scratch block pallete - e.g. video sensing + """ code: str name: str = None @@ -40,4 +47,4 @@ class Extensions(enums._EnumWrapper): TRANSLATE = Extension("translate", "Translate Extension") VIDEOSENSING = Extension("videoSensing", "Video Sensing Extension") WEDO2 = Extension("wedo2", "LEGO Education WeDo 2.0 Extension") - COREEXAMPLE = Extension("coreExample", "CoreEx Extension") + COREEXAMPLE = Extension("coreExample", "CoreEx Extension") # hidden extension! From 9fcbb2560b24c8d81155d20842fa0b03c8f96329 Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:24:55 +0100 Subject: [PATCH 11/21] doc: field.py --- scratchattach/editor/field.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scratchattach/editor/field.py b/scratchattach/editor/field.py index 2a0dc088..b8e4a898 100644 --- a/scratchattach/editor/field.py +++ b/scratchattach/editor/field.py @@ -38,6 +38,9 @@ def __repr__(self): @property def value_id(self): + """ + Get the id of the value associated with this field (if applicable) - when value is var/list/broadcast + """ if self.id is not None: return self.id else: @@ -48,6 +51,9 @@ def value_id(self): @property def value_str(self): + """ + Convert the associated value to a string - if this is a VLB, return the VLB name + """ if not isinstance(self.value, base.NamedIDComponent): return self.value else: @@ -55,6 +61,9 @@ def value_str(self): @property def name(self) -> str: + """ + Fetch the name of this field using the associated block + """ for _name, _field in self.block.fields.items(): if _field is self: return _name From 63a5523970ff232bc6b19246e07222a562569e8e Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:25:48 +0100 Subject: [PATCH 12/21] doc: inputs.py --- scratchattach/editor/inputs.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scratchattach/editor/inputs.py b/scratchattach/editor/inputs.py index c43050b2..3a8dba8d 100644 --- a/scratchattach/editor/inputs.py +++ b/scratchattach/editor/inputs.py @@ -8,8 +8,11 @@ from dataclasses import dataclass -@dataclass(init=True) +@dataclass class ShadowStatus: + """ + Dataclass representing a possible shadow value and giving it a name + """ idx: int name: str From 09e8873a7619bdf504305c7b4856b9b17c826f85 Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:28:50 +0100 Subject: [PATCH 13/21] doc: meta.py --- scratchattach/editor/meta.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/scratchattach/editor/meta.py b/scratchattach/editor/meta.py index 88b9a56f..9eef4f87 100644 --- a/scratchattach/editor/meta.py +++ b/scratchattach/editor/meta.py @@ -7,7 +7,7 @@ from typing import Optional -@dataclass(init=True, repr=True) +@dataclass class PlatformMeta(base.JSONSerializable): name: str = None url: str = field(repr=True, default=None) @@ -36,8 +36,13 @@ def from_json(data: dict | None): META_SET_PLATFORM = False -def set_meta_platform(true_false: bool = False): +def set_meta_platform(true_false: bool = None): + """ + toggle whether to set the meta platform by default (or specify a value) + """ global META_SET_PLATFORM + if true_false is None: + true_false = bool(1 - true_false) META_SET_PLATFORM = true_false @@ -69,7 +74,10 @@ def __repr__(self): @property def vm_is_valid(self): - # Thanks to TurboWarp for this pattern ↓↓↓↓, I just copied it + """ + Check whether the vm value is valid using a regex + Thanks to TurboWarp for this pattern ↓↓↓↓, I just copied it + """ return re.match("^([0-9]+\\.[0-9]+\\.[0-9]+)($|-)", self.vm) is not None def to_json(self): From 110a94e5ce549b2f3b6feb8c0ae742253a8dde91 Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:30:43 +0100 Subject: [PATCH 14/21] doc: monitor.py --- scratchattach/editor/monitor.py | 82 ++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/scratchattach/editor/monitor.py b/scratchattach/editor/monitor.py index 75a778c0..2f78dba0 100644 --- a/scratchattach/editor/monitor.py +++ b/scratchattach/editor/monitor.py @@ -2,6 +2,8 @@ from typing import Optional, TYPE_CHECKING +from typing_extensions import deprecated + if TYPE_CHECKING: from . import project @@ -26,6 +28,8 @@ def __init__(self, reporter: Optional[base.NamedIDComponent] = None, """ Represents a variable/list monitor https://en.scratch-wiki.info/wiki/Scratch_File_Format#Monitors + + Instantiating these yourself and attaching these to projects can lead to interesting results! """ assert isinstance(reporter, base.SpriteSubComponent) or reporter is None @@ -135,41 +139,43 @@ def link_using_project(self): self.reporter = new_vlb self.reporter_id = None - # @staticmethod - # def from_reporter(reporter: Block, _id: str = None, mode: str = "default", - # opcode: str = None, sprite_name: str = None, value=0, width: int | float = 0, - # height: int | float = 0, - # x: int | float = 5, y: int | float = 5, visible: bool = False, slider_min: int | float = 0, - # slider_max: int | float = 100, is_discrete: bool = True, params: dict = None): - # if "reporter" not in reporter.stack_type: - # warnings.warn(f"{reporter} is not a reporter block; the monitor will return '0'") - # elif "(menu)" in reporter.stack_type: - # warnings.warn(f"{reporter} is a menu block; the monitor will return '0'") - # # Maybe add note that length of list doesn't work fsr?? idk - # if _id is None: - # _id = reporter.opcode - # if opcode is None: - # opcode = reporter.opcode # .replace('_', ' ') - - # if params is None: - # params = {} - # for field in reporter.fields: - # if field.value_id is None: - # params[field.id] = field.value - # else: - # params[field.id] = field.value, field.value_id - - # return Monitor( - # _id, - # mode, - # opcode, - - # params, - # sprite_name, - # value, - - # width, height, - # x, y, - # visible, - # slider_min, slider_max, is_discrete - # ) + # todo: consider reimplementing this + @deprecated("This method does not work correctly (This may be fixed in the future)") + @staticmethod + def from_reporter(reporter: Block, _id: str = None, mode: str = "default", + opcode: str = None, sprite_name: str = None, value=0, width: int | float = 0, + height: int | float = 0, + x: int | float = 5, y: int | float = 5, visible: bool = False, slider_min: int | float = 0, + slider_max: int | float = 100, is_discrete: bool = True, params: dict = None): + if "reporter" not in reporter.stack_type: + warnings.warn(f"{reporter} is not a reporter block; the monitor will return '0'") + elif "(menu)" in reporter.stack_type: + warnings.warn(f"{reporter} is a menu block; the monitor will return '0'") + # Maybe add note that length of list doesn't work fsr?? idk + if _id is None: + _id = reporter.opcode + if opcode is None: + opcode = reporter.opcode # .replace('_', ' ') + + if params is None: + params = {} + for field in reporter.fields: + if field.value_id is None: + params[field.id] = field.value + else: + params[field.id] = field.value, field.value_id + + return Monitor( + _id, + mode, + opcode, + + params, + sprite_name, + value, + + width, height, + x, y, + visible, + slider_min, slider_max, is_discrete + ) From 822a5f8592f199159becde7003bc74b900c235cf Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:33:56 +0100 Subject: [PATCH 15/21] doc: mutation.py --- scratchattach/editor/mutation.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scratchattach/editor/mutation.py b/scratchattach/editor/mutation.py index e12566a1..6fbc8168 100644 --- a/scratchattach/editor/mutation.py +++ b/scratchattach/editor/mutation.py @@ -12,7 +12,7 @@ from . import block -@dataclass(init=True) +@dataclass class ArgumentType(base.Base): type: str proc_str: str @@ -38,7 +38,7 @@ def default(self) -> str | None: return None -@dataclass(init=True, repr=True) +@dataclass class ArgSettings(base.Base): ids: bool names: bool @@ -61,7 +61,7 @@ def __lt__(self, other): return int(self) > int(other) -@dataclass(init=True, repr=True) +@dataclass class Argument(base.MutationSubComponent): name: str default: str = '' @@ -103,6 +103,10 @@ class ArgTypes(enums._EnumWrapper): def parse_proc_code(_proc_code: str) -> list[str, ArgumentType] | None: + """ + Parse a proccode (part of a mutation) into argument types and strings + """ + if _proc_code is None: return None token = '' @@ -209,6 +213,9 @@ def argument_settings(self) -> ArgSettings: @property def parsed_proc_code(self) -> list[str, ArgumentType] | None: + """ + Parse the proc code into arguments & strings + """ return parse_proc_code(self.proc_code) @staticmethod From 2e7721efcf5f9790aec8130e92f9d7558273a34a Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:34:26 +0100 Subject: [PATCH 16/21] edit: pallete.py remove redundant dataclass args --- scratchattach/editor/pallete.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scratchattach/editor/pallete.py b/scratchattach/editor/pallete.py index 587fb485..64694912 100644 --- a/scratchattach/editor/pallete.py +++ b/scratchattach/editor/pallete.py @@ -12,13 +12,13 @@ from ..utils.enums import _EnumWrapper -@dataclass(init=True, repr=True) +@dataclass class FieldUsage: name: str value_type: prim.PrimTypes = None -@dataclass(init=True, repr=True) +@dataclass class SpecialFieldUsage(FieldUsage): name: str attrs: list[str] = None @@ -28,14 +28,14 @@ class SpecialFieldUsage(FieldUsage): value_type: None = None -@dataclass(init=True, repr=True) +@dataclass class InputUsage: name: str value_type: prim.PrimTypes = None default_obscurer: BlockUsage = None -@dataclass(init=True, repr=True) +@dataclass class BlockUsage: opcode: str fields: list[FieldUsage] = None From 688edc0ca7b8977b020a2baa84776fc3710a69a7 Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:34:51 +0100 Subject: [PATCH 17/21] edit: prim.py remove redundant dataclass args --- scratchattach/editor/prim.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scratchattach/editor/prim.py b/scratchattach/editor/prim.py index 98fd0f94..c7dca950 100644 --- a/scratchattach/editor/prim.py +++ b/scratchattach/editor/prim.py @@ -8,7 +8,7 @@ from ..utils import enums, exceptions -@dataclass(init=True, repr=True) +@dataclass class PrimType(base.JSONSerializable): code: int name: str From 1df85917f6b22864947f203a37d15cae1a4d38db Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:36:56 +0100 Subject: [PATCH 18/21] doc: project.py --- scratchattach/editor/project.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scratchattach/editor/project.py b/scratchattach/editor/project.py index 1793d433..171756e4 100644 --- a/scratchattach/editor/project.py +++ b/scratchattach/editor/project.py @@ -14,6 +14,9 @@ class Project(base.JSONExtractable): + """ + sa.editor's equivalent of the ProjectBody. Represents the editor contents of a scratch project + """ def __init__(self, _name: Optional[str] = None, _meta: Optional[meta.Meta] = None, _extensions: Iterable[extension.Extension] = (), _monitors: Iterable[monitor.Monitor] = (), _sprites: Iterable[sprite.Sprite] = (), *, _asset_data: Optional[list[asset.AssetFile]] = None, _session: Optional[session.Session] = None): @@ -268,6 +271,9 @@ def export(self, fp: str, *, auto_open: bool = False, export_as_zip: bool = True os.system(f"explorer.exe \"{fp}\"") def add_monitor(self, _monitor: monitor.Monitor) -> monitor.Monitor: + """ + Bind a monitor to this project. Doing these manually can lead to interesting results. + """ _monitor.project = self _monitor.reporter_id = self.new_id self.monitors.append(_monitor) From 26046544d5e35a719a405a3583c72311592151db Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:40:58 +0100 Subject: [PATCH 19/21] doc: sprite.py --- scratchattach/editor/sprite.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scratchattach/editor/sprite.py b/scratchattach/editor/sprite.py index 528ca953..229d8cba 100644 --- a/scratchattach/editor/sprite.py +++ b/scratchattach/editor/sprite.py @@ -120,6 +120,9 @@ def link_comments(self): _comment.link_using_sprite() def add_local_global(self, _vlb: base.NamedIDComponent): + """ + Add a global variable/list to this sprite (for when an overarching project/stage is not available) + """ self._local_globals.append(_vlb) _vlb.sprite = self From c7b702748347eb2668a5b0ff1eb871b0e11ad965 Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 22:42:31 +0100 Subject: [PATCH 20/21] doc: twconfig.py --- scratchattach/editor/twconfig.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scratchattach/editor/twconfig.py b/scratchattach/editor/twconfig.py index 858bd005..07a50a3e 100644 --- a/scratchattach/editor/twconfig.py +++ b/scratchattach/editor/twconfig.py @@ -17,7 +17,7 @@ _END = " // _twconfig_" -@dataclass(init=True, repr=True) +@dataclass class TWConfig(base.JSONSerializable): framerate: int = None, interpolation: bool = False, @@ -100,6 +100,7 @@ def get_twconfig_data(string: str) -> dict | None: return None +# todo: move this to commons.py? def none_if_eq(data, compare) -> Any | None: """ Returns None if data and compare are the same From 0cda893c4b1e3423c5b0698bbb3c9a7e7444e115 Mon Sep 17 00:00:00 2001 From: r Date: Tue, 3 Jun 2025 23:05:21 +0100 Subject: [PATCH 21/21] delete todo.md --- scratchattach/editor/todo.md | 105 ----------------------------------- 1 file changed, 105 deletions(-) delete mode 100644 scratchattach/editor/todo.md diff --git a/scratchattach/editor/todo.md b/scratchattach/editor/todo.md deleted file mode 100644 index 203a81e6..00000000 --- a/scratchattach/editor/todo.md +++ /dev/null @@ -1,105 +0,0 @@ -# Things to add to scratchattach.editor (sbeditor v2) - -## All - -- [ ] Docstrings -- [x] Dealing with stuff from the backpack (it's in a weird format): This may require a whole separate module -- [ ] Getter functions (`@property`) instead of directly editing attrs (make them protected attrs) -- [ ] Check if whitespace chars break IDs -- [ ] Maybe blockchain should be renamed to 'script' -- [ ] Perhaps use sprites as blockchain wrappers due to their existing utility (loading of local globals etc) -- [ ] bs4 styled search function -- [ ] ScratchJR project parser (lol) -- [ ] Error checking (for when you need to specify sprite etc) -- [x] Split json unpacking and the use of .from_json method so that it is easy to just extract json data (but not parse - it) - -## Project - -- [x] Asset list -- [ ] Obfuscation -- [x] Detection for twconfig -- [x] Edit twconfig -- [ ] Find targets - -## Block - -### Finding blocks/attrs - -- [x] Top level block (stack parent) -- [x] Previous chain -- [x] Attached chain -- [x] Complete chain -- [x] Block categories -- [x] Block shape attr aka stack type (Stack/hat/c-mouth/end/reporter/boolean detection) -- [x] `can_next` property -- [x] `is_input` property: Check if block is an input obscurer -- [x] `parent_input` property: Get input that this block obscures -- [x] `stack_tree` old 'subtree' property: Get the 'ast' of this blockchain (a 'tree' structure - well actually a list - of lists) -- [x] `children` property - list of all blocks with this block as a parent except next block (any input obscurers) -- [x] Detection for turbowarp debug blocks - (proc codes: - `"​​log​​ %s", - "​​breakpoint​​", - "​​error​​ %s", - "​​warn​​ %s"` - note: they all have ZWSPs) -- [x] Detection for `` and `` and `` booleans - -### Adding/removing blocks - -- [x] Add block to sprite -- [x] Duplicating (single) block -- [x] Attach block -- [x] Duplicating blockchain -- [x] Slot above (if possible - raise error if not) -- [x] Attach blockchain -- [x] Delete block -- [x] Delete blockchain -- [x] Add/edit inputs -- [x] Add/edit fields -- [x] Add mutation -- [x] Add comment -- [x] Get comment - -## Mutation - -- [ ] Proc code builder -- [x] get type of argument (bool/str) inside argument class -- [ ] to/from json for args? - -## Sprite - -### Finding ID components - -- [x] Find var/list/broadcast -- [x] Find block/prim -- [ ] Add costume/sound -- [ ] Add var/list/broadcast -- [ ] Add arbitrary block/blockchain -- [ ] Asset count -- [ ] Obfuscation -- [ ] Var/list/broadcast/block/comment/whole id list (like `_EnumWrapper.all_of`) -- [ ] Get custom blocks list -- [ ] With statements for sprite to allow for choosing default sprite - -## Vars/lists/broadcasts - -- [ ] idk - -## Monitors - -- [ ] Get relevant var/list if applicable -- [ ] Generate from block - -## Assets - -- [x] Download assets -- [ ] Upload asset -- [ ] Load from file (auto-detect type) - -## Pallet - -- [ ] Add all block defaults (like sbuild.py) -- [ ] Actions (objects that behave like blocks but add multiple blocks - e.g. a 'superjoin' block that you can use to - join more than 2 strings with one block (by actually building multiple join blocks)) \ No newline at end of file