add getloot command

This commit is contained in:
2025-08-26 20:22:13 +02:00
parent 9760df2947
commit 95cbdccd8c
4 changed files with 92 additions and 8 deletions

View File

@@ -43,10 +43,25 @@ When using/giving an item or qbucks the itemlock will be set at the start of the
Admins can toggle the itemlock on chatters with the [`itemlock`](#administrative-commands) command. This will stop a chatter from giving, receiving and using items and qweribucks.
It will NOT stop them from using items by cheering, but if that cheer item usage fails, they will not be given an equivalent item as compensation.
Items can be used with the alias as a command (example: `blast qwerinope`) or with the [`use` command](#item-commands).
Items can be used with the alias as a command (example: `blast qwerinope`) or with the [`use` command](#qweribucksitem-commands).
When an Item is used it is removed from the inventory of the chatter.
### Lootbox
There is no lootbox item, you just get loot when using the [`getloot` command](#qweribucksitem-commands). The cooldown is 10 minutes. You can't get loot if your itemlock is set.
Each loot drop has between 50 and 150 qbucks. Here is the drop table for items with chances.
ITEM|RATE
-|-
`grenade`|`1/5`
`blaster`|`1/5`
`tnt`|`1/20`
`silver bullet`|`1/250`
Each of these rates get pulled 5 times, then the result is added to your inventory.
It's theoretically possible to get 5 of each item.
### Chatterbot/streamerbot
This depends on if the `CHATTER_IS_STREAMER` environment variable is set.
@@ -70,22 +85,18 @@ COMMAND|FUNCTION|USER|ALIASES|DISABLEABLE
`stats [target]`|Get timeout and some item stats for yourself or specified user this month|anyone|`stats` `monthlystats`|:white_check_mark:
`alltime [target]`|Get timeout and some item stats for yourself or specified user of all time|anyone|`alltime` `alltimestats`|:white_check_mark:
### Qweribucks commands
### Qweribucks/Item commands
COMMAND|FUNCTION|USER|ALIASES|DISABLEABLE
-|-|-|-|-
`getloot`|Get a random assortment of items and qbucks every 10 minutes. [(drop rates)](#lootbox)|anyone|`getloot` `loot` `dig`|:white_check_mark:
`getbalance [target]`|Get balance of target or self|anyone|`getbalance` `balance` `qbucks` `qweribucks` `wallet` `getwallet`|:white_check_mark:
`donate {target} {amount}`|Give the targeted user some or all of your qweribucks|anyone|`donate`|:white_check_mark:
`admindonate {target} {amount}`|Gives the targeted user amount of qweribucks|admins|`admindonate`|:white_check_mark:
### Item commands
COMMAND|FUNCTION|USER|ALIASES|DISABLEABLE
-|-|-|-|-
`iteminfo {item}`|Get item function and aliases|anyone|`iteminfo` `itemhelp` `info`|:white_check_mark:
`inventory [target]`|Get inventory contents of target or self|anyone|`inventory` `inv`|:white_check_mark:
`give {target} {item} {amount}`|Give targeted user amount of items|anyone|`give`|:white_check_mark:
`use {item} ...`|Use item. More info at [The items section](#items)|anyone|`use`|:x:
`admindonate {target} {amount}`|Gives the targeted user amount of qweribucks|admins|`admindonate`|:white_check_mark:
`admingive {target} {item} {amount}`|Give targeted user amount of new items|admins|`admingive`|:white_check_mark:
### Administrative commands

60
src/commands/getloot.ts Normal file
View File

@@ -0,0 +1,60 @@
import { redis } from "bun";
import { Command, sendMessage } from "commands";
import { getUserRecord, updateUserRecord } from "db/dbUser";
import items from "items";
import { buildTimeString } from "lib/dateManager";
const COOLDOWN = 10 * 60 * 1000; // 10 mins (ms)
export default new Command('getloot', ['getloot', 'dig', 'loot'], 'chatter', async (msg, user) => {
if (!await redis.exists('streamIsLive')) { await sendMessage(`No loot while stream is offline`, msg.messageId); return; };
if (await user.itemLock()) { await sendMessage(`Cannot get loot (itemlock)`, msg.messageId); return; };
const userData = await getUserRecord(user);
const lastlootbox = Date.parse(userData.lastlootbox);
const now = Date.now();
if ((lastlootbox + COOLDOWN) > now) { await sendMessage(`Wait ${buildTimeString(now - COOLDOWN, lastlootbox)} for another lootbox.`, msg.messageId); return; };
await user.setLock();
userData.lastlootbox = new Date(now).toISOString();
const gainedqbucks = Math.floor(Math.random() * 100) + 50; // range from 50 to 150
userData.balance += gainedqbucks;
const itemDiff = {
grenade: 0,
blaster: 0,
tnt: 0,
silverbullet: 0
};
for (let i = 0; i < 5; i++) {
if (Math.floor(Math.random() * 5) === 0) itemDiff.grenade += 1;
if (Math.floor(Math.random() * 5) === 0) itemDiff.blaster += 1;
if (Math.floor(Math.random() * 25) === 0) itemDiff.tnt += 1;
if (Math.floor(Math.random() * 250) === 0) itemDiff.silverbullet += 1;
};
for (const [item, amount] of Object.entries(itemDiff)) {
if (userData.inventory[item]) userData.inventory[item] += amount;
};
const itemstrings: string[] = [`${gainedqbucks} qbucks`];
for (const [item, amount] of Object.entries(itemDiff)) {
if (amount === 0) continue;
const selection = items.get(item);
if (!selection) continue;
itemstrings.push(`${amount} ${selection.prettyName + (amount === 1 ? '' : selection.plural)}`);
};
const last = itemstrings.pop();
const itemstring = itemstrings.length === 0 ? last : itemstrings.join(', ') + " and " + last;
const message = `You got ${itemstring}`;
await Promise.all([
updateUserRecord(user, userData),
sendMessage(message, msg.messageId),
user.clearLock()
]);
});

10
src/events/streamState.ts Normal file
View File

@@ -0,0 +1,10 @@
import { redis } from "bun";
import { eventSub, streamerId } from "main";
eventSub.onStreamOnline(streamerId, async _msg => {
await redis.set('streamIsLive', '1');
});
eventSub.onStreamOffline(streamerId, async _msg => {
await redis.del('streamIsLive');
});

View File

@@ -45,6 +45,9 @@ mods.forEach(async mod => {
logger.info(`Set the mod status of ${mod.userDisplayName} in the Redis/Valkey database.`);
});
const streamdata = await streamerApi.streams.getStreamByUserId(streamerId);
if (streamdata) await redis.set('streamIsLive', '1');
await import("./events");
await import("./web");