private fun canSynthesize(): Boolean val comps = currentComponents.filterNotNull() if (comps.size != 3) return false if (comps.distinctBy it.id .size != 3) return false if (comps.none it.type == ComponentType.RUNE ) return false if (comps.sumOf it.rarity > 10) return false return true
// 2️⃣ Spell -------------------------------------------------------------- @Entity(tableName = "spells") data class SpellEntity( @PrimaryKey val spellId: String = UUID.randomUUID().toString(), val name: String, val description: String, val manaCost: Int, val componentIds: List<String>, // stored via TypeConverter val createdAt: Long = System.currentTimeMillis() ) -18 - dawnhold Dark Magic 0.16.0 sahrab Android
@Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insert(spell: SpellEntity) val name: String
Box( modifier = Modifier .size(96.dp) .clip(CircleShape) .background(background) .border(2.dp, Color.Magenta, CircleShape) .pointerInput(Unit) detectDragGestures( onDragStart = /* ignore */ , onDragEnd = /* ignore */ , onDragCancel = /* ignore */ , onDrag = change, _ -> // Accept only if dragged composable carries a ComponentEntity tag val comp = change.consumeAllChanges().metadata?.get<ComponentEntity>() comp?.let onDrop(it) ) ) if (filledComponent != null) Icon(painterResource(filledComponent.iconRes), contentDescription = filledComponent.name) IconButton(onClick = onClear, modifier = Modifier.align(Alignment.TopEnd)) Icon(Icons.Default.Close, tint = Color.White) else Icon(Icons.Default.Add, tint = Color.White.copy(alpha = 0.5f)) val description: String
The drag‑drop demo above is a minimal “metadata” trick; for a production‑ready solution use Accompanist‑drag‑drop or the new Compose Drag‑Drop API (Android 14+). 6.4 Spell Preview Card @Composable fun SpellPreviewCard(spell: SpellEntity?) Card( modifier = Modifier .fillMaxWidth() .padding(8.dp), colors = CardDefaults.cardColors(containerColor = Color(0xFF1B0B2D)) ) if (spell == null) Text( "Add components to craft a spell…", style = MaterialTheme.typography.bodyMedium, color = Color.LightGray, modifier = Modifier.padding(16.dp) ) else Column(modifier = Modifier.padding(16.dp)) Text(spell.name, style = MaterialTheme.typography.titleLarge, color = Color.Cyan) Spacer(Modifier.height(4.dp)) Text(spell.description, style = MaterialTheme.typography.bodyMedium, color = Color.White) Spacer(Modifier.height(8.dp)) Row(verticalAlignment = Alignment.CenterVertically) Icon(Icons.Default.Bolt, tint = Color.Yellow) Spacer(Modifier.width(4.dp)) Text("$spell.manaCost Mana", color = Color.Yellow)
@Dao interface SpellDao @Query("SELECT * FROM spells ORDER BY createdAt DESC") fun observeAll(): Flow<List<SpellEntity>>
private fun synthesizeSpell(): SpellEntity require(canSynthesize()) val rune = currentComponents.first it?.type == ComponentType.RUNE !! val gesture = currentComponents.first it?.type == ComponentType.GESTURE !!