|
@@ -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,
|
|
|
):
|