make emotions named instead, add drop prop

This commit is contained in:
Evan Carroll 2026-01-13 16:49:07 -06:00
parent 989e20757b
commit ea3b444d71
19 changed files with 1429 additions and 150 deletions

View file

@ -343,6 +343,45 @@ impl std::str::FromStr for EmotionState {
}
}
impl EmotionState {
/// Convert a keybinding index (0-11) to an emotion state.
pub fn from_index(i: u8) -> Option<Self> {
match i {
0 => Some(Self::Neutral),
1 => Some(Self::Happy),
2 => Some(Self::Sad),
3 => Some(Self::Angry),
4 => Some(Self::Surprised),
5 => Some(Self::Thinking),
6 => Some(Self::Laughing),
7 => Some(Self::Crying),
8 => Some(Self::Love),
9 => Some(Self::Confused),
10 => Some(Self::Sleeping),
11 => Some(Self::Wink),
_ => None,
}
}
/// Convert emotion state to its index (0-11).
pub fn to_index(&self) -> u8 {
match self {
Self::Neutral => 0,
Self::Happy => 1,
Self::Sad => 2,
Self::Angry => 3,
Self::Surprised => 4,
Self::Thinking => 5,
Self::Laughing => 6,
Self::Crying => 7,
Self::Love => 8,
Self::Confused => 9,
Self::Sleeping => 10,
Self::Wink => 11,
}
}
}
// =============================================================================
// User Models
// =============================================================================
@ -485,6 +524,8 @@ pub struct Scene {
pub is_hidden: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
/// Default public channel ID for this scene.
pub default_channel_id: Option<Uuid>,
}
/// Minimal scene info for listings.
@ -541,6 +582,67 @@ pub struct SpotSummary {
// Props Models
// =============================================================================
/// Origin source for a prop in inventory.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[cfg_attr(feature = "ssr", derive(sqlx::Type))]
#[cfg_attr(feature = "ssr", sqlx(type_name = "prop_origin", rename_all = "snake_case"))]
#[serde(rename_all = "snake_case")]
pub enum PropOrigin {
#[default]
ServerLibrary,
RealmLibrary,
UserUpload,
}
impl std::fmt::Display for PropOrigin {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PropOrigin::ServerLibrary => write!(f, "server_library"),
PropOrigin::RealmLibrary => write!(f, "realm_library"),
PropOrigin::UserUpload => write!(f, "user_upload"),
}
}
}
/// An inventory item (user-owned prop).
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "ssr", derive(sqlx::FromRow))]
pub struct InventoryItem {
pub id: Uuid,
pub prop_name: String,
pub prop_asset_path: String,
pub layer: Option<AvatarLayer>,
pub is_transferable: bool,
pub is_portable: bool,
pub origin: PropOrigin,
pub acquired_at: DateTime<Utc>,
}
/// Response for inventory list.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InventoryResponse {
pub items: Vec<InventoryItem>,
}
/// A prop dropped in a channel, available for pickup.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "ssr", derive(sqlx::FromRow))]
pub struct LooseProp {
pub id: Uuid,
pub channel_id: Uuid,
pub server_prop_id: Option<Uuid>,
pub realm_prop_id: Option<Uuid>,
pub position_x: f64,
pub position_y: f64,
pub dropped_by: Option<Uuid>,
pub expires_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
/// Prop name (JOINed from source prop).
pub prop_name: String,
/// Asset path for rendering (JOINed from source prop).
pub prop_asset_path: String,
}
/// A server-wide prop (global library).
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "ssr", derive(sqlx::FromRow))]