@@ -39,6 +39,7 @@ def __init__(self, bot: ActBot):
3939 self .store .autocomplete ("item_id" )(self .buyable_items_autocomplete )
4040 self .equip .autocomplete ("item_id" )(self .actor_equippable_items_autocomplete )
4141 self .unequip .autocomplete ("item_id" )(self .actor_equipped_items_autocomplete )
42+ self .use .autocomplete ("item_id" )(self .actor_consumable_items_autocomplete )
4243
4344 # ----------------------------------------------------------------------------------------------------
4445
@@ -147,42 +148,10 @@ async def store(self, interaction: Interaction, item_id: str = ""):
147148 description = item .description ,
148149 )
149150 embed .add_field (name = "Price" , value = f"💰 **{ intcomma (item .price )} **" )
150- if item .health_bonus :
151- embed .add_field (
152- name = "Health" ,
153- value = f":heart: **{ numsign (intcomma (item .health_bonus ))} **" ,
154- )
155- if item .energy_bonus :
156- embed .add_field (
157- name = "Energy" ,
158- value = f"⚡ **{ numsign (intcomma (item .energy_bonus ))} **" ,
159- )
160- if item .max_health_bonus :
161- embed .add_field (
162- name = "Max Health" ,
163- value = f":heart: **{ numsign (intcomma (item .max_health_bonus ))} **" ,
164- )
165- if item .max_energy_bonus :
166- embed .add_field (
167- name = "Max Energy" ,
168- value = f"⚡ **{ numsign (intcomma (item .max_energy_bonus ))} **" ,
169- )
170- if item .attack_bonus :
171- embed .add_field (
172- name = "Attack" ,
173- value = f":crossed_swords: **{ numsign (intcomma (item .attack_bonus ))} **" ,
174- )
175- if item .defense_bonus :
176- embed .add_field (
177- name = "Defense" ,
178- value = f"🛡 **{ numsign (intcomma (item .defense_bonus ))} **" ,
179- )
180- if item .speed_bonus :
181- embed .add_field (
182- name = "Speed" , value = f"🥾 **{ numsign (intcomma (item .speed_bonus ))} **"
183- )
184151 embed .set_thumbnail (url = item .icon_url )
185- await interaction .response .send_message (embed = embed )
152+ await interaction .response .send_message (
153+ embed = self .add_item_stats_embed_fields (embed , item , show_emoji = False )
154+ )
186155 else :
187156 embed = EmbedX .info (emoji = "🏬" , title = "Store" )
188157 items = self .BUYABLE_ITEMS
@@ -308,6 +277,16 @@ async def equip(self, interaction: Interaction, item_id: str):
308277 member
309278 )
310279
280+ # Check max
281+ if len (actor .equipped_items ) >= actor .MAX_EQUIPMENT :
282+ await interaction .response .send_message (
283+ embed = EmbedX .warning (
284+ f"You've reached your equipment limit of **{ actor .MAX_EQUIPMENT } ** items."
285+ ),
286+ ephemeral = True ,
287+ )
288+ return
289+
311290 # Get item
312291 await interaction .response .defer (ephemeral = True )
313292 item_stack = actor .item_stacks .get (item_id )
@@ -328,6 +307,7 @@ async def equip(self, interaction: Interaction, item_id: str):
328307 )
329308 return
330309 actor .equipped_items [item .id ] = item
310+ actor .add_item_stats (item )
331311 db .save (actor )
332312 await interaction .followup .send (
333313 embed = EmbedX .success (
@@ -337,12 +317,19 @@ async def equip(self, interaction: Interaction, item_id: str):
337317
338318 # Send public response
339319 if isinstance (interaction .channel , Messageable ):
320+ embed = EmbedX .info (
321+ emoji = "🧰" ,
322+ title = "Equipment" ,
323+ description = f"{ member .mention } has equipped an item." ,
324+ )
325+ embed .add_field (
326+ name = "Item ✅" ,
327+ value = f"{ item .emoji or item .alt_emoji } **{ item .name } **" ,
328+ )
329+ embed .set_author (name = member .display_name , icon_url = member .display_avatar )
330+ embed .set_thumbnail (url = item .icon_url )
340331 await interaction .channel .send (
341- embed = EmbedX .info (
342- emoji = "🧰" ,
343- title = "Equipment" ,
344- description = f"{ member .mention } has equipped **{ item .emoji or item .alt_emoji } { item .name } **." ,
345- ),
332+ embed = self .add_item_stats_embed_fields (embed , item ),
346333 )
347334
348335 @app_commands .guild_only ()
@@ -383,6 +370,7 @@ async def unequip(self, interaction: Interaction, item_id: str):
383370 )
384371 return
385372 del actor .equipped_items [item .id ]
373+ actor .add_item_stats (item , scale = - 1 )
386374 db .save (actor )
387375 await interaction .followup .send (
388376 embed = EmbedX .success (
@@ -392,29 +380,122 @@ async def unequip(self, interaction: Interaction, item_id: str):
392380
393381 # Send public response
394382 if isinstance (interaction .channel , Messageable ):
383+ embed = EmbedX .info (
384+ emoji = "🧰" ,
385+ title = "Equipment" ,
386+ description = f"{ member .mention } has unequipped an item." ,
387+ )
388+ embed .add_field (
389+ name = "Item ❎" ,
390+ value = f"{ item .emoji or item .alt_emoji } **{ item .name } **" ,
391+ )
392+ embed .set_author (name = member .display_name , icon_url = member .display_avatar )
393+ embed .set_thumbnail (url = item .icon_url )
395394 await interaction .channel .send (
396- embed = EmbedX .info (
397- emoji = "🧰" ,
398- title = "Equipment" ,
399- description = f"{ member .mention } has unequipped **{ item .emoji or item .alt_emoji } { item .name } **." ,
400- ),
395+ embed = self .add_item_stats_embed_fields (embed , item , scale = - 1 ),
401396 )
402397
403398 @app_commands .guild_only ()
404399 @app_commands .command (description = "Use a consumable item" )
405- async def use (self , interaction : Interaction , item : str ):
406- await interaction .response .send_message (
407- embed = add_preview_notice (
408- EmbedX .info (
409- emoji = "🎒" ,
410- title = "Item Consumption" ,
411- description = f"{ interaction .user .mention } used **{ item } **." ,
412- )
413- ),
400+ @app_commands .rename (item_id = "item" )
401+ async def use (self , interaction : Interaction , item_id : str ):
402+ # Check guild & member
403+ member = interaction .user
404+ if not interaction .guild or not isinstance (member , Member ):
405+ await interaction .response .send_message (
406+ embed = EmbedX .warning ("This command cannot be used in this context." ),
407+ ephemeral = True ,
408+ )
409+ return
410+
411+ # Get actor
412+ db = self .bot .get_db (interaction .guild )
413+ actor = db .find_one (Actor , Actor .id == member .id ) or self .bot .create_actor (
414+ member
415+ )
416+
417+ # Get item
418+ await interaction .response .defer (ephemeral = True )
419+ item_stack = actor .item_stacks .get (item_id )
420+ item = item_stack .item if item_stack else None
421+ if not item_stack or not item or item .type != ItemType .CONSUMABLE :
422+ await interaction .followup .send (
423+ embed = EmbedX .error (f"Invalid **item** input: `{ item_id } `\n " )
424+ )
425+ return
426+
427+ # Consume item
428+ actor .add_item_stats (item )
429+ item_stack .quantity = max (0 , item_stack .quantity - 1 )
430+ if item_stack .quantity <= 0 :
431+ del actor .item_stacks [item .id ]
432+ db .save (actor )
433+ await interaction .followup .send (
434+ embed = EmbedX .success (
435+ f"You consumed **{ item .emoji or item .alt_emoji } { item .name } **."
436+ )
414437 )
415438
439+ # Send public response
440+ if isinstance (interaction .channel , Messageable ):
441+ embed = EmbedX .info (
442+ emoji = "🍴" ,
443+ title = "Consumption" ,
444+ description = f"{ member .mention } has consumed an item." ,
445+ )
446+ embed .add_field (
447+ name = "Item 🔻" ,
448+ value = f"{ item .emoji or item .alt_emoji } **{ item .name } **" ,
449+ )
450+ embed .set_author (name = member .display_name , icon_url = member .display_avatar )
451+ embed .set_thumbnail (url = item .icon_url )
452+ await interaction .channel .send (
453+ embed = self .add_item_stats_embed_fields (embed , item )
454+ )
455+
416456 # ----------------------------------------------------------------------------------------------------
417457
458+ def add_item_stats_embed_fields (
459+ self , embed : Embed , item : Item , scale : int = 1 , show_emoji : bool = True
460+ ):
461+ emoji = (" 🔼" if scale >= 0 else " 🔻" ) if show_emoji else ""
462+ if item .health_bonus :
463+ embed .add_field (
464+ name = f"Health{ emoji } " ,
465+ value = f":heart: **{ numsign (intcomma (scale * item .health_bonus ))} **" ,
466+ )
467+ if item .energy_bonus :
468+ embed .add_field (
469+ name = f"Energy{ emoji } " ,
470+ value = f"⚡ **{ numsign (intcomma (scale * item .energy_bonus ))} **" ,
471+ )
472+ if item .max_health_bonus :
473+ embed .add_field (
474+ name = f"Max Health{ emoji } " ,
475+ value = f":heart: **{ numsign (intcomma (scale * item .max_health_bonus ))} **" ,
476+ )
477+ if item .max_energy_bonus :
478+ embed .add_field (
479+ name = f"Max Energy{ emoji } " ,
480+ value = f"⚡ **{ numsign (intcomma (scale * item .max_energy_bonus ))} **" ,
481+ )
482+ if item .attack_bonus :
483+ embed .add_field (
484+ name = f"Attack{ emoji } " ,
485+ value = f":crossed_swords: **{ numsign (intcomma (scale * item .attack_bonus ))} **" ,
486+ )
487+ if item .defense_bonus :
488+ embed .add_field (
489+ name = f"Defense{ emoji } " ,
490+ value = f"🛡 **{ numsign (intcomma (scale * item .defense_bonus ))} **" ,
491+ )
492+ if item .speed_bonus :
493+ embed .add_field (
494+ name = f"Speed{ emoji } " ,
495+ value = f"🥾 **{ numsign (intcomma (scale * item .speed_bonus ))} **" ,
496+ )
497+ return embed
498+
418499 async def buyable_items_autocomplete (
419500 self , interaction : Interaction , current : str
420501 ) -> list [app_commands .Choice [str ]]:
@@ -430,12 +511,37 @@ async def buyable_items_autocomplete(
430511 ][:25 ]
431512 ]
432513
514+ async def actor_consumable_items_autocomplete (
515+ self , interaction : Interaction , current : str
516+ ) -> list [app_commands .Choice [str ]]:
517+ member = interaction .user
518+ if not isinstance (member , Member ):
519+ return []
520+ actor = self .bot .get_db (interaction .guild ).find_one (
521+ Actor , Actor .id == interaction .user .id
522+ ) or self .bot .create_actor (member )
523+ return [
524+ app_commands .Choice (
525+ name = f"{ item .alt_emoji } { item .name } " ,
526+ value = item .id ,
527+ )
528+ for item in [
529+ item_stack .item
530+ for item_stack in actor .item_stacks .values ()
531+ if item_stack .item .type == ItemType .CONSUMABLE
532+ and current .lower () in item_stack .item .name .lower ()
533+ ][:25 ]
534+ ]
535+
433536 async def actor_equippable_items_autocomplete (
434537 self , interaction : Interaction , current : str
435538 ) -> list [app_commands .Choice [str ]]:
539+ member = interaction .user
540+ if not isinstance (member , Member ):
541+ return []
436542 actor = self .bot .get_db (interaction .guild ).find_one (
437543 Actor , Actor .id == interaction .user .id
438- ) or self .bot .create_actor (interaction . user )
544+ ) or self .bot .create_actor (member )
439545 return [
440546 app_commands .Choice (
441547 name = f"{ item .alt_emoji } { item .name } " ,
@@ -453,9 +559,12 @@ async def actor_equippable_items_autocomplete(
453559 async def actor_equipped_items_autocomplete (
454560 self , interaction : Interaction , current : str
455561 ) -> list [app_commands .Choice [str ]]:
562+ member = interaction .user
563+ if not isinstance (member , Member ):
564+ return []
456565 actor = self .bot .get_db (interaction .guild ).find_one (
457566 Actor , Actor .id == interaction .user .id
458- ) or self .bot .create_actor (interaction . user )
567+ ) or self .bot .create_actor (member )
459568 return [
460569 app_commands .Choice (
461570 name = f"{ item .alt_emoji } { item .name } " ,
0 commit comments