Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 224 additions & 0 deletions extensions/GameDevHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
// GameDevHelper - Fenicf0x

Check warning on line 1 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / format

File was not formatted with prettier. Usually, commenting !format will fix this.
// build 1.04
(function(Scratch) {
'use strict';

const is_ok = Scratch && Scratch.extensions && Scratch.extensions.unsandboxed;
if (!is_ok) {
console.error("GdevHelper: need unsandboxed mode!");
return; }

class Gdev_Toolbox {
constructor() {
const r = Scratch.vm.runtime;
const _s = r.variableSetValue;

Check warning on line 14 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / type-warnings

Type warning - may indicate a bug - ignore if no bug

Property 'variableSetValue' does not exist on type 'Runtime'.
r.variableSetValue = function(id, val) {

Check warning on line 15 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / type-warnings

Type warning - may indicate a bug - ignore if no bug

Property 'variableSetValue' does not exist on type 'Runtime'.
_s.call(this, id, val);
r.startHats('gamedevhelper_whenVariableChanges');
};
}

getInfo() {
return {
id: 'gamedevhelper',
name: 'Game Dev Helper',

Check failure on line 24 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / lint

Extension name should usually be translated
color1: '#58ff4c',
blocks: [
"--- Math & Curves ---",
{
opcode: 'weighted_rand',
blockType: Scratch.BlockType.REPORTER,
text: 'pick random [min] to [max] weight [w]',

Check failure on line 31 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / lint

Block text should usually be translated
arguments: {
min: { type: Scratch.ArgumentType.NUMBER, defaultValue: 1 },
max: { type: Scratch.ArgumentType.NUMBER, defaultValue: 10 },
w: { type: Scratch.ArgumentType.NUMBER, defaultValue: 1 }
}
},
{ opcode: 'flipCoin', blockType: Scratch.BlockType.REPORTER, text: 'true or false?' },

Check failure on line 38 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / lint

Block text should usually be translated
{
opcode: 'calc_power',
blockType: Scratch.BlockType.REPORTER,
text: '[n1] ^ [n2]',

Check failure on line 42 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / lint

Block text should usually be translated
arguments: { n1: { type: Scratch.ArgumentType.NUMBER, defaultValue: 2 }, n2: { type: Scratch.ArgumentType.NUMBER, defaultValue: 3 } }
},
{ opcode: 'is_even_num', blockType: Scratch.BlockType.BOOLEAN, text: '[num] is even?', arguments: { num: { type: Scratch.ArgumentType.NUMBER, defaultValue: 2 } } },

Check failure on line 45 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / lint

Block text should usually be translated
{ opcode: 'check_range', blockType: Scratch.BlockType.BOOLEAN, text: 'is [v] between [a] and [b]?',

Check failure on line 46 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / lint

Block text should usually be translated
arguments: { v: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, a: { type: Scratch.ArgumentType.NUMBER, defaultValue: 1 }, b: { type: Scratch.ArgumentType.NUMBER, defaultValue: 10 } }
},
{
opcode: 'round_number',
blockType: Scratch.BlockType.REPORTER,
text: 'round [val] to [prec] places',

Check failure on line 52 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / lint

Block text should usually be translated
arguments: { val: { type: Scratch.ArgumentType.NUMBER, defaultValue: 3.14 }, prec: { type: Scratch.ArgumentType.NUMBER, defaultValue: 2 } }
},

"--- Game Data Logic ---",
{
opcode: 'parse_save_data',
blockType: Scratch.BlockType.REPORTER,
text: 'extract value from [str] at key [k]',

Check failure on line 60 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / lint

Block text should usually be translated
arguments: {
str: { type: Scratch.ArgumentType.STRING, defaultValue: 'score:100|hp:50' },
k: { type: Scratch.ArgumentType.STRING, defaultValue: 'score' }
}
},
{
opcode: 'grab_end',
blockType: Scratch.BlockType.REPORTER,
text: 'last letter of [t]',

Check failure on line 69 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / lint

Block text should usually be translated
arguments: { t: { type: Scratch.ArgumentType.STRING, defaultValue: 'apple' } }
},
{
opcode: 'get_word_count',
blockType: Scratch.BlockType.REPORTER,
text: 'words in [input]',

Check failure on line 75 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / lint

Block text should usually be translated
arguments: { input: { type: Scratch.ArgumentType.STRING, defaultValue: 'hello world' } }
},
{
opcode: 'validate_id',
blockType: Scratch.BlockType.BOOLEAN,
text: 'is ID [val] valid format [ptn]?',
arguments: {
val: { type: Scratch.ArgumentType.STRING, defaultValue: 'SKU-123' },
ptn: { type: Scratch.ArgumentType.STRING, defaultValue: 'abc-###' }
}
},

"--- Controls ---",
{
opcode: 'kill_scripts',
blockType: Scratch.BlockType.COMMAND,
text: 'stop scripts for [target]',
arguments: { target: { type: Scratch.ArgumentType.STRING, menu: 'SPRITE_MENU' } }
},
{
opcode: 'get_visibility',
blockType: Scratch.BlockType.BOOLEAN,
text: 'is [obj] hidden?',
arguments: { obj: { type: Scratch.ArgumentType.STRING, menu: 'SPRITE_MENU' } }
},
{
opcode: 'mouse_set',
blockType: Scratch.BlockType.COMMAND,
text: 'set cursor [mode]',
arguments: { mode: { type: Scratch.ArgumentType.STRING, menu: 'VIS_MENU' } }
},

"--- Events ---",
{
opcode: 'whenVariableChanges',
blockType: Scratch.BlockType.HAT,
text: 'when any variable changes'
}
],
menus: {
VIS_MENU: { acceptReporters: true, items: ['visible', 'hidden'] },
SPRITE_MENU: { acceptReporters: true, items: 'fetch_targets' }
}
};
}

_fixCasting(v) {
if (typeof v === 'boolean') return v;
if (!isNaN(v) && v !== '') return Number(v);
return String(v);
}

fetch_targets() {
const names = [];
const tgts = Scratch.vm.runtime.targets;
for (let i = 0; i < tgts.length; i++) {
if (!tgts[i].isStage) names.push(tgts[i].getName());
}
return names.length > 0 ? names : ['None'];
}

weighted_rand(arg) {
const low = this._fixCasting(arg.min);
const high = this._fixCasting(arg.max);
const w = this._fixCasting(arg.w) || 1;

let tmp = Math.random();
const r = Math.pow(tmp, 1 / w);

Check warning on line 143 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / type-warnings

Type warning - may indicate a bug - ignore if no bug

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
return Math.floor(r * (high - low + 1)) + low;

Check warning on line 144 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / type-warnings

Type warning - may indicate a bug - ignore if no bug

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check warning on line 144 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / type-warnings

Type warning - may indicate a bug - ignore if no bug

The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check warning on line 144 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / type-warnings

Type warning - may indicate a bug - ignore if no bug

Operator '+' cannot be applied to types 'number' and 'string | number | boolean'.
}

flipCoin() { return Math.random() < 0.5 ? 'true' : 'false'; }

calc_power(val) {
let res = Math.pow(this._fixCasting(val.n1), this._fixCasting(val.n2));

Check warning on line 150 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / type-warnings

Type warning - may indicate a bug - ignore if no bug

Argument of type 'string | number | boolean' is not assignable to parameter of type 'number'. Type 'string' is not assignable to type 'number'.
return res;
}

is_even_num(data) { return (this._fixCasting(data.num) % 2) === 0; }

Check warning on line 154 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / type-warnings

Type warning - may indicate a bug - ignore if no bug

The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

check_range(arg) {
const n = this._fixCasting(arg.v);
return n >= this._fixCasting(arg.a) && n <= this._fixCasting(arg.b); }

round_number(arg) {
const p = Math.pow(10, this._fixCasting(arg.prec));

Check warning on line 161 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / type-warnings

Type warning - may indicate a bug - ignore if no bug

Argument of type 'string | number | boolean' is not assignable to parameter of type 'number'. Type 'string' is not assignable to type 'number'.
return Math.round(this._fixCasting(arg.val) * p) / p;

Check warning on line 162 in extensions/GameDevHelper.js

View workflow job for this annotation

GitHub Actions / type-warnings

Type warning - may indicate a bug - ignore if no bug

The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
}

parse_save_data(data) {
const raw = String(data.str);
const key = String(data.k);
const segments = raw.split('|');
for (let i = 0; i < segments.length; i++) {
const pair = segments[i].split(':');
if (pair[0] === key) return pair[1] || "";
}
return "";
}

grab_end(arg) {
const s = String(arg.t);
return s ? s[s.length - 1] : "";
}

get_word_count(arg) {
const s = String(arg.input).trim();
if (!s) return 0;
return s.split(/\s+/).length;
}

validate_id(arg) {
const input = String(arg.val);
const pattern = String(arg.ptn);
if (input.length !== pattern.length) return false;

for (let i = 0; i < pattern.length; i++) {
let p_char = pattern[i];
let i_char = input[i];
if (p_char === '#') {
if (!/[0-9]/.test(i_char)) return false;
} else if (p_char !== i_char) {
return false;
}
}
return true;
}

kill_scripts(arg) {
const rt = Scratch.vm.runtime;
const t = rt.getSpriteTargetByName(arg.target);
if (t) rt.stopForTarget(t);
}

get_visibility(arg) {
const s = Scratch.vm.runtime.getSpriteTargetByName(arg.obj);
return s ? !s.visible : false;
}

mouse_set(arg) {
try {
const c = Scratch.vm.runtime.renderer.canvas;
c.style.cursor = (arg.mode === 'hidden') ? 'none' : 'default';
} catch (e) { /* fail silent */ }
}
}

Scratch.extensions.register(new Gdev_Toolbox());
})(Scratch);
Loading