From fd8796e2c976e8ddf6bd1b88db51b53ce215b373 Mon Sep 17 00:00:00 2001
From: david <david@polyomino.com>
Date: Sat, 22 Jun 2024 16:03:05 +1000
Subject: [PATCH] Update for v-24f22

Second attempt
---
 .build/buildnumber.txt     |  2 +-
 README.md                  | 10 ++++++----
 src/standalone_inlined.txt | 26 +++++++++++++++++---------
 3 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/.build/buildnumber.txt b/.build/buildnumber.txt
index a586f53..43b5406 100644
--- a/.build/buildnumber.txt
+++ b/.build/buildnumber.txt
@@ -1 +1 @@
-1780
\ No newline at end of file
+1781
\ No newline at end of file
diff --git a/README.md b/README.md
index d917774..439d0e2 100644
--- a/README.md
+++ b/README.md
@@ -14,9 +14,10 @@ PuzzleScript Next is a combination of the work of many authors:
 * and ongoing development work inspired by its many users (like you).
 
 ## New Features and Fixes
-The latest version is Release v-24e01. 
-* Inline expansion of rules referring to the absence of an object by a relative reference now works correctly.
-For example: `late [ wall no wall:>:quarterTiles ] -> [ wall wall:>:fill ]`
+The latest version is Release v-24f22. 
+New fixes:
+* A child object that defines no sprite and/or colour inherits them from its parent (hat tricks).
+* The `share` link now targets the correct URL wherever it is hosted.
 
 Recent new features include the following. For detail see the documentation.
 * Level branching based on a LINK command, and a test program showing how it can be used.
@@ -24,9 +25,10 @@ Recent new features include the following. For detail see the documentation.
 * The menus now more distinctively identify this is PuzzleScript Next.
 
 Several other bugs have already been fixed.
+* Inline expansion of rules referring to the absence of an object by a relative reference now works correctly.
+For example: `late [ wall no wall:>:quarterTiles ] -> [ wall wall:>:fill ]`
 * No longer crashes on resizing the browser window.
 * Setting sound volume has been fixed to be compatible with Pattern:Script.
-* Share authorisation now works correctly independntly of where it is hosted.
 * Undo across a link now works correctly.
 * An object that has a `copy:` referring to an implied TAG object now resolves correctly.
 * A TAG object with a sprite that is redefined uses the second sprite instead of appending it.
diff --git a/src/standalone_inlined.txt b/src/standalone_inlined.txt
index b38a2b9..9674664 100644
--- a/src/standalone_inlined.txt
+++ b/src/standalone_inlined.txt
@@ -6904,7 +6904,7 @@ function regenSpriteImages() {
     
     objectSprites.forEach((s,i) => {
         if (s) {
-            spriteImages[i] = s.text ? createTextSprite('t' + s.text, s.text, s.colors, s.scale)
+            spriteImages[i] = s.text ? createTextSprite('t' + i.toString(), s.text, s.colors, s.scale)
                 : createSprite(i.toString(), s.dat, s.colors, state.sprite_size);
         }
     });
@@ -12644,13 +12644,14 @@ var codeMirrorFn = function() {
             const candname = state.objects_candname = symbols.candname;
             registerOriginalCaseName(state, candname, mixedCase, state.lineNumber);
 
-            // use existing if there is one, to maintain the correct order of addition.
+            // use existing if there is one, to maintain the correct order of addition
+            // preserve colors and sprite matrix, not transforms
             const newobj = state.objects[candname] || {       // doc: array of objects indexed by name
-                lineNumber: state.lineNumber
+                lineNumber: state.lineNumber,
+                colors: [],
+                spritematrix: [],
             };
             delete newobj.canRedef;
-            newobj.colors = [];
-            newobj.spritematrix = [];
             newobj.transforms = [];
             delete state.objects[candname];
             state.objects[candname] = newobj;
@@ -18130,6 +18131,7 @@ function mouseAction(event,click,id) {
 			}
 		} else if (messageselected===false && (state.levels[curLevelNo].message || messagetext != "")) {
 			messageselected=true;
+			//console.log(`MA TS=${prevTimestamp} Timer = ${timer} qms=${quittingMessageScreen}`);
 			timer=0;
 			quittingMessageScreen=true;
 			tryPlayCloseMessageSound();
@@ -18704,10 +18706,11 @@ function pollGamepads() {
 
 let debugTimestamp
 function checkKey(e,justPressed) {
-    if (debugSwitch.includes('input') && justPressed) console.log('checkKey', e, justPressed);
+    if (debugSwitch.includes('input') && justPressed) console.log('checkKey', prevTimestamp, e, justPressed);
     if (debugSwitch.includes('key')) {
 		const ele = document.getElementById('debug');
-		ele.innerHTML = `key-${e.keyCode} just=${justPressed} last=${~~(prevTimestamp-debugTimestamp)} TS=${~~prevTimestamp} delta=${~~(deltatime*1000)} keybuffer=${keybuffer.length}`;
+		if (ele)
+			ele.innerHTML = `key-${e.keyCode} just=${justPressed} last=${~~(prevTimestamp-debugTimestamp)} TS=${~~prevTimestamp} delta=${~~(deltatime*1000)} keybuffer=${keybuffer.length}`;
 		debugTimestamp = prevTimestamp;
 	}
 	ULBS();
@@ -18909,6 +18912,7 @@ function checkKey(e,justPressed) {
 			}
 		}
     }
+    if (debugSwitch.includes('input')) console.log('checkKey', prevTimestamp, throttle_movement, inputdir, input_throttle_timer, repeatinterval);
     if (throttle_movement && inputdir>=0&&inputdir<=3) {
     	if (lastinput==inputdir && input_throttle_timer<repeatinterval) {
     		return;
@@ -18983,6 +18987,7 @@ function checkKey(e,justPressed) {
 					nextLevel();
 					return;
 				} else if (messageselected===false) {
+					//console.log(`CK TS=${prevTimestamp} Timer = ${timer} qms=${quittingMessageScreen}`);
     				messageselected=true;
     				timer=0;
     				quittingMessageScreen=true;
@@ -19039,6 +19044,7 @@ function update() {
         }
     }
     if (quittingMessageScreen) {
+		//console.log(`UP TS=${prevTimestamp} Timer = ${timer} qms=${quittingMessageScreen}`);
         if (timer/1000>0.15) {
             quittingMessageScreen=false;
             if (state.levels[curLevelNo].message) {
@@ -19074,7 +19080,8 @@ function update() {
 	    	var key = keybuffer[keyRepeatIndex];
 			if (debugSwitch.includes('key')) {
 				const ele = document.getElementById('debug');
-				ele.innerHTML = `key-${key} TL=${~~ticklength} last=${~~(prevTimestamp-debugTimestamp)} TS=${~~prevTimestamp} delta=${~~(deltatime*1000)} keybuffer=${keybuffer.length}`;
+				if (ele)
+					ele.innerHTML = `key-${key} TL=${~~ticklength} last=${~~(prevTimestamp-debugTimestamp)} TS=${~~prevTimestamp} delta=${~~(deltatime*1000)} keybuffer=${keybuffer.length}`;
 				debugTimestamp = prevTimestamp;
 			}
 	        checkKey({keyCode:key},false);
@@ -19105,7 +19112,8 @@ var loop = function(timestamp){
 		deltatime = timestamp - prevTimestamp
 		if (debugSwitch.includes('key')) {
 			const ele = document.getElementById('debug');
-			ele.innerHTML = `timestamp=${~~timestamp} deltatime=${~~(deltatime*1000)} keybuffer=${keybuffer.length}`;
+			if (ele)
+				ele.innerHTML = `timer=${timer.toFixed()} TS=${~~timestamp} delta=${~~(deltatime*1000)} KB=${keybuffer.length}`;
 		}
 	}
 	prevTimestamp = timestamp