← back to browse
goat command

mine

mine ores & upgrade pickaxe

0
views
0
likes
0
installs

Aliases: mining

raw source
const mongoose = require("mongoose");

const minerSchema = new mongoose.Schema({
  userID: { type: String, required: true, unique: true },
  userName: { type: String, default: "Unknown" },
  balance: { type: Number, default: 1000 },
  xp: { type: Number, default: 0 },
  level: { type: Number, default: 1 },
  energy: { type: Number, default: 100 },
  maxEnergy: { type: Number, default: 100 },
  lastMineTime: { type: Number, default: 0 },
  title: { type: String, default: "miner" },
  pickaxe: { type: String, default: "Wooden Pickaxe" },
  inventory: {
    stone: { type: Number, default: 0 },
    iron: { type: Number, default: 0 },
    gold: { type: Number, default: 0 },
    diamond: { type: Number, default: 0 },
    netherite: { type: Number, default: 0 },
    ruby: { type: Number, default: 0 },
    emerald: { type: Number, default: 0 }
  },
  dailyTasks: {
    mineCount: { type: Number, default: 0 },
    foundDiamond: { type: Number, default: 0 },
    upgradedPickaxe: { type: Boolean, default: false },
    claimedReward: { type: Boolean, default: false },
    lastReset: { type: Number, default: 0 }
  }
});

const MinerUser = mongoose.models.DiabloMinerUser || mongoose.model("DiabloMinerUser", minerSchema);

const PICKAXES = {
  "Wooden Pickaxe": { price: 0, multiplier: 1, reqLevel: 1 },
  "Iron Pickaxe": { price: 5000000, multiplier: 3, reqLevel: 3 },
  "Gold Pickaxe": { price: 50000000, multiplier: 6, reqLevel: 5 },
  "Diamond Pickaxe": { price: 500000000, multiplier: 12, reqLevel: 10 },
  "Laser Drill": { price: 5000000000, multiplier: 30, reqLevel: 20 }
};

const ORES = {
  stone: { name: "Stone", emoji: "πŸͺ¨", value: 50000, xp: 20, chance: 40 },
  iron: { name: "Iron", emoji: "βš™οΈ", value: 250000, xp: 50, chance: 30 },
  gold: { name: "Gold", emoji: "πŸͺ™", value: 1000000, xp: 150, chance: 15 },
  diamond: { name: "Diamond", emoji: "πŸ’Ž", value: 10000000, xp: 500, chance: 8 },
  netherite: { name: "Netherite", emoji: "🌌", value: 100000000, xp: 2000, chance: 3 },
  ruby: { name: "Ruby", emoji: "πŸ”΄", value: 20000000, xp: 800, chance: 2 },
  emerald: { name: "Emerald", emoji: "🟒", value: 5000000, xp: 300, chance: 2 }
};

const TITLES = {
  1: "miner",
  5: "digger",
  10: "excavator",
  20: "gold miner",
  30: "dragon miner",
  40: "netherite lord",
  50: "gem king",
  70: "elite miner",
  90: "mythic digger",
  100: "immortal miner"
};

module.exports = {
  config: {
    name: "mine",
    aliases: ["mining"],
    version: "3.0.0",
    author: "protik shah",
    countDown: 3,
    role: 0,
    shortDescription: "mine ores & upgrade pickaxe",
    category: "game",
    guide: {
      en: "⛏️ {p}mine\nπŸ›’ {p}mine shop\nπŸŽ’ {p}mine inv\nπŸ“‹ {p}mine task\nπŸ† {p}mine top"
    }
  },

  formatMoney: (num) => {
    if (num >= 1e9) return (num / 1e9).toFixed(1) + "B";
    if (num >= 1e6) return (num / 1e6).toFixed(1) + "M";
    if (num >= 1e3) return (num / 1e3).toFixed(1) + "K";
    return num.toString();
  },

  progressBar: (current, max, size = 15) => {
    const filled = Math.round((current / max) * size);
    const empty = size - filled;
    return "[" + "β–ˆ".repeat(filled) + "β–‘".repeat(empty) + "] " + current + "/" + max;
  },

  getTitle: (level) => {
    let title = "miner";
    for (const [lv, t] of Object.entries(TITLES)) {
      if (level >= parseInt(lv)) title = t;
    }
    return title;
  },

  regenEnergy: (user) => {
    const now = Date.now();
    const REGEN = 2 * 60 * 1000;
    const elapsed = now - (user.lastMineTime || 0);
    const added = Math.floor(elapsed / REGEN);
    if (added > 0) {
      user.energy = Math.min(user.maxEnergy || 100, user.energy + added);
      user.lastMineTime = now;
    }
  },

  checkDailyReset: (user) => {
    const now = Date.now();
    const ONE_DAY = 24 * 60 * 60 * 1000;
    if (!user.dailyTasks || now - user.dailyTasks.lastReset > ONE_DAY) {
      user.dailyTasks = {
        mineCount: 0,
        foundDiamond: 0,
        upgradedPickaxe: false,
        claimedReward: false,
        lastReset: now
      };
    }
  },

  onStart: async function ({ api, event, args, message }) {
    const sendMsg = (txt) => message?.reply ? message.reply(txt) : api.sendMessage(txt, event.threadID, event.messageID);
    const { senderID } = event;
    const sub = (args[0] || "").toLowerCase();

    try {
      let user = await MinerUser.findOne({ userID: senderID });
      if (!user) {
        user = new MinerUser({ userID: senderID });
        await user.save();
      }

      try {
        const info = await api.getUserInfo(senderID);
        user.userName = info[senderID]?.name || senderID;
        await user.save();
      } catch (e) {}

      this.regenEnergy(user);
      this.checkDailyReset(user);

      // ===== SHOP =====
      if (sub === "shop" || sub === "mineshop") {
        const item = args.slice(1).join(" ").trim();
        if (!item) {
          let txt = "πŸ›’ ═[ MINING SHOP ]═ πŸ›’\n\n";
          txt += `πŸ‘€ ${user.userName}  |  πŸ’³ $${this.formatMoney(user.balance)}\n`;
          txt += `⛏️ ${user.pickaxe}  |  Lv.${user.level}\n\n`;
          for (const [name, info] of Object.entries(PICKAXES)) {
            const owned = user.pickaxe === name ? " βœ…" : "";
            const locked = user.level < info.reqLevel ? " πŸ”’" : "";
            txt += `${info.reqLevel <= user.level ? "🟒" : "πŸ”΄"} ${name}  $${this.formatMoney(info.price)}  x${info.multiplier}${owned}${locked}\n`;
          }
          txt += `\nπŸ’‘ BUY: {p}mine shop <pickaxe name>`;
          return sendMsg(txt);
        }

        const matched = Object.keys(PICKAXES).find(k => k.toLowerCase() === item.toLowerCase());
        if (!matched) return sendMsg("❌ Pickaxe not found.");
        const info = PICKAXES[matched];
        if (user.level < info.reqLevel) return sendMsg(`❌ Need level ${info.reqLevel}`);
        if (user.balance < info.price) return sendMsg(`❌ Insufficient funds. Need $${this.formatMoney(info.price)}`);
        if (user.pickaxe === matched) return sendMsg("❌ Already owned.");
        user.balance -= info.price;
        user.pickaxe = matched;
        user.dailyTasks.upgradedPickaxe = true;
        await user.save();
        return sendMsg(`πŸŽ‰ Upgraded to **${matched}**! (x${info.multiplier} multiplier)`);
      }

      // ===== INVENTORY =====
      if (sub === "inv" || sub === "mineinv") {
        let txt = "πŸŽ’ MINING INVENTORY πŸŽ’\n\n";
        let total = 0;
        for (const [key, amount] of Object.entries(user.inventory)) {
          if (amount > 0) {
            const ore = ORES[key];
            txt += `${ore.emoji} ${ore.name}  x${amount}  ($${this.formatMoney(amount * ore.value)})\n`;
            total += amount * ore.value;
          }
        }
        if (total === 0) txt += "🟑 Inventory empty. Mine some ores!\n";
        txt += `\nπŸ“Š TOTAL VALUE: $${this.formatMoney(total)}`;
        txt += `\nπŸ’‘ SELL: {p}mine sell`;
        return sendMsg(txt);
      }

      // ===== SELL =====
      if (sub === "sell") {
        let total = 0;
        for (const [key, amount] of Object.entries(user.inventory)) {
          if (amount > 0) {
            total += amount * ORES[key].value;
            user.inventory[key] = 0;
          }
        }
        if (total === 0) return sendMsg("🟑 Nothing to sell.");
        user.balance += total;
        await user.save();
        return sendMsg(`πŸ’° Sold all ores for **$${this.formatMoney(total)}**!\nπŸ’³ NEW BALANCE: $${this.formatMoney(user.balance)}`);
      }

      // ===== DAILY TASK =====
      if (sub === "task" || sub === "minetask") {
        const task = user.dailyTasks;
        if (args[1] && args[1].toLowerCase() === "claim") {
          if (task.claimedReward) return sendMsg("❌ Already claimed today.");
          if (task.mineCount < 5 || task.foundDiamond < 1 || !task.upgradedPickaxe) {
            return sendMsg("❌ Complete all tasks first.");
          }
          const bonus = 5000000 * user.level;
          const bonusXP = 1000 * user.level;
          user.balance += bonus;
          user.xp += bonusXP;
          task.claimedReward = true;
          await user.save();
          return sendMsg(`🎁 DAILY REWARD CLAIMED 🎁\n\nπŸ’΅ +$${this.formatMoney(bonus)}\n⭐ +${bonusXP} XP`);
        }

        let txt = "πŸ“‹DAILY MINING TASKSπŸ“‹\n\n";
        txt += `πŸ‘€ ${user.userName}  |  Lv.${user.level}\n\n`;
        txt += `1. ⛏️ Mine 5 times  : ${task.mineCount >= 5 ? "βœ…" : "❌"}  [${task.mineCount}/5]\n`;
        txt += `2. πŸ’Ž Find Diamond  : ${task.foundDiamond >= 1 ? "βœ…" : "❌"}\n`;
        txt += `3. ⬆️ Upgrade Pickaxe : ${task.upgradedPickaxe ? "βœ…" : "❌"}\n\n`;
        if (task.mineCount >= 5 && task.foundDiamond >= 1 && task.upgradedPickaxe) {
          txt += task.claimedReward ? "πŸŽ‰ Already claimed today!" : "🎁 Type `{p}mine task claim` to collect!";
        } else {
          txt += "πŸ’‘ Complete all tasks to unlock reward!";
        }
        return sendMsg(txt);
      }

      // ===== LEADERBOARD =====
      if (sub === "top" || sub === "minetop") {
        const all = await MinerUser.find({});
        const sorted = all
          .map(u => ({ ...u, userName: u.userName || u.userID }))
          .sort((a, b) => b.level - a.level || b.balance - a.balance)
          .slice(0, 10);

        let txt = "πŸ†β• MINING LEADERBOARDβ•πŸ†\n\n";
        let rank = 1;
        for (const u of sorted) {
          const name = u.userName || u.userID;
          const medal = rank === 1 ? "πŸ₯‡" : rank === 2 ? "πŸ₯ˆ" : rank === 3 ? "πŸ₯‰" : `#${rank}`;
          txt += `${medal} ${name.slice(0, 18)}  |  Lv.${u.level}  |  $${this.formatMoney(u.balance)}\n`;
          rank++;
        }
        if (rank === 1) txt += "🟑 No data found.";
        return sendMsg(txt);
      }

      // ===== CORE MINE =====
      if (user.energy < 1) {
        return sendMsg(`πŸ”‹ Out of energy!\n⚑ ${this.progressBar(0, user.maxEnergy, 15)}\n⏳ Recharges 1 every 2 min.`);
      }

      const pick = PICKAXES[user.pickaxe] || PICKAXES["Wooden Pickaxe"];
      const luck = pick.multiplier;
      const rand = Math.random() * 100;
      let found = "stone";
      for (const [key, ore] of Object.entries(ORES)) {
        if (rand < ore.chance * (luck * 0.3)) { found = key; break; }
      }

      const ore = ORES[found];
      user.energy -= 1;
      user.lastMineTime = Date.now();
      user.inventory[found] = (user.inventory[found] || 0) + 1;
      user.xp += ore.xp;
      user.dailyTasks.mineCount += 1;
      if (found === "diamond") user.dailyTasks.foundDiamond += 1;

      let leveled = false;
      const reqXP = user.level * 500;
      if (user.xp >= reqXP) {
        user.level += 1;
        user.xp -= reqXP;
        user.maxEnergy += 5;
        user.energy = user.maxEnergy;
        user.title = this.getTitle(user.level);
        leveled = true;
      }

      await user.save();

      let msg = "⛏️═MINING RESULT═⛏️\n\n";
      msg += `${ore.emoji} Found: **${ore.name}**\n`;
      msg += `πŸ’° Value: +$${this.formatMoney(ore.value)}\n`;
      msg += `⭐ XP: +${ore.xp}\n`;
      msg += `⚑ Energy: ${this.progressBar(user.energy, user.maxEnergy, 15)}\n`;
      msg += `⛏️ Pickaxe: ${user.pickaxe} (x${luck})\n`;
      msg += `🏷️ Title: ${user.title}`;
      if (leveled) msg += `\n\nπŸŽ‰ LEVEL UP! Reached **Lv.${user.level}**! (Energy fully restored!)`;
      return sendMsg(msg);

    } catch (err) {
      console.error("Mine Error:", err);
      return sendMsg("❌ Mining error.");
    }
  }
};

View raw file