summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordavidovski <david@davidovski.xyz>2025-10-15 04:01:15 +0100
committerdavidovski <david@davidovski.xyz>2025-10-15 04:01:15 +0100
commitdc825ad776f9fe9f763267874f6fa70c4870fc46 (patch)
treed8d2bcf26b180f2c1abbab4e0dc1929dd88e05ab
parent10b327e9f6441a8863227ce3e075a5a587654065 (diff)
v5
-rw-r--r--pom.xml2
-rw-r--r--src/main/java/net/uomc/mineshaft/DailyCommand.java3
-rw-r--r--src/main/java/net/uomc/mineshaft/EnchantCommand.java64
-rw-r--r--src/main/java/net/uomc/mineshaft/FishCommand.java10
-rw-r--r--src/main/java/net/uomc/mineshaft/FurnaceCommand.java4
-rw-r--r--src/main/java/net/uomc/mineshaft/MineCommand.java135
-rw-r--r--src/main/java/net/uomc/mineshaft/Mineshaft.java105
-rw-r--r--src/main/java/net/uomc/mineshaft/MineshaftItem.java57
-rw-r--r--src/main/java/net/uomc/mineshaft/PickaxeCommand.java17
-rw-r--r--src/main/java/net/uomc/mineshaft/Pickaxes.java122
-rw-r--r--src/main/java/net/uomc/mineshaft/RobCommand.java7
-rw-r--r--src/main/java/net/uomc/mineshaft/crafting/Crafting.java68
-rw-r--r--src/main/java/net/uomc/mineshaft/crafting/CraftingRecipe.java21
-rw-r--r--src/main/java/net/uomc/mineshaft/resources/Resource.java2
-rw-r--r--src/main/java/net/uomc/mineshaft/resources/ResourceManager.java9
-rw-r--r--src/main/java/net/uomc/mineshaft/resources/commands/GiveResourcesCommand.java112
-rw-r--r--src/main/java/net/uomc/mineshaft/resources/commands/ValuesCommand.java7
-rw-r--r--src/main/java/net/uomc/mineshaft/resources/market/MarketCommand.java62
-rw-r--r--src/main/java/net/uomc/mineshaft/resources/market/MarketManager.java86
-rw-r--r--src/main/java/net/uomc/mineshaft/resources/market/Offer.java2
20 files changed, 650 insertions, 245 deletions
diff --git a/pom.xml b/pom.xml
index a90f2a8..a8499f8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>net.uomc.mineshaft</groupId>
<artifactId>Mineshaft</artifactId>
- <version>0.3.1</version>
+ <version>0.5.2</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
diff --git a/src/main/java/net/uomc/mineshaft/DailyCommand.java b/src/main/java/net/uomc/mineshaft/DailyCommand.java
index fc814d1..129c336 100644
--- a/src/main/java/net/uomc/mineshaft/DailyCommand.java
+++ b/src/main/java/net/uomc/mineshaft/DailyCommand.java
@@ -29,12 +29,13 @@ public class DailyCommand extends CooldownCommand {
award = bot.sumItems(award,
bot.getMineCommand().getAwards(e.getMember(),
bot.getMineCommand().getOre(
- bot.getPickaxes().getPickaxeLevel(e.getMember()))));
+ e.getMember())));
}
;
String awardsList = bot.createItemList(award, "+%s", ", ");
bot.sendSuccessMessage(e, "You received your daily ores:\n**" + awardsList +"**");
+ bot.addItems(e.getMember(), award);
return true;
}
}
diff --git a/src/main/java/net/uomc/mineshaft/EnchantCommand.java b/src/main/java/net/uomc/mineshaft/EnchantCommand.java
index f85c92b..f147636 100644
--- a/src/main/java/net/uomc/mineshaft/EnchantCommand.java
+++ b/src/main/java/net/uomc/mineshaft/EnchantCommand.java
@@ -15,7 +15,7 @@ public class EnchantCommand extends DetailedCommand {
private static final String COMMAND_IMAGE = "https://minecraft.wiki/images/Enchanting_Table.gif";
private static final double MIN_DISCOUNT = 0.4;
- private static final double MAX_BOOKSHELVES = 24;
+ private static final long MAX_BOOKSHELVES = 24;
private static final String COMMAND_TITLE = "Enchanting Table";
Mineshaft bot;
@@ -42,20 +42,20 @@ public class EnchantCommand extends DetailedCommand {
}
int fortune = bot.getPickaxes().getPickaxeFortune(e.getMember());
+ int efficiency = bot.getPickaxes().getPickaxeEfficiency(e.getMember());
long bookshelves = bot.getItem(e.getMember(), MineshaftItem.BOOKSHELF);
String bookshelfDiscountPercent = "-" + (int) Math.ceil((1 -bookshelfDiscount(bookshelves))*100) + "%";
- long xpLevel = getXpLevel(fortune, bookshelves);
- long lapisLevel = getLapisLevel(fortune, bookshelves);
- long xpLevelNormal = getXpLevel(fortune, 0);
- long lapisLevelNormal = getLapisLevel(fortune, 0);
+ long xpLevel = getXpLevel(fortune+efficiency, bookshelves);
+ long lapisLevel = getLapisLevel(fortune+efficiency, bookshelves);
- String curr = "";
- if (fortune > 0) {
- curr = "Your pickaxe has **Fortune " + Pickaxes.getRomanNumber(fortune) + "**\n\n";
- }
+ long xpLevelNormal = getXpLevel(fortune+efficiency, 0);
+ long lapisLevelNormal = getLapisLevel(fortune+efficiency, 0);
+
+ String curr = "Your pickaxe " + getPickaxeEnchantmentsString(fortune, efficiency);
+ curr += "\n\n";
- String description = curr + "Enchant your pickaxe with `" + b.getPrefixManager().getPrefix(e.getGuild()) + "enchant fortune`\n\n";
+ String description = curr + "Enchant your pickaxe with `" + b.getPrefixManager().getPrefix(e.getGuild()) + "enchant pickaxe`\n\n";
description += "**Cost:**\n";
@@ -89,24 +89,44 @@ public class EnchantCommand extends DetailedCommand {
e.getMessage().replyEmbeds(em.build()).queue();
}
+ public String getPickaxeEnchantmentsString(int fortune, int efficiency) {
+ String curr = "";
+ if (fortune > 0 || efficiency > 0) {
+ curr = "is enchanted with ";
+ if (fortune > 0)
+ curr += "**Fortune " + Pickaxes.getRomanNumber(fortune) + "** ";
+ if (efficiency > 0)
+ curr += "**Efficiency " + Pickaxes.getRomanNumber(efficiency) + "** ";
+ } else {
+ curr = "has no enchantments";
+ }
+ return curr;
+ }
+
private long getLapisLevel(int fortune, long bookshelves) {
return (long) (Math.pow(2, fortune + 4) * bookshelfDiscount(bookshelves));
}
+ private long getXpLevel(int fortune, long bookshelves) {
+ return (long) (15000l * Math.pow(fortune + 1, 2) * bookshelfDiscount(bookshelves));
+ }
+
private double bookshelfDiscount(long bookshelves) {
double b = Math.min(bookshelves, MAX_BOOKSHELVES);
- return MIN_DISCOUNT + Math.log10( 1.0 + (9.0 * ((MAX_BOOKSHELVES - b) / MAX_BOOKSHELVES))) * MIN_DISCOUNT;
+ return MIN_DISCOUNT + Math.log(
+ 1.0 + ( (Math.E - 1) * (
+ (double) (MAX_BOOKSHELVES - b) / (double) MAX_BOOKSHELVES))
+ ) * (double) (1-MIN_DISCOUNT);
}
- private long getXpLevel(int fortune, long bookshelves) {
- return (long) (15000l * Math.pow(fortune + 1, 2) * bookshelfDiscount(bookshelves));
- }
private void enchant(MessageReceivedEvent e, String[] args) {
int fortune = bot.getPickaxes().getPickaxeFortune(e.getMember());
+ int efficiency = bot.getPickaxes().getPickaxeEfficiency(e.getMember());
+
long bookshelves = bot.getItem(e.getMember(), MineshaftItem.BOOKSHELF);
- long xpLevel = getXpLevel(fortune, bookshelves);
- long lapisLevel = getLapisLevel(fortune, bookshelves);
+ long xpLevel = getXpLevel(fortune + efficiency, bookshelves);
+ long lapisLevel = getLapisLevel(fortune + efficiency, bookshelves);
long memberLapis = bot.getItem(e.getMember(), MineshaftItem.LAPIS);
long memberXp = bot.getItem(e.getMember(), MineshaftItem.XP);
@@ -123,10 +143,16 @@ public class EnchantCommand extends DetailedCommand {
bot.removeItem(e.getMember(), MineshaftItem.LAPIS, lapisLevel);
bot.removeItem(e.getMember(), MineshaftItem.XP, xpLevel);
- int level = bot.getPickaxes().incrementFortune(e.getMember());
- bot.sendSuccessMessage(e, ":white_check_mark: You enchanted your pickaxe. Now it has **Fortune " + Pickaxes.getRomanNumber(level) + "**");
+ String newEnch = "";
+ if (Math.random() > 0.5) {
+ int level = bot.getPickaxes().incrementFortune(e.getMember());
+ newEnch = "**Fortune " + Pickaxes.getRomanNumber(level) + "**";
+ } else {
+ int level = bot.getPickaxes().incrementEfficiency(e.getMember());
+ newEnch = "**Efficiency " + Pickaxes.getRomanNumber(level) + "**";
+ }
+ bot.sendSuccessMessage(e, ":white_check_mark: You enchanted your pickaxe. You now have " + newEnch);
}
-
}
diff --git a/src/main/java/net/uomc/mineshaft/FishCommand.java b/src/main/java/net/uomc/mineshaft/FishCommand.java
index 3df7994..2eac218 100644
--- a/src/main/java/net/uomc/mineshaft/FishCommand.java
+++ b/src/main/java/net/uomc/mineshaft/FishCommand.java
@@ -25,6 +25,7 @@ import net.uomc.mineshaft.resources.ResourceManager;
public class FishCommand extends CooldownCommand {
private static final double XP_SPAWN_AMOUNT = 2000;
private static final double BOOK_SPAWN_CHANCE = 0.05;
+ private static final double STRING_SPAWN_CHANCE = 0.5;
private static long MIN_WAIT_MS = 1500;
private static long MAX_WAIT_MS = 10000;
@@ -41,6 +42,7 @@ public class FishCommand extends CooldownCommand {
protected FishCommand(Mineshaft bot) {
super(bot);
setCooldown(20l * 1000l);
+
this.bot = bot;
setDetails(CommandDetails.from("fish", "go fishing"));
}
@@ -49,7 +51,6 @@ public class FishCommand extends CooldownCommand {
public boolean trigger(MessageReceivedEvent e) {
e.getMessage().addReaction(Emoji.fromUnicode(EmojiParser.parseToUnicode(REACTION_FISH))).queue();
- double random = Math.random();
long waitTime = MIN_WAIT_MS + (long) (Math.random() * (MAX_WAIT_MS - MIN_WAIT_MS));
long reelTime = MIN_REEL_MS + (long) (Math.random() * (MAX_REEL_MS - MIN_REEL_MS));
@@ -99,12 +100,17 @@ public class FishCommand extends CooldownCommand {
public Map<MineshaftItem, Long> getAwards(Member member) {
Map<MineshaftItem, Long> award = new HashMap<>();
- if (Math.random() < BOOK_SPAWN_CHANCE) {
+ double random = Math.random();
+ if (random < BOOK_SPAWN_CHANCE) {
award.put(MineshaftItem.BOOK, 1l);
+ } else if (random < STRING_SPAWN_CHANCE) {
+ award.put(MineshaftItem.STRING, 8l);
+ award.put(MineshaftItem.XP, (long) Math.ceil(Math.random() * XP_SPAWN_AMOUNT * 0.5));
} else {
award.put(MineshaftItem.FISH, Math.random() > 0.5 ? 1l : 2l);
award.put(MineshaftItem.XP, (long) Math.ceil(Math.random() * XP_SPAWN_AMOUNT));
}
+
return award;
}
}
diff --git a/src/main/java/net/uomc/mineshaft/FurnaceCommand.java b/src/main/java/net/uomc/mineshaft/FurnaceCommand.java
index 8c2b628..9212ac6 100644
--- a/src/main/java/net/uomc/mineshaft/FurnaceCommand.java
+++ b/src/main/java/net/uomc/mineshaft/FurnaceCommand.java
@@ -36,9 +36,9 @@ public class FurnaceCommand extends CooldownCommand {
public FurnaceCommand(Mineshaft bot) {
super(bot);
- setCommandDetails(CommandDetails.from("furnace", "get free ingots", "furnace"));
+ setCommandDetails(CommandDetails.from("furnace,furnaces,furn", "get free ingots", "furnace"));
this.bot = bot;
- setCooldown(60l * 60l * 1000l);
+ setCooldown(30l * 60l * 1000l);
}
@Override
diff --git a/src/main/java/net/uomc/mineshaft/MineCommand.java b/src/main/java/net/uomc/mineshaft/MineCommand.java
index ecee140..730ae85 100644
--- a/src/main/java/net/uomc/mineshaft/MineCommand.java
+++ b/src/main/java/net/uomc/mineshaft/MineCommand.java
@@ -46,9 +46,13 @@ public class MineCommand extends CooldownCommand {
private static final double DIAMOND_SPAWN_AMOUNT = 1;
private static final double OBSIDIAN_SPAWN_AMOUNT = 1;
private static final double XP_SPAWN_AMOUNT = 1000;
+ private static final double QUARTZ_SPAWN_AMOUNT = 16;
+ private static final double SKULL_SPAWN_AMOUNT = 1;
+ private static final double NETHERITE_SPAWN_AMOUNT = 1;
private Map<String, String> ores;
private List<String> oresList;
+ private List<String> netherOresList;
private Mineshaft bot;
@@ -57,14 +61,15 @@ public class MineCommand extends CooldownCommand {
this.bot = bot;
setCooldown(15l * 1000l);
+
setDetails(CommandDetails.from("mine", "mine diamonds"));
this.ores = loadOreImages();
oresList = loadOreOrder();
+ netherOresList = loadNetherOreOrder();
}
public List<String> loadOreOrder() {
- // lololol no
return List.of(
"coal",
"copper",
@@ -74,10 +79,44 @@ public class MineCommand extends CooldownCommand {
"gold",
"diamond",
"emerald",
+ "obsidian",
"obsidian"
);
}
+ public List<String> loadNetherOreOrder() {
+ return List.of(
+ "quartz",
+ "quartz",
+ "quartz",
+ "quartz",
+ "gold",
+ "gold",
+ "skull",
+ "skull",
+ "netherite",
+ "netherite"
+ );
+ }
+
+ private int levelToMaxOre(int pickaxe) {
+ switch (pickaxe) {
+ case 0: // stone pickaxe
+ return 2; // copper
+ case 1: // copper pickaxe
+ return 4; // lapis
+ case 2: // iron pickaxe
+ return 6; // gold
+ case 3: // gold pickaxe
+ return 8; // diamond
+ case 4: // diamond pickaxe
+ return 9; // obsidian
+ case 5: // netherite pickaxe
+ return 10; // obsidian, 2
+ }
+ return 9;
+ }
+
public Map<String, String> loadOreImages() {
Map<String, String> ores = new LinkedHashMap<String, String>();
JSONObject config = bot.getConfig();
@@ -94,12 +133,22 @@ public class MineCommand extends CooldownCommand {
return ores;
}
- public MineshaftItem getOre(int pickaxe) {
+ public MineshaftItem getOre(Member m) {
+ return getOre(m, false);
+ }
+
+ public MineshaftItem getOre(Member m, boolean nether) {
+ int pickaxe = bot.getPickaxes().getPickaxeLevel(m);
double random = Math.random();
int maxOre = levelToMaxOre(pickaxe);
- int i = (int) Math.floor(Math.pow(random, 2) * maxOre);
- String oreName = oresList.get(i);
+
+ List<String> list = oresList;
+ if(nether) list = netherOresList;
+
+ double c = getEfficiencyCurve(m);
+ int i = (int) Math.floor(Math.pow(random, c) * maxOre);
+ String oreName = list.get(i);
MineshaftItem ore = MineshaftItem.valueOf(oreName.toUpperCase());
return ore;
}
@@ -107,34 +156,23 @@ public class MineCommand extends CooldownCommand {
@Override
public boolean trigger(MessageReceivedEvent e) {
- int pickaxe = bot.getPickaxes().getPickaxeLevel(e.getMember());
- MineshaftItem ore = getOre(pickaxe);
- int i = oresList.indexOf(ore.toString().toLowerCase());
+ boolean nether = bot.getPickaxes().isNether(e.getMember());
+ MineshaftItem ore = getOre(e.getMember(), nether);
+ int i;
+ if (nether) {
+ i = oresList.indexOf(ore.toString().toLowerCase());
+ } else {
+ i = netherOresList.indexOf(ore.toString().toLowerCase());
+ }
- spawnDrop(e.getChannel(), ore, i, m -> {});
+ spawnDrop(e.getChannel(), ore, i, nether, m -> {});
e.getMessage().addReaction(Emoji.fromUnicode(EmojiParser.parseToUnicode(":pick:"))).queue();
return true;
}
- private int levelToMaxOre(int pickaxe) {
- switch (pickaxe) {
- case 0: // stone pickaxe
- return 2; // copper
- case 1: // copper pickaxe
- return 4; // lapis
- case 2: // iron pickaxe
- return 6; // gold
- case 3: // gold pickaxe
- return 8; // diamond
- case 4: // diamond pickaxe
- return 9; // obsidian
- // TODO for obsidian u can make nether portal
- }
- return 9;
- }
- public void spawnDrop(MessageChannel channel, MineshaftItem ore, int oreLevel, Consumer<MessageChannel> then) {
- sendDrop(channel, ore, m -> {
+ public void spawnDrop(MessageChannel channel, MineshaftItem ore, int oreLevel, boolean nether, Consumer<MessageChannel> then) {
+ sendDrop(channel, ore, nether, m -> {
EventWaiter eventWaiter = new EventWaiter();
channel.getJDA().addEventListener(eventWaiter);
@@ -155,14 +193,14 @@ public class MineCommand extends CooldownCommand {
});
}, DROP_DURATION_SECONDS, TimeUnit.SECONDS, () -> {
cleanup(channel, m, ore);
- endDrop(m, ore);
});
});
}
public void cleanup(MessageChannel channel, Message message, MineshaftItem ore) {
- message.delete().queue();
+
+ message.delete().queue(a -> {}, x -> {});
channel.getHistoryAfter(message, 100).queueAfter(5, TimeUnit.SECONDS, h -> {
ArrayList<Message> msgs = new ArrayList<Message>();
@@ -176,11 +214,11 @@ public class MineCommand extends CooldownCommand {
;
}
- public void sendDrop(MessageChannel channel, MineshaftItem ore, Consumer<Message> callback) {
+ public void sendDrop(MessageChannel channel, MineshaftItem ore, boolean nether, Consumer<Message> callback) {
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setColor(bot.getColor());
- embedBuilder.setImage(getOreUrl(ore));
+ embedBuilder.setImage(getOreUrl(ore, nether));
embedBuilder.setTitle(String.format(DROP_TITLE));
embedBuilder.setDescription(String.format(DROP_DESCRIPTION, getPickString(ore), PeelingUtils.formatTimeRelativeFromNow(DROP_DURATION_SECONDS * 1000l)));
@@ -195,10 +233,6 @@ public class MineCommand extends CooldownCommand {
embedBuilder.setColor(bot.getColor());
Map<MineshaftItem, Long> awards = getAwards(member, ore);
- int fortune = bot.getPickaxes().getPickaxeFortune(member);
- if (fortune > 0) {
- bot.multiply(awards, fortune + 1);
- }
bot.addItems(member, awards);
String awardsList = bot.createItemList(awards, "+%s");
@@ -208,6 +242,7 @@ public class MineCommand extends CooldownCommand {
channel.sendMessageEmbeds(embedBuilder.build()).queue(callback);
}
+
public void endDrop(Message message, MineshaftItem ore) {
EmbedBuilder embedBuilder = new EmbedBuilder();
@@ -221,8 +256,12 @@ public class MineCommand extends CooldownCommand {
});
}
- public String getOreUrl(MineshaftItem ore) {
- String oreName = ore.toString();
+ public String getOreUrl(MineshaftItem ore, boolean nether) {
+ String prefix = "";
+ if (nether)
+ prefix = "nether_";
+
+ String oreName = prefix + ore.toString();
if (ores.containsKey(oreName))
return ores.get(oreName);
@@ -262,6 +301,7 @@ public class MineCommand extends CooldownCommand {
break;
case EMERALD:
award.put(MineshaftItem.EMERALD, (long) Math.ceil(Math.random() * EMERALD_SPAWN_AMOUNT));
+ award.put(MineshaftItem.XP, (long) Math.ceil(Math.random() * XP_SPAWN_AMOUNT * 5l));
break;
case DIAMOND:
award.put(MineshaftItem.DIAMOND, (long) Math.ceil(Math.random() * DIAMOND_SPAWN_AMOUNT));
@@ -269,12 +309,33 @@ public class MineCommand extends CooldownCommand {
break;
case OBSIDIAN:
award.put(MineshaftItem.OBSIDIAN, (long) Math.ceil(Math.random() * OBSIDIAN_SPAWN_AMOUNT));
+ break;
+ case QUARTZ:
+ award.put(MineshaftItem.QUARTZ, (long) Math.ceil(Math.random() * QUARTZ_SPAWN_AMOUNT));
+ award.put(MineshaftItem.XP, (long) Math.ceil(Math.random() * XP_SPAWN_AMOUNT * 5l));
+ break;
+ case SKULL:
+ award.put(MineshaftItem.SKULL, (long) Math.ceil(Math.random() * SKULL_SPAWN_AMOUNT));
+ award.put(MineshaftItem.XP, (long) Math.ceil(Math.random() * XP_SPAWN_AMOUNT * 10l));
+ break;
+ case NETHERITE:
+ award.put(MineshaftItem.NETHERITE, (long) Math.ceil(Math.random() * NETHERITE_SPAWN_AMOUNT));
award.put(MineshaftItem.XP, (long) Math.ceil(Math.random() * XP_SPAWN_AMOUNT * 10l));
break;
default:
break;
}
+ return bot.multiply(award, getPickaxeFortuneCurve(member));
+ }
+
+ public double getEfficiencyCurve(Member m) {
+ return 1 + Math.pow(0.5, bot.getPickaxes().getPickaxeEfficiency(m) / 2);
- return award;
}
+ private double getPickaxeFortuneCurve(Member m) {
+ int fortune = bot.getPickaxes().getPickaxeFortune(m);
+ return fortune + Math.pow(1.2, fortune + 1);
+ }
+
+
}
diff --git a/src/main/java/net/uomc/mineshaft/Mineshaft.java b/src/main/java/net/uomc/mineshaft/Mineshaft.java
index ebdcf21..1584529 100644
--- a/src/main/java/net/uomc/mineshaft/Mineshaft.java
+++ b/src/main/java/net/uomc/mineshaft/Mineshaft.java
@@ -1,6 +1,9 @@
package net.uomc.mineshaft;
import net.uomc.mineshaft.crafting.Crafting;
+import net.uomc.mineshaft.farm.CompostCommand;
+import net.uomc.mineshaft.farm.FarmCommand;
+import net.uomc.mineshaft.farm.TradeCommand;
import net.uomc.mineshaft.resources.Resource;
import java.io.IOException;
import java.util.Arrays;
@@ -29,6 +32,7 @@ import com.mouldycheerio.dbot.util.PeelingUtils;
import net.dv8tion.jda.api.entities.Member;
import net.uomc.mineshaft.resources.ResourceManager;
+import net.uomc.mineshaft.resources.market.MarketCommand;
public class Mineshaft extends CustomBot {
@@ -38,6 +42,7 @@ public class Mineshaft extends CustomBot {
private Pickaxes pickaxes;
private Crafting crafting;
private MineCommand mineCommand;
+ private EnchantCommand enchantCommand;
public Mineshaft(JSONObject config) throws LoginException, JSONException, IOException, InterruptedException {
super(config);
@@ -54,15 +59,21 @@ public class Mineshaft extends CustomBot {
resourceManager = new ResourceManager(this);
+ getCommandController().addCommand(new MarketCommand(resourceManager.getMarketManager()));
getCommandController().addCommand(new DailyCommand(this));
- getCommandController().addCommand(new EnchantCommand(this));
+
+ enchantCommand = new EnchantCommand(this);
+ getCommandController().addCommand(enchantCommand);
getCommandController().addCommand(new FurnaceCommand(this));
getCommandController().addCommand(new PickaxeCommand(this));
+ getCommandController().addCommand(new Portal(this));
+
mineCommand = new MineCommand(this);
getCommandController().addCommand(mineCommand);
getCommandController().addCommand(new FishCommand(this));
getCommandController().addCommand(new RobCommand(this));
+ getCommandController().addCommand(new TradeCommand(this));
getCommandController().removeCommand("help");
@@ -74,7 +85,7 @@ public class Mineshaft extends CustomBot {
notes.append("Upgrade your **pickaxe** and find new ores `m!pickaxe`\n");
notes.append("**Craft** new items `m!craft`\n");
notes.append("Fight other players! `m!pvp`\n");
- notes.append("Share your resources `m!give`\n");
+ notes.append("Trade your resources `m!market` and `m!give`\n");
notes.append("Become the **top** valuable player `m!top`\n");
notes.append("\nGet free **daily** ores with `m!daily`\n");
@@ -85,26 +96,59 @@ public class Mineshaft extends CustomBot {
// TODO update when changes
String title = "Patch Notes";
StringBuilder notes = new StringBuilder();
- notes.append("### v0.3.1\n");
- notes.append("- Added furnace crafting recipe\n");
- notes.append("- Added `m!daily` to get daily commands\n");
- notes.append("- Balanced amount of ores needed to upgrade pickaxe\n");
- notes.append("- Fix obsidian not spawning\n");
- notes.append("- Added `m!cooldowns`\n");
- notes.append("### v0.3\n");
- notes.append("- Added items for all ores `m!inventory`\n");
- notes.append("- Added pickaxe levels `m!pickaxe`\n");
- notes.append(" - Pickaxe can be upgraded, giving access to better ores (`m!pickaxe upgrade`)\n");
- notes.append("- Added enchanting `m!enchant`\n");
- notes.append(" - Your pickaxe can be enchanted by spending lapis and xp\n");
- notes.append(" - Owning bookshelves gives you a discount on the amount of levels it costs to enchant\n");
- notes.append("- Added crafting `m!craft`\n");
- notes.append(" - Enchanting table and books can now be crafted!\n");
- notes.append("- Fishing now drops books\n");
- notes.append("- Rob has been relaced with `m!kill`\n");
- notes.append(" - Killing a player will drop some of their items\n");
- notes.append("- Added obsidian\n");
- notes.append("- Removed `m!flip`, this will be added in a future update (with a new mechanic)\n");
+ notes.append("### v0.5.2\n");
+ notes.append("- Fix trader giving impossible item prices\n");
+ notes.append("- Items can only be given to players who are in the same dimension\n");
+ notes.append("### v0.5.1\n");
+ notes.append("- Kill only works if you are in the same dimension as the other player\n");
+ notes.append("- Farm cannot be accessed from the nether\n");
+ notes.append("- Added `m!top pickaxes`\n");
+ notes.append("### v0.5\n");
+ notes.append("- Added compostor\n");
+ notes.append(" - compost items with `m!compost`\n");
+ notes.append(" - The more compostors you own, the more items you can compost at a time\n");
+ notes.append("- Added farming `m!farm`\n");
+ notes.append(" - Crops can be planted and harvested\n");
+ notes.append(" - Size of farm can be expanded with bone meal\n");
+ notes.append("- Added villager item\n");
+ notes.append(" - Villagers allow you to trade with the wandering trader `m!trade`\n");
+ notes.append("- Added Carrots, Potatos and Sugar cane\n");
+ notes.append("- Added `m!top [item]` to list who has the most of an item\n");
+ notes.append("- Fixed `m!daily`\n");
+ notes.append("- Fixed typos\n");
+ notes.append("### v0.4\n");
+ notes.append("- Added nether\n");
+ notes.append(" - 10 obsidian can now be used to craft a portal\n");
+ notes.append(" - Nether spawns new ores \n");
+ notes.append("- Netherite pickaxe is now achievable\n");
+ notes.append("- Fishing will have a chance to give you string\n");
+ notes.append("- String can be crafted into wool and beds\n");
+ notes.append("- Added Efficiency enchantment\n");
+ notes.append(" - Further increases spawn rates of rarer ores\n");
+ notes.append("- Enchantments are now applied to `m!daily`'s loot\n");
+ notes.append("- Furnace can now be accessed every 30 minutes\n");
+ notes.append("- Added `m!market` for trading items\n");
+ notes.append("- Fix `m!give` to work properly\n");
+ //notes.append("### v0.3.1\n");
+ //notes.append("- Added furnace crafting recipe\n");
+ //notes.append("- Added `m!daily` to get daily commands\n");
+ //notes.append("- Balanced amount of ores needed to upgrade pickaxe\n");
+ //notes.append("- Fix obsidian not spawning\n");
+ //notes.append("- Added `m!cooldowns`\n");
+ //notes.append("### v0.3\n");
+ //notes.append("- Added items for all ores `m!inventory`\n");
+ //notes.append("- Added pickaxe levels `m!pickaxe`\n");
+ //notes.append(" - Pickaxe can be upgraded, giving access to better ores (`m!pickaxe upgrade`)\n");
+ //notes.append("- Added enchanting `m!enchant`\n");
+ //notes.append(" - Your pickaxe can be enchanted by spending lapis and xp\n");
+ //notes.append(" - Owning bookshelves gives you a discount on the amount of levels it costs to enchant\n");
+ //notes.append("- Added crafting `m!craft`\n");
+ //notes.append(" - Enchanting table and books can now be crafted!\n");
+ //notes.append("- Fishing now drops books\n");
+ //notes.append("- Rob has been relaced with `m!kill`\n");
+ //notes.append(" - Killing a player will drop some of their items\n");
+ //notes.append("- Added obsidian\n");
+ //notes.append("- Removed `m!flip`, this will be added in a future update (with a new mechanic)\n");
sendMessage(e, title, notes.toString());
});
@@ -142,6 +186,15 @@ public class Mineshaft extends CustomBot {
b.sendMessage(e, "Active cooldowns", cooldowns.toString());
});
+ getCommandController().removeCommand("top");
+ getCommandController().addCommand(new MineshaftLeaderBoardCommand(this));
+
+ getCommandController().removeCommand("give");
+ getCommandController().addCommand(new MineshaftGiveResourcesCommand(this));
+
+ getCommandController().addCommand(new FarmCommand(this));
+ getCommandController().addCommand(new CompostCommand(this));
+
logger = new FullLogger(this);
}
@@ -269,4 +322,12 @@ public class Mineshaft extends CustomBot {
return Collections.unmodifiableMap(lacking);
}
+
+ public Crafting getCrafting() {
+ return crafting;
+ }
+
+ public EnchantCommand getEnchantCommand() {
+ return enchantCommand;
+ }
}
diff --git a/src/main/java/net/uomc/mineshaft/MineshaftItem.java b/src/main/java/net/uomc/mineshaft/MineshaftItem.java
index 91a4957..8956b93 100644
--- a/src/main/java/net/uomc/mineshaft/MineshaftItem.java
+++ b/src/main/java/net/uomc/mineshaft/MineshaftItem.java
@@ -1,33 +1,46 @@
package net.uomc.mineshaft;
public enum MineshaftItem {
- COAL("coal"),
- IRON("iron"),
- COPPER("copper"),
- LAPIS("lapis"),
- REDSTONE("redstone"),
- GOLD("gold"),
- EMERALD("emerald"),
- DIAMOND("diamond"),
- NETHERITE("netherite"),
- OBSIDIAN("obsidian"),
- FISH("fish"),
- BOOK("book"),
- XP("xp"),
- ENCHANTING_TABLE("enchanting_table"),
- BOOKSHELF("bookshelf"),
- FURNACE("furnace")
+ COAL,
+ IRON,
+ COPPER,
+ LAPIS,
+ REDSTONE,
+ GOLD,
+ EMERALD,
+ DIAMOND,
+ NETHERITE,
+ OBSIDIAN,
+ FISH,
+ BOOK,
+ XP,
+ ENCHANTING_TABLE,
+ BOOKSHELF,
+ FURNACE,
+ PORTAL,
+ QUARTZ,
+ SKULL,
+ STRING,
+ WOOL,
+ BED,
+ BEACON,
+ SLOT_MACHINE,
+ VILLAGER,
+ PAPER,
+ CANE,
+ CARROT,
+ POTATO,
+ COMPOSTER,
+ BONEMEAL,
+ IRON_FARM,
;
- private final String text;
-
- MineshaftItem(String string) {
- text = string;
+ MineshaftItem() {
}
@Override
public String toString() {
- return text;
+ return super.toString().toLowerCase();
}
-
+
}
diff --git a/src/main/java/net/uomc/mineshaft/PickaxeCommand.java b/src/main/java/net/uomc/mineshaft/PickaxeCommand.java
index 6ca3e08..31ac11c 100644
--- a/src/main/java/net/uomc/mineshaft/PickaxeCommand.java
+++ b/src/main/java/net/uomc/mineshaft/PickaxeCommand.java
@@ -52,6 +52,7 @@ public class PickaxeCommand extends DetailedCommand {
String nextPick = bot.getPickaxes().getNextPickaxeName(e.getMember());
String pickImage = bot.getPickaxes().getPickaxeImage(e.getMember());
int fortune = bot.getPickaxes().getPickaxeFortune(e.getMember());
+ int efficiency = bot.getPickaxes().getPickaxeEfficiency(e.getMember());
Member target = PeelingUtils.getSingleMentionFromArgs(e);
String p1 = target.equals(e.getMember()) ? "You currently have" : String.format("%s currently has", e.getMember().getEffectiveName());
@@ -65,11 +66,7 @@ public class PickaxeCommand extends DetailedCommand {
upgradeString = "";
}
- String enchants = String.format("\n*%s pickaxe has no enchantments*", p2);
- if (fortune > 0) {
- enchants = String.format("\n%s pickaxe is enchanted with **Fortune %s**", p2,
- Pickaxes.getRomanNumber(fortune));
- }
+ String enchants = String.format("\n%s ", p2) + bot.getEnchantCommand().getPickaxeEnchantmentsString(fortune, efficiency);
EmbedBuilder em = new EmbedBuilder();
em.setTitle(p2);
@@ -87,23 +84,19 @@ public class PickaxeCommand extends DetailedCommand {
switch ((int) level) {
case 0:
cost.put(MineshaftItem.COPPER, 16l);
- //cost.put(MineshaftItem.XP, 5000l);
break;
case 1:
cost.put(MineshaftItem.IRON, 32l);
- //cost.put(MineshaftItem.XP, 10000l);
break;
case 2:
- cost.put(MineshaftItem.GOLD, 48l);
- //cost.put(MineshaftItem.XP, 64000l);
+ cost.put(MineshaftItem.GOLD, 64l);
break;
case 3:
- cost.put(MineshaftItem.DIAMOND, 64l);
- //cost.put(MineshaftItem.XP, 128000l);
+ cost.put(MineshaftItem.DIAMOND, 32l);
break;
case 4:
- cost.put(MineshaftItem.DIAMOND, 9999999999999999l);
+ cost.put(MineshaftItem.NETHERITE, 128l);
break;
}
diff --git a/src/main/java/net/uomc/mineshaft/Pickaxes.java b/src/main/java/net/uomc/mineshaft/Pickaxes.java
index 42a1f92..16d6958 100644
--- a/src/main/java/net/uomc/mineshaft/Pickaxes.java
+++ b/src/main/java/net/uomc/mineshaft/Pickaxes.java
@@ -3,20 +3,27 @@ package net.uomc.mineshaft;
import java.io.File;
import java.sql.SQLException;
import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
import org.json.JSONObject;
import com.mouldycheerio.dbot.util.DatabaseUtils;
import com.mouldycheerio.dbot.util.PeelingUtils;
+import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
-class Pickaxes {
+public class Pickaxes {
private static final int MAX_PICKAXE_LEVEL = 5;
private static final String LEVEL_TABLE = "levels";
private static final String FORTUNE_TABLE = "ench_fortune";
+ private static final String EFFICIENCY_TABLE = "ench_efficiency";
+ private static final String DIMENSION_TABLE = "dimension";
+
+ private static final String FARM_LEVEL_TABLE = "farm";
private String pickaxesDb;
@@ -27,11 +34,45 @@ class Pickaxes {
private void initDB() {
try {
- DatabaseUtils.createSimpleKVtable(pickaxesDb, LEVEL_TABLE);
DatabaseUtils.createSimpleKVtable(pickaxesDb, FORTUNE_TABLE);
} catch (SQLException e) {
- // e.printStackTrace();
}
+ try {
+ DatabaseUtils.createSimpleKVtable(pickaxesDb, DIMENSION_TABLE);
+ } catch (SQLException e) {
+ }
+ try {
+ DatabaseUtils.createSimpleKVtable(pickaxesDb, EFFICIENCY_TABLE);
+ } catch (SQLException e) {
+ }
+ try {
+ DatabaseUtils.createSimpleKVtable(pickaxesDb, LEVEL_TABLE);
+ } catch (SQLException e) {
+ }
+ try {
+ DatabaseUtils.createSimpleKVtable(pickaxesDb, FARM_LEVEL_TABLE);
+ } catch (SQLException e) {
+ }
+ }
+
+ public void setFarmLevel(Member member, long value) {
+ try {
+ DatabaseUtils.putInKVtable(pickaxesDb, FARM_LEVEL_TABLE, member.getId() + ":" + member.getGuild().getId(), value);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ public long getFarmLevel(String member, String guild) {
+ try {
+ return DatabaseUtils.getInKVtable(pickaxesDb, FARM_LEVEL_TABLE, member + ":" + guild);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return 0l;
+ }
+
+ public long getFarmLevel(Member member) {
+ return getFarmLevel(member.getId(), member.getGuild().getId());
}
public void setLevel(Member member, long value) {
@@ -42,15 +83,52 @@ class Pickaxes {
}
}
+ public long getLevel(String member, String guild) {
+ try {
+ return DatabaseUtils.getInKVtable(pickaxesDb, LEVEL_TABLE, member + ":" + guild);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return 0l;
+ }
+
public long getLevel(Member member) {
+ return getLevel(member.getId(), member.getGuild().getId());
+ }
+ public List<String> getMembersGuilds() {
+ try {
+ return DatabaseUtils.listKeys(pickaxesDb, LEVEL_TABLE);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return Collections.emptyList();
+ }
+
+ public List<String> getMembers(Guild guild) {
+ return getMembersGuilds().stream().filter(m -> guild.getId().equals(m.split(":")[1])).map(m -> m.split(":")[0]).collect(Collectors.toList());
+ }
+
+ private void setEfficiency(Member member, long value) {
try {
- return DatabaseUtils.getInKVtable(pickaxesDb, LEVEL_TABLE, member.getId() + ":" + member.getGuild().getId());
+ DatabaseUtils.putInKVtable(pickaxesDb, EFFICIENCY_TABLE, member.getId() + ":" + member.getGuild().getId(), value);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public long getEfficiency(String member, String guild) {
+ try {
+ return DatabaseUtils.getInKVtable(pickaxesDb, EFFICIENCY_TABLE, member + ":" + guild);
} catch (SQLException e) {
e.printStackTrace();
}
return 0l;
}
+ public long getEfficiency(Member member) {
+ return getEfficiency(member.getId(), member.getGuild().getId());
+ }
+
private void setFortune(Member member, long value) {
try {
DatabaseUtils.putInKVtable(pickaxesDb, FORTUNE_TABLE, member.getId() + ":" + member.getGuild().getId(), value);
@@ -59,15 +137,36 @@ class Pickaxes {
}
}
- private long getFortune(Member member) {
+ public long getFortune(String member, String guild) {
try {
- return DatabaseUtils.getInKVtable(pickaxesDb, FORTUNE_TABLE, member.getId() + ":" + member.getGuild().getId());
+ return DatabaseUtils.getInKVtable(pickaxesDb, FORTUNE_TABLE, member + ":" + guild);
} catch (SQLException e) {
e.printStackTrace();
}
return 0l;
}
+ public long getFortune(Member member) {
+ return getFortune(member.getId(), member.getGuild().getId());
+ }
+
+ public void setNether(Member member, boolean nether) {
+ try {
+ DatabaseUtils.putInKVtable(pickaxesDb, DIMENSION_TABLE, member.getId() + ":" + member.getGuild().getId(), nether ? 1: 0);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public boolean isNether(Member member) {
+ try {
+ return DatabaseUtils.getInKVtable(pickaxesDb, DIMENSION_TABLE, member.getId() + ":" + member.getGuild().getId()) == 1;
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
public boolean isEnchanted(Member member) {
long fortune = getFortune(member);
return fortune > 0;
@@ -85,7 +184,7 @@ class Pickaxes {
return pickaxeLevelToName(level);
}
- private static String pickaxeLevelToName(long level) {
+ public static String pickaxeLevelToName(long level) {
switch ((int) level) {
case 0:
return "Stone";
@@ -144,11 +243,20 @@ class Pickaxes {
return (int) getFortune(member);
}
+ public int getPickaxeEfficiency(Member member) {
+ return (int) getEfficiency(member);
+ }
+
public int incrementFortune(Member member) {
setFortune(member, getFortune(member) + 1);
return (int) getFortune(member);
}
+ public int incrementEfficiency(Member member) {
+ setEfficiency(member, getEfficiency(member) + 1);
+ return (int) getEfficiency(member);
+ }
+
public static String getRomanNumber(int number) {
return String.join("", Collections.nCopies(number, "I"))
.replace("IIIII", "V")
diff --git a/src/main/java/net/uomc/mineshaft/RobCommand.java b/src/main/java/net/uomc/mineshaft/RobCommand.java
index c04f2f4..9ff8a12 100644
--- a/src/main/java/net/uomc/mineshaft/RobCommand.java
+++ b/src/main/java/net/uomc/mineshaft/RobCommand.java
@@ -28,7 +28,7 @@ import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
public class RobCommand extends CooldownCommand {
private static final int TO_PICK = 3;
- private static final double MAX_AMOUNT_PERCENT = 0.2;
+ private static final double MAX_AMOUNT_PERCENT = 0.35;
private static final long DROP_DURATION_SECONDS = 90;
private static final String LOOT_STRING = "loot";
private Mineshaft bot;
@@ -57,6 +57,11 @@ public class RobCommand extends CooldownCommand {
}
Member target = mentionToMember.get();
+ if (bot.getPickaxes().isNether(target) != bot.getPickaxes().isNether(e.getMember())) {
+ e.getMessage().reply(":x: You tried to kill " + target.getAsMention() + " but they were in a different dimension!").queue();
+ return false;
+ }
+
String response = target.getAsMention() + " was slain by " + e.getAuthor().getAsMention();
Map<MineshaftItem, Long> rob = getRob(target);
diff --git a/src/main/java/net/uomc/mineshaft/crafting/Crafting.java b/src/main/java/net/uomc/mineshaft/crafting/Crafting.java
index 5bbef1c..6e2f670 100644
--- a/src/main/java/net/uomc/mineshaft/crafting/Crafting.java
+++ b/src/main/java/net/uomc/mineshaft/crafting/Crafting.java
@@ -19,6 +19,7 @@ import net.uomc.mineshaft.resources.Resource;
import net.uomc.mineshaft.Mineshaft;
import net.uomc.mineshaft.MineshaftItem;
import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
@@ -45,6 +46,7 @@ public class Crafting extends DetailedCommand {
addRecipe(
CraftingRecipe.make(MineshaftItem.BOOKSHELF)
.addIngredient(MineshaftItem.BOOK, 3)
+ .setUnlockCondition((m) -> bot.getItem(m, MineshaftItem.BOOK) > 0)
.setBuyMessage("**+1 enchanting table level**")
);
@@ -53,6 +55,56 @@ public class Crafting extends DetailedCommand {
.addIngredient(MineshaftItem.COAL, 800l)
.setBuyMessage("Use `" + bot.getCommandController().getPrefix() + "furnace` to get free ores")
);
+
+ addRecipe(
+ CraftingRecipe.make(MineshaftItem.PORTAL)
+ .addIngredient(MineshaftItem.OBSIDIAN, 10l)
+ .setUnlockCondition((m) -> bot.getItem(m, MineshaftItem.OBSIDIAN) > 0)
+ .setBuyMessage("You can now use your `" + bot.getCommandController().getPrefix() + "portal`")
+ );
+
+ addRecipe(
+ CraftingRecipe.make(MineshaftItem.WOOL)
+ .addIngredient(MineshaftItem.STRING, 4l)
+ .setUnlockCondition((m) -> bot.getItem(m, MineshaftItem.STRING) > 0)
+ );
+
+ addRecipe(
+ CraftingRecipe.make(MineshaftItem.BED)
+ .addIngredient(MineshaftItem.WOOL, 3l)
+ .setUnlockCondition((m) -> bot.getItem(m, MineshaftItem.STRING) > 0)
+ );
+
+ addRecipe(
+ CraftingRecipe.make(MineshaftItem.VILLAGER)
+ .addIngredient(MineshaftItem.EMERALD, 64l)
+ .addIngredient(MineshaftItem.BED, 1l)
+ .setUnlockCondition((m) -> bot.getItem(m, MineshaftItem.BED) > 0 && bot.getItem(m, MineshaftItem.EMERALD) > 0)
+ .setBuyMessage("You are now able to `" + bot.getCommandController().getPrefix() + "trade` with the wandering trader")
+ );
+
+ addRecipe(
+ CraftingRecipe.make(MineshaftItem.COMPOSTER)
+ .addIngredient(MineshaftItem.IRON, 14l)
+ .setUnlockCondition((m) ->
+ bot.getItem(m, MineshaftItem.FISH) > 0
+ || bot.getItem(m, MineshaftItem.POTATO) > 0
+ || bot.getItem(m, MineshaftItem.CARROT) > 0
+ || bot.getItem(m, MineshaftItem.CANE) > 0)
+ .setBuyMessage("You are now able to `" + bot.getCommandController().getPrefix() + "compost` your items")
+ );
+
+ addRecipe(
+ CraftingRecipe.make(MineshaftItem.PAPER)
+ .addIngredient(MineshaftItem.CANE, 3l)
+ .setUnlockCondition((m) -> bot.getItem(m, MineshaftItem.CANE) > 0)
+ );
+
+ addRecipe(
+ CraftingRecipe.make(MineshaftItem.BOOK)
+ .addIngredient(MineshaftItem.PAPER, 27l)
+ .setUnlockCondition((m) -> bot.getItem(m, MineshaftItem.PAPER) > 0)
+ );
}
@@ -72,9 +124,9 @@ public class Crafting extends DetailedCommand {
return;
}
- String description = "This is your crafting table. Craft an item with `" + b.getPrefixManager().getPrefix(e.getGuild()) + "craft [item]`\n\n";
+ String description = "This is your crafting table. Craft an item with `" + b.getPrefixManager().getPrefix(e.getGuild()) + "craft [item] [amount]`\n\n";
- description += getCraftingRecipesList();
+ description += getCraftingRecipesList(e.getMember());
EmbedBuilder em = new EmbedBuilder();
em.setTitle(COMMAND_TITLE);
@@ -82,13 +134,19 @@ public class Crafting extends DetailedCommand {
em.setThumbnail(COMMAND_IMAGE);
em.setColor(PeelingUtils.hex2Rgb("#93764c"));
- em.setFooter(EmojiParser.parseToUnicode(":bulb:") + "View your inventory with " +b.getPrefixManager().getPrefix(e.getGuild()) + "inv");
+ if (bot.getItem(e.getMember(), MineshaftItem.DIAMOND) < 1) {
+ em.setFooter(EmojiParser.parseToUnicode(":bulb:") + "View your inventory with " +b.getPrefixManager().getPrefix(e.getGuild()) + "inv");
+ } else {
+ em.setFooter(EmojiParser.parseToUnicode(":bulb:") + "Come back once you have more items to unlock more recipes!");
+ }
e.getMessage().replyEmbeds(em.build()).queue();
}
- public String getCraftingRecipesList() {
- return getRecipes().stream().map(recipe -> {
+ public String getCraftingRecipesList(Member member) {
+ return getRecipes().stream()
+ .filter(r -> r.isUnlocked(member))
+ .map(recipe -> {
Resource r = bot.getItem(recipe.getItem());
return "**" + r.getPrettyName() + "**\n"
diff --git a/src/main/java/net/uomc/mineshaft/crafting/CraftingRecipe.java b/src/main/java/net/uomc/mineshaft/crafting/CraftingRecipe.java
index cb4892e..5f624a0 100644
--- a/src/main/java/net/uomc/mineshaft/crafting/CraftingRecipe.java
+++ b/src/main/java/net/uomc/mineshaft/crafting/CraftingRecipe.java
@@ -3,6 +3,11 @@ package net.uomc.mineshaft.crafting;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import net.dv8tion.jda.api.entities.Member;
+import net.uomc.mineshaft.Mineshaft;
import net.uomc.mineshaft.MineshaftItem;
public class CraftingRecipe {
@@ -11,6 +16,7 @@ public class CraftingRecipe {
Map<MineshaftItem, Long> ingredients;
String buyMessage;
+ Function<Member, Boolean> unlockCondition;
private CraftingRecipe(MineshaftItem item, long quantity, Map<MineshaftItem, Long> ingredients) {
this.item = item;
@@ -41,13 +47,28 @@ public class CraftingRecipe {
}
public String getBuyMessage() {
+ if (buyMessage == null)
+ return "";
return buyMessage;
}
+ public boolean isUnlocked(Member m) {
+ if (unlockCondition == null)
+ return true;
+
+ return unlockCondition.apply(m);
+ }
+
public CraftingRecipe setBuyMessage(String message) {
buyMessage = message;
return this;
}
+
+ public CraftingRecipe setUnlockCondition(Function<Member, Boolean> function) {
+ this.unlockCondition = function;
+ return this;
+ }
+
public Map<MineshaftItem, Long> getMissingIngredients(Map<MineshaftItem, Long> items) {
return getMissingIngredients(items, 1);
}
diff --git a/src/main/java/net/uomc/mineshaft/resources/Resource.java b/src/main/java/net/uomc/mineshaft/resources/Resource.java
index 1cd508e..3b02050 100644
--- a/src/main/java/net/uomc/mineshaft/resources/Resource.java
+++ b/src/main/java/net/uomc/mineshaft/resources/Resource.java
@@ -123,7 +123,7 @@ public class Resource extends JSONObject {
}
public long getValue() {
- if (total() <= 0) {
+ if (total() <= 0 || resourceManager.getPrimaryResource().total() <= 0) {
return -1;
} else {
return resourceManager.getPrimaryResource().total() / total();
diff --git a/src/main/java/net/uomc/mineshaft/resources/ResourceManager.java b/src/main/java/net/uomc/mineshaft/resources/ResourceManager.java
index 8c58ab3..da1bd83 100644
--- a/src/main/java/net/uomc/mineshaft/resources/ResourceManager.java
+++ b/src/main/java/net/uomc/mineshaft/resources/ResourceManager.java
@@ -45,6 +45,7 @@ public class ResourceManager {
private MarketManager marketManager;
+
public ResourceManager(CustomBot customBot) {
this.bot = customBot;
configFile = new File(customBot.getDatadir(), "resources_config.json");
@@ -169,6 +170,10 @@ public class ResourceManager {
return resource == null ? resources.get(0) : resource;
}
+ public long getTotalResources() {
+ return resources.stream().mapToLong(r -> r.total()).sum();
+
+ }
public String getPrimaryResourceName() {
return primaryResource;
@@ -221,4 +226,8 @@ public class ResourceManager {
});
return string.toString();
}
+
+ public MarketManager getMarketManager() {
+ return marketManager;
+ }
}
diff --git a/src/main/java/net/uomc/mineshaft/resources/commands/GiveResourcesCommand.java b/src/main/java/net/uomc/mineshaft/resources/commands/GiveResourcesCommand.java
index a98a452..2925bd4 100644
--- a/src/main/java/net/uomc/mineshaft/resources/commands/GiveResourcesCommand.java
+++ b/src/main/java/net/uomc/mineshaft/resources/commands/GiveResourcesCommand.java
@@ -2,6 +2,8 @@ package net.uomc.mineshaft.resources.commands;
import static java.lang.Math.abs;
+import java.util.List;
+import java.util.Arrays;
import java.util.Optional;
import com.mouldycheerio.dbot.CustomBot;
@@ -9,7 +11,6 @@ import com.mouldycheerio.dbot.commands.CommandDetails;
import com.mouldycheerio.dbot.util.PeelingUtils;
import net.dv8tion.jda.api.entities.Member;
-import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.uomc.mineshaft.resources.Resource;
import net.uomc.mineshaft.resources.ResourceManager;
@@ -20,66 +21,73 @@ public class GiveResourcesCommand extends ResourceCommand {
public GiveResourcesCommand(ResourceManager resourceManager) {
super(resourceManager);
- setCommandDetails(CommandDetails.from("give,trade", "Give a user an item", "give [@user] [quantity] [item]"));
+ setCommandDetails(CommandDetails.from("give", "Give a user an item", "give [@user] [quantity] [item]"));
usage = "\n`" + getCommandDetails().getUsage() + "`";
}
@Override
public void execute(MessageReceivedEvent e, CustomBot op, String[] args) {
- if (args.length > 1) {
- String usermention = args[0];
- String quantitystring = args[1];
- String resourcename = getResourceManager().getPrimaryResourceName();
- if (args.length > 2) {
- resourcename = args[2];
- }
-
- boolean generate = false;
- String ownerid = op.getConfig().getString("ownerid");
- if (ownerid.equals(e.getAuthor().getId())) {
- if (args.length > 3) {
- if (args[3].equals("generate")) {
- generate = true;
- }
- }
- }
- Optional<Member> mentionToUser = PeelingUtils.mentionToMember(usermention, e.getGuild());
- if (mentionToUser.isPresent()) {
- Member member = mentionToUser.get();
- try {
- long quantity = Long.parseLong(quantitystring);
- quantity = abs(quantity);
-
- Resource resource = getResourceManager().getResource(resourcename);
- if (resource != null) {
-
- if (!generate && quantity > resource.get(e.getMember())) {
- op.sendErrorMessage(e,":x: You do not have enough " + resource.getName() + "!");
- } else {
- if (!generate) {
- resource.increment(e.getMember(), -quantity);
- }
- resource.increment(member, quantity);
- op.sendSuccessMessage(e, ":white_check_mark: You gave " + member.getAsMention() + " " + resource.prettyValue(quantity));
- }
- } else {
- op.sendErrorMessage(e, ":x: Please provide a valid resource!" + usage);
-
- }
-
- } catch (NumberFormatException ex) {
- op.sendErrorMessage(e,":x: Please provide a valid quantity!" + usage);
-
- }
-
- } else {
- op.sendErrorMessage(e, ":x: That user was not found!" + usage);
- }
- } else {
+ if (args.length < 3) {
op.sendErrorMessage(e, ":x: Invalid usage!" + usage);
+ return;
+ }
+ List<String> argList = Arrays.asList(args);
+
+ Optional<String> memberMention = argList.stream().filter(s -> s.startsWith("<@")).findFirst();
+
+ if (memberMention.isEmpty()) {
+ op.sendErrorMessage(e, ":x: Invalid usage!" + usage);
+ return;
+ }
+
+ Optional<Long> quantity = argList.stream().filter(s -> PeelingUtils.isLong(s)).map(s -> Long.parseLong(s))
+ .findFirst();
+ if (quantity.isEmpty()) {
+ op.sendErrorMessage(e, ":x: Invalid usage!" + usage);
+ return;
+ }
+ Optional<String> resourceName = argList.stream().filter(s -> !s.startsWith("<@") && !PeelingUtils.isLong(s))
+ .findFirst();
+ if (resourceName.isEmpty()) {
+ op.sendErrorMessage(e, ":x: Invalid usage!" + usage);
+ return;
+ }
+
+ boolean generate = argList.stream().filter(s -> "generate".equals(s)).findFirst().isPresent();
+ if (!e.getMember().getId().equals(op.getOwnerID())){
+ generate = false;
}
+
+ Optional<Member> mentionToUser = PeelingUtils.mentionToMember(memberMention.get(), e.getGuild());
+
+ if (!mentionToUser.isPresent()) {
+ op.sendErrorMessage(e, ":x: That user was not found!" + usage);
+ return;
+ }
+
+ Member member = mentionToUser.get();
+ long q = abs(quantity.get());
+
+ Resource resource = getResourceManager().getResource(resourceName.get());
+ if (resource == null) {
+ op.sendErrorMessage(e, ":x: Please provide a valid resource!" + usage);
+ return;
+ }
+
+ if (!generate && q > resource.get(e.getMember())) {
+ op.sendErrorMessage(e, ":x: You do not have enough " + resource.getName() + "!");
+ return;
+ }
+
+ if (!generate) {
+ resource.increment(e.getMember(), -q);
+ }
+
+ resource.increment(member, q);
+ op.sendSuccessMessage(e,
+ ":white_check_mark: You gave " + member.getAsMention() + " " + resource.prettyValue(q));
}
}
diff --git a/src/main/java/net/uomc/mineshaft/resources/commands/ValuesCommand.java b/src/main/java/net/uomc/mineshaft/resources/commands/ValuesCommand.java
index c094d83..084856b 100644
--- a/src/main/java/net/uomc/mineshaft/resources/commands/ValuesCommand.java
+++ b/src/main/java/net/uomc/mineshaft/resources/commands/ValuesCommand.java
@@ -7,6 +7,7 @@ import java.util.List;
import com.mouldycheerio.dbot.CustomBot;
import com.mouldycheerio.dbot.commands.CommandDetails;
import com.mouldycheerio.dbot.commands.CommandFail;
+import com.mouldycheerio.dbot.util.PeelingUtils;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.uomc.mineshaft.resources.Resource;
@@ -21,8 +22,6 @@ public class ValuesCommand extends ResourceCommand {
@Override
public void execute(MessageReceivedEvent e, CustomBot b, String[] args) throws CommandFail {
- long total = getResourceManager().getPrimaryResource().total();
-
List<Resource> resources = new ArrayList<Resource>(getResourceManager().getResources());
Collections.sort(resources, (r1, r2) -> Long.compare(r2.getValue(),r1.getValue()));
@@ -33,13 +32,11 @@ public class ValuesCommand extends ResourceCommand {
if (v < 0) {
stringBuilder.append("**???**");
} else {
- stringBuilder.append("**" + getResourceManager().getPrimaryResource().prettyValue(v) + "**");
+ stringBuilder.append("**" +PeelingUtils.amountToString(v) + "**");
}
stringBuilder.append("\n");
});
b.sendMessage(e, "Estimated Market Values", stringBuilder.toString());
}
-
-
}
diff --git a/src/main/java/net/uomc/mineshaft/resources/market/MarketCommand.java b/src/main/java/net/uomc/mineshaft/resources/market/MarketCommand.java
index 47b0536..7b4122a 100644
--- a/src/main/java/net/uomc/mineshaft/resources/market/MarketCommand.java
+++ b/src/main/java/net/uomc/mineshaft/resources/market/MarketCommand.java
@@ -6,12 +6,14 @@ import com.mouldycheerio.dbot.CustomBot;
import com.mouldycheerio.dbot.commands.CommandDetails;
import com.mouldycheerio.dbot.commands.DetailedCommand;
import com.mouldycheerio.dbot.util.PeelingUtils;
+import com.vdurmont.emoji.EmojiParser;
import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.entities.MessageEmbed.Field;
+import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.uomc.mineshaft.resources.Resource;
import net.uomc.mineshaft.resources.ResourceManager;
-import net.uomc.mineshaft.resources.market.Offer;
public class MarketCommand extends DetailedCommand {
private ResourceManager resourceManager;
@@ -26,21 +28,30 @@ public class MarketCommand extends DetailedCommand {
@Override
public void execute(MessageReceivedEvent e, CustomBot op, String[] args) {
+ market(e, op, args);
+ }
- marketManager.processOffers();
+ private void market(MessageReceivedEvent e, CustomBot op, String[] args) {
+ marketManager.processOffers(e.getGuild());
if (args.length == 0) {
- // TODO allow multipages with <-, ->
-
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setTitle("Market");
embedBuilder.setColor(op.color);
- if (marketManager.getEmbedFields().size() == 0) {
+ List<Field> embedFields = marketManager.getEmbedFields(e.getGuild());
+ if (embedFields.size() == 0) {
embedBuilder.setDescription("**:x: There are no available offers!**\n" + "Create one with `market sell`");
e.getMessage().replyEmbeds(embedBuilder.build()).queue();
} else {
- embedBuilder.setDescription("Use `" + op.getPrefixManager().getPrefix(e.getGuild()) + "market buy [id]` to accept an offer");
- PeelingUtils.pagesEmbed(e.getAuthor(), e.getChannel(), embedBuilder, marketManager.getEmbedFields());
- }
+ embedBuilder.setDescription(
+ "Use `" + op.getPrefixManager().getPrefix(e.getGuild()) + "market buy [id]` to accept an offer\n"
++ "Use `" + op.getPrefixManager().getPrefix(e.getGuild()) + "market sell` to create an offer\n"
+ );
+
+ e.getMessage().addReaction(Emoji.fromUnicode(EmojiParser.parseToUnicode(":white_check_mark:")))
+ .queue((r) -> {
+ PeelingUtils.pagesEmbed(e.getAuthor(), e.getChannel(), embedBuilder, embedFields);
+ });
+ }
} else if (args.length > 0) {
if (args[0].equals("buy")) {
@@ -76,7 +87,7 @@ public class MarketCommand extends DetailedCommand {
offer.setSellingQuantity(sellQ);
offer.setSellingResource(sellR);
- marketManager.addOffer(offer);
+ marketManager.addOffer(e.getGuild(), offer);
op.sendSuccessMessage(e, ":white_check_mark: successfully listed **" + offer.getAsString(resourceManager) + "** offer id: `" + offer.getID() + "`");
} else {
op.sendErrorMessage(e, ":x: You don't have enough " + sellR + " to offer");
@@ -99,19 +110,20 @@ public class MarketCommand extends DetailedCommand {
int q1 = (int) (Math.random() * 10);
int q2 = (int) (Math.random() * 10);
- op.sendMessage(
- e, "incorrect usage",
+ op.sendErrorMessage(
+ e,
":x: usage: `market sell [items] for [price]`\ni.e: `market sell " + q1 + " " + resource1.getName() + " for " + q2 + " " + resource2.getName() + "`"
);
}
private void buy(MessageReceivedEvent e, CustomBot op, String[] args) {
String id = args[1];
- Offer offer = marketManager.getOffer(id);
+ Offer offer = marketManager.getOffer(e.getGuild(), id);
if (offer != null) {
offer.getMember(e.getGuild(), seller -> {
- if (seller.equals(e.getAuthor())) {
- op.sendErrorMessage(e, ":x: you cannot accept your own offer");
+
+ if (e.getMember().equals(seller)) {
+ op.sendErrorMessage(e, ":x: You cannot accept your own offer");
} else {
long buyingQuantity = offer.getBuyingQuantity();
Resource buyingResource = offer.getBuyingResource(resourceManager);
@@ -120,6 +132,12 @@ public class MarketCommand extends DetailedCommand {
long sellingQuantity = offer.getSellingQuantity();
Resource sellingResource = offer.getSellingResource(resourceManager);
+ if (sellingResource.get(seller) < sellingQuantity) {
+ op.sendErrorMessage(e, ":x: This offer no longer exists as " + seller.getAsMention() + "does not have enough " + sellingResource.getName());
+ marketManager.removeOffer(e.getGuild(), offer);
+ return;
+ }
+
buyingResource.increment(e.getMember(), -buyingQuantity);
sellingResource.increment(e.getMember(), sellingQuantity);
@@ -127,6 +145,7 @@ public class MarketCommand extends DetailedCommand {
buyingResource.increment(seller, buyingQuantity);
sellingResource.increment(seller, -sellingQuantity);
}
+
seller.getUser().openPrivateChannel().queue(pc -> {
pc.sendMessage(
"**" + e.getAuthor().getAsTag() + "** has accepted your market offer: **" + offer.getAsString(resourceManager) + "** [" + offer.getID() + "]"
@@ -134,26 +153,25 @@ public class MarketCommand extends DetailedCommand {
.queue();
});
- String from = "";
- if (seller != null) {
- from = " from " + seller.getAsMention();
- }
+ String from = " from " + seller.getAsMention();
- marketManager.removeOffer(offer);
- op.sendSuccessMessage(
+ marketManager.removeOffer(e.getGuild(), offer);
+ e.getMessage().addReaction(Emoji.fromUnicode(EmojiParser.parseToUnicode(":white_check_mark:"))).queue((r) -> {
+ op.sendMessageRaw(
e, ":white_check_mark: successfully bought **" + sellingResource.prettyValue(sellingQuantity) + "** for **"
+ buyingResource.prettyValue(buyingQuantity) + "**" + from
);
+ });
} else {
long have = buyingResource.get(e.getMember());
long more = buyingQuantity - have;
- op.sendErrorMessage(e, ":x: you need **" + buyingResource.prettyValue(more) + "** more to buy this");
+ op.sendErrorMessage(e, ":x: You need **" + buyingResource.prettyValue(more) + "** more to buy this");
}
}
});
} else {
- op.sendErrorMessage(e, ":x: please specify a valid id!");
+ op.sendErrorMessage(e, ":x: Please specify a valid id!");
}
}
}
diff --git a/src/main/java/net/uomc/mineshaft/resources/market/MarketManager.java b/src/main/java/net/uomc/mineshaft/resources/market/MarketManager.java
index 05517aa..3b820b5 100644
--- a/src/main/java/net/uomc/mineshaft/resources/market/MarketManager.java
+++ b/src/main/java/net/uomc/mineshaft/resources/market/MarketManager.java
@@ -3,8 +3,10 @@ package net.uomc.mineshaft.resources.market;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.stream.Collectors;
import org.json.JSONObject;
@@ -12,6 +14,7 @@ import org.json.JSONObject;
import com.mouldycheerio.dbot.CustomBot;
import com.mouldycheerio.dbot.util.PeelingUtils;
+import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.MessageEmbed.Field;
import net.dv8tion.jda.api.entities.User;
import net.uomc.mineshaft.resources.Resource;
@@ -21,7 +24,7 @@ import net.uomc.mineshaft.resources.market.Offer;
public class MarketManager {
private ResourceManager resourceManager;
- private List<Offer> offers = new ArrayList<Offer>();
+ private Map<Guild, List<Offer>> guildOffers = new HashMap<Guild, List<Offer>>();
private File dataFile;
@@ -38,27 +41,48 @@ public class MarketManager {
public void load() {
JSONObject loadJSON = PeelingUtils.loadJSON(dataFile);
- if (loadJSON.has("offers")) {
- loadJSON.getJSONArray("offers").forEach(o -> {
- if (o instanceof JSONObject) {
- Offer offer = new Offer((JSONObject) o);
- offers.add(offer);
- }
+ if (loadJSON.has("guilds")) {
+ loadJSON.getJSONObject("guilds").keySet().forEach(g -> {
+ Guild guild = bot.getClient().getGuildById(g);
+ if (guild == null)
+ return;
+
+ guildOffers.put(guild, new ArrayList<Offer>());
+
+ loadJSON.getJSONObject("guilds").getJSONArray(g).forEach(o -> {
+ if (o instanceof JSONObject) {
+ Offer offer = new Offer((JSONObject) o);
+ guildOffers.get(guild).add(offer);
+ }
+ });
});
}
}
public void save() {
JSONObject jsonObject = new JSONObject();
- for (Offer offer : offers) {
- jsonObject.append("offers", offer);
- }
+
+ JSONObject guilds = new JSONObject();
+
+ guildOffers.forEach((g, l) -> {
+ l.forEach(o -> {
+ guilds.append(g.getId(), o);
+ });
+ });
+ jsonObject.put("guilds", guilds);
PeelingUtils.saveJSON(dataFile, jsonObject);
}
- public Offer getOffer(String id) {
- for (Offer offer : offers) {
+ public List<Offer> getOffers(Guild guild) {
+ if (!guildOffers.containsKey(guild)) {
+ guildOffers.put(guild, new ArrayList<Offer>());
+ }
+ return guildOffers.get(guild);
+ }
+
+ public Offer getOffer(Guild guild, String id) {
+ for (Offer offer : getOffers(guild)) {
if (id.equals(offer.getID() + "")) {
return offer;
}
@@ -66,27 +90,23 @@ public class MarketManager {
return null;
}
- public void addOffer(Offer offer) {
- offers.add(offer);
- processOffers();
+ public void addOffer(Guild guild, Offer offer) {
+ getOffers(guild).add(offer);
+ processOffers(guild);
+ save();
}
- public void processOffers() {
- // TODO uhhh we should bring this back
- //Iterator<Offer> iterator = offers.iterator();
+ public void processOffers(Guild guild) {
+ // TODO Fix tis
+ //Iterator<Offer> iterator = getOffers(guild).iterator();
//while (iterator.hasNext()) {
// Offer offer = iterator.next();
- // bot.getClient().retrieveUserById(offer.getUserID()).queue(seller -> {
- // long quantity = offer.getSellingQuantity();
- // Resource resource = offer.getSellingResource(resourceManager);
- // long l = resource.get(seller);
- // if (l < quantity) {
+ // if (l < quantity) {
- // sendNoLongerValidMessage(offer, seller);
- // iterator.remove();
- // }
- // });
+ // sendNoLongerValidMessage(offer, seller);
+ // iterator.remove();
+ // }
//}
//save();
@@ -98,17 +118,17 @@ public class MarketManager {
});
}
- public void removeOffer(Offer o) {
- offers.remove(o);
+ public void removeOffer(Guild guild, Offer o) {
+ getOffers(guild).remove(o);
save();
}
- public List<Offer> listOffers() {
- return Collections.unmodifiableList(offers);
+ public List<Offer> listOffers(Guild guild) {
+ return Collections.unmodifiableList(getOffers(guild));
}
- public List<Field> getEmbedFields() {
- return listOffers().stream().map(
+ public List<Field> getEmbedFields(Guild guild) {
+ return listOffers(guild).stream().map(
o -> new Field(
"[" + o.getID() + "] "
+ o.getAsString(resourceManager),
diff --git a/src/main/java/net/uomc/mineshaft/resources/market/Offer.java b/src/main/java/net/uomc/mineshaft/resources/market/Offer.java
index 9e01acd..d093f2f 100644
--- a/src/main/java/net/uomc/mineshaft/resources/market/Offer.java
+++ b/src/main/java/net/uomc/mineshaft/resources/market/Offer.java
@@ -53,7 +53,7 @@ public class Offer extends JSONObject {
}
public void getMember(Guild guild, Consumer<Member> c) {
- c.accept(guild.getMemberById(getUserID()));
+ guild.retrieveMemberById(getUserID()).queue(c);
}
public Member getMember(Guild guild) {