i think weapons working real ?
This commit is contained in:
parent
5be9dbfe21
commit
783af8652c
|
@ -0,0 +1,47 @@
|
|||
import { GuildMember, CommandInteraction, SlashCommandBuilder } from 'discord.js';
|
||||
import { weaponAutocomplete, getItem, getItemQuantity, formatItems } from '../lib/rpg/items';
|
||||
import { Command } from '../types/index';
|
||||
import { initHealth, dealDamage, BLOOD_ITEM, BLOOD_ID } from '../lib/rpg/pvp';
|
||||
|
||||
export default {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('attack')
|
||||
.setDescription('Attack someone using a weapon you have')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('weapon')
|
||||
.setAutocomplete(true)
|
||||
.setDescription('The weapon to use')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addUserOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setRequired(true)
|
||||
.setDescription('Who to attack with the weapon')
|
||||
)
|
||||
.setDMPermission(false),
|
||||
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
|
||||
const member = interaction.member! as GuildMember;
|
||||
await initHealth(member.id);
|
||||
const weaponID = parseInt(interaction.options.getString('weapon', true));
|
||||
const user = interaction.options.getUser('user', true);
|
||||
|
||||
await interaction.deferReply({ephemeral: true});
|
||||
|
||||
const weapon = await getItem(weaponID);
|
||||
if (!weapon) return interaction.followUp('No such item exists!');
|
||||
if (weapon.type !== 'weapon') return interaction.followUp('That is not a weapon!');
|
||||
|
||||
const dmg = weapon.maxStack;
|
||||
await dealDamage(user.id, dmg);
|
||||
const newHealth = await getItemQuantity(user.id, BLOOD_ID);
|
||||
|
||||
await interaction.followUp(`You hit ${user} for ${BLOOD_ITEM.emoji} **${dmg}** damage! They are now at ${formatItems(BLOOD_ITEM, newHealth.quantity)}.`);
|
||||
},
|
||||
|
||||
autocomplete: weaponAutocomplete,
|
||||
} satisfies Command;
|
|
@ -4,6 +4,7 @@ import { getStation, canUseStation, craftingStations, verb, CraftingStation } fr
|
|||
import { formatItem, getItemQuantity, formatItems, getMaxStack, giveItem, formatItemsArray } from '../lib/rpg/items';
|
||||
import { getRecipe, defaultRecipes, formatRecipe, resolveCustomRecipe } from '../lib/rpg/recipes';
|
||||
import { Command } from '../types/index';
|
||||
import { initHealth } from '../lib/rpg/pvp';
|
||||
|
||||
export default {
|
||||
data: new SlashCommandBuilder()
|
||||
|
@ -30,6 +31,8 @@ export default {
|
|||
|
||||
const member = interaction.member! as GuildMember;
|
||||
|
||||
await initHealth(member.id);
|
||||
|
||||
const recipeID = parseInt(interaction.options.getString('recipe', true));
|
||||
|
||||
await interaction.deferReply({ephemeral: true});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { GuildMember, EmbedBuilder, SlashCommandBuilder, CommandInteraction } from 'discord.js';
|
||||
import { EmbedBuilder, SlashCommandBuilder, CommandInteraction } from 'discord.js';
|
||||
import { writeTmpFile } from '../lib/util';
|
||||
import { Command } from '../types/index';
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { GuildMember, CommandInteraction, SlashCommandBuilder } from 'discord.js';
|
||||
import { ItemInventory, db } from '../lib/db';
|
||||
import { formatItems, getItem } from '../lib/rpg/items';
|
||||
import { initHealth } from '../lib/rpg/pvp';
|
||||
import { Command } from '../types/index';
|
||||
|
||||
export default {
|
||||
|
@ -14,6 +15,8 @@ export default {
|
|||
|
||||
const member = interaction.member! as GuildMember;
|
||||
|
||||
await initHealth(member.id);
|
||||
|
||||
await interaction.deferReply({ephemeral: true});
|
||||
|
||||
const itemsList = await db<ItemInventory>('itemInventories')
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { GuildMember, CommandInteraction, SlashCommandBuilder } from 'discord.js';
|
||||
import { changeLinkedCounterInteraction, linkedCounterAutocomplete } from '../lib/rpg/counter';
|
||||
import { Command } from '../types/index';
|
||||
import { initHealth } from '../lib/rpg/pvp';
|
||||
|
||||
export default {
|
||||
data: new SlashCommandBuilder()
|
||||
|
@ -27,6 +28,8 @@ export default {
|
|||
|
||||
const member = interaction.member! as GuildMember;
|
||||
|
||||
await initHealth(member.id);
|
||||
|
||||
const amount = Math.trunc(interaction.options.getInteger('amount') || 1);
|
||||
const type = interaction.options.getString('type')!;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { GuildMember, CommandInteraction, SlashCommandBuilder } from 'discord.js';
|
||||
import { changeLinkedCounterInteraction, linkedCounterAutocomplete } from '../lib/rpg/counter';
|
||||
import { initHealth } from '../lib/rpg/pvp';
|
||||
import { Command } from '../types/index';
|
||||
|
||||
export default {
|
||||
|
@ -27,6 +28,8 @@ export default {
|
|||
|
||||
const member = interaction.member! as GuildMember;
|
||||
|
||||
await initHealth(member.id);
|
||||
|
||||
const amount = Math.trunc(interaction.options.getInteger('amount') || 1);
|
||||
const type = interaction.options.getString('type')!;
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { AutocompleteInteraction } from 'discord.js';
|
||||
import { CustomItem, ItemInventory, db } from '../db';
|
||||
import { MAX_HEALTH } from './pvp';
|
||||
|
||||
export type DefaultItem = Omit<CustomItem, 'guild'>; // uses negative IDs
|
||||
export type Item = DefaultItem | CustomItem;
|
||||
|
@ -118,7 +117,7 @@ export const defaultItems: DefaultItem[] = [
|
|||
description: 'ow',
|
||||
emoji: '🩸',
|
||||
type: 'plain',
|
||||
maxStack: MAX_HEALTH,
|
||||
maxStack: 50,
|
||||
untradable: false
|
||||
},
|
||||
{
|
||||
|
@ -374,18 +373,23 @@ export function formatItemsArray(items: Items[], disableBold = false) {
|
|||
return items.map(i => formatItems(i.item, i.quantity, disableBold)).join(' ');
|
||||
}
|
||||
|
||||
function createItemAutocomplete(onlyCustom: boolean) {
|
||||
function createItemAutocomplete(onlyCustom: boolean, filterType: 'plain' | 'weapon' | 'consumable' | null) {
|
||||
return async (interaction: AutocompleteInteraction) => {
|
||||
const focused = interaction.options.getFocused();
|
||||
|
||||
const customItems = await db<CustomItem>('customItems')
|
||||
const itemQuery = db<CustomItem>('customItems')
|
||||
.select('emoji', 'name', 'id')
|
||||
// @ts-expect-error this LITERALLY works
|
||||
.whereLike(db.raw('UPPER(name)'), `%${focused.toUpperCase()}%`)
|
||||
.where('guild', interaction.guildId!)
|
||||
.limit(25);
|
||||
|
||||
if (filterType) itemQuery.where('type', filterType);
|
||||
|
||||
const customItems = await itemQuery;
|
||||
|
||||
const foundDefaultItems = defaultItems.filter(item => item.name.toUpperCase().includes(focused.toUpperCase()));
|
||||
let foundDefaultItems = defaultItems.filter(item => item.name.toUpperCase().includes(focused.toUpperCase()));
|
||||
if (filterType) foundDefaultItems = foundDefaultItems.filter(i => i.type === filterType);
|
||||
|
||||
let items;
|
||||
if (onlyCustom) {
|
||||
|
@ -400,5 +404,8 @@ function createItemAutocomplete(onlyCustom: boolean) {
|
|||
};
|
||||
}
|
||||
|
||||
export const itemAutocomplete = createItemAutocomplete(false);
|
||||
export const customItemAutocomplete = createItemAutocomplete(true);
|
||||
export const itemAutocomplete = createItemAutocomplete(false, null);
|
||||
export const customItemAutocomplete = createItemAutocomplete(true, null);
|
||||
export const plainAutocomplete = createItemAutocomplete(false, 'plain');
|
||||
export const weaponAutocomplete = createItemAutocomplete(false, 'weapon');
|
||||
export const consumableAutocomplete = createItemAutocomplete(false, 'consumable');
|
|
@ -1,7 +1,11 @@
|
|||
import { InitHealth, db } from '../db';
|
||||
import { DefaultItems, getDefaultItem, giveItem } from './items';
|
||||
import { InitHealth, ItemInventory, db } from '../db';
|
||||
import { DefaultItems, getDefaultItem, giveItem, getItemQuantity, formatItems } from './items';
|
||||
import { Client } from 'discord.js';
|
||||
|
||||
export const MAX_HEALTH = 100;
|
||||
export const BLOOD_ID = DefaultItems.BLOOD;
|
||||
export const BLOOD_ITEM = getDefaultItem(BLOOD_ID);
|
||||
export const MAX_HEALTH = BLOOD_ITEM.maxStack;
|
||||
const BLOOD_GAIN_PER_HOUR = 5;
|
||||
|
||||
export async function initHealth(user: string) {
|
||||
const isInitialized = await db<InitHealth>('initHealth')
|
||||
|
@ -9,7 +13,37 @@ export async function initHealth(user: string) {
|
|||
.first();
|
||||
|
||||
if (!isInitialized) {
|
||||
giveItem(user, getDefaultItem(DefaultItems.BLOOD), MAX_HEALTH);
|
||||
giveItem(user, BLOOD_ITEM, MAX_HEALTH);
|
||||
await db<InitHealth>('initHealth').insert({ user });
|
||||
}
|
||||
}
|
||||
|
||||
export async function getHealth(user: string) {
|
||||
return await getItemQuantity(user, BLOOD_ID);
|
||||
}
|
||||
|
||||
export async function dealDamage(user: string, dmg: number) {
|
||||
return await giveItem(user, BLOOD_ITEM, -dmg);
|
||||
}
|
||||
|
||||
async function healthCron(bot: Client) {
|
||||
await db<ItemInventory>('itemInventories')
|
||||
.where('item', BLOOD_ID)
|
||||
.update({
|
||||
quantity: db.raw('MIN(quantity + ?, ?)', [BLOOD_GAIN_PER_HOUR, MAX_HEALTH])
|
||||
});
|
||||
|
||||
const debtedUsers = await db<ItemInventory>('itemInventories')
|
||||
.select('user', 'quantity')
|
||||
.where('quantity', '<', '0');
|
||||
|
||||
for (const debted of debtedUsers) {
|
||||
const user = await bot.users.fetch(debted.user);
|
||||
if (!user) continue;
|
||||
await user.send(`${formatItems(BLOOD_ITEM, debted.quantity)} You are bleeding out to death`);
|
||||
}
|
||||
}
|
||||
|
||||
export function init(bot: Client) {
|
||||
setInterval(() => healthCron(bot), 1_000 * 60 * 60);
|
||||
}
|
Loading…
Reference in New Issue