More work on Missions

This commit is contained in:
Sam 2018-06-23 11:26:54 +01:00 committed by Alexander Meech
parent f898526012
commit 166d551fe0
9 changed files with 190 additions and 65 deletions

View File

@ -2,20 +2,26 @@ package mineplex.core.mission;
import java.util.Calendar;
import org.bukkit.ChatColor;
public enum MissionLength
{
DAY("Daily", "Resets everyday", Calendar.DAY_OF_WEEK),
WEEK("Weekly", "Resets every Monday", Calendar.WEEK_OF_YEAR),
EVENT("Special Event", "Limited time only!", -1);
DAY("Daily", "Resets everyday", ChatColor.GREEN, 5, Calendar.DAY_OF_WEEK),
WEEK("Weekly", "Resets every Monday", ChatColor.AQUA, 3, Calendar.WEEK_OF_YEAR),
EVENT("Special Event", "Limited time only!", ChatColor.RED, 14, -1);
private final String _name, _resetInfo;
private final ChatColor _chatColour;
private final byte _colourData;
private final int _calendarField;
MissionLength(String name, String resetInfo, int calendarField)
MissionLength(String name, String resetInfo, ChatColor chatColour, int colourData, int calendarField)
{
_name = name;
_resetInfo = resetInfo;
_chatColour = chatColour;
_colourData = (byte) colourData;
_calendarField = calendarField;
}
@ -29,6 +35,16 @@ public enum MissionLength
return _resetInfo;
}
public ChatColor getChatColour()
{
return _chatColour;
}
public byte getColourData()
{
return _colourData;
}
public int getCalendarField()
{
return _calendarField;

View File

@ -2,13 +2,13 @@ package mineplex.core.mission;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@ -29,6 +29,8 @@ import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilServer;
import mineplex.core.donation.DonationManager;
import mineplex.core.mission.MissionRepository.MissionQuery;
import mineplex.core.mission.commands.DebugMissionCommand;
import mineplex.core.mission.commands.StartMissionCommand;
import mineplex.core.mission.ui.MissionShop;
import mineplex.core.newnpc.NPC;
@ -42,7 +44,8 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
public enum Perm implements Permission
{
START_MISSION_COMMAND
START_MISSION_COMMAND,
DEBUG_MISSION_COMMAND
}
private static final String NPC_METADATA = "MISSION_NPC";
@ -55,6 +58,8 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
private final MissionRepository _repository;
private final MissionShop _shop;
private boolean _debug;
private MissionManager()
{
super("Mission");
@ -78,12 +83,14 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
private void generatePermissions()
{
PermissionGroup.ADMIN.setPermission(Perm.START_MISSION_COMMAND, true, true);
PermissionGroup.ADMIN.setPermission(Perm.DEBUG_MISSION_COMMAND, true, true);
}
@Override
public void addCommands()
{
addCommand(new StartMissionCommand(this));
addCommand(new DebugMissionCommand(this));
}
private void populateTrackers()
@ -115,13 +122,14 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException
{
MissionClient client = Get(uuid);
Calendar calendar = Calendar.getInstance();
TimeZone utc = TimeZone.getTimeZone("UTC");
Calendar now = Calendar.getInstance(utc);
while (resultSet.next())
{
int missionId = resultSet.getInt("missionId");
int progress = resultSet.getInt("progress");
Timestamp startTime = resultSet.getTimestamp("startTime");
long startTime = resultSet.getLong("startTime");
Mission mission = getMission(missionId);
@ -132,15 +140,10 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
int lengthField = mission.getLength().getCalendarField();
if (lengthField == -1)
{
return;
}
Calendar start = Calendar.getInstance(utc);
start.setTimeInMillis(startTime);
Calendar start = Calendar.getInstance();
start.setTimeInMillis(startTime.getTime());
if (calendar.get(lengthField) != start.get(lengthField))
if (lengthField != -1 && now.get(lengthField) != start.get(lengthField))
{
runAsync(() -> _repository.clearProgress(accountId, missionId));
}
@ -175,7 +178,7 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
});
}
public void completeMission(Player player, Mission<?> mission)
private void completeMission(Player player, Mission<?> mission)
{
MissionClient client = Get(player);
@ -185,7 +188,7 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
}
player.sendMessage("");
player.sendMessage(" " + C.mHead + C.Bold + mission.getLength().getName() + " Mission Complete! " + C.mBody + C.Bold + mission.getName());
player.sendMessage(" " + mission.getLength().getChatColour()+ C.Bold + mission.getLength().getName() + " Mission Complete! " + C.mElem + C.Bold + mission.getName());
player.sendMessage(" " + C.cGray + mission.getDescription());
player.sendMessage("");
@ -220,11 +223,15 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
return;
}
if (_debug)
{
player.sendMessage(F.main(getName(), F.name(mission.getName()) + " incremented " + F.count(amount) + "."));
}
client.incrementProgress(mission, amount);
}, trackerType);
}
// TODO this may not be good enough. might have to bulk query or change implementation?
private void processUnsavedProgress()
{
for (Player player : UtilServer.getPlayersCollection())
@ -232,6 +239,8 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
selectNewMissions(player);
saveProgress(player);
}
runAsync(_repository::bulkProcess);
}
private void selectNewMissions(Player player)
@ -240,6 +249,16 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
selectNewMissions(player, client, MissionLength.DAY, 3);
selectNewMissions(player, client, MissionLength.WEEK, 2);
for (Mission mission : getMissionsOf(MissionLength.EVENT))
{
if (client.isActive(mission))
{
continue;
}
startMission(player, mission);
}
}
private void selectNewMissions(Player player, MissionClient client, MissionLength length, int max)
@ -271,11 +290,11 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
private List<Mission> getMissionsOf(MissionLength length)
{
return _missions.stream()
.filter(mission -> mission.getLength() != length)
.filter(mission -> mission.getLength() == length)
.collect(Collectors.toList());
}
public void saveProgress(Player player)
private void saveProgress(Player player)
{
MissionClient client = Get(player);
Map<Mission, Integer> unsaved = client.saveProgress();
@ -287,13 +306,18 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
int accountId = ClientManager.getAccountId(player);
runAsync(() -> unsaved.forEach((mission, progress) ->
unsaved.forEach((mission, progress) ->
{
if (_repository.incrementProgress(accountId, mission.getId(), progress) && mission.isComplete(client.getProgress(mission)))
boolean complete = mission.isComplete(client.getProgress(mission));
_repository.incrementProgress(new MissionQuery(accountId, mission, progress, () ->
{
if (complete)
{
runSync(() -> completeMission(player, mission));
}
}));
});
}
private void applyForMissions(Consumer<Mission> function, MissionTrackerType trackerType)
@ -319,7 +343,7 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
LivingEntity entity = npc.getEntity();
entity.setCustomName(C.cGreenB + "Señor Missions");
entity.setCustomName(C.cGreenB + "Sam the Slime");
entity.setCustomNameVisible(true);
}
@ -332,6 +356,13 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
}
}
public boolean toggleDebug()
{
_debug = !_debug;
return _debug;
}
public DonationManager getDonationManager()
{
return _donationManager;

View File

@ -1,18 +1,16 @@
package mineplex.core.mission;
import org.bukkit.Material;
import mineplex.core.game.GameDisplay;
import mineplex.core.reward.rewards.ExperienceReward;
import mineplex.core.reward.rewards.GemReward;
import mineplex.core.reward.rewards.TreasureShardReward;
import mineplex.core.treasure.reward.RewardRarity;
public class MissionPopulator
{
public static void populateMissions(MissionManager manager)
{
Mission.<Material>newBuilder(manager, 1)
Mission.<GameDisplay>newBuilder(manager, 1)
.name("Winner")
.description("Win %s games")
.length(MissionLength.DAY)
@ -21,7 +19,7 @@ public class MissionPopulator
.rewards(new GemReward(2000))
.build();
Mission.<Material>newBuilder(manager, 2)
Mission.<GameDisplay>newBuilder(manager, 2)
.name("Killer")
.description("Kill %s players")
.length(MissionLength.DAY)
@ -30,7 +28,7 @@ public class MissionPopulator
.rewards(new ExperienceReward(100))
.build();
Mission.<Material>newBuilder(manager, 3)
Mission.<GameDisplay>newBuilder(manager, 3)
.name("Killer II")
.description("Kill %s players")
.length(MissionLength.WEEK)
@ -38,6 +36,16 @@ public class MissionPopulator
.tracker(MissionTrackerType.GAME_KILL)
.rewards(new TreasureShardReward(500))
.build();
Mission.<GameDisplay>newBuilder(manager, 4)
.name("Cake Winner")
.description("Win %s games of Cake Wars Standard")
.length(MissionLength.EVENT)
.requiredProgress(1)
.tracker(MissionTrackerType.GAME_WIN)
.trackerData(GameDisplay.CakeWars4)
.rewards(new TreasureShardReward(750))
.build();
}
}

View File

@ -1,37 +1,67 @@
package mineplex.core.mission;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnLong;
public class MissionRepository extends RepositoryBase
{
private static final String START_QUEST = "INSERT INTO accountMissions (accountId, missionId) VALUES (?,?);";
private static final String INCREMENT_PROGRESS = "UPDATE accountMissions SET progress=progress+? WHERE accountId=? AND missionId=?;";
private static final String START_QUEST = "INSERT INTO accountMissions (accountId, missionId, startTime) VALUES (?,?,?);";
private static final String INCREMENT_PROGRESS = "UPDATE accountMissions SET progress=progress+{0} WHERE accountId={1} AND missionId={2};";
private static final String COMPLETE_QUEST = "UPDATE accountMissions SET complete=1 WHERE accountId=? AND missionId=?;";
private static final String CLEAR_PROGRESS = "DELETE FROM accountMissions WHERE accountId=? AND missionId=?";
private final List<MissionQuery> _queries;
MissionRepository()
{
super(DBPool.getAccount());
_queries = new ArrayList<>();
}
public boolean startMission(int accountId, int missionId)
{
return accountId != -1 && executeInsert(START_QUEST, null,
new ColumnInt("accountId", accountId),
new ColumnInt("missionId", missionId)
new ColumnInt("missionId", missionId),
new ColumnLong("startTime", System.currentTimeMillis())
) > 0;
}
public boolean incrementProgress(int accountId, int missionId, int progress)
public void incrementProgress(MissionQuery query)
{
return accountId != -1 && executeUpdate(INCREMENT_PROGRESS,
new ColumnInt("progress", progress),
new ColumnInt("accountId", accountId),
new ColumnInt("missionId", missionId)
) > 0;
if (query._accountId == -1)
{
return;
}
_queries.add(query);
}
public void bulkProcess()
{
if (_queries.isEmpty())
{
return;
}
String sqlQuery = _queries.stream()
.map(query -> query._query)
.collect(Collectors.joining(""));
if (executeUpdate(sqlQuery) > 0)
{
_queries.forEach(query -> query._callback.run());
}
_queries.clear();
}
public boolean completeQuest(int accountId, int missionId)
@ -49,4 +79,21 @@ public class MissionRepository extends RepositoryBase
new ColumnInt("missionId", missionId)
) > 0;
}
static class MissionQuery
{
private final String _query;
private final int _accountId;
private final Runnable _callback;
MissionQuery(int accountId, Mission mission, int progress, Runnable callback)
{
_query = INCREMENT_PROGRESS
.replace("{0}", String.valueOf(progress))
.replace("{1}", String.valueOf(accountId))
.replace("{2}", String.valueOf(mission.getId()));
_accountId = accountId;
_callback = callback;
}
}
}

View File

@ -0,0 +1,23 @@
package mineplex.core.mission.commands;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.util.F;
import mineplex.core.mission.MissionManager;
import mineplex.core.mission.MissionManager.Perm;
public class DebugMissionCommand extends CommandBase<MissionManager>
{
public DebugMissionCommand(MissionManager plugin)
{
super(plugin, Perm.DEBUG_MISSION_COMMAND, "missiondebug");
}
@Override
public void Execute(Player caller, String[] args)
{
caller.sendMessage(F.main(Plugin.getName(), "Mission Debug: " + F.ed(Plugin.toggleDebug())));
}
}

View File

@ -22,7 +22,7 @@ public class MissionMainPage extends ShopPageBase<MissionManager, MissionShop>
MissionMainPage(MissionManager plugin, MissionShop shop, Player player)
{
super(plugin, shop, plugin.getClientManager(), plugin.getDonationManager(), "Missions", player, 27);
super(plugin, shop, plugin.getClientManager(), plugin.getDonationManager(), "Missions", player, 36);
buildPage();
}
@ -30,7 +30,7 @@ public class MissionMainPage extends ShopPageBase<MissionManager, MissionShop>
@Override
protected void buildPage()
{
int slot = 10;
int row = 0, column = 0;
MissionClient client = _plugin.Get(getPlayer());
Set<Mission> questsSet = client.getAllQuests().keySet();
@ -55,7 +55,7 @@ public class MissionMainPage extends ShopPageBase<MissionManager, MissionShop>
int progress = client.getProgress(mission);
ItemBuilder builder = new ItemBuilder(Material.PAPER)
.setTitle(C.mHead + mission.getName() + C.mBody + " (" + mission.getLength().getName() + ")")
.setTitle(mission.getLength().getChatColour() + mission.getName() + C.mBody + " (" + mission.getLength().getName() + ")")
.addLore(mission.getDescription(), "");
mission.getRewards().forEach(reward ->
@ -83,16 +83,21 @@ public class MissionMainPage extends ShopPageBase<MissionManager, MissionShop>
builder.addLore(C.cGreen + "You have completed this mission");
}
if (lastLength == null)
if (lastLength == null || lastLength != mission.getLength())
{
lastLength = mission.getLength();
}
else if (lastLength != mission.getLength())
{
slot++;
row++;
column = 0;
addButtonNoAction(getSlot(row, column), new ItemBuilder(Material.STAINED_GLASS_PANE, lastLength.getColourData())
.setTitle(lastLength.getChatColour() + lastLength.getName())
.build());
column = 2;
}
addButtonNoAction(slot++, builder.build());
addButtonNoAction(getSlot(row, column++), builder.build());
}
}
}

View File

@ -7,7 +7,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -197,11 +196,8 @@ public class GameTeamModule extends Module
{
_preferences.forEach((player, preference) ->
{
Bukkit.broadcastMessage(player.getName() + " = " + preference.getDisplayName());
if (getGame().getTeamSelector().canJoinTeam(preference, 1, target, total))
{
Bukkit.broadcastMessage("Set!");
getGame().SetPlayerTeam(player, preference, true);
}
});

View File

@ -11,6 +11,7 @@ import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import mineplex.core.account.permissions.Permission;
import mineplex.core.account.permissions.PermissionGroup;
import mineplex.core.command.CommandBase;
import mineplex.core.command.ICommand;
import mineplex.core.common.jsonchat.ClickEvent;
@ -87,6 +88,7 @@ public class TeamRequestsModule extends Module
}
};
PermissionGroup.PLAYER.setPermission(Perm.TEAM_COMMAND, true, true);
getGame().getArcadeManager().addCommand(_teamCommand);
getGame().getTeamModule().setPrioritisePreferences(true);
}

View File

@ -3,18 +3,17 @@ package nautilus.game.arcade.game.team.selectors;
import java.util.Comparator;
import java.util.List;
import org.bukkit.Bukkit;
import nautilus.game.arcade.game.Game;
import nautilus.game.arcade.game.GameTeam;
public class FillToSelector extends EvenTeamSelector
{
private final int _amount;
public FillToSelector(Game game, int amount)
{
_amount = amount;
game.getTeamModule().setPlayersPerTeam(_amount);
game.getTeamModule().setPlayersPerTeam(amount);
}
@Override
@ -26,6 +25,10 @@ public class FillToSelector extends EvenTeamSelector
.max(Comparator.comparingInt(GameTeam::GetSize))
.orElse(null);
teams.stream()
.filter(team -> canJoinTeam(team, desiredAmount, target, total))
.forEach(team -> Bukkit.broadcastMessage(team.getDisplayName()));
if (primaryChoice != null)
{
return primaryChoice;
@ -35,10 +38,4 @@ public class FillToSelector extends EvenTeamSelector
// Just get the emptiest team.
return super.getTeamToJoin(teams, desiredAmount, target, total);
}
@Override
public boolean canJoinTeam(GameTeam team, int desiredAmount, int target, int total)
{
return team.GetSize() + desiredAmount <= _amount;
}
}