mirror of
https://github.com/litruv/PNGTuber-Plus.git
synced 2026-07-24 02:26:02 +10:00
wobble sync groups !build
This commit is contained in:
452
autoload/wobble_sync_manager.gd
Normal file
452
autoload/wobble_sync_manager.gd
Normal file
@@ -0,0 +1,452 @@
|
||||
extends Node
|
||||
|
||||
## WobbleSyncGroupManager - Manages synchronized wobble groups for sprites
|
||||
## Follows class-based OOP pattern as requested
|
||||
|
||||
var syncGroups: Dictionary = {} # groupName: WobbleSyncGroup
|
||||
var spriteGroupMembership: Dictionary = {} # spriteId: groupName
|
||||
|
||||
signal group_created(group_name: String)
|
||||
signal group_deleted(group_name: String)
|
||||
signal sprite_joined_group(sprite_id: int, group_name: String)
|
||||
signal sprite_left_group(sprite_id: int, group_name: String)
|
||||
|
||||
func _ready():
|
||||
print("DEBUG: WobbleSyncManager._ready() called")
|
||||
print("DEBUG: WobbleSyncManager autoload initialized successfully")
|
||||
print("DEBUG: Initial syncGroups: ", syncGroups)
|
||||
print("DEBUG: Initial spriteGroupMembership: ", spriteGroupMembership)
|
||||
|
||||
class WobbleSyncGroup:
|
||||
var name: String
|
||||
var xFrq: float = 0.0
|
||||
var xAmp: float = 0.0
|
||||
var yFrq: float = 0.0
|
||||
var yAmp: float = 0.0
|
||||
var rFrq: float = 0.0
|
||||
var rAmp: float = 0.0
|
||||
var memberSprites: Array = []
|
||||
|
||||
func _init(group_name: String):
|
||||
name = group_name
|
||||
|
||||
## Set wobble parameters for the entire group
|
||||
func setWobbleParameters(x_frq: float, x_amp: float, y_frq: float, y_amp: float, r_frq: float, r_amp: float, manager_ref):
|
||||
print("DEBUG: WobbleSyncGroup.setWobbleParameters called for group '", name, "' with ", memberSprites.size(), " members")
|
||||
print("DEBUG: Member sprite IDs: ", memberSprites)
|
||||
xFrq = x_frq
|
||||
xAmp = x_amp
|
||||
yFrq = y_frq
|
||||
yAmp = y_amp
|
||||
rFrq = r_frq
|
||||
rAmp = r_amp
|
||||
|
||||
# Update all member sprites using the manager reference
|
||||
var sprites = manager_ref.get_tree().get_nodes_in_group("saved")
|
||||
print("DEBUG: Found ", sprites.size(), " total sprites in 'saved' group")
|
||||
|
||||
var updated_count = 0
|
||||
for sprite in sprites:
|
||||
print("DEBUG: Checking sprite ID ", sprite.id, " (type: ", typeof(sprite.id), ") against member list")
|
||||
if sprite.id in memberSprites:
|
||||
print("DEBUG: Updating sprite ID ", sprite.id, " with new wobble values (no scaling - values stored as-is)")
|
||||
# Preserve the sprite's group membership
|
||||
var current_group = sprite.wobbleSyncGroup
|
||||
sprite.xFrq = xFrq
|
||||
sprite.xAmp = xAmp
|
||||
sprite.yFrq = yFrq
|
||||
sprite.yAmp = yAmp
|
||||
sprite.rFrq = rFrq
|
||||
sprite.rAmp = rAmp
|
||||
# Restore group membership in case it got cleared
|
||||
sprite.wobbleSyncGroup = current_group
|
||||
updated_count += 1
|
||||
else:
|
||||
print("DEBUG: Sprite ID ", sprite.id, " not in member list")
|
||||
|
||||
print("DEBUG: Updated ", updated_count, " sprites in group '", name, "'")
|
||||
|
||||
## Add sprite to this group
|
||||
func addSprite(sprite_id): # Remove type constraint to handle float IDs
|
||||
print("DEBUG: WobbleSyncGroup.addSprite called with sprite_id: ", sprite_id, " (type: ", typeof(sprite_id), ")")
|
||||
if sprite_id not in memberSprites:
|
||||
memberSprites.append(sprite_id)
|
||||
print("DEBUG: Added sprite to memberSprites. Current members: ", memberSprites)
|
||||
else:
|
||||
print("DEBUG: Sprite already in memberSprites")
|
||||
|
||||
## Remove sprite from this group
|
||||
func removeSprite(sprite_id): # Remove type constraint
|
||||
memberSprites.erase(sprite_id)
|
||||
|
||||
## Check if group is empty
|
||||
func isEmpty() -> bool:
|
||||
return memberSprites.size() == 0
|
||||
|
||||
## Get group data for saving
|
||||
func toSaveData() -> Dictionary:
|
||||
return {
|
||||
"name": name,
|
||||
"xFrq": xFrq,
|
||||
"xAmp": xAmp,
|
||||
"yFrq": yFrq,
|
||||
"yAmp": yAmp,
|
||||
"rFrq": rFrq,
|
||||
"rAmp": rAmp,
|
||||
"memberSprites": memberSprites
|
||||
}
|
||||
|
||||
## Load group data from save
|
||||
func fromSaveData(data: Dictionary):
|
||||
name = data.get("name", "")
|
||||
xFrq = data.get("xFrq", 0.0)
|
||||
xAmp = data.get("xAmp", 0.0)
|
||||
yFrq = data.get("yFrq", 0.0)
|
||||
yAmp = data.get("yAmp", 0.0)
|
||||
rFrq = data.get("rFrq", 0.0)
|
||||
rAmp = data.get("rAmp", 0.0)
|
||||
memberSprites = data.get("memberSprites", [])
|
||||
|
||||
## Create a new wobble sync group
|
||||
func createGroup(group_name: String, sprite_id = -1) -> bool: # Remove type constraint
|
||||
if group_name.strip_edges() == "" or syncGroups.has(group_name):
|
||||
return false
|
||||
|
||||
var group = WobbleSyncGroup.new(group_name)
|
||||
syncGroups[group_name] = group
|
||||
|
||||
# If a sprite ID is provided, add it and copy its wobble values
|
||||
if sprite_id != -1:
|
||||
var sprite = getSpriteById(sprite_id)
|
||||
if sprite:
|
||||
# Store the sprite's raw wobble values directly
|
||||
group.setWobbleParameters(sprite.xFrq, sprite.xAmp, sprite.yFrq, sprite.yAmp, sprite.rFrq, sprite.rAmp, self)
|
||||
addSpriteToGroup(sprite_id, group_name)
|
||||
|
||||
group_created.emit(group_name)
|
||||
Global.pushUpdate("Created wobble sync group: " + group_name)
|
||||
return true
|
||||
|
||||
## Delete a wobble sync group
|
||||
func deleteGroup(group_name: String):
|
||||
if not syncGroups.has(group_name):
|
||||
return
|
||||
|
||||
var group = syncGroups[group_name]
|
||||
|
||||
# Remove all sprites from the group
|
||||
for sprite_id in group.memberSprites.duplicate():
|
||||
removeSpriteFromGroup(sprite_id, group_name)
|
||||
|
||||
syncGroups.erase(group_name)
|
||||
group_deleted.emit(group_name)
|
||||
Global.pushUpdate("Deleted wobble sync group: " + group_name)
|
||||
|
||||
## Add sprite to a group
|
||||
func addSpriteToGroup(sprite_id, group_name: String) -> bool: # Remove type constraint
|
||||
print("DEBUG: addSpriteToGroup called with sprite_id: ", sprite_id, " (type: ", typeof(sprite_id), "), group: '", group_name, "'")
|
||||
|
||||
if not syncGroups.has(group_name):
|
||||
print("DEBUG: Group '", group_name, "' not found")
|
||||
return false
|
||||
|
||||
# Remove sprite from any existing group first
|
||||
removeSpriteFromAllGroups(sprite_id)
|
||||
|
||||
var group = syncGroups[group_name]
|
||||
group.addSprite(sprite_id)
|
||||
spriteGroupMembership[sprite_id] = group_name
|
||||
print("DEBUG: Added sprite ", sprite_id, " to group '", group_name, "'. Group now has ", group.memberSprites.size(), " members")
|
||||
|
||||
# Sync the sprite's wobble parameters to the group
|
||||
var sprite = getSpriteById(sprite_id)
|
||||
if sprite:
|
||||
print("DEBUG: Found sprite object, syncing wobble parameters to group values")
|
||||
sprite.wobbleSyncGroup = group_name
|
||||
sprite.xFrq = group.xFrq
|
||||
sprite.xAmp = group.xAmp
|
||||
sprite.yFrq = group.yFrq
|
||||
sprite.yAmp = group.yAmp
|
||||
sprite.rFrq = group.rFrq
|
||||
sprite.rAmp = group.rAmp
|
||||
|
||||
sprite_joined_group.emit(sprite_id, group_name)
|
||||
Global.pushUpdate("Added sprite to wobble sync group: " + group_name)
|
||||
return true
|
||||
|
||||
## Remove sprite from a specific group
|
||||
func removeSpriteFromGroup(sprite_id, group_name: String): # Remove type constraint
|
||||
print("DEBUG: removeSpriteFromGroup called for sprite ID: ", sprite_id, " (type: ", typeof(sprite_id), "), group: '", group_name, "'")
|
||||
if not syncGroups.has(group_name):
|
||||
print("DEBUG: Group '", group_name, "' not found")
|
||||
return
|
||||
|
||||
var group = syncGroups[group_name]
|
||||
print("DEBUG: Group before removal has ", group.memberSprites.size(), " members: ", group.memberSprites)
|
||||
group.removeSprite(sprite_id)
|
||||
spriteGroupMembership.erase(sprite_id)
|
||||
print("DEBUG: Group after removal has ", group.memberSprites.size(), " members: ", group.memberSprites)
|
||||
|
||||
# Clear the sprite's sync group reference
|
||||
var sprite = getSpriteById(sprite_id)
|
||||
if sprite:
|
||||
print("DEBUG: Clearing sprite's wobbleSyncGroup property")
|
||||
sprite.wobbleSyncGroup = ""
|
||||
else:
|
||||
print("DEBUG: Could not find sprite object for ID: ", sprite_id)
|
||||
|
||||
sprite_left_group.emit(sprite_id, group_name)
|
||||
|
||||
# Auto-delete empty groups
|
||||
if group.isEmpty():
|
||||
deleteGroup(group_name)
|
||||
else:
|
||||
Global.pushUpdate("Removed sprite from wobble sync group: " + group_name)
|
||||
|
||||
## Remove sprite from all groups
|
||||
func removeSpriteFromAllGroups(sprite_id): # Remove type constraint
|
||||
print("DEBUG: removeSpriteFromAllGroups called for sprite ID: ", sprite_id)
|
||||
if spriteGroupMembership.has(sprite_id):
|
||||
var group_name = spriteGroupMembership[sprite_id]
|
||||
print("DEBUG: Found sprite in group '", group_name, "', removing...")
|
||||
removeSpriteFromGroup(sprite_id, group_name)
|
||||
else:
|
||||
print("DEBUG: Sprite not found in any group membership")
|
||||
|
||||
## Update wobble parameters for a group
|
||||
func updateGroupWobble(group_name: String, x_frq: float, x_amp: float, y_frq: float, y_amp: float, r_frq: float, r_amp: float):
|
||||
print("DEBUG: updateGroupWobble called for group '", group_name, "' with values - xFrq:", x_frq, " xAmp:", x_amp, " yFrq:", y_frq, " yAmp:", y_amp, " rFrq:", r_frq, " rAmp:", r_amp)
|
||||
|
||||
if not syncGroups.has(group_name):
|
||||
print("DEBUG: Group '", group_name, "' not found in syncGroups!")
|
||||
print("DEBUG: Available groups: ", syncGroups.keys())
|
||||
print("DEBUG: This suggests the avatar's wobble sync groups were never loaded from the save file!")
|
||||
print("DEBUG: Either the save file doesn't contain wobbleSyncGroups, or the loading process didn't run.")
|
||||
return
|
||||
|
||||
var group = syncGroups[group_name]
|
||||
print("DEBUG: Found group, calling setWobbleParameters on group with ", group.memberSprites.size(), " members")
|
||||
group.setWobbleParameters(x_frq, x_amp, y_frq, y_amp, r_frq, r_amp, self)
|
||||
|
||||
## Get sprite's current group name
|
||||
func getSpriteGroupName(sprite_id: int) -> String:
|
||||
return spriteGroupMembership.get(sprite_id, "")
|
||||
|
||||
## Get all group names
|
||||
func getGroupNames() -> Array:
|
||||
print("DEBUG: getGroupNames called. syncGroups has ", syncGroups.size(), " groups: ", syncGroups.keys())
|
||||
print("DEBUG: getGroupNames - syncGroups reference: ", syncGroups)
|
||||
print("DEBUG: getGroupNames - self reference: ", self)
|
||||
return syncGroups.keys()
|
||||
|
||||
## Test function to manually load wobble sync groups
|
||||
func testManualLoad():
|
||||
print("DEBUG: testManualLoad called - creating test data...")
|
||||
var test_data = {
|
||||
"ears": {
|
||||
"name": "ears",
|
||||
"xFrq": 0.0,
|
||||
"xAmp": 0.0,
|
||||
"yFrq": 0.019,
|
||||
"yAmp": 3.0,
|
||||
"rFrq": 0.399,
|
||||
"rAmp": 47.0,
|
||||
"memberSprites": [3291286625.0]
|
||||
}
|
||||
}
|
||||
print("DEBUG: Calling loadSaveData with test data...")
|
||||
await loadSaveData(test_data)
|
||||
print("DEBUG: testManualLoad completed. syncGroups now has: ", syncGroups.size(), " groups")
|
||||
|
||||
## Check if a group exists
|
||||
func hasGroup(group_name: String) -> bool:
|
||||
return syncGroups.has(group_name)
|
||||
|
||||
## Get sprite by ID
|
||||
func getSpriteById(sprite_id): # Remove type constraint to handle float IDs
|
||||
var sprites = get_tree().get_nodes_in_group("saved")
|
||||
for sprite in sprites:
|
||||
if sprite.id == sprite_id:
|
||||
return sprite
|
||||
return null
|
||||
|
||||
## Clean up orphaned sprites (sprites that no longer exist)
|
||||
func cleanupOrphanedSprites():
|
||||
var existing_sprite_ids = []
|
||||
var sprites = get_tree().get_nodes_in_group("saved")
|
||||
for sprite in sprites:
|
||||
existing_sprite_ids.append(sprite.id)
|
||||
|
||||
# Check each group for orphaned sprite IDs
|
||||
for group_name in syncGroups.keys():
|
||||
var group = syncGroups[group_name]
|
||||
var orphaned_ids = []
|
||||
|
||||
for sprite_id in group.memberSprites:
|
||||
if sprite_id not in existing_sprite_ids:
|
||||
orphaned_ids.append(sprite_id)
|
||||
|
||||
# Remove orphaned IDs
|
||||
for orphaned_id in orphaned_ids:
|
||||
group.removeSprite(orphaned_id)
|
||||
spriteGroupMembership.erase(orphaned_id)
|
||||
|
||||
# Delete empty groups
|
||||
if group.isEmpty():
|
||||
deleteGroup(group_name)
|
||||
|
||||
## Get save data for all groups
|
||||
func getSaveData() -> Dictionary:
|
||||
var save_data = {}
|
||||
for group_name in syncGroups.keys():
|
||||
var group = syncGroups[group_name]
|
||||
save_data[group_name] = group.toSaveData()
|
||||
return save_data
|
||||
|
||||
## Load save data for all groups
|
||||
func loadSaveData(save_data: Dictionary):
|
||||
print("DEBUG: ========================")
|
||||
print("DEBUG: WobbleSyncManager.loadSaveData called with save_data: ", save_data)
|
||||
print("DEBUG: save_data type: ", typeof(save_data))
|
||||
print("DEBUG: save_data.keys(): ", save_data.keys())
|
||||
print("DEBUG: save_data.size(): ", save_data.size())
|
||||
print("DEBUG: self reference: ", self)
|
||||
print("DEBUG: syncGroups before clear: ", syncGroups)
|
||||
|
||||
# Check if save_data is valid
|
||||
if save_data == null or typeof(save_data) != TYPE_DICTIONARY:
|
||||
print("DEBUG: ERROR - Invalid save_data provided")
|
||||
return
|
||||
|
||||
if save_data.size() == 0:
|
||||
print("DEBUG: WARNING - Empty save_data provided")
|
||||
return
|
||||
|
||||
# Clear existing groups
|
||||
print("DEBUG: Clearing existing syncGroups (had ", syncGroups.size(), " groups)")
|
||||
syncGroups.clear()
|
||||
spriteGroupMembership.clear()
|
||||
print("DEBUG: Cleared existing data. syncGroups now has ", syncGroups.size(), " groups")
|
||||
|
||||
# Load groups from save data
|
||||
var loaded_groups = 0
|
||||
print("DEBUG: Starting group loading loop...")
|
||||
for group_name in save_data.keys():
|
||||
print("DEBUG: ---- Processing group '", group_name, "' (attempt ", loaded_groups + 1, ") ----")
|
||||
var group_data = save_data[group_name]
|
||||
print("DEBUG: Group data type: ", typeof(group_data))
|
||||
print("DEBUG: Group data: ", group_data)
|
||||
|
||||
if typeof(group_data) == TYPE_DICTIONARY:
|
||||
print("DEBUG: Creating WobbleSyncGroup instance...")
|
||||
var group = WobbleSyncGroup.new(group_name)
|
||||
print("DEBUG: Created new WobbleSyncGroup instance for '", group_name, "'")
|
||||
print("DEBUG: Calling fromSaveData...")
|
||||
group.fromSaveData(group_data)
|
||||
print("DEBUG: Called fromSaveData on group '", group_name, "'")
|
||||
print("DEBUG: Adding to syncGroups dictionary...")
|
||||
syncGroups[group_name] = group
|
||||
loaded_groups += 1
|
||||
print("DEBUG: Added group '", group_name, "' to syncGroups. Total groups now: ", syncGroups.size())
|
||||
print("DEBUG: syncGroups.keys() now: ", syncGroups.keys())
|
||||
print("DEBUG: Group memberSprites: ", group.memberSprites)
|
||||
|
||||
# Update sprite group membership
|
||||
print("DEBUG: Updating sprite group membership...")
|
||||
for sprite_id in group.memberSprites:
|
||||
spriteGroupMembership[sprite_id] = group_name
|
||||
print("DEBUG: Added sprite ", sprite_id, " to spriteGroupMembership for group '", group_name, "'")
|
||||
print("DEBUG: ---- Finished processing group '", group_name, "' ----")
|
||||
else:
|
||||
print("DEBUG: ERROR - Group data for '", group_name, "' is not a Dictionary, skipping")
|
||||
|
||||
print("DEBUG: ========================")
|
||||
print("DEBUG: GROUP LOADING COMPLETE")
|
||||
print("DEBUG: Loaded ", loaded_groups, " groups total")
|
||||
print("DEBUG: Final syncGroups after loading: ", syncGroups.keys())
|
||||
print("DEBUG: Final syncGroups size: ", syncGroups.size())
|
||||
print("DEBUG: Final syncGroups contents: ", syncGroups)
|
||||
print("DEBUG: Final spriteGroupMembership: ", spriteGroupMembership)
|
||||
print("DEBUG: ========================")
|
||||
|
||||
# If no groups were loaded, clear any orphaned group references on sprites
|
||||
if syncGroups.size() == 0:
|
||||
print("DEBUG: No groups loaded, clearing orphaned sprite group references")
|
||||
var sprites = get_tree().get_nodes_in_group("saved")
|
||||
for sprite in sprites:
|
||||
if sprite.wobbleSyncGroup != "":
|
||||
print("DEBUG: Clearing orphaned group reference '", sprite.wobbleSyncGroup, "' from sprite ID ", sprite.id)
|
||||
sprite.wobbleSyncGroup = ""
|
||||
else:
|
||||
print("DEBUG: Groups loaded successfully, syncing sprite parameters...")
|
||||
# Apply wobble parameters to sprites with better timing
|
||||
await get_tree().process_frame # Wait for sprites to be loaded
|
||||
await get_tree().process_frame # Extra frame to ensure everything is ready
|
||||
|
||||
for group_name in syncGroups.keys():
|
||||
var group = syncGroups[group_name]
|
||||
print("DEBUG: Syncing parameters for group '", group_name, "' with ", group.memberSprites.size(), " members")
|
||||
for sprite_id in group.memberSprites:
|
||||
var sprite = getSpriteById(sprite_id)
|
||||
if sprite:
|
||||
print("DEBUG: Syncing sprite ID ", sprite_id, " to group '", group_name, "'")
|
||||
sprite.wobbleSyncGroup = group_name
|
||||
sprite.xFrq = group.xFrq
|
||||
sprite.xAmp = group.xAmp
|
||||
sprite.yFrq = group.yFrq
|
||||
sprite.yAmp = group.yAmp
|
||||
sprite.rFrq = group.rFrq
|
||||
sprite.rAmp = group.rAmp
|
||||
# Force a complete opacity update after modifying sprite properties
|
||||
if sprite.has_method("updateOpacity"):
|
||||
sprite.updateOpacity()
|
||||
if sprite.has_method("updateShaderOpacity"):
|
||||
sprite.updateShaderOpacity()
|
||||
else:
|
||||
print("DEBUG: ERROR - Could not find sprite with ID ", sprite_id)
|
||||
|
||||
print("DEBUG: ========================")
|
||||
print("DEBUG: loadSaveData FUNCTION COMPLETE")
|
||||
print("DEBUG: Final verification - syncGroups has ", syncGroups.size(), " groups: ", syncGroups.keys())
|
||||
print("DEBUG: ========================")
|
||||
|
||||
## Called when a sprite is deleted to clean up references
|
||||
func onSpriteDeleted(sprite_id): # Remove type constraint
|
||||
removeSpriteFromAllGroups(sprite_id)
|
||||
|
||||
## Debug function to check data consistency
|
||||
func checkDataConsistency():
|
||||
print("=== WOBBLE SYNC DATA CONSISTENCY CHECK ===")
|
||||
|
||||
# Check each group's member sprites
|
||||
for group_name in syncGroups.keys():
|
||||
var group = syncGroups[group_name]
|
||||
print("Group '", group_name, "' has ", group.memberSprites.size(), " members: ", group.memberSprites)
|
||||
|
||||
for sprite_id in group.memberSprites:
|
||||
# Check if sprite exists
|
||||
var sprite = getSpriteById(sprite_id)
|
||||
if sprite == null:
|
||||
print(" ERROR: Sprite ID ", sprite_id, " in group but sprite object not found!")
|
||||
else:
|
||||
# Check if sprite's wobbleSyncGroup matches
|
||||
if sprite.wobbleSyncGroup != group_name:
|
||||
print(" ERROR: Sprite ID ", sprite_id, " in group '", group_name, "' but sprite.wobbleSyncGroup = '", sprite.wobbleSyncGroup, "'")
|
||||
else:
|
||||
print(" OK: Sprite ID ", sprite_id, " consistent")
|
||||
|
||||
# Check if membership mapping is correct
|
||||
if not spriteGroupMembership.has(sprite_id) or spriteGroupMembership[sprite_id] != group_name:
|
||||
print(" ERROR: Sprite ID ", sprite_id, " in group but spriteGroupMembership is wrong!")
|
||||
|
||||
# Check membership mapping for orphaned entries
|
||||
for sprite_id in spriteGroupMembership.keys():
|
||||
var group_name = spriteGroupMembership[sprite_id]
|
||||
if not syncGroups.has(group_name):
|
||||
print("ERROR: Sprite ID ", sprite_id, " mapped to non-existent group '", group_name, "'")
|
||||
else:
|
||||
var group = syncGroups[group_name]
|
||||
if sprite_id not in group.memberSprites:
|
||||
print("ERROR: Sprite ID ", sprite_id, " mapped to group '", group_name, "' but not in group's member list")
|
||||
|
||||
print("=== END CONSISTENCY CHECK ===")
|
||||
Reference in New Issue
Block a user