Skip to content

Commit 824b4ad

Browse files
authored
add individual camera follow blocks
1 parent 07179bd commit 824b4ad

1 file changed

Lines changed: 120 additions & 9 deletions

File tree

static/extensions/Gen1x/lighting.js

Lines changed: 120 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,11 +1316,15 @@ self.onmessage = ({ data: msg }) => {
13161316
}
13171317

13181318
_getCameraState() {
1319+
return this._getCameraStateByName(this.cameraFollowName || 'default');
1320+
}
1321+
1322+
_getCameraStateByName(name) {
13191323
if (!isPenguinMod) return null;
13201324
const runtime = Scratch.vm.runtime;
13211325
if (typeof runtime.getCamera !== 'function') return null;
13221326
try {
1323-
return runtime.getCamera(this.cameraFollowName || 'default');
1327+
return runtime.getCamera(name);
13241328
} catch (e) {
13251329
return null;
13261330
}
@@ -1336,6 +1340,39 @@ self.onmessage = ({ data: msg }) => {
13361340
this._markDirty();
13371341
}
13381342

1343+
setLightCameraFollow(args) {
1344+
const id = Scratch.Cast.toString(args.ID);
1345+
const state = Scratch.Cast.toString(args.STATE);
1346+
if (!this.lights[id]) return;
1347+
if (state === 'none') {
1348+
this.lights[id].cameraOverride = 'none';
1349+
} else if (state === 'global') {
1350+
this.lights[id].cameraOverride = null;
1351+
} else if (state === 'custom') {
1352+
if (this.lights[id].cameraOverride === null || this.lights[id].cameraOverride === 'none') {
1353+
this.lights[id].cameraOverride = this.cameraFollowName || 'default';
1354+
}
1355+
}
1356+
this._markDirty();
1357+
}
1358+
1359+
setLightCameraName(args) {
1360+
const id = Scratch.Cast.toString(args.ID);
1361+
const name = Scratch.Cast.toString(args.NAME) || 'default';
1362+
if (!this.lights[id]) return;
1363+
this.lights[id].cameraOverride = name;
1364+
this._markDirty();
1365+
}
1366+
1367+
getLightCameraFollow(args) {
1368+
const id = Scratch.Cast.toString(args.ID);
1369+
if (!this.lights[id]) return '';
1370+
const ov = this.lights[id].cameraOverride;
1371+
if (ov === null || ov === undefined) return 'global';
1372+
if (ov === 'none') return 'none';
1373+
return ov;
1374+
}
1375+
13391376
_fillUBOData(w, h) {
13401377
const lights = Object.values(this.lights);
13411378
const n = lights.length;
@@ -1345,24 +1382,50 @@ self.onmessage = ({ data: msg }) => {
13451382
}
13461383
const buf = this._uboData;
13471384

1348-
let camX = 0, camY = 0, camScale = 1, camDirRad = 0;
1385+
let globalCamX = 0, globalCamY = 0, globalCamScale = 1, globalCamDirRad = 0;
13491386
if (this.cameraFollow && isPenguinMod) {
13501387
const cam = this._getCameraState();
13511388
if (cam) {
1352-
camX = cam.pos[0];
1353-
camY = cam.pos[1];
1354-
camScale = cam.scale || 1;
1355-
camDirRad = cam.dir * (Math.PI / 180);
1389+
globalCamX = cam.pos[0];
1390+
globalCamY = cam.pos[1];
1391+
globalCamScale = cam.scale || 1;
1392+
globalCamDirRad = cam.dir * (Math.PI / 180);
13561393
}
13571394
}
13581395

1359-
const cosA = Math.cos(-camDirRad);
1360-
const sinA = Math.sin(-camDirRad);
1396+
const _camCache = {};
1397+
const _resolveCamera = (name) => {
1398+
if (_camCache[name] !== undefined) return _camCache[name];
1399+
const cam = this._getCameraStateByName(name);
1400+
_camCache[name] = cam;
1401+
return cam;
1402+
};
13611403

13621404
for (let i = 0; i < n; i++) {
13631405
const li = lights[i];
13641406
const base = i * 12;
13651407

1408+
let camX = globalCamX, camY = globalCamY, camScale = globalCamScale, camDirRad = globalCamDirRad;
1409+
1410+
if (isPenguinMod && li.cameraOverride !== undefined && li.cameraOverride !== null) {
1411+
if (li.cameraOverride === 'none') {
1412+
camX = 0; camY = 0; camScale = 1; camDirRad = 0;
1413+
} else {
1414+
const cam = _resolveCamera(li.cameraOverride);
1415+
if (cam) {
1416+
camX = cam.pos[0];
1417+
camY = cam.pos[1];
1418+
camScale = cam.scale || 1;
1419+
camDirRad = cam.dir * (Math.PI / 180);
1420+
} else {
1421+
camX = 0; camY = 0; camScale = 1; camDirRad = 0;
1422+
}
1423+
}
1424+
}
1425+
1426+
const cosA = Math.cos(-camDirRad);
1427+
const sinA = Math.sin(-camDirRad);
1428+
13661429
let lx = li.x - camX;
13671430
let ly = li.y - camY;
13681431
const rx = (lx * cosA - ly * sinA) / camScale;
@@ -1753,6 +1816,51 @@ self.onmessage = ({ data: msg }) => {
17531816
}
17541817
},
17551818
'---',
1819+
{
1820+
opcode: 'setLightCameraFollow',
1821+
blockType: Scratch.BlockType.COMMAND,
1822+
hideFromPalette: !isPenguinMod,
1823+
text: 'set light [ID] camera follow [STATE]',
1824+
arguments: {
1825+
ID: {
1826+
type: Scratch.ArgumentType.STRING,
1827+
defaultValue: 'light1'
1828+
},
1829+
STATE: {
1830+
type: Scratch.ArgumentType.STRING,
1831+
menu: 'lightCameraFollowMenu'
1832+
}
1833+
}
1834+
},
1835+
{
1836+
opcode: 'setLightCameraName',
1837+
blockType: Scratch.BlockType.COMMAND,
1838+
hideFromPalette: !isPenguinMod,
1839+
text: 'set light [ID] to follow camera [NAME]',
1840+
arguments: {
1841+
ID: {
1842+
type: Scratch.ArgumentType.STRING,
1843+
defaultValue: 'light1'
1844+
},
1845+
NAME: {
1846+
type: Scratch.ArgumentType.STRING,
1847+
defaultValue: 'default'
1848+
}
1849+
}
1850+
},
1851+
{
1852+
opcode: 'getLightCameraFollow',
1853+
blockType: Scratch.BlockType.REPORTER,
1854+
hideFromPalette: !isPenguinMod,
1855+
text: 'light [ID] camera follow',
1856+
arguments: {
1857+
ID: {
1858+
type: Scratch.ArgumentType.STRING,
1859+
defaultValue: 'light1'
1860+
}
1861+
}
1862+
},
1863+
'---',
17561864
'---',
17571865
{
17581866
blockType: Scratch.BlockType.LABEL,
@@ -1963,7 +2071,6 @@ self.onmessage = ({ data: msg }) => {
19632071
}
19642072
}
19652073
},
1966-
'---',
19672074
{
19682075
blockType: Scratch.BlockType.LABEL,
19692076
text: 'Read Lights'
@@ -2208,6 +2315,10 @@ self.onmessage = ({ data: msg }) => {
22082315
acceptReporters: false,
22092316
items: ['on', 'off']
22102317
},
2318+
lightCameraFollowMenu: {
2319+
acceptReporters: false,
2320+
items: ['global', 'none', 'custom']
2321+
},
22112322
settingMenu: {
22122323
acceptReporters: false,
22132324
items: ['shadowOpacity', 'ambient', 'bloomAmount', 'bloomRadius', 'bloomThreshold', 'pixelated', 'pixelSize', 'contrast', 'colorTemp', 'resetLightsOnStart', 'renderThread', 'cameraFollow', 'cameraFollowName']

0 commit comments

Comments
 (0)