Merge missions from JR
This commit is contained in:
parent
c24f799503
commit
4da27da27b
177
Plugins/Mineplex.Core/src/mineplex/core/mission/Mission.java
Normal file
177
Plugins/Mineplex.Core/src/mineplex/core/mission/Mission.java
Normal file
@ -0,0 +1,177 @@
|
||||
package mineplex.core.mission;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import mineplex.core.mission.trackers.BlockBreakTracker;
|
||||
import mineplex.core.reward.Reward;
|
||||
|
||||
public class Mission<T>
|
||||
{
|
||||
|
||||
private final int _id;
|
||||
private final String _name;
|
||||
private final MissionLength _length;
|
||||
private final int _requiredProgress;
|
||||
private final String _statName;
|
||||
private final T _data;
|
||||
private final List<Reward> _rewards;
|
||||
private final String _description;
|
||||
|
||||
private Mission(int id, String name, MissionLength length, int requiredProgress, String statName, T data, List<Reward> rewards, String description)
|
||||
{
|
||||
_id = id;
|
||||
_name = name;
|
||||
_length = length;
|
||||
_requiredProgress = requiredProgress;
|
||||
_statName = statName;
|
||||
_data = data;
|
||||
_rewards = rewards;
|
||||
_description = String.format(description, requiredProgress);
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
public MissionLength getLength()
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
|
||||
public String getStatName()
|
||||
{
|
||||
return _statName;
|
||||
}
|
||||
|
||||
public int getRequiredProgress()
|
||||
{
|
||||
return _requiredProgress;
|
||||
}
|
||||
|
||||
public boolean validateData(T data)
|
||||
{
|
||||
return _data == null || _data.equals(data);
|
||||
}
|
||||
|
||||
public List<Reward> getRewards()
|
||||
{
|
||||
return _rewards;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return _description;
|
||||
}
|
||||
|
||||
public boolean isComplete(int progress)
|
||||
{
|
||||
return progress >= getRequiredProgress();
|
||||
}
|
||||
|
||||
public static <T> QuestBuilder<T> newBuilder(MissionManager manager, int id)
|
||||
{
|
||||
return new QuestBuilder<>(manager, id);
|
||||
}
|
||||
|
||||
public static final class QuestBuilder<T>
|
||||
{
|
||||
|
||||
private final MissionManager _manager;
|
||||
private final int _id;
|
||||
|
||||
private String _name;
|
||||
private MissionLength _length;
|
||||
private int _requiredProgress;
|
||||
private MissionTracker _tracker;
|
||||
private T _data;
|
||||
private final List<Reward> _rewards;
|
||||
private String _description;
|
||||
|
||||
private QuestBuilder(MissionManager manager, int id)
|
||||
{
|
||||
_manager = manager;
|
||||
_id = id;
|
||||
_rewards = new ArrayList<>(2);
|
||||
}
|
||||
|
||||
public QuestBuilder<T> name(String name)
|
||||
{
|
||||
_name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuestBuilder<T> length(MissionLength length)
|
||||
{
|
||||
_length = length;
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuestBuilder<T> requiredProgress(int requiredProgress)
|
||||
{
|
||||
_requiredProgress = requiredProgress;
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuestBuilder<T> trackBlockBreak()
|
||||
{
|
||||
_tracker = _manager.getTracker(BlockBreakTracker.class);
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuestBuilder<T> trackData(T data)
|
||||
{
|
||||
_data = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuestBuilder<T> rewards(Reward... rewards)
|
||||
{
|
||||
_rewards.addAll(Arrays.asList(rewards));
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuestBuilder<T> description(String description)
|
||||
{
|
||||
_description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void build()
|
||||
{
|
||||
if (_name == null || _name.isEmpty())
|
||||
{
|
||||
throw new IllegalStateException("The name cannot be null or empty! Mission [" + _id + "]");
|
||||
}
|
||||
else if (_length == null)
|
||||
{
|
||||
throw new IllegalStateException("The length cannot be null! Mission [" + _id + "]");
|
||||
}
|
||||
else if (_requiredProgress <= 0)
|
||||
{
|
||||
throw new IllegalStateException("The required progress must be greater than 0! Mission [" + _id + "]");
|
||||
}
|
||||
else if (_tracker == null)
|
||||
{
|
||||
throw new IllegalStateException("The tracker cannot be null! Mission [" + _id + "]");
|
||||
}
|
||||
else if (_rewards.isEmpty())
|
||||
{
|
||||
throw new IllegalStateException("The rewards cannot be empty! Mission [" + _id + "]");
|
||||
}
|
||||
else if (_description == null || _description.isEmpty())
|
||||
{
|
||||
throw new IllegalStateException("The description cannot be null or empty! Mission [" + _id + "]");
|
||||
}
|
||||
|
||||
_manager.addQuest(new Mission<>(_id, _name, _length, _requiredProgress, _tracker.getStatName(), _data, _rewards, _description));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
package mineplex.core.mission;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class MissionClient
|
||||
{
|
||||
|
||||
private final Map<Mission, Integer> _progress, _unsavedProgress;
|
||||
private final Set<Mission> _completed;
|
||||
|
||||
MissionClient()
|
||||
{
|
||||
_progress = new HashMap<>();
|
||||
_unsavedProgress = new HashMap<>();
|
||||
_completed = new HashSet<>();
|
||||
}
|
||||
|
||||
void startMission(Mission mission, int startingAmount)
|
||||
{
|
||||
if (mission.isComplete(startingAmount))
|
||||
{
|
||||
_completed.add(mission);
|
||||
}
|
||||
else
|
||||
{
|
||||
_progress.put(mission, startingAmount);
|
||||
}
|
||||
}
|
||||
|
||||
void completeQuest(Mission mission)
|
||||
{
|
||||
_progress.remove(mission);
|
||||
_completed.add(mission);
|
||||
}
|
||||
|
||||
public <T> boolean canProgress(Mission<T> mission, T data)
|
||||
{
|
||||
return _progress.containsKey(mission) && mission.validateData(data);
|
||||
}
|
||||
|
||||
public <T> int incrementProgress(Mission<T> mission, int amount, boolean unsaved)
|
||||
{
|
||||
int previousAmount = getProgress(mission) + incrementMap(_unsavedProgress, mission, amount);
|
||||
|
||||
if (unsaved && isAtPercentage(previousAmount, amount, mission.getRequiredProgress(), 1))
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
if (isAtPercentage(previousAmount, amount, mission.getRequiredProgress(), 0.75))
|
||||
{
|
||||
return 75;
|
||||
}
|
||||
else if (isAtPercentage(previousAmount, amount, mission.getRequiredProgress(), 0.5))
|
||||
{
|
||||
return 50;
|
||||
}
|
||||
else if (isAtPercentage(previousAmount, amount, mission.getRequiredProgress(), 0.25))
|
||||
{
|
||||
return 25;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int incrementMap(Map<Mission, Integer> map, Mission mission, int amount)
|
||||
{
|
||||
int newAmount = map.getOrDefault(mission, 0) + amount;
|
||||
map.put(mission, newAmount);
|
||||
return newAmount;
|
||||
}
|
||||
|
||||
private boolean isAtPercentage(int previous, int amount, int max, double percent)
|
||||
{
|
||||
double previousPercent = (double) previous / max, nowPercent = (double) (previous + amount) / max;
|
||||
|
||||
return previousPercent < percent && nowPercent >= percent;
|
||||
}
|
||||
|
||||
public Map<Mission, Integer> saveProgress()
|
||||
{
|
||||
Map<Mission, Integer> unsaved = new HashMap<>(_unsavedProgress);
|
||||
|
||||
_unsavedProgress.forEach((mission, progress) -> incrementMap(_progress, mission, progress));
|
||||
clearUnsavedProgress();
|
||||
|
||||
return unsaved;
|
||||
}
|
||||
|
||||
public void clearUnsavedProgress()
|
||||
{
|
||||
_unsavedProgress.clear();
|
||||
}
|
||||
|
||||
public int getProgress(Mission mission)
|
||||
{
|
||||
return _progress.getOrDefault(mission, -1);
|
||||
}
|
||||
|
||||
public boolean isComplete(Mission mission)
|
||||
{
|
||||
return _completed.contains(mission);
|
||||
}
|
||||
|
||||
public boolean isActive(Mission mission)
|
||||
{
|
||||
return _progress.containsKey(mission) || isComplete(mission);
|
||||
}
|
||||
|
||||
public Map<Mission, Integer> getAllQuests()
|
||||
{
|
||||
Map<Mission, Integer> quests = new HashMap<>(_progress);
|
||||
|
||||
_completed.forEach(mission -> quests.put(mission, mission.getRequiredProgress()));
|
||||
|
||||
return quests;
|
||||
}
|
||||
|
||||
public int getMissionsOf(MissionLength length)
|
||||
{
|
||||
return (int) getAllQuests().keySet().stream()
|
||||
.map(Mission::getLength)
|
||||
.filter(other -> other == length)
|
||||
.count();
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package mineplex.core.mission;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
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);
|
||||
|
||||
private final String _name, _resetInfo;
|
||||
private final int _calendarField;
|
||||
|
||||
MissionLength(String name, String resetInfo, int calendarField)
|
||||
{
|
||||
_name = name;
|
||||
_resetInfo = resetInfo;
|
||||
_calendarField = calendarField;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
public String getResetInfo()
|
||||
{
|
||||
return _resetInfo;
|
||||
}
|
||||
|
||||
public int getCalendarField()
|
||||
{
|
||||
return _calendarField;
|
||||
}
|
||||
}
|
@ -0,0 +1,346 @@
|
||||
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.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Slime;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
||||
import mineplex.core.MiniDbClientPlugin;
|
||||
import mineplex.core.ReflectivelyCreateMiniPlugin;
|
||||
import mineplex.core.account.permissions.Permission;
|
||||
import mineplex.core.account.permissions.PermissionGroup;
|
||||
import mineplex.core.common.util.C;
|
||||
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.commands.StartMissionCommand;
|
||||
import mineplex.core.mission.ui.MissionShop;
|
||||
import mineplex.core.newnpc.NPC;
|
||||
import mineplex.core.newnpc.NewNPCManager;
|
||||
import mineplex.core.newnpc.SimpleNPC;
|
||||
import mineplex.core.newnpc.event.NPCInteractEvent;
|
||||
|
||||
@ReflectivelyCreateMiniPlugin
|
||||
public class MissionManager extends MiniDbClientPlugin<MissionClient>
|
||||
{
|
||||
|
||||
public enum Perm implements Permission
|
||||
{
|
||||
START_MISSION_COMMAND
|
||||
}
|
||||
|
||||
private static final String NPC_METADATA = "MISSION_NPC";
|
||||
|
||||
private final DonationManager _donationManager;
|
||||
|
||||
private final List<Mission> _missions;
|
||||
private final Set<MissionTracker> _missionTrackers;
|
||||
private final MissionRepository _repository;
|
||||
private final MissionShop _shop;
|
||||
|
||||
private boolean _requireManualSaving;
|
||||
|
||||
private MissionManager()
|
||||
{
|
||||
super("Mission");
|
||||
|
||||
_donationManager = require(DonationManager.class);
|
||||
|
||||
_missions = new ArrayList<>();
|
||||
_missionTrackers = new HashSet<>();
|
||||
_repository = new MissionRepository();
|
||||
_shop = new MissionShop(this);
|
||||
|
||||
populateTrackers();
|
||||
|
||||
generatePermissions();
|
||||
|
||||
runSyncTimer(this::processUnsavedProgress, 20, 60);
|
||||
}
|
||||
|
||||
private void generatePermissions()
|
||||
{
|
||||
PermissionGroup.ADMIN.setPermission(Perm.START_MISSION_COMMAND, true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCommands()
|
||||
{
|
||||
addCommand(new StartMissionCommand(this));
|
||||
}
|
||||
|
||||
private void populateTrackers()
|
||||
{
|
||||
addTracker();
|
||||
}
|
||||
|
||||
void addQuest(Mission mission)
|
||||
{
|
||||
_missions.add(mission);
|
||||
}
|
||||
|
||||
private void addTracker(MissionTracker... trackers)
|
||||
{
|
||||
for (MissionTracker tracker : trackers)
|
||||
{
|
||||
registerEvents(tracker);
|
||||
_missionTrackers.add(tracker);
|
||||
}
|
||||
}
|
||||
|
||||
public void setRequireManualSaving(boolean requireManualSaving)
|
||||
{
|
||||
_requireManualSaving = requireManualSaving;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException
|
||||
{
|
||||
MissionClient client = Get(uuid);
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
|
||||
while (resultSet.next())
|
||||
{
|
||||
int missionId = resultSet.getInt("missionId");
|
||||
int progress = resultSet.getInt("progress");
|
||||
Timestamp startTime = resultSet.getTimestamp("startTime");
|
||||
|
||||
Mission mission = getMission(missionId);
|
||||
|
||||
if (mission == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int lengthField = mission.getLength().getCalendarField();
|
||||
|
||||
if (lengthField == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Calendar start = Calendar.getInstance();
|
||||
start.setTimeInMillis(startTime.getTime());
|
||||
|
||||
if (calendar.get(lengthField) != start.get(lengthField))
|
||||
{
|
||||
runAsync(() -> _repository.clearProgress(accountId, missionId));
|
||||
}
|
||||
else
|
||||
{
|
||||
client.startMission(mission, progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MissionClient addPlayer(UUID uuid)
|
||||
{
|
||||
return new MissionClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuery(int accountId, String uuid, String name)
|
||||
{
|
||||
return "SELECT * FROM accountMissions WHERE accountId=" + accountId + ";";
|
||||
}
|
||||
|
||||
public void startMission(Player player, Mission mission)
|
||||
{
|
||||
runAsync(() ->
|
||||
{
|
||||
if (_repository.startMission(ClientManager.getAccountId(player), mission.getId()))
|
||||
{
|
||||
Get(player).startMission(mission, 0);
|
||||
player.sendMessage(F.main(getName(), "Started a new " + F.name(mission.getLength().getName()) + " mission! " + F.name(mission.getName()) + "."));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void completeMission(Player player, Mission<?> mission)
|
||||
{
|
||||
MissionClient client = Get(player);
|
||||
|
||||
if (client.isComplete(mission))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player.sendMessage("");
|
||||
player.sendMessage(" " + C.mHead + C.Bold + mission.getLength().getName() + " Mission Complete! " + C.mBody + C.Bold + mission.getName());
|
||||
player.sendMessage(" " + C.cGray + mission.getDescription());
|
||||
player.sendMessage("");
|
||||
|
||||
mission.getRewards().forEach(reward -> reward.giveReward(player, data ->
|
||||
{
|
||||
String message = data.getRarity().getColor() + data.getFriendlyName();
|
||||
|
||||
if (data.getHeader() == null)
|
||||
{
|
||||
message = data.getRarity().getDarkColor() + "> " + message;
|
||||
}
|
||||
|
||||
player.sendMessage(" " + message);
|
||||
}));
|
||||
|
||||
player.sendMessage("");
|
||||
player.playSound(player.getLocation(), Sound.LEVEL_UP, 1, (float) Math.random());
|
||||
|
||||
client.completeQuest(mission);
|
||||
runAsync(() -> _repository.completeQuest(ClientManager.getAccountId(player), mission.getId()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> void incrementProgress(Player player, int amount, String statName, T data)
|
||||
{
|
||||
MissionClient client = Get(player);
|
||||
|
||||
applyForMissions(mission ->
|
||||
{
|
||||
if (!client.canProgress(mission, data))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int percentage = client.incrementProgress(mission, amount, _requireManualSaving);
|
||||
|
||||
if (percentage > 0)
|
||||
{
|
||||
player.sendMessage(F.main(getName(), F.name(mission.getName()) + " mission is " + F.count(percentage + "%") + " complete."));
|
||||
}
|
||||
}, statName);
|
||||
}
|
||||
|
||||
// TODO this may not be good enough. might have to bulk query or change implementation?
|
||||
private void processUnsavedProgress()
|
||||
{
|
||||
for (Player player : UtilServer.getPlayersCollection())
|
||||
{
|
||||
selectNewMissions(player);
|
||||
|
||||
if (!_requireManualSaving)
|
||||
{
|
||||
saveProgress(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void selectNewMissions(Player player)
|
||||
{
|
||||
MissionClient client = Get(player);
|
||||
|
||||
selectNewMissions(player, client, MissionLength.DAY, 3);
|
||||
selectNewMissions(player, client, MissionLength.WEEK, 2);
|
||||
}
|
||||
|
||||
private void selectNewMissions(Player player, MissionClient client, MissionLength length, int max)
|
||||
{
|
||||
int current = client.getMissionsOf(length);
|
||||
|
||||
if (current >= max)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Mission> missions = getMissionsOf(length);
|
||||
missions.removeIf(client::isActive);
|
||||
|
||||
for (int i = current; i <= max; i++)
|
||||
{
|
||||
Mission mission = UtilAlg.Random(missions);
|
||||
|
||||
if (mission == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
missions.remove(mission);
|
||||
startMission(player, mission);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Mission> getMissionsOf(MissionLength length)
|
||||
{
|
||||
return _missions.stream()
|
||||
.filter(mission -> mission.getLength() != length)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void saveProgress(Player player)
|
||||
{
|
||||
MissionClient client = Get(player);
|
||||
Map<Mission, Integer> unsaved = client.saveProgress();
|
||||
|
||||
if (unsaved.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int accountId = ClientManager.getAccountId(player);
|
||||
|
||||
runAsync(() -> unsaved.forEach((mission, progress) ->
|
||||
{
|
||||
if (_repository.incrementProgress(accountId, mission.getId(), progress) && mission.isComplete(client.getProgress(mission)))
|
||||
{
|
||||
runSync(() -> completeMission(player, mission));
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private void applyForMissions(Consumer<Mission> function, String statName)
|
||||
{
|
||||
_missions.stream()
|
||||
.filter(mission -> mission.getStatName().equals(statName))
|
||||
.forEach(function);
|
||||
}
|
||||
|
||||
public Mission getMission(int id)
|
||||
{
|
||||
return _missions.stream()
|
||||
.filter(mission -> mission.getId() == id)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public void createNPC(NewNPCManager manager, Location location)
|
||||
{
|
||||
NPC npc = SimpleNPC.of(location, Slime.class, NPC_METADATA);
|
||||
|
||||
manager.addNPC(npc);
|
||||
|
||||
LivingEntity entity = npc.getEntity();
|
||||
|
||||
entity.setCustomName(C.mElem + C.Bold + "Señor Missions");
|
||||
entity.setCustomNameVisible(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void npcInteract(NPCInteractEvent event)
|
||||
{
|
||||
if (event.getNpc().getMetadata().equals(NPC_METADATA))
|
||||
{
|
||||
_shop.attemptShopOpen(event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
public DonationManager getDonationManager()
|
||||
{
|
||||
return _donationManager;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package mineplex.core.mission;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
public class MissionPopulator
|
||||
{
|
||||
|
||||
public static void populateMissions(MissionManager manager)
|
||||
{
|
||||
Mission.<Material>newBuilder(manager, 1)
|
||||
.name("Wood Collector")
|
||||
.description("Cut %s Logs")
|
||||
.length(MissionLength.DAY)
|
||||
.requiredProgress(10)
|
||||
.trackBlockBreak()
|
||||
.trackData(Material.LOG)
|
||||
.rewards()
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package mineplex.core.mission;
|
||||
|
||||
import mineplex.serverdata.database.DBPool;
|
||||
import mineplex.serverdata.database.RepositoryBase;
|
||||
import mineplex.serverdata.database.column.ColumnInt;
|
||||
|
||||
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 COMPLETE_QUEST = "UPDATE accountMissions SET complete=1 WHERE accountId=? AND missionId=?;";
|
||||
private static final String CLEAR_PROGRESS = "DELETE FROM accountMissions WHERE accountId=? AND missionId=?";
|
||||
|
||||
MissionRepository()
|
||||
{
|
||||
super(DBPool.getAccount());
|
||||
}
|
||||
|
||||
public boolean startMission(int accountId, int missionId)
|
||||
{
|
||||
return accountId != -1 && executeInsert(START_QUEST, null,
|
||||
new ColumnInt("accountId", accountId),
|
||||
new ColumnInt("missionId", missionId)
|
||||
) > 0;
|
||||
}
|
||||
|
||||
public boolean incrementProgress(int accountId, int missionId, int progress)
|
||||
{
|
||||
return accountId != -1 && executeUpdate(INCREMENT_PROGRESS,
|
||||
new ColumnInt("progress", progress),
|
||||
new ColumnInt("accountId", accountId),
|
||||
new ColumnInt("missionId", missionId)
|
||||
) > 0;
|
||||
}
|
||||
|
||||
public boolean completeQuest(int accountId, int missionId)
|
||||
{
|
||||
return accountId != -1 && executeUpdate(COMPLETE_QUEST,
|
||||
new ColumnInt("accountId", accountId),
|
||||
new ColumnInt("missionId", missionId)
|
||||
) > 0;
|
||||
}
|
||||
|
||||
public boolean clearProgress(int accountId, int missionId)
|
||||
{
|
||||
return accountId != -1 && executeUpdate(CLEAR_PROGRESS,
|
||||
new ColumnInt("accountId", accountId),
|
||||
new ColumnInt("missionId", missionId)
|
||||
) > 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package mineplex.core.mission;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public class MissionTracker<T> implements Listener
|
||||
{
|
||||
|
||||
protected final MissionManager _manager;
|
||||
private final String _statName;
|
||||
|
||||
public MissionTracker(MissionManager manager, String statName)
|
||||
{
|
||||
_manager = manager;
|
||||
_statName = statName;
|
||||
}
|
||||
|
||||
protected void incrementProgress(Player player, int amount, T data)
|
||||
{
|
||||
_manager.incrementProgress(player, amount, _statName, data);
|
||||
}
|
||||
|
||||
public String getStatName()
|
||||
{
|
||||
return _statName;
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
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.Mission;
|
||||
import mineplex.core.mission.MissionManager;
|
||||
import mineplex.core.mission.MissionManager.Perm;
|
||||
|
||||
public class StartMissionCommand extends CommandBase<MissionManager>
|
||||
{
|
||||
|
||||
public StartMissionCommand(MissionManager plugin)
|
||||
{
|
||||
super(plugin, Perm.START_MISSION_COMMAND, "startmission");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
if (args.length < 1)
|
||||
{
|
||||
caller.sendMessage(F.main(Plugin.getName(), "/" + _aliasUsed + " <id>"));
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
int id = Integer.parseInt(args[0]);
|
||||
Mission mission = Plugin.getMission(id);
|
||||
|
||||
if (mission == null)
|
||||
{
|
||||
caller.sendMessage(F.main(Plugin.getName(), "That is not a valid mission id."));
|
||||
return;
|
||||
}
|
||||
|
||||
Plugin.startMission(caller, mission);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
caller.sendMessage(F.main(Plugin.getName(), F.elem(args[0]) + " is not a number."));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package mineplex.core.mission.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.itemstack.ItemBuilder;
|
||||
import mineplex.core.mission.Mission;
|
||||
import mineplex.core.mission.MissionClient;
|
||||
import mineplex.core.mission.MissionLength;
|
||||
import mineplex.core.mission.MissionManager;
|
||||
import mineplex.core.reward.rewards.QuantifiableReward;
|
||||
import mineplex.core.reward.RewardData;
|
||||
import mineplex.core.shop.page.ShopPageBase;
|
||||
|
||||
public class MissionMainPage extends ShopPageBase<MissionManager, MissionShop>
|
||||
{
|
||||
|
||||
MissionMainPage(MissionManager plugin, MissionShop shop, Player player)
|
||||
{
|
||||
super(plugin, shop, plugin.getClientManager(), plugin.getDonationManager(), "Missions", player, 27);
|
||||
|
||||
buildPage();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void buildPage()
|
||||
{
|
||||
int slot = 10;
|
||||
MissionClient client = _plugin.Get(getPlayer());
|
||||
|
||||
Set<Mission> questsSet = client.getAllQuests().keySet();
|
||||
List<Mission> questSorted = new ArrayList<>(questsSet);
|
||||
|
||||
questSorted.sort((o1, o2) ->
|
||||
{
|
||||
int primaryComp = o1.getLength().compareTo(o2.getLength());
|
||||
|
||||
if (primaryComp != 0)
|
||||
{
|
||||
return primaryComp;
|
||||
}
|
||||
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
});
|
||||
|
||||
MissionLength lastLength = null;
|
||||
|
||||
for (Mission<?> mission : questSorted)
|
||||
{
|
||||
int progress = client.getProgress(mission);
|
||||
|
||||
ItemBuilder builder = new ItemBuilder(Material.PAPER)
|
||||
.setTitle(C.mHead + mission.getName() + C.mBody + " (" + mission.getLength().getName() + ")")
|
||||
.addLore(mission.getDescription(), "");
|
||||
|
||||
mission.getRewards().forEach(reward ->
|
||||
{
|
||||
RewardData rewardData = reward.getFakeRewardData(getPlayer());
|
||||
String amount = "";
|
||||
|
||||
if (reward instanceof QuantifiableReward)
|
||||
{
|
||||
amount = ((QuantifiableReward) reward).getQuantity() + " ";
|
||||
}
|
||||
|
||||
builder.addLore(C.mBody + " - " + rewardData.getRarity().getColor() + amount + rewardData.getFriendlyName());
|
||||
});
|
||||
|
||||
builder.addLore("", mission.getLength().getResetInfo(), "");
|
||||
|
||||
if (!client.isComplete(mission))
|
||||
{
|
||||
builder.setGlow(true);
|
||||
builder.addLore(F.property("Progress", C.mCount + progress + C.Reset + "/" + C.mCount + mission.getRequiredProgress()));
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.addLore(C.cGreen + "You have completed this mission");
|
||||
}
|
||||
|
||||
if (lastLength == null)
|
||||
{
|
||||
lastLength = mission.getLength();
|
||||
}
|
||||
else if (lastLength != mission.getLength())
|
||||
{
|
||||
slot++;
|
||||
}
|
||||
|
||||
addButtonNoAction(slot++, builder.build());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package mineplex.core.mission.ui;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.mission.MissionManager;
|
||||
import mineplex.core.shop.ShopBase;
|
||||
import mineplex.core.shop.page.ShopPageBase;
|
||||
|
||||
public class MissionShop extends ShopBase<MissionManager>
|
||||
{
|
||||
|
||||
public MissionShop(MissionManager plugin)
|
||||
{
|
||||
super(plugin, plugin.getClientManager(), plugin.getDonationManager(), "Mission");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ShopPageBase<MissionManager, ? extends ShopBase<MissionManager>> buildPagesFor(Player player)
|
||||
{
|
||||
return new MissionMainPage(getPlugin(), this, player);
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ import mineplex.core.reward.RewardData;
|
||||
import mineplex.core.stats.StatsManager;
|
||||
import mineplex.core.treasure.reward.RewardRarity;
|
||||
|
||||
public class ExperienceReward extends Reward
|
||||
public class ExperienceReward extends Reward implements QuantifiableReward
|
||||
{
|
||||
|
||||
private static final StatsManager STATS_MANAGER = Managers.require(StatsManager.class);
|
||||
@ -53,4 +53,10 @@ public class ExperienceReward extends Reward
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQuantity()
|
||||
{
|
||||
return _minExperience;
|
||||
}
|
||||
}
|
||||
|
@ -5,16 +5,16 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import mineplex.core.common.currency.GlobalCurrency;
|
||||
import mineplex.core.treasure.reward.RewardRarity;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.reward.Reward;
|
||||
import mineplex.core.reward.RewardData;
|
||||
import mineplex.core.reward.RewardType;
|
||||
import mineplex.core.treasure.reward.RewardRarity;
|
||||
|
||||
public class GemReward extends Reward
|
||||
public class GemReward extends Reward implements QuantifiableReward
|
||||
{
|
||||
|
||||
private int _minGemCount;
|
||||
private int _maxGemCount;
|
||||
private final int _minGemCount;
|
||||
private final int _maxGemCount;
|
||||
|
||||
public GemReward(int minGemCount, int maxGemCount, int shardValue, RewardRarity rarity)
|
||||
{
|
||||
@ -27,11 +27,19 @@ public class GemReward extends Reward
|
||||
@Override
|
||||
public RewardData giveRewardCustom(Player player)
|
||||
{
|
||||
int gemsToReward = RANDOM.nextInt(_maxGemCount - _minGemCount) + _minGemCount;
|
||||
int gems;
|
||||
|
||||
DONATION_MANAGER.rewardCurrency(GlobalCurrency.GEM, player, "Treasure Chest", gemsToReward);
|
||||
if (_minGemCount == _maxGemCount)
|
||||
{
|
||||
gems = _minGemCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
gems = UtilMath.rRange(_minGemCount, _maxGemCount);
|
||||
}
|
||||
DONATION_MANAGER.rewardCurrency(GlobalCurrency.GEM, player, "Treasure Chest", gems);
|
||||
|
||||
return new RewardData(null, getRarity().getColor() + gemsToReward + " Gems", new ItemStack(Material.EMERALD), getRarity());
|
||||
return new RewardData(null, getRarity().getColor() + gems + " Gems", new ItemStack(Material.EMERALD), getRarity());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -51,4 +59,10 @@ public class GemReward extends Reward
|
||||
{
|
||||
return obj instanceof GemReward;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQuantity()
|
||||
{
|
||||
return _minGemCount;
|
||||
}
|
||||
}
|
||||
|
@ -7,15 +7,15 @@ import mineplex.core.reward.Reward;
|
||||
import mineplex.core.reward.RewardData;
|
||||
import mineplex.core.treasure.reward.RewardRarity;
|
||||
|
||||
public class InventoryReward extends Reward
|
||||
public class InventoryReward extends Reward implements QuantifiableReward
|
||||
{
|
||||
|
||||
private ItemStack _itemStack;
|
||||
private String _name;
|
||||
private String _packageName;
|
||||
private String _header;
|
||||
private int _minAmount;
|
||||
private int _maxAmount;
|
||||
private final ItemStack _itemStack;
|
||||
private final String _name;
|
||||
private final String _packageName;
|
||||
private final String _header;
|
||||
private final int _minAmount;
|
||||
private final int _maxAmount;
|
||||
|
||||
public InventoryReward(String name, String packageName, String header, ItemStack itemStack, RewardRarity rarity, int shardValue)
|
||||
{
|
||||
@ -91,4 +91,10 @@ public class InventoryReward extends Reward
|
||||
{
|
||||
return _packageName.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQuantity()
|
||||
{
|
||||
return _minAmount;
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package mineplex.core.reward.rewards;
|
||||
|
||||
public interface QuantifiableReward
|
||||
{
|
||||
|
||||
int getQuantity();
|
||||
|
||||
}
|
@ -16,7 +16,7 @@ import mineplex.core.reward.RewardData;
|
||||
import mineplex.core.treasure.reward.RewardRarity;
|
||||
import mineplex.serverdata.database.DBPool;
|
||||
|
||||
public class SpinTicketReward extends Reward
|
||||
public class SpinTicketReward extends Reward implements QuantifiableReward
|
||||
{
|
||||
|
||||
private static final ItemStack ITEM_STACK = new ItemStack(Material.PAPER);
|
||||
@ -102,4 +102,10 @@ public class SpinTicketReward extends Reward
|
||||
{
|
||||
return getClass().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQuantity()
|
||||
{
|
||||
return _min;
|
||||
}
|
||||
}
|
@ -12,14 +12,14 @@ import mineplex.core.reward.Reward;
|
||||
import mineplex.core.reward.RewardData;
|
||||
import mineplex.core.treasure.reward.RewardRarity;
|
||||
|
||||
public class TreasureShardReward extends Reward
|
||||
public class TreasureShardReward extends Reward implements QuantifiableReward
|
||||
{
|
||||
|
||||
private static final ItemStack ITEM_STACK = new ItemStack(Material.PRISMARINE_SHARD);
|
||||
|
||||
private Reward _otherReward;
|
||||
private int _shardsMin = 0;
|
||||
private int _shardsMax = 0;
|
||||
private final int _shardsMin;
|
||||
private final int _shardsMax;
|
||||
|
||||
public TreasureShardReward(Reward otherReward, RewardRarity rarity)
|
||||
{
|
||||
@ -48,7 +48,16 @@ public class TreasureShardReward extends Reward
|
||||
public RewardData giveRewardCustom(Player player)
|
||||
{
|
||||
RewardData rewardData;
|
||||
final int shards = UtilMath.rRange(_shardsMin, _shardsMax);
|
||||
int shards;
|
||||
|
||||
if (_shardsMin == _shardsMax)
|
||||
{
|
||||
shards = _shardsMin;
|
||||
}
|
||||
else
|
||||
{
|
||||
shards = UtilMath.rRange(_shardsMin, _shardsMax);;
|
||||
}
|
||||
|
||||
if (_otherReward != null)
|
||||
{
|
||||
@ -85,5 +94,11 @@ public class TreasureShardReward extends Reward
|
||||
{
|
||||
return obj instanceof TreasureShardReward;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQuantity()
|
||||
{
|
||||
return _shardsMin;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user