Browse Source

First pass at giftcha, fix some error messages, and fix initial balance

Kirk Trombley 3 years ago
parent
commit
a9f95cff2e
1 changed files with 67 additions and 7 deletions
  1. 67 7
      commands/commands/rollcoin.py

+ 67 - 7
commands/commands/rollcoin.py

@@ -69,7 +69,7 @@ class RollcoinWallet:
             for rarity in [NFT_MAX_RARITY, *NFT_RARITY[1:]]
         }
         counts[NFT_RARITY[0]] = num_nfts - sum(counts.values())
-        return "\n\t".join(f"{rarity.title()}: {100 * c / num_nfts:.02f}%" for rarity in [*NFT_RARITY, NFT_MAX_RARITY] if (c := counts[rarity]) > 0)
+        return "\n\t".join(f"{rarity.title()}: {c} ({100 * c / num_nfts:.02f}%)" for rarity in [*NFT_RARITY, NFT_MAX_RARITY] if (c := counts[rarity]) > 0)
 
 
 SPECIAL_AMOUNTS = {
@@ -174,7 +174,7 @@ async def tip(
     if (target_id := wallet_lookup.get(target_name.lower(), None)) is None:
         RollbotFailure.INVALID_ARGUMENTS.raise_exc(f"Cannot find wallet belonging to {target_name}")
 
-    target_wallet = await wallets.load_or(target_id)
+    target_wallet = await wallets.load_or(target_id, balance=10)
     sender_wallet.balance -= amount
     target_wallet.balance += amount
     await wallets.save(target_id, target_wallet)
@@ -527,7 +527,7 @@ async def gacha(
     logger: Logger,
     req: Request,
     name_api_key: NameAPIKey,
-    pulls: Arg(0, convert=int, required=False, default=1, fail_msg="Number of pulls must be an integer"),
+    pulls: Arg(0, convert=int, required=False, default=1, fail_msg="Number of pulls must be an integer, not {}"),
     reply: Reply,
 ):
     """
@@ -565,12 +565,72 @@ async def gacha(
     state.treasury += len(pulled)
     await state_store.save(GLOBAL_STATE_KEY, state)
 
+
+@as_command
+async def giftcha(
+    sender_wallet: SenderWallet,
+    get_sender_wallet: Lazy(SenderWallet), # used for re-querying to mitigate race condition
+    sender_id: Sender,
+    wallet_store: Data(RollcoinWallet),
+    get_state: Lazy(State),
+    state_store: Data(RollcoinState),
+    sleep_time: GachaSleep,
+    logger: Logger,
+    req: Request,
+    name_api_key: NameAPIKey,
+    wallet_lookup: WalletLookup,
+    target_name: Arg(0, missing_msg="Must provide a target to tax"),
+    pulls: Arg(1, convert=int, required=False, default=1, fail_msg="Number of pulls must be an integer, not {}"),
+    reply: Reply,
+):
+    """
+    Spend one RollCoin to pull from the gachapon, but selflessly gift the resulting NFT to someone else!
+    """
+    if not (1 <= pulls <= 10):
+        RollbotFailure.INVALID_ARGUMENTS.raise_exc("Number of pulls must be between 1 and 10")
+
+    if sender_wallet.balance < pulls:
+        yield f"You only have {sender_wallet.balance} RollCoins available, and gacha pulls cost one each!", reply
+        return
+
+    if (target_id := wallet_lookup.get(target_name.lower(), None)) is None:
+        RollbotFailure.INVALID_ARGUMENTS.raise_exc(f"Could not find a wallet for {target_name}")
+
+    target_name = target_name.title()
+
+    info, img = await pull_gacha(req, name_api_key, logger)
+    pulled = [info]
+    if pulls == 1:
+        yield f"{target_name} received...\n\t{info}", img, reply
+    else:
+        yield f"{target_name} received (1/{pulls})...\n\t{info}", img, reply
+        for i in range(pulls - 1):
+            await asyncio.sleep(sleep_time)
+            try:
+                info, img = await pull_gacha(req, name_api_key, logger)
+                yield f"{target_name} received ({i + 2}/{pulls})...\n\t{info}", img, reply
+                pulled.append(info)
+            except:
+                logger.exception("Failed to pull")
+                yield f"Failed to pull from gachapon! You will not be charged the coin for this pull.", reply
+    
+    sender_wallet = await get_sender_wallet()
+    sender_wallet.balance -= len(pulled)
+    await wallet_store.save(sender_id, sender_wallet)
+    target_wallet = await wallet_store.load_or(target_id, balance=10)
+    target_wallet.nfts += pulled
+    await wallet_store.save(target_id, target_wallet)
+    state = await get_state()
+    state.treasury += len(pulled)
+    await state_store.save(GLOBAL_STATE_KEY, state)
+
+
 # ADMIN COMMANDS
 
 @as_command
 async def deflate(
     origin_admin: OriginAdmin,
-    power: Arg(0, convert=int, missing_msg="Must provide power to deflate by", fail_msg="Power to deflate by must be an integer"),
+    power: Arg(0, convert=int, missing_msg="Must provide power to deflate by", fail_msg="Power to deflate by must be an integer, not {}"),
     wallet_store: Data(RollcoinWallet),
     state_store: Data(RollcoinState),
 ):
@@ -598,7 +658,7 @@ async def deflate(
 @as_command
 async def brrr(
     origin_admin: OriginAdmin,
-    coins: Arg(0, convert=float, missing_msg="Must provide coins to mint", fail_msg="Coins to mint by must be a number"),
+    coins: Arg(0, convert=float, missing_msg="Must provide coins to mint", fail_msg="Coins to mint by must be a number, not {}"),
     state_store: Data(RollcoinState),
 ):
     """
@@ -622,7 +682,7 @@ async def tax(
     origin_admin: OriginAdmin,
     wallet_lookup: WalletLookup,
     target_name: Arg(0, missing_msg="Must provide a target to tax"),
-    coins: Arg(1, convert=float, missing_msg="Must provide coins to tax", fail_msg="Coins to tax by must be a number"),
+    coins: Arg(1, convert=float, missing_msg="Must provide coins to tax", fail_msg="Coins to tax by must be a number, not {}"),
     wallet_store: Data(RollcoinWallet),
     state_store: Data(RollcoinState),
 ):
@@ -647,7 +707,7 @@ async def tax(
 @as_command
 async def market(
     origin_admin: OriginAdmin,
-    target_state: Arg(0, convert=int, missing_msg="Must provide target state for market", fail_msg="Target market state must be an integer"),
+    target_state: Arg(0, convert=int, missing_msg="Must provide target state for market", fail_msg="Target market state must be an integer, not {}"),
     state_store: Data(RollcoinState),
     messages: MarketMessages,
 ):