Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added wager option to normal and pvp races #8

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 193 additions & 1 deletion src/main/java/io/github/hielkemaps/racecommand/Commands.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
import io.github.hielkemaps.racecommand.wrapper.PlayerManager;
import io.github.hielkemaps.racecommand.wrapper.PlayerWrapper;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
Expand Down Expand Up @@ -196,7 +199,9 @@ public Commands() {
arguments = new ArrayList<>();
arguments.add(new LiteralArgument("join").withRequirement(playerHasJoinableRaces));
arguments.add(new StringArgument("player").replaceSuggestions(ArgumentSuggestions.strings((info) -> PlayerManager.getPlayer(((Player) info.sender()).getUniqueId()).getJoinableRaces())));
new CommandAPICommand("race").withArguments(arguments).executesPlayer((p, args) -> {
new CommandAPICommand("race").withArguments(arguments)
.withOptionalArguments(new BooleanArgument("pay_wager")).withUsage("/race join [player]")
.executesPlayer((p, args) -> {
String raceName = (String) args.get(0);
Race race = RaceManager.getRace(raceName);
if (race == null) {
Expand All @@ -218,6 +223,52 @@ public Commands() {
return;
}

int minWager = race.getMinimumWager();
Boolean payWager = (Boolean) args.get("pay_wager");
if (minWager > 0) {
// Has minimum wager

if (minWager > wPlayer.getPlayerPoints() && !wPlayer.isInRace()) {
// Player does not have enough points
p.sendMessage(Component.text("This race requires you to pay a minimum wager of " + minWager + " parcoins, but you don't have enough parcoins. Please ask the race creator to lower the entry cost or get more parcoins yourself", NamedTextColor.YELLOW));
return;
} else if (wPlayer.isInRace()) {
// Maybe player has wager in current race, that could be enough to pay the minimum wager for this race
Race raceWithPlayer = RaceManager.getRace(p.getUniqueId());

if (raceWithPlayer == null || raceWithPlayer.hasStarted()) {
// no race or race has started means not enough parcoins to join
p.sendMessage(Component.text("This race requires you to pay a minimum wager of " + minWager + " parcoins, but you don't have enough parcoins. Please ask the race creator to lower the entry cost or get more parcoins yourself", NamedTextColor.YELLOW));
return;
}

RacePlayer racePlayer = raceWithPlayer.getRacePlayer(p.getUniqueId());

if (racePlayer == null) {
// Invalid state, but still has not enough parcoins to join
p.sendMessage(Component.text("This race requires you to pay a minimum wager of " + minWager + " parcoins, but you don't have enough parcoins. Please ask the race creator to lower the entry cost or get more parcoins yourself", NamedTextColor.YELLOW));
return;
}

if (!racePlayer.hasWager() || racePlayer.getTotalWager() < minWager) {
// Either has no wager in current race, so not enough parcoins
// Or the total wager in current race is not enough to pay the minimum wager for this race
p.sendMessage(Component.text("This race requires you to pay a minimum wager of " + minWager + " parcoins, but you don't have enough parcoins. Please ask the race creator to lower the entry cost or get more parcoins yourself", NamedTextColor.YELLOW));
return;
}
}

if (payWager == null || !payWager) {
// pay_wager was not set or was false
// Player can pay minimum wager
Component msg = Main.PREFIX
.append(Component.text("This race requires you to pay a minimum wager of " + race.getMinimumWager() + " parcoins to join. Are you sure you want to join? "))
.append(Component.text("[Yes]", NamedTextColor.GREEN).clickEvent(ClickEvent.runCommand("/race join " + raceName + " " + true)));
p.sendMessage(msg);
return;
}
}

//If player in existing race, leave
if (wPlayer.isInRace()) {
Race raceToLeave = RaceManager.getRace(p);
Expand All @@ -236,6 +287,18 @@ public Commands() {
//Join race
if (!wPlayer.acceptInvite(raceName)) {
throw CommandAPI.failWithString("Could not join race");
} else {
if (payWager != null && payWager) {
// pay_wager was true
wPlayer.takePlayerPoints(minWager);

Component message = Main.PREFIX
.append(Component.text("You payed ", NamedTextColor.GRAY))
.append(Component.text(minWager, NamedTextColor.YELLOW))
.append(Component.text(" Parcoins", NamedTextColor.GRAY));

p.sendMessage(message);
}
}
}
}).register();
Expand Down Expand Up @@ -280,6 +343,24 @@ public Commands() {
}
p.sendMessage("Visibility: " + (race.isPublic() ? ChatColor.GREEN + "Public" : ChatColor.RED + "Private"));
p.sendMessage("Type: " + race.getTypeString());
if (race.getMinimumWager() > 0) {
p.sendMessage("Minimum wager: " + ChatColor.GRAY + race.getMinimumWager());
}
if (race.isEvent()) {
Component msg = Component.text("Guaranteed prizes: \n 1st: ")
.append(Component.text(race.getFirstPrize(), NamedTextColor.GOLD, TextDecoration.BOLD))
.append(Component.text("\n 2nd: "))
.append(Component.text(race.getSecondPrize(), NamedTextColor.GRAY, TextDecoration.BOLD))
.append(Component.text("\n 3rd: "))
.append(Component.text(race.getThirdPrize(), TextColor.color(164, 102, 40), TextDecoration.BOLD))
.append(Component.text("\n 4th+: "))
.append(Component.text(race.getFourthPlusPrize(), NamedTextColor.WHITE, TextDecoration.BOLD));

p.sendMessage(msg);
}
if (race.getTotalPrizePool() > 0) {
p.sendMessage((race.isEvent() ? "Extra prize pool: " : "Prize pool: ") + ChatColor.GOLD + ChatColor.BOLD + race.getTotalPrizePool());
}
p.sendMessage("Players:");

for (RacePlayer racePlayer : race.getPlayers()) {
Expand Down Expand Up @@ -467,6 +548,117 @@ public Commands() {
}
}).register();

//Option set minimum wager
arguments = new ArrayList<>();
arguments.add(new LiteralArgument("option").withRequirement(playerInRace.and(playerIsRaceOwner)));
arguments.add(new LiteralArgument("wager").withRequirement(playerInRace.and(Predicate.not(playerInInfectedRace)))); // Don't allow wagers in infected races (Idk how I would hand out the parcoins xD)
arguments.add(new IntegerArgument("minimum", 10));
new CommandAPICommand("race")
.withArguments((arguments))
.executesPlayer((p, args) -> {
try {
int wager = (int) args.get(0);

Race race = RaceManager.getRace(p);
if (race == null) return;

// Only allow wager to be set when no other player are in the race
if (race.getPlayers().size() != 1) {
p.sendMessage(Main.PREFIX.append(Component.text("You can only set the minimum wage if no other players have joined the race", NamedTextColor.RED)));
return;
}

int oldWager = race.getMinimumWager();

PlayerWrapper wPlayer = PlayerManager.getPlayer(p.getUniqueId());

if (wager > wPlayer.getPlayerPoints() + oldWager) {
p.sendMessage(Main.PREFIX.append(Component.text("You must be able to pay the minimum wager yourself!", NamedTextColor.RED)));
return;
}

if (race.setMinimumWager(wager)) {
if (oldWager > wager) {
// Don't want the rainbow text flashing on the screen, just for giving some of the parcoins back :)
race.getPlayers().get(0).givePointsSilently(oldWager - wager);
p.sendMessage(Main.PREFIX.append(Component.text("Added ", NamedTextColor.GRAY))
.append(Component.text(oldWager - wager, NamedTextColor.YELLOW))
.append(Component.text(" parcoins", NamedTextColor.GRAY)));
} else {
race.getPlayers().get(0).takePoints(wager - oldWager);
}
p.sendMessage(Main.PREFIX.append(Component.text("Minimum wager set to " + wager)));
} else {
// no change, no need to remove / add points
p.sendMessage(Main.PREFIX.append(Component.text("Minimum wager was already set to " + wager, NamedTextColor.RED)));
}

race.getPlayers().get(0).setNewWager(wager);
} catch(NullPointerException e) {
p.sendMessage(Main.PREFIX.append(Component.text("You must enter a number higher than 10 as the minimum wager", NamedTextColor.RED)));
}
}).register();

//wager increase
arguments = new ArrayList<>();
arguments.add(new LiteralArgument("wager").withRequirement(playerInRace));
arguments.add(new LiteralArgument("increase"));
arguments.add(new IntegerArgument("amount", 1));
new CommandAPICommand("race")
.withArguments(arguments)
.executesPlayer((p, args) -> {
Integer wager = (Integer) args.get(0);

if (wager == null) return;

Race race = RaceManager.getRace(p);

if (race == null) return;

RacePlayer player = race.getRacePlayer(p.getUniqueId());
if (player.getWrapper().getPlayerPoints() < wager) {
p.sendMessage(Component.text("You don't have enough parcoins!", NamedTextColor.RED));
} else {
player.increaseAdditionalWager(wager);
player.takePointsSilently(wager);
Component msg = Component.text("Increased wager with ", NamedTextColor.GRAY)
.append(Component.text(wager, NamedTextColor.GOLD))
.append(Component.text("!", NamedTextColor.GRAY));

p.sendMessage(msg);
}
}).register();

//wager decrease
arguments = new ArrayList<>();
arguments.add(new LiteralArgument("wager").withRequirement(playerInRace));
arguments.add(new LiteralArgument("decrease"));
arguments.add(new IntegerArgument("amount", 1));
new CommandAPICommand("race")
.withArguments(arguments)
.executesPlayer((p, args) -> {
Integer wager = (Integer) args.get(0);

if (wager == null) return;

Race race = RaceManager.getRace(p);

if (race == null) return;

RacePlayer player = race.getRacePlayer(p.getUniqueId());
if (player.getAdditionalWager() < wager) {
p.sendMessage(Component.text("You can at most remove " + player.getAdditionalWager() + " from your wagers!", NamedTextColor.RED));
} else {
player.increaseAdditionalWager(-wager);
player.givePointsSilently(wager);
Component msg = Component.text("Decreased wager with ", NamedTextColor.GRAY)
.append(Component.text(wager, NamedTextColor.GOLD))
.append(Component.text("!", NamedTextColor.GRAY));

p.sendMessage(msg);
}
}).register();

//Force join - OP ONLY
arguments = new ArrayList<>();
arguments.add(new LiteralArgument("forcejoin").withRequirement(playerInRace.and(playerisOP.or(playerIsRaceOwner))).withPermission(CommandPermission.OP));
Expand Down
78 changes: 73 additions & 5 deletions src/main/java/io/github/hielkemaps/racecommand/race/Race.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,14 @@ public abstract class Race {
protected String type;
protected String formattedType;
private int place = 1;
private int totalPrizePool = 0;

//options
private boolean isPublic = false;
private int countDown = 5;
private boolean broadcast = false;
private boolean ghostPlayers = false;
private int minimumWager = 0;

private boolean isEvent = false;

Expand Down Expand Up @@ -154,6 +156,31 @@ private void start() {
return;
}

// Recalculate prize pool, just in case something went wrong in adding / removing parcoins
int actualPrizePool = 0;
for (RacePlayer racePlayer : players) {
actualPrizePool += racePlayer.getTotalWager();
}

// When setting the prizes of the race, add the prizes to the already existing prizes
// In case the race is an event and has already loaded some prizes
// Rather than overriding the event prizes, we should add the prize pool to the existing prizes
if (actualPrizePool > 0) {
if (players.size() == 2) {
// 1st: 100%
setPrizes(getFirstPrize() + actualPrizePool, getSecondPrize(), getThirdPrize(), getFourthPlusPrize());
} else if (players.size() == 3) {
// 1st: 70%, 2nd: 30%
int firstPrize = (int) Math.round(actualPrizePool * 0.7);
setPrizes(getFirstPrize() + firstPrize, getSecondPrize() + actualPrizePool - firstPrize, getThirdPrize(), getFourthPlusPrize());
} else {
// 1st: 60%, 2nd: 25%, 3rd: 15%
int firstPrize = (int) Math.round(actualPrizePool * 0.6);
int secondPrize = (int) Math.round(actualPrizePool * 0.25);
setPrizes(getFirstPrize() + firstPrize, getSecondPrize() + secondPrize, getThirdPrize() + actualPrizePool - firstPrize - secondPrize, getFourthPlusPrize());
}
}

hasStarted = true;
onRaceStart();

Expand Down Expand Up @@ -287,6 +314,9 @@ public void addPlayer(UUID uuid) {
sendMessageToRaceMembers(joinMsg);
RacePlayer newPlayer = new RacePlayer(this, uuid);
players.add(newPlayer);
if (minimumWager > 0) {
newPlayer.setNewWager(minimumWager);
}

PlayerWrapper pw = PlayerManager.getPlayer(uuid);
pw.setInRace(true);
Expand Down Expand Up @@ -328,6 +358,7 @@ public void removePlayer(Player player) {
public void removePlayerSilent(UUID uuid) {
RacePlayer racePlayer = getRacePlayer(uuid);
onPlayerLeave(racePlayer);
racePlayer.refundAllWagers();
players.remove(racePlayer);

Component leaveMessage = Main.PREFIX
Expand Down Expand Up @@ -366,6 +397,7 @@ protected void disband() {
} else {
player.sendMessage(Main.PREFIX.append(Component.text("The race has been disbanded")));
}
racePlayer.refundAllWagers();
}
}

Expand Down Expand Up @@ -399,6 +431,17 @@ public boolean setBroadcast(boolean value) {
return true;
}

public boolean setMinimumWager(int wage) {
if (wage == minimumWager) return false;

minimumWager = wage;
return true;
}

public int getMinimumWager() {
return minimumWager;
}

public boolean isStarting() {
return isStarting;
}
Expand Down Expand Up @@ -566,6 +609,15 @@ public List<RacePlayer> getPlayers() {
return players;
}

public int getTotalPrizePool() {
return totalPrizePool;
}

public int increasePrizePool(int addedPrizes) {
totalPrizePool += addedPrizes;
return totalPrizePool;
}

public boolean isOwner(UUID uniqueId) {
return uniqueId.equals(owner);
}
Expand All @@ -577,11 +629,11 @@ public void onPlayerFinish(RacePlayer player, int place, int time) {
.append(Component.text(" (" + Util.getTimeString(time) + ")", NamedTextColor.WHITE));
sendMessage(finishMsg);

if (isEvent) {
if (place == 1) player.givePoints(prizes[0]);
if (place == 2) player.givePoints(prizes[1]);
if (place == 3) player.givePoints(prizes[2]);
if (place >= 4) player.givePoints(prizes[3]);
if (isEvent || totalPrizePool > 0) {
if (place == 1 && prizes[0] > 0) player.givePoints(getFirstPrize());
if (place == 2 && prizes[1] > 0) player.givePoints(getSecondPrize());
if (place == 3 && prizes[2] > 0) player.givePoints(getThirdPrize());
if (place >= 4 && prizes[3] > 0) player.givePoints(getFourthPlusPrize());
}
}

Expand Down Expand Up @@ -623,4 +675,20 @@ public void setPrizes(int first, int second, int third, int fourth) {
prizes[2] = third;
prizes[3] = fourth;
}

public int getFirstPrize() {
return prizes[0];
}

public int getSecondPrize() {
return prizes[1];
}

public int getThirdPrize() {
return prizes[2];
}

public int getFourthPlusPrize() {
return prizes[3];
}
}
Loading