diff --git a/README.md b/README.md
index 1b05f34..0a76cbb 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,14 @@ https://github.com/edencomputing/attprefabulator/releases/
### Release Notes
+- v1.7.0 - Snap groups to ground! Fixed issue with accidentally deleting yourself or other protected prefabs as part of a group. Cloning regular objects works now!. Cloned objects will also spawn offset by 1 meter in the 'up' direction for visibility. Cloning now uses the save/load connection to prevent interruption since it can take some time on large groups.
+
+- v1.6.5 - Added the community storage multiplier
+
+- v1.6.4 - Added the new player set-home command, and options to set it to player location, user location, an exact position, or respawn point (reset)
+
+- v1.6.3 - Added preliminary version of keyboard support for moving prefabs
+
- v1.6.2 - Oops! Hotfix for loading of spawnables and subscriptions
- v1.6.1 - Added prefab and group cloning! Also time of day to server settings, and title tags to all icon-only controls.
diff --git a/index.js b/index.js
index a32b26b..71c9b25 100644
--- a/index.js
+++ b/index.js
@@ -1194,8 +1194,34 @@ wsAddHandler( 'select_prefab_group', async( data ) => {
wsAddHandler( 'delete_prefab_group', async( data ) => {
console.log( "Deleting a prefab group: ", data.id, data.group )
- attConsole.onMessage = ( message ) => {
+ let itemsToDelete = []
+ let scanned = 0
+ attSaveLoad.onMessage = async ( message ) => {
console.log( `delete prefab event: `, message )
+ if ( !!message.data.Command.FullName )
+ {
+ switch( message.data.Command.FullName )
+ {
+ case "select.get":
+ scanned++
+ if ( !blacklistItems[ message.data.Result.PrefabHash ] )
+ {
+ itemsToDelete.push( message.data.Result )
+ }
+ console.log( `scanned: ${scanned}, total: ${itemsToDelete.length}`)
+ if ( scanned == group.items.length )
+ {
+ // Finished scanning, delete the remainder
+ for( let i = 0; i < itemsToDelete.length; i++ )
+ {
+ await attSaveLoad.send(`select ${itemsToDelete[i].Identifier}`)
+ await attSaveLoad.send(`select destroy`)
+ }
+ wsSendJSON({'result': 'OK', data: data })
+ }
+ break
+ }
+ }
}
if ( prefabGroups[ data.id ] )
{
@@ -1203,8 +1229,7 @@ wsAddHandler( 'delete_prefab_group', async( data ) => {
for( let i = 0; i < group.items.length; i++ )
{
let item = group.items[i]
- await attConsole.send(`select ${item.Identifier}`)
- await attConsole.send(`select destroy`)
+ await attSaveLoad.send(`select get ${item.Identifier}`)
}
delete prefabGroups[ data.id ]
}
@@ -1239,7 +1264,7 @@ wsAddHandler( 'clone_prefab', async( data ) => {
wsSendJSON({ 'result': 'OK', data: data, group: newGroup })
}
}
- attConsole.onMessage = async( message ) => {
+ attSaveLoad.onMessage = async( message ) => {
console.log( "clone_prefab group onMessage: ", message )
switch( message.data.Command.FullName )
{
@@ -1252,13 +1277,13 @@ wsAddHandler( 'clone_prefab', async( data ) => {
newGroup[ngi] = {}
newGroup[ngi].pos = message.data.Result.Position
newGroup[ngi].rot = message.data.Result.Rotation
- await attConsole.send(`select tostring`)
+ await attSaveLoad.send(`select tostring`)
}
break
case "select.tostring":
let prefabString = message.data.ResultString
- await attConsole.send(`spawn string ${player} ${prefabString}`)
+ await attSaveLoad.send(`spawn string ${player} ${prefabString}`)
break
case "spawn.string":
@@ -1267,9 +1292,9 @@ wsAddHandler( 'clone_prefab', async( data ) => {
newGroup[ngi].Name = message.data.Result[0].Name
let pos = newGroup[ngi].pos
let rot = newGroup[ngi].rot
- await attConsole.send(`select ${prefabId}`)
- await attConsole.send(`select rotate exact ${rot[0]},${rot[1]},${rot[2]}`)
- await attConsole.send(`select move exact ${pos[0]},${pos[1]},${pos[2]}`)
+ await attSaveLoad.send(`select ${prefabId}`)
+ await attSaveLoad.send(`select rotate exact ${rot[0]},${rot[1]},${rot[2]}`)
+ await attSaveLoad.send(`select move exact ${pos[0]},${pos[1]+1},${pos[2]}`)
break
case "select move.exact":
@@ -1281,14 +1306,14 @@ wsAddHandler( 'clone_prefab', async( data ) => {
let selectItemToString = async ( ind ) => {
let item = groupItems[ind]
console.log( "getting item: ", ind, item )
- await attConsole.send(`select ${item.Identifier}`)
- await attConsole.send(`select get ${item.Identifier}`)
+ await attSaveLoad.send(`select ${item.Identifier}`)
+ await attSaveLoad.send(`select get ${item.Identifier}`)
}
selectItemToString( ind )
} else {
- let newItem
- attConsole.onMessage = async ( message ) => {
+ let newItem = {}
+ attSaveLoad.onMessage = async ( message ) => {
console.log( "clone_prefab onMessage: ", message )
switch( message.data.Command.FullName )
{
@@ -1300,29 +1325,32 @@ wsAddHandler( 'clone_prefab', async( data ) => {
} else {
newItem.pos = message.data.Result.Position
newItem.rot = message.data.Result.Rotation
- await attConsole.send('select tostring')
+ await attSaveLoad.send('select tostring')
}
break
case "select.tostring":
// Re-spawn from the string
console.log( "select.tostring response: ", message.data.ResultString )
- await attConsole.send(`spawn string ${player} ${message.data.ResultString}`)
+ await attSaveLoad.send(`spawn string ${player} ${message.data.ResultString}`)
break
case "spawn.string":
// Collect the ID and name and return it to the UI
+ console.log( "moving new item to: ", newItem )
let hash = message.data.Result[0].Identifier
let pos = newItem.pos
let rot = newItem.rot
- await attConsole.send(`select ${hash}`)
- await attConsole.send(`select rotate exact ${rot[0]},${rot[1]}.${rot[2]}`)
- await attConsole.send(`select move exact ${pos[0]},${pos[1]}.${pos[2]}`)
+ await attSaveLoad.send(`select ${hash}`)
+ console.log( `select rotate exact ${rot[0]},${rot[1]}.${rot[2]}` )
+ console.log( `select move exact ${pos[0]},${pos[1]}.${pos[2]}` )
+ await attSaveLoad.send(`select rotate exact ${rot[0]},${rot[1]},${rot[2]}`)
+ await attSaveLoad.send(`select move exact ${pos[0]},${pos[1]+1},${pos[2]}`)
wsSendJSON( { result: 'OK', data: data, prefab: message.data.Result[0] } )
break
}
}
- await attConsole.send( `select ${data.hash}` )
- await attConsole.send( `select get ${data.hash}`)
+ await attSaveLoad.send( `select ${data.hash}` )
+ await attSaveLoad.send( `select get ${data.hash}`)
}
})
diff --git a/package.json b/package.json
index c5cbb02..f9170f5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "prefabulator",
- "version": "1.6.5",
+ "version": "1.7.0",
"productName": "Prefabulator",
"description": "Add, remove and modify prefabs in A Township Tale",
"main": "electron-start.js",
diff --git a/public/script/main.js b/public/script/main.js
index d24ca0c..37665d5 100644
--- a/public/script/main.js
+++ b/public/script/main.js
@@ -1596,6 +1596,7 @@ $(document).ready(() => {
let player = $("input#PlayerConfigUserId").val()
console.log( "copy selected prefab: ", optSelected )
wsSendJSON({ 'action': 'clone_prefab', 'player': player, 'hash': optSelected })
+ spinnerReplace( "CopySelectedPrefab" )
}
})
@@ -1729,6 +1730,7 @@ $(document).ready(() => {
selectPrefabById( "SelectedPrefabSelect", hash, name )
}
}
+ spinnerRevert( "CopySelectedPrefab" )
})
wsAddHandler('select_prefab_group', ( message ) => {
@@ -1756,16 +1758,40 @@ function delSpinner( e, ihtml )
$(e.target).html(ihtml)
}
+let sprActive = false
+let sprCurrentHtml = ''
+function spinnerReplace( elem )
+{
+ if ( !sprActive )
+ {
+ sprCurrentHtml = $("#"+elem).html()
+ $("#"+elem).html( '')
+ $("#"+elem).addClass('disabled')
+ sprActive = true
+ }
+}
+
+function spinnerRevert( elem )
+{
+ $("#"+elem).html( sprCurrentHtml )
+ $("#"+elem).removeClass('disabled')
+ sprActive = false
+}
+
function deletePrefab( id ) {
console.log( "delete prefab: ", id )
+ wsAddHandler('delete_prefab_group', ( message ) => {
+ if ( message.result == 'OK' )
+ {
+ $("#SelectedPrefabSelect option:selected").remove()
+ let newSelected = $("#SelectedPrefabSelect option:last").val()
+ $("#SelectedPrefabSelect").val( newSelected ).trigger('change')
+ }
+ })
if ( `${id}`.includes('group') )
{
let groupId = `${id}`.split('_')[1]
wsSendJSON( { action: 'delete_prefab_group', id: groupId, group: prefabGroups[groupId] } )
-
- $("#SelectedPrefabSelect option:selected").remove()
- let newSelected = $("#SelectedPrefabSelect option:last").val()
- $("#SelectedPrefabSelect").val( newSelected ).trigger('change')
} else {
dataSet = { 'selectedPrefabId': id }
dataSet.action = 'destroy_prefab'
diff --git a/views/SpawnPrefabs.pug b/views/SpawnPrefabs.pug
index 0521b7f..6e7504b 100644
--- a/views/SpawnPrefabs.pug
+++ b/views/SpawnPrefabs.pug
@@ -1,4 +1,4 @@
-div#SpawnPrefabs.SubMessage.pt-3(class="container hidden")
+div#SpawnPrefabs.SubMessage.pt-3(class="container")
div.ControlsMini.d-flex.w-100.m-0
i(class="fas fa-search px-2")
input#SearchNearestItems.form-control.w-100(style="flex:1" type="text" placeholder="Search spawnable items")