From 440ec649fc7c8a17eafaf451cfda7a3be29b985f Mon Sep 17 00:00:00 2001 From: Jordan Irwin Date: Wed, 29 May 2024 18:45:36 -0700 Subject: [PATCH] Track completions of Snowballs for Mr. Yeti --- .../server/maps/quests/Snowballs.java | 41 +++++++------- .../server/maps/quests/SnowballsTest.java | 55 +++++++++++++++++-- 2 files changed, 71 insertions(+), 25 deletions(-) diff --git a/src/games/stendhal/server/maps/quests/Snowballs.java b/src/games/stendhal/server/maps/quests/Snowballs.java index 05fa406d414..d16f32f47b2 100644 --- a/src/games/stendhal/server/maps/quests/Snowballs.java +++ b/src/games/stendhal/server/maps/quests/Snowballs.java @@ -1,6 +1,6 @@ /* $Id$ */ /*************************************************************************** - * (C) Copyright 2003-2010 - Stendhal * + * (C) Copyright 2003-2024 - Stendhal * *************************************************************************** *************************************************************************** * * @@ -62,7 +62,7 @@ * required between repetitions */ -public class Snowballs extends AbstractQuest { +public class Snowballs extends CompletionsTrackingQuest { private static final int REQUIRED_SNOWBALLS = 25; @@ -78,13 +78,13 @@ public String getSlotName() { @Override public boolean isCompleted(final Player player) { return player.hasQuest(QUEST_SLOT) - && !player.getQuest(QUEST_SLOT).equals("start") - && !player.getQuest(QUEST_SLOT).equals("rejected"); + && !player.getQuest(QUEST_SLOT, 0).equals("start") + && !player.getQuest(QUEST_SLOT, 0).equals("rejected"); } @Override public boolean isRepeatable(final Player player) { - return new AndCondition(new QuestNotInStateCondition(QUEST_SLOT, "start"), new QuestStartedCondition(QUEST_SLOT), new TimePassedCondition(QUEST_SLOT,REQUIRED_MINUTES)).fire(player, null, null); + return new AndCondition(new QuestNotInStateCondition(QUEST_SLOT, 0, "start"), new QuestStartedCondition(QUEST_SLOT), new TimePassedCondition(QUEST_SLOT, 0, REQUIRED_MINUTES)).fire(player, null, null); } @Override @@ -94,7 +94,7 @@ public List getHistory(final Player player) { return res; } res.add("I went down into the icy caves and met Mr. Yeti."); - final String questState = player.getQuest(QUEST_SLOT); + final String questState = player.getQuest(QUEST_SLOT, 0); if (questState.equals("rejected")) { res.add("I didn't want to help Mr. Yeti out this time and he harshly send me away..."); return res; @@ -128,7 +128,7 @@ private void prepareRequestingStep() { npc.add(ConversationStates.IDLE, ConversationPhrases.GREETING_MESSAGES, new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestInStateCondition(QUEST_SLOT, "start"), + new QuestInStateCondition(QUEST_SLOT, 0, "start"), new PlayerHasItemWithHimCondition("snowball", REQUIRED_SNOWBALLS)), ConversationStates.QUEST_ITEM_BROUGHT, "Greetings stranger! I see you have the snow I asked for. Are these snowballs for me?", @@ -138,7 +138,7 @@ private void prepareRequestingStep() { npc.add(ConversationStates.IDLE, ConversationPhrases.GREETING_MESSAGES, new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestInStateCondition(QUEST_SLOT, "start"), + new QuestInStateCondition(QUEST_SLOT, 0, "start"), new NotCondition(new PlayerHasItemWithHimCondition("snowball", REQUIRED_SNOWBALLS))), ConversationStates.ATTENDING, "You're back already? Don't forget that you promised to collect a bunch of snowballs for me!", @@ -149,8 +149,8 @@ private void prepareRequestingStep() { ConversationPhrases.GREETING_MESSAGES, new AndCondition(new GreetingMatchesNameCondition(npc.getName()), new QuestStartedCondition(QUEST_SLOT), - new QuestNotInStateCondition(QUEST_SLOT, "start"), - new TimePassedCondition(QUEST_SLOT, REQUIRED_MINUTES)), + new QuestNotInStateCondition(QUEST_SLOT, 0, "start"), + new TimePassedCondition(QUEST_SLOT, 0, REQUIRED_MINUTES)), ConversationStates.ATTENDING, "Greetings again! Have you seen my latest snow sculptures? I need a #favor again ...", null); @@ -160,11 +160,11 @@ private void prepareRequestingStep() { ConversationPhrases.GREETING_MESSAGES, new AndCondition(new GreetingMatchesNameCondition(npc.getName()), new QuestStartedCondition(QUEST_SLOT), - new QuestNotInStateCondition(QUEST_SLOT, "start"), - new NotCondition(new TimePassedCondition(QUEST_SLOT, REQUIRED_MINUTES))), + new QuestNotInStateCondition(QUEST_SLOT, 0, "start"), + new NotCondition(new TimePassedCondition(QUEST_SLOT, 0, REQUIRED_MINUTES))), ConversationStates.ATTENDING, null, - new SayTimeRemainingAction(QUEST_SLOT, REQUIRED_MINUTES, "I have enough snow for my new sculpture. Thank you for helping! " + new SayTimeRemainingAction(QUEST_SLOT, 0, REQUIRED_MINUTES, "I have enough snow for my new sculpture. Thank you for helping! " + "I might start a new one in" )); // asks about quest - has never started it @@ -178,7 +178,7 @@ private void prepareRequestingStep() { // asks about quest but already on it npc.add(ConversationStates.ATTENDING, ConversationPhrases.QUEST_MESSAGES, - new QuestInStateCondition(QUEST_SLOT, "start"), + new QuestInStateCondition(QUEST_SLOT, 0, "start"), ConversationStates.ATTENDING, "You already promised me to bring some snowballs! Twenty five pieces, remember ...", null); @@ -186,7 +186,7 @@ private void prepareRequestingStep() { // asks about quest - has done it but it's repeatable now npc.add(ConversationStates.ATTENDING, ConversationPhrases.QUEST_MESSAGES, - new AndCondition(new QuestStartedCondition(QUEST_SLOT), new QuestNotInStateCondition(QUEST_SLOT, "start"), new TimePassedCondition(QUEST_SLOT, REQUIRED_MINUTES)), + new AndCondition(new QuestStartedCondition(QUEST_SLOT), new QuestNotInStateCondition(QUEST_SLOT, 0, "start"), new TimePassedCondition(QUEST_SLOT, 0, REQUIRED_MINUTES)), ConversationStates.QUEST_OFFERED, "I like to make snow sculptures, but the snow in this cavern is not good enough. Would you help me and get some snowballs? I need twenty five of them.", null); @@ -194,7 +194,7 @@ private void prepareRequestingStep() { // asks about quest - has done it and it's too soon to do again npc.add(ConversationStates.ATTENDING, ConversationPhrases.QUEST_MESSAGES, - new AndCondition(new QuestStartedCondition(QUEST_SLOT), new QuestNotInStateCondition(QUEST_SLOT, "start"), new NotCondition(new TimePassedCondition(QUEST_SLOT, REQUIRED_MINUTES))), + new AndCondition(new QuestStartedCondition(QUEST_SLOT), new QuestNotInStateCondition(QUEST_SLOT, 0, "start"), new NotCondition(new TimePassedCondition(QUEST_SLOT, 0, REQUIRED_MINUTES))), ConversationStates.ATTENDING, "I have enough snow to finish my sculpture, but thanks for asking.", null); @@ -205,7 +205,7 @@ private void prepareRequestingStep() { null, ConversationStates.ATTENDING, "Fine. You can loot the snowballs from the ice golem in this cavern, but be careful there is something huge nearby! Come back when you get twenty five snowballs.", - new SetQuestAction(QUEST_SLOT, "start")); + new SetQuestAction(QUEST_SLOT, 0, "start")); // player is not willing to help npc.add(ConversationStates.QUEST_OFFERED, @@ -213,7 +213,7 @@ private void prepareRequestingStep() { null, ConversationStates.ATTENDING, "So what are you doing here? Go away!", - new SetQuestAndModifyKarmaAction(QUEST_SLOT, "rejected", -5.0)); + new SetQuestAndModifyKarmaAction(QUEST_SLOT, 0, "rejected", -5.0)); } private void prepareBringingStep() { @@ -223,7 +223,8 @@ private void prepareBringingStep() { final List reward = new LinkedList(); reward.add(new DropItemAction("snowball", REQUIRED_SNOWBALLS)); reward.add(new IncreaseXPAction(50)); - reward.add(new SetQuestToTimeStampAction(QUEST_SLOT)); + reward.add(incrementCompletionsAction()); + reward.add(new SetQuestToTimeStampAction(QUEST_SLOT, 0)); // player gets either cod or perch, which we don't have a standard action for // and the npc says the name of the reward, too reward.add(new ChatAction() { @@ -272,7 +273,7 @@ public void addToWorld() { fillQuestInfo( "Snowballs for Mr. Yeti", "The inhabitant of the icy region in Faiumoni needs your help to collect some snowballs for him.", - false); + false, 1); prepareRequestingStep(); prepareBringingStep(); } diff --git a/tests/games/stendhal/server/maps/quests/SnowballsTest.java b/tests/games/stendhal/server/maps/quests/SnowballsTest.java index 237e34f7c0a..f5338c4b696 100644 --- a/tests/games/stendhal/server/maps/quests/SnowballsTest.java +++ b/tests/games/stendhal/server/maps/quests/SnowballsTest.java @@ -1,3 +1,14 @@ +/*************************************************************************** + * Copyright © 2010-2024 - Faiumoni e. V. * + *************************************************************************** + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ package games.stendhal.server.maps.quests; import static org.hamcrest.Matchers.greaterThan; @@ -14,6 +25,7 @@ import org.junit.BeforeClass; import org.junit.Test; +import games.stendhal.common.MathHelper; import games.stendhal.server.core.engine.SingletonRepository; import games.stendhal.server.core.engine.StendhalRPZone; import games.stendhal.server.entity.npc.SpeakerNPC; @@ -59,8 +71,18 @@ public void testQuest() { // ----------------------------------------------- + final int completions = MathHelper.parseIntDefault(player.getQuest(questSlot, 1), 0); + String[] responses = new String[] { + "Greetings stranger! Have you seen my snow sculptures? I need a #favor from someone friendly like you." + }; + if (completions > 0) { + responses = new String[] { + "Greetings again! Have you seen my latest snow sculptures? I need a #favor again ..." + }; + } + en.step(player, "hi"); - assertEquals("Greetings stranger! Have you seen my snow sculptures? I need a #favor from someone friendly like you.", getReply(npc)); + assertEquals(responses[0], getReply(npc)); en.step(player, "favor"); assertEquals("I like to make snow sculptures, but the snow in this cavern is not good enough. Would you help me and get some snowballs? I need twenty five of them.", getReply(npc)); en.step(player, "no"); @@ -68,7 +90,7 @@ public void testQuest() { en.step(player, "bye"); assertEquals("Bye.", getReply(npc)); - assertEquals(player.getQuest(questSlot), "rejected"); + assertEquals(player.getQuest(questSlot, 0), "rejected"); en.step(player, "hi"); assertEquals("Greetings stranger! Have you seen my snow sculptures? I need a #favor from someone friendly like you.", getReply(npc)); @@ -79,7 +101,7 @@ public void testQuest() { en.step(player, "bye"); assertEquals("Bye.", getReply(npc)); - assertEquals(player.getQuest(questSlot), "start"); + assertEquals(player.getQuest(questSlot, 0), "start"); en.step(player, "hi"); assertEquals("You're back already? Don't forget that you promised to collect a bunch of snowballs for me!", getReply(npc)); @@ -128,7 +150,7 @@ public void testQuest() { assertTrue(player.isEquipped("perch", 20) || player.isEquipped("cod", 20) ); assertNotNull(player.getQuest(questSlot)); - assertFalse(player.getQuest(questSlot).equals("start")); + assertFalse(player.getQuest(questSlot, 0).equals("start")); en.step(player, "hi"); assertEquals("I have enough snow for my new sculpture. Thank you for helping! I might start a new one in 2 hours.", getReply(npc)); @@ -140,7 +162,7 @@ public void testQuest() { // [09:49] Admin kymara changed your state of the quest 'snowballs' from '1288518569387' to '0' // [09:49] Changed the state of quest 'snowballs' from '1288518569387' to '0' - player.setQuest(questSlot, "0"); + player.setQuest(questSlot, 0, "0"); en.step(player, "hi"); assertEquals("Greetings again! Have you seen my latest snow sculptures? I need a #favor again ...", getReply(npc)); @@ -151,4 +173,27 @@ public void testQuest() { en.step(player, "bye"); assertEquals("Bye.", getReply(npc)); } + + @Test + public void testCompletions() { + for (int count = 0; count < 5; count++) { + assertEquals(count, MathHelper.parseIntDefault(player.getQuest(questSlot, 1), 0)); + testQuest(); + // reset so can be repeated + player.setQuest(questSlot, 0, "0"); + } + assertEquals("5", player.getQuest(questSlot, 1)); + + // check that completions count is retained after quest is rejected & started + en.step(player, "hi"); + en.step(player, "task"); + en.step(player, "no"); + assertEquals("rejected", player.getQuest(questSlot, 0)); + assertEquals("5", player.getQuest(questSlot, 1)); + en.step(player, "task"); + en.step(player, "yes"); + assertEquals("start", player.getQuest(questSlot, 0)); + assertEquals("5", player.getQuest(questSlot, 1)); + en.step(player, "bye"); + } }