fix some emotion bugs

This commit is contained in:
Evan Carroll 2026-01-13 14:08:38 -06:00
parent bd28e201a2
commit 989e20757b
11 changed files with 1203 additions and 190 deletions

View file

@ -820,6 +820,28 @@ pub struct Avatar {
pub e_confused_7: Option<Uuid>,
pub e_confused_8: Option<Uuid>,
// Emotion: Sleeping (e10)
pub e_sleeping_0: Option<Uuid>,
pub e_sleeping_1: Option<Uuid>,
pub e_sleeping_2: Option<Uuid>,
pub e_sleeping_3: Option<Uuid>,
pub e_sleeping_4: Option<Uuid>,
pub e_sleeping_5: Option<Uuid>,
pub e_sleeping_6: Option<Uuid>,
pub e_sleeping_7: Option<Uuid>,
pub e_sleeping_8: Option<Uuid>,
// Emotion: Wink (e11)
pub e_wink_0: Option<Uuid>,
pub e_wink_1: Option<Uuid>,
pub e_wink_2: Option<Uuid>,
pub e_wink_3: Option<Uuid>,
pub e_wink_4: Option<Uuid>,
pub e_wink_5: Option<Uuid>,
pub e_wink_6: Option<Uuid>,
pub e_wink_7: Option<Uuid>,
pub e_wink_8: Option<Uuid>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
@ -1722,3 +1744,84 @@ impl Default for EmotionAvailability {
}
}
}
// =============================================================================
// Full Avatar with Paths
// =============================================================================
/// Full avatar data with all inventory UUIDs resolved to asset paths.
///
/// This struct contains all 135 slots (27 content layer + 108 emotion layer)
/// with paths pre-resolved, enabling client-side emotion availability computation
/// and rendering without additional server queries.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AvatarWithPaths {
pub avatar_id: Uuid,
pub current_emotion: i16,
/// Asset paths for skin layer positions 0-8
pub skin_layer: [Option<String>; 9],
/// Asset paths for clothes layer positions 0-8
pub clothes_layer: [Option<String>; 9],
/// Asset paths for accessories layer positions 0-8
pub accessories_layer: [Option<String>; 9],
/// Asset paths for all 12 emotions, each with 9 positions.
/// Index: emotions[emotion_index][position] where emotion_index is 0-11
/// (neutral, happy, sad, angry, surprised, thinking, laughing, crying, love, confused, sleeping, wink)
pub emotions: [[Option<String>; 9]; 12],
/// Whether each emotion has at least one slot populated (UUID exists, even if path lookup failed).
/// This matches the old get_emotion_availability behavior.
pub emotions_available: [bool; 12],
}
impl Default for AvatarWithPaths {
fn default() -> Self {
Self {
avatar_id: Uuid::nil(),
current_emotion: 0,
skin_layer: Default::default(),
clothes_layer: Default::default(),
accessories_layer: Default::default(),
emotions: Default::default(),
emotions_available: [false; 12],
}
}
}
impl AvatarWithPaths {
/// Compute emotion availability from the avatar data.
/// Uses pre-computed emotions_available which checks if UUIDs exist (not just resolved paths).
pub fn compute_emotion_availability(&self) -> EmotionAvailability {
let mut preview_paths: [Option<String>; 12] = Default::default();
for (i, emotion_layer) in self.emotions.iter().enumerate() {
// Preview is position 4 (center)
preview_paths[i] = emotion_layer[4].clone();
}
EmotionAvailability {
available: self.emotions_available,
preview_paths,
}
}
/// Get the 9-path emotion layer for a specific emotion index (0-11).
pub fn get_emotion_layer(&self, emotion: usize) -> [Option<String>; 9] {
if emotion < 12 {
self.emotions[emotion].clone()
} else {
Default::default()
}
}
/// Convert to AvatarRenderData for the current emotion.
pub fn to_render_data(&self) -> AvatarRenderData {
AvatarRenderData {
avatar_id: self.avatar_id,
current_emotion: self.current_emotion,
skin_layer: self.skin_layer.clone(),
clothes_layer: self.clothes_layer.clone(),
accessories_layer: self.accessories_layer.clone(),
emotion_layer: self.get_emotion_layer(self.current_emotion as usize),
}
}
}