From 814be97fe68265e67f57e43560f609d7ccfdc983 Mon Sep 17 00:00:00 2001 From: Jordan Irwin Date: Mon, 15 Apr 2024 15:36:57 -0700 Subject: [PATCH] Track which slot indexes are used to store quest completions count in... ...QuestInfo https://github.com/arianne/stendhal/issues/230 --- .../server/maps/quests/AbstractQuest.java | 66 +++++++++++++++++-- .../server/maps/quests/QuestInfo.java | 57 +++++++++++++++- 2 files changed, 118 insertions(+), 5 deletions(-) diff --git a/src/games/stendhal/server/maps/quests/AbstractQuest.java b/src/games/stendhal/server/maps/quests/AbstractQuest.java index 71c027450a..79fdfa1189 100644 --- a/src/games/stendhal/server/maps/quests/AbstractQuest.java +++ b/src/games/stendhal/server/maps/quests/AbstractQuest.java @@ -18,6 +18,7 @@ import java.util.List; import games.stendhal.server.core.engine.SingletonRepository; import games.stendhal.server.entity.npc.NPCList; import games.stendhal.server.entity.player.Player; +import marauroa.common.Pair; /** * Abstract class for quests. This is a default implementation of IQuest. @@ -45,12 +46,55 @@ public abstract class AbstractQuest implements IQuest { * @param name - name of the quest * @param description - short description of this quest in a neutral tense (not first person) * @param repeatable - is quest repeatable or not + * @param completionsOpenIndex + * Slot index where completions count is stored while quest is in open state. + * @param completionsCompleteIndex + * Slot index where completions count is stored while quest is in complete state. */ - public void fillQuestInfo(final String name, final String description, boolean repeatable) { + public void fillQuestInfo(final String name, final String description, boolean repeatable, + final Integer completionsOpenIndex, final Integer completionsCompleteIndex) { questInfo.setName(name); questInfo.setDescription(description); questInfo.setRepeatable(repeatable); questInfo.setSuggestedMinLevel(this.getMinLevel()); + questInfo.setCompletionsIndexes(completionsOpenIndex, completionsCompleteIndex); + } + + /** + * fill fields of questInfo object with info about this quest + * @param name - name of the quest + * @param description - short description of this quest in a neutral tense (not first person) + * @param repeatable - is quest repeatable or not + * @param completionsIndex + * Slot index where completions count is stored while quest in open or complete state. + */ + public void fillQuestInfo(final String name, final String description, boolean repeatable, + final int completionsIndex) { + fillQuestInfo(name, description, repeatable, completionsIndex, completionsIndex); + } + + /** + * fill fields of questInfo object with info about this quest + * @param name - name of the quest + * @param description - short description of this quest in a neutral tense (not first person) + * @param repeatable - is quest repeatable or not + * @param completionsIndexes + * Pair of indexes where first value represents slot index for open state and second represents + * index for complete state. + */ + public void fillQuestInfo(final String name, final String description, boolean repeatable, + final Pair completionsIndex) { + fillQuestInfo(name, description, repeatable, completionsIndex.first(), completionsIndex.second()); + } + + /** + * fill fields of questInfo object with info about this quest + * @param name - name of the quest + * @param description - short description of this quest in a neutral tense (not first person) + * @param repeatable - is quest repeatable or not + */ + public void fillQuestInfo(final String name, final String description, boolean repeatable) { + fillQuestInfo(name, description, repeatable, null, null); } /** NPCList. */ @@ -103,9 +147,23 @@ public abstract class AbstractQuest implements IQuest { @Override public int getCompletedCount(final Player player) { - // default is to check if in a completed state, quests must override to parse slot state to get - // actual number - return isCompleted(player) ? 1 : 0; + final String questSlot = getSlotName(); + final boolean completed = isCompleted(player); + if (player.hasQuest(questSlot)) { + final String[] state = player.getQuest(questSlot).split(";"); + final Pair completionsIndexes = questInfo.getCompletionsIndexes(); + Integer stateIndex = null; + if (completed) { + stateIndex = completionsIndexes.second(); + } else { + stateIndex = completionsIndexes.first(); + } + if (stateIndex != null && state.length > stateIndex) { + return Integer.parseInt(state[stateIndex]); + } + } + // default is to return 1 if quest is in complete state and 0 otherwise + return completed ? 1 : 0; } @Override diff --git a/src/games/stendhal/server/maps/quests/QuestInfo.java b/src/games/stendhal/server/maps/quests/QuestInfo.java index a5cd89c518..0055b9d64e 100644 --- a/src/games/stendhal/server/maps/quests/QuestInfo.java +++ b/src/games/stendhal/server/maps/quests/QuestInfo.java @@ -1,6 +1,6 @@ /* $Id$ */ /*************************************************************************** - * (C) Copyright 2003-2010 - Stendhal * + * (C) Copyright 2003-2024 - Stendhal * *************************************************************************** *************************************************************************** * * @@ -15,6 +15,8 @@ package games.stendhal.server.maps.quests; import java.util.HashMap; import java.util.Map; +import marauroa.common.Pair; + /** * Static info about quests, filled with fillQuestInfo in each quest * @@ -36,6 +38,14 @@ public class QuestInfo { private int suggestedMinLevel; + /** Quest slot indexes where completions count is stored. */ + private final Pair completionsIndexes; + + + public QuestInfo() { + completionsIndexes = new Pair<>(null, null); + } + public int getSuggestedMinLevel() { return suggestedMinLevel; } @@ -92,4 +102,49 @@ public class QuestInfo { this.repeatable = repeatable; } + /** + * Sets quest slot indexes to check for completions count. + * + * @param openIndex + * Index where count is stored while quest is in open state. + * @param completeIndex + * Index where count is stored while quest is in complete state. + */ + public void setCompletionsIndexes(final Integer openIndex, final Integer completeIndex) { + completionsIndexes.setFirst(openIndex); + completionsIndexes.setSecond(completeIndex); + } + + /** + * Sets quest slot indexes to check for completions count. + * + * @param index + * Index where count is stored while quest in open or complete state. + */ + public void setCompletionsIndexes(final Integer index) { + setCompletionsIndexes(index, index); + } + + /** + * Sets quest slot indexes to check for completions count. + * + * @param completionsIndexes + * Pair where `first` attribute represents slot index for open state and `second` attribute + * represents index for complete state. + */ + public void setCompletionsIndexes(final Pair completionsIndexes) { + this.completionsIndexes.setFirst(completionsIndexes.first()); + this.completionsIndexes.setSecond(completionsIndexes.second()); + } + + /** + * Retrieves quest slot indexes where completions count are stored. + * + * @return + * A `marauroa.common.Pair` where `first` attribute represents slot index while quest is in + * open state and `second` represents slot index while quest is in complete state. + */ + public Pair getCompletionsIndexes() { + return completionsIndexes; + } }