Add ignore-block-replace quest option (#1960)

This commit is contained in:
therbz 2022-05-15 17:19:07 +01:00 committed by GitHub
parent baf377e304
commit 11612439f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 161 additions and 82 deletions

View File

@ -48,4 +48,8 @@ public interface Options {
boolean canHandleOfflinePlayers();
void setHandleOfflinePlayers(final boolean handleOfflinePlayers);
boolean canIgnoreBlockReplace();
void setIgnoreBlockReplace(final boolean ignoreBlockReplace);
}

View File

@ -2389,6 +2389,9 @@ public class Quests extends JavaPlugin implements QuestsAPI {
if (config.contains("quests." + questKey + ".options.handle-offline-players")) {
opts.setHandleOfflinePlayers(config.getBoolean("quests." + questKey + ".options.handle-offline-players"));
}
if (config.contains("quests." + questKey + ".options.ignore-block-replace")) {
opts.setIgnoreBlockReplace(config.getBoolean("quests." + questKey + ".options.ignore-block-replace"));
}
}
@SuppressWarnings({ "unchecked", "unused", "deprecation" })

View File

@ -411,7 +411,7 @@ public class OptionsPrompt extends QuestsEditorNumericPrompt {
super(context);
}
private final int size = 4;
private final int size = 5;
@Override
public int getSize() {
@ -429,8 +429,9 @@ public class OptionsPrompt extends QuestsEditorNumericPrompt {
case 1:
case 2:
case 3:
return ChatColor.BLUE;
case 4:
return ChatColor.BLUE;
case 5:
return ChatColor.GREEN;
default:
return null;
@ -447,6 +448,8 @@ public class OptionsPrompt extends QuestsEditorNumericPrompt {
case 3:
return ChatColor.YELLOW + Lang.get("optIgnoreSilkTouch");
case 4:
return ChatColor.YELLOW + Lang.get("optIgnoreBlockReplace");
case 5:
return ChatColor.YELLOW + Lang.get("done");
default:
return null;
@ -487,6 +490,16 @@ public class OptionsPrompt extends QuestsEditorNumericPrompt {
: ChatColor.RED + Lang.get("false")) + ChatColor.GRAY + ")";
}
case 4:
final Boolean ignoreBlockReplaceOpt = (Boolean) context.getSessionData(CK.OPT_IGNORE_BLOCK_REPLACE);
if (ignoreBlockReplaceOpt == null) {
final boolean defaultOpt = new BukkitOptions().canIgnoreBlockReplace();
return ChatColor.GRAY + "(" + (defaultOpt ? ChatColor.GREEN + Lang.get("true")
: ChatColor.RED + Lang.get("false")) + ChatColor.GRAY + ")";
} else {
return ChatColor.GRAY + "(" + (ignoreBlockReplaceOpt ? ChatColor.GREEN + Lang.get("true")
: ChatColor.RED + Lang.get("false")) + ChatColor.GRAY + ")";
}
case 5:
return "";
default:
return null;
@ -526,6 +539,10 @@ public class OptionsPrompt extends QuestsEditorNumericPrompt {
tempPrompt = new OptionsGeneralPrompt(context);
return new OptionsTrueFalsePrompt(context);
case 4:
tempKey = CK.OPT_IGNORE_BLOCK_REPLACE;
tempPrompt = new OptionsGeneralPrompt(context);
return new OptionsTrueFalsePrompt(context);
case 5:
tempKey = null;
tempPrompt = null;
try {

View File

@ -93,64 +93,68 @@ public class BlockListener implements Listener {
}));
}
}
if (currentStage.containsObjective(placeType)) {
for (final ItemStack is : quester.getQuestData(quest).blocksPlaced) {
if (evt.getBlock().getType().equals(is.getType()) && is.getAmount() > 0) {
ItemStack toPlace = new ItemStack(is.getType(), 64);
for (final ItemStack stack : currentStage.getBlocksToPlace()) {
if (ItemUtil.compareItems(is, stack, true) == 0) {
toPlace = stack;
}
}
final QuesterPreUpdateObjectiveEvent preEvent
= new QuesterPreUpdateObjectiveEvent(quester, quest,
new BukkitObjective(placeType, is.getAmount(), toPlace.getAmount()));
plugin.getServer().getPluginManager().callEvent(preEvent);
final int index = quester.getQuestData(quest).blocksPlaced.indexOf(is);
final int newAmount = is.getAmount() - 1;
is.setAmount(newAmount);
quester.getQuestData(quest).blocksPlaced.set(index, is);
final QuesterPostUpdateObjectiveEvent postEvent
= new QuesterPostUpdateObjectiveEvent(quester, quest,
new BukkitObjective(placeType, newAmount, toPlace.getAmount()));
plugin.getServer().getPluginManager().callEvent(postEvent);
}
}
}
dispatchedPlaceQuestIDs.addAll(quester.dispatchMultiplayerEverything(quest, placeType,
(final IQuester q, final IQuest cq) -> {
if (!dispatchedPlaceQuestIDs.contains(cq.getId())) {
for (final ItemStack is : q.getQuestData(cq).blocksPlaced) {
if (evt.getBlock().getType().equals(is.getType()) && is.getAmount() > 0) {
ItemStack toPlace = new ItemStack(is.getType(), 64);
for (final ItemStack stack : quester.getCurrentStage(cq).getBlocksToPlace()) {
if (ItemUtil.compareItems(is, stack, true) == 0) {
toPlace = stack;
}
}
final QuesterPreUpdateObjectiveEvent preEvent
= new QuesterPreUpdateObjectiveEvent((Quester) q, cq,
new BukkitObjective(placeType, is.getAmount(), toPlace.getAmount()));
plugin.getServer().getPluginManager().callEvent(preEvent);
final int index = q.getQuestData(cq).blocksPlaced.indexOf(is);
final int newAmount = is.getAmount() - 1;
is.setAmount(newAmount);
q.getQuestData(cq).blocksPlaced.set(index, is);
final QuesterPostUpdateObjectiveEvent postEvent
= new QuesterPostUpdateObjectiveEvent((Quester) q, cq,
new BukkitObjective(placeType, newAmount, toPlace.getAmount()));
plugin.getServer().getPluginManager().callEvent(postEvent);
if (quest.getOptions().canIgnoreBlockReplace()) {
// Ignore blocks broken once replaced (self)
if (currentStage.containsObjective(placeType)) {
for (final ItemStack is : quester.getQuestData(quest).blocksPlaced) {
if (evt.getBlock().getType().equals(is.getType()) && is.getAmount() > 0) {
ItemStack toPlace = new ItemStack(is.getType(), 64);
for (final ItemStack stack : currentStage.getBlocksToPlace()) {
if (ItemUtil.compareItems(is, stack, true) == 0) {
toPlace = stack;
}
}
final QuesterPreUpdateObjectiveEvent preEvent
= new QuesterPreUpdateObjectiveEvent(quester, quest,
new BukkitObjective(placeType, is.getAmount(), toPlace.getAmount()));
plugin.getServer().getPluginManager().callEvent(preEvent);
final int index = quester.getQuestData(quest).blocksPlaced.indexOf(is);
final int newAmount = is.getAmount() - 1;
is.setAmount(newAmount);
quester.getQuestData(quest).blocksPlaced.set(index, is);
final QuesterPostUpdateObjectiveEvent postEvent
= new QuesterPostUpdateObjectiveEvent(quester, quest,
new BukkitObjective(placeType, newAmount, toPlace.getAmount()));
plugin.getServer().getPluginManager().callEvent(postEvent);
}
return null;
}));
}
}
// Ignore blocks broken once replaced (party support)
dispatchedPlaceQuestIDs.addAll(quester.dispatchMultiplayerEverything(quest, placeType,
(final IQuester q, final IQuest cq) -> {
if (!dispatchedPlaceQuestIDs.contains(cq.getId())) {
for (final ItemStack is : q.getQuestData(cq).blocksPlaced) {
if (evt.getBlock().getType().equals(is.getType()) && is.getAmount() > 0) {
ItemStack toPlace = new ItemStack(is.getType(), 64);
for (final ItemStack stack : quester.getCurrentStage(cq).getBlocksToPlace()) {
if (ItemUtil.compareItems(is, stack, true) == 0) {
toPlace = stack;
}
}
final QuesterPreUpdateObjectiveEvent preEvent
= new QuesterPreUpdateObjectiveEvent((Quester) q, cq,
new BukkitObjective(placeType, is.getAmount(), toPlace.getAmount()));
plugin.getServer().getPluginManager().callEvent(preEvent);
final int index = q.getQuestData(cq).blocksPlaced.indexOf(is);
final int newAmount = is.getAmount() - 1;
is.setAmount(newAmount);
q.getQuestData(cq).blocksPlaced.set(index, is);
final QuesterPostUpdateObjectiveEvent postEvent
= new QuesterPostUpdateObjectiveEvent((Quester) q, cq,
new BukkitObjective(placeType, newAmount, toPlace.getAmount()));
plugin.getServer().getPluginManager().callEvent(postEvent);
}
}
}
return null;
}));
}
if (currentStage.containsObjective(cutType)) {
if (player.getItemInHand().getType().equals(Material.SHEARS)) {
quester.cutBlock(quest, blockItemStack);
@ -212,7 +216,8 @@ public class BlockListener implements Listener {
final Quester quester = plugin.getQuester(player.getUniqueId());
final ObjectiveType placeType = ObjectiveType.PLACE_BLOCK;
final ObjectiveType breakType = ObjectiveType.BREAK_BLOCK;
final Set<String> dispatchedQuestIDs = new HashSet<>();
final Set<String> dispatchedPlaceQuestIDs = new HashSet<>();
final Set<String> dispatchedBreakQuestIDs = new HashSet<>();
for (final IQuest quest : plugin.getLoadedQuests()) {
if (!evt.isCancelled()) {
if (!quester.meetsCondition(quest, true)) {
@ -226,38 +231,73 @@ public class BlockListener implements Listener {
quester.placeBlock(quest, blockItemStack);
}
if (currentStage.containsObjective(breakType)) {
for (final ItemStack is : quester.getQuestData(quest).blocksBroken) {
if (evt.getBlock().getType().equals(is.getType()) && is.getAmount() > 0) {
ItemStack toBreak = new ItemStack(is.getType(), 64);
for (final ItemStack stack : currentStage.getBlocksToBreak()) {
if (ItemUtil.compareItems(is, stack, true) == 0) {
toBreak = stack;
if (quest.getOptions().canIgnoreBlockReplace()) {
// Ignore blocks replaced once broken (self)
if (currentStage.containsObjective(breakType)) {
for (final ItemStack is : quester.getQuestData(quest).blocksBroken) {
if (evt.getBlock().getType().equals(is.getType()) && is.getAmount() > 0) {
ItemStack toBreak = new ItemStack(is.getType(), 64);
for (final ItemStack stack : currentStage.getBlocksToBreak()) {
if (ItemUtil.compareItems(is, stack, true) == 0) {
toBreak = stack;
}
}
final QuesterPreUpdateObjectiveEvent preEvent
= new QuesterPreUpdateObjectiveEvent(quester, quest,
new BukkitObjective(placeType, is.getAmount(), toBreak.getAmount()));
plugin.getServer().getPluginManager().callEvent(preEvent);
final int index = quester.getQuestData(quest).blocksBroken.indexOf(is);
final int newAmount = is.getAmount() - 1;
is.setAmount(newAmount);
quester.getQuestData(quest).blocksBroken.set(index, is);
final QuesterPostUpdateObjectiveEvent postEvent
= new QuesterPostUpdateObjectiveEvent(quester, quest,
new BukkitObjective(placeType, newAmount, toBreak.getAmount()));
plugin.getServer().getPluginManager().callEvent(postEvent);
}
final QuesterPreUpdateObjectiveEvent preEvent
= new QuesterPreUpdateObjectiveEvent(quester, quest,
new BukkitObjective(placeType, is.getAmount(), toBreak.getAmount()));
plugin.getServer().getPluginManager().callEvent(preEvent);
final int index = quester.getQuestData(quest).blocksBroken.indexOf(is);
final int newAmount = is.getAmount() - 1;
is.setAmount(newAmount);
quester.getQuestData(quest).blocksBroken.set(index, is);
final QuesterPostUpdateObjectiveEvent postEvent
= new QuesterPostUpdateObjectiveEvent(quester, quest,
new BukkitObjective(placeType, newAmount, toBreak.getAmount()));
plugin.getServer().getPluginManager().callEvent(postEvent);
}
}
// Ignore blocks replaced once broken (party support)
dispatchedBreakQuestIDs.addAll(quester.dispatchMultiplayerEverything(quest, breakType,
(final IQuester q, final IQuest cq) -> {
if (!dispatchedBreakQuestIDs.contains(cq.getId())) {
for (final ItemStack is : q.getQuestData(cq).blocksBroken) {
if (evt.getBlock().getType().equals(is.getType()) && is.getAmount() > 0) {
ItemStack toBreak = new ItemStack(is.getType(), 64);
for (final ItemStack stack : quester.getCurrentStage(cq).getBlocksToBreak()) {
if (ItemUtil.compareItems(is, stack, true) == 0) {
toBreak = stack;
}
}
final QuesterPreUpdateObjectiveEvent preEvent
= new QuesterPreUpdateObjectiveEvent((Quester) q, cq,
new BukkitObjective(breakType, is.getAmount(), toBreak.getAmount()));
plugin.getServer().getPluginManager().callEvent(preEvent);
final int index = q.getQuestData(cq).blocksBroken.indexOf(is);
final int newAmount = is.getAmount() - 1;
is.setAmount(newAmount);
q.getQuestData(cq).blocksBroken.set(index, is);
final QuesterPostUpdateObjectiveEvent postEvent
= new QuesterPostUpdateObjectiveEvent((Quester) q, cq,
new BukkitObjective(breakType, newAmount, toBreak.getAmount()));
plugin.getServer().getPluginManager().callEvent(postEvent);
}
}
}
return null;
}));
}
}
dispatchedQuestIDs.addAll(quester.dispatchMultiplayerEverything(quest, placeType,
dispatchedPlaceQuestIDs.addAll(quester.dispatchMultiplayerEverything(quest, placeType,
(final IQuester q, final IQuest cq) -> {
if (!dispatchedQuestIDs.contains(cq.getId())) {
if (!dispatchedPlaceQuestIDs.contains(cq.getId())) {
q.placeBlock(cq, blockItemStack);
}
return null;

View File

@ -22,6 +22,7 @@ public class BukkitOptions implements Options {
private double shareDistance = 0.0D;
private int shareProgressLevel = 1;
private boolean shareSameQuestOnly = true;
private boolean ignoreBlockReplace = true;
public boolean canAllowCommands() {
return allowCommands;
@ -94,4 +95,12 @@ public class BukkitOptions implements Options {
public void setHandleOfflinePlayers(final boolean handleOfflinePlayers) {
this.handleOfflinePlayers = handleOfflinePlayers;
}
public boolean canIgnoreBlockReplace() {
return ignoreBlockReplace;
}
public void setIgnoreBlockReplace(final boolean ignoreBlockReplace) {
this.ignoreBlockReplace = ignoreBlockReplace;
}
}

View File

@ -283,6 +283,7 @@ public class BukkitQuestFactory implements QuestFactory, ConversationAbandonedLi
context.setSessionData(CK.OPT_SHARE_SAME_QUEST_ONLY, opt.canShareSameQuestOnly());
context.setSessionData(CK.OPT_SHARE_DISTANCE, opt.getShareDistance());
context.setSessionData(CK.OPT_HANDLE_OFFLINE_PLAYERS, opt.canHandleOfflinePlayers());
context.setSessionData(CK.OPT_IGNORE_BLOCK_REPLACE, opt.canIgnoreBlockReplace());
// Stages (Objectives)
int index = 1;
for (final IStage stage : q.getStages()) {
@ -925,6 +926,8 @@ public class BukkitQuestFactory implements QuestFactory, ConversationAbandonedLi
? context.getSessionData(CK.OPT_SHARE_DISTANCE) : null);
opts.set("handle-offline-players", context.getSessionData(CK.OPT_HANDLE_OFFLINE_PLAYERS) != null
? context.getSessionData(CK.OPT_HANDLE_OFFLINE_PLAYERS) : null);
opts.set("ignore-block-replace", context.getSessionData(CK.OPT_IGNORE_BLOCK_REPLACE) != null
? context.getSessionData(CK.OPT_IGNORE_BLOCK_REPLACE) : null);
if (opts.getKeys(false).isEmpty()) {
section.set("options", null);
}

View File

@ -150,6 +150,7 @@ public class CK {
public static final String OPT_SHARE_SAME_QUEST_ONLY = "shareSameQuestOnlyOpt";
public static final String OPT_SHARE_DISTANCE = "shareDistance";
public static final String OPT_HANDLE_OFFLINE_PLAYERS = "handleOfflinePlayers";
public static final String OPT_IGNORE_BLOCK_REPLACE = "ignoreBlockReplace";
// Actions
public static final String E_OLD_EVENT = "oldEvent";
public static final String E_NAME = "evtName";

View File

@ -486,6 +486,7 @@ optDistancePrompt: "Enter a distance (number) for share radius, <clear>, <cancel
optAllowCommands: "Allow commands during quest"
optAllowQuitting: "Allow quitting during quest"
optIgnoreSilkTouch: "Ignore blocks broken with Silk Touch"
optIgnoreBlockReplace: "Ignore blocks replaced once broken"
optCommandsDenied: "You cannot use commands during <quest>."
optPluginListTitle: "- Available Plugins -"
optExternalPartyPlugin: "Set provider via Unite"

View File

@ -482,6 +482,7 @@ optDistancePrompt: "Enter a distance (number) for share radius, <clear>, <cancel
optAllowCommands: "Allow commands during quest"
optAllowQuitting: "Allow quitting during quest"
optIgnoreSilkTouch: "Ignore blocks broken with Silk Touch"
optIgnoreBlockReplace: "Ignore blocks replaced once broken"
optCommandsDenied: "You cannot use commands during <quest>."
optPluginListTitle: "- Available Plugins -"
optExternalPartyPlugin: "Set provider via Unite"