add the ability to make props non-droppable

This commit is contained in:
Evan Carroll 2026-01-13 17:46:56 -06:00
parent ea3b444d71
commit 845d64c981
5 changed files with 82 additions and 14 deletions

View file

@ -46,14 +46,40 @@ pub async fn list_channel_loose_props<'e>(
///
/// Deletes from inventory and inserts into loose_props with 30-minute expiry.
/// Returns the created loose prop.
pub async fn drop_prop_to_canvas<'e>(
executor: impl PgExecutor<'e>,
/// Returns an error if the prop is non-droppable (essential prop).
pub async fn drop_prop_to_canvas(
pool: &sqlx::PgPool,
inventory_item_id: Uuid,
user_id: Uuid,
channel_id: Uuid,
position_x: f64,
position_y: f64,
) -> Result<LooseProp, AppError> {
// First check if the item exists and is droppable
let item_check: Option<(bool,)> = sqlx::query_as(
r#"SELECT is_droppable FROM props.inventory WHERE id = $1 AND user_id = $2"#,
)
.bind(inventory_item_id)
.bind(user_id)
.fetch_optional(pool)
.await?;
match item_check {
None => {
return Err(AppError::NotFound(
"Inventory item not found or not owned by user".to_string(),
));
}
Some((false,)) => {
return Err(AppError::Forbidden(
"This prop cannot be dropped - it is an essential prop".to_string(),
));
}
Some((true,)) => {
// Item is droppable, proceed with the drop operation
}
}
// Use a CTE to delete from inventory and insert to loose_props in one query
let prop = sqlx::query_as::<_, LooseProp>(
r#"
@ -111,10 +137,10 @@ pub async fn drop_prop_to_canvas<'e>(
.bind(channel_id)
.bind(position_x as f32)
.bind(position_y as f32)
.fetch_optional(executor)
.fetch_optional(pool)
.await?
.ok_or_else(|| {
AppError::NotFound("Inventory item not found or not owned by user".to_string())
AppError::Internal("Unexpected error dropping prop to canvas".to_string())
})?;
Ok(prop)
@ -144,6 +170,7 @@ pub async fn pick_up_loose_prop<'e>(
COALESCE(sp.default_layer, rp.default_layer) as layer,
COALESCE(sp.is_transferable, rp.is_transferable) as is_transferable,
COALESCE(sp.is_portable, true) as is_portable,
COALESCE(sp.is_droppable, rp.is_droppable, true) as is_droppable,
dp.server_prop_id,
dp.realm_prop_id
FROM deleted_prop dp
@ -161,6 +188,7 @@ pub async fn pick_up_loose_prop<'e>(
origin,
is_transferable,
is_portable,
is_droppable,
provenance,
acquired_at
)
@ -174,10 +202,11 @@ pub async fn pick_up_loose_prop<'e>(
'server_library'::props.prop_origin,
COALESCE(si.is_transferable, true),
COALESCE(si.is_portable, true),
COALESCE(si.is_droppable, true),
'[]'::jsonb,
now()
FROM source_info si
RETURNING id, prop_name, prop_asset_path, layer, is_transferable, is_portable, acquired_at
RETURNING id, prop_name, prop_asset_path, layer, is_transferable, is_portable, is_droppable, acquired_at
)
SELECT
ii.id,
@ -186,6 +215,7 @@ pub async fn pick_up_loose_prop<'e>(
ii.layer,
ii.is_transferable,
ii.is_portable,
ii.is_droppable,
'server_library'::props.prop_origin as origin,
ii.acquired_at
FROM inserted_item ii