Rework avatars.

Now we have a concept of an avatar at the server, realm, and scene level
and we have the groundwork for a realm store. New uesrs no longer props,
they get a default avatar. New system supports gender
{male,female,neutral} and {child,adult}.
This commit is contained in:
Evan Carroll 2026-01-22 21:04:27 -06:00
parent e4abdb183f
commit 6fb90e42c3
55 changed files with 7392 additions and 512 deletions

View file

@ -58,7 +58,8 @@ pub async fn join_channel<'e>(
}
/// Ensure an active avatar exists for a user in a realm.
/// Uses the user's default avatar (slot 0) if none exists.
/// If user has a custom avatar (slot 0), use it. Otherwise, avatar_id is NULL
/// and the system will use server/realm default avatars based on user preferences.
pub async fn ensure_active_avatar<'e>(
executor: impl PgExecutor<'e>,
user_id: Uuid,
@ -67,9 +68,9 @@ pub async fn ensure_active_avatar<'e>(
sqlx::query(
r#"
INSERT INTO auth.active_avatars (user_id, realm_id, avatar_id, current_emotion)
SELECT $1, $2, id, 1
FROM auth.avatars
WHERE user_id = $1 AND slot_number = 0
SELECT $1, $2,
(SELECT id FROM auth.avatars WHERE user_id = $1 AND slot_number = 0),
'happy'::server.emotion_state
ON CONFLICT (user_id, realm_id) DO NOTHING
"#,
)
@ -175,7 +176,7 @@ pub async fn get_channel_members<'e>(
cm.facing_direction,
cm.is_moving,
cm.is_afk,
COALESCE(aa.current_emotion, 0::smallint) as current_emotion,
COALESCE(aa.current_emotion, 'happy'::server.emotion_state) as current_emotion,
cm.joined_at,
COALESCE('guest' = ANY(u.tags), false) as is_guest
FROM scene.instance_members cm
@ -214,7 +215,7 @@ pub async fn get_channel_member<'e>(
cm.facing_direction,
cm.is_moving,
cm.is_afk,
COALESCE(aa.current_emotion, 0::smallint) as current_emotion,
COALESCE(aa.current_emotion, 'happy'::server.emotion_state) as current_emotion,
cm.joined_at,
COALESCE('guest' = ANY(u.tags), false) as is_guest
FROM scene.instance_members cm