From 449dfffa59a17e2101f1f5d0dd9fafb1bdeb7e1a Mon Sep 17 00:00:00 2001 From: Hendrik Brummermann Date: Sat, 21 Oct 2023 10:55:55 +0200 Subject: [PATCH] converted tests to QuestManuscript --- .../factory/FriendAchievementFactory.java | 9 +- .../entity/npc/quest/QuestOfferBuilder.java | 41 ++- .../server/entity/player/UpdateConverter.java | 20 + .../server/maps/amazon/hut/PrincessNPC.java | 2 +- .../maps/orril/river/CampingGirlNPC.java | 2 +- .../server/maps/quests/AmazonPrincess.java | 259 +++---------- .../server/maps/quests/BeerForHayunn.java | 235 +++--------- .../stendhal/server/maps/quests/Campfire.java | 292 +++------------ .../server/maps/quests/EggsForMarianne.java | 327 +++-------------- .../server/maps/quests/HatForMonogenes.java | 201 +++------- .../server/maps/quests/LookBookforCeryl.java | 227 +++--------- .../server/maps/quests/PlinksToy.java | 211 +++-------- .../server/maps/quests/TrapsForKlaas.java | 344 +++++------------- .../factory/FriendAchievementFactoryTest.java | 7 +- ...KillBlordroughsAchievementFactoryTest.java | 1 - .../factory/QuestAchievementFactoryTest.java | 10 +- .../maps/quests/AmazonPrincessTest.java | 45 +-- .../server/maps/quests/AntivenomRingTest.java | 4 +- .../server/maps/quests/BeerForHayunnTest.java | 15 +- .../server/maps/quests/CampfireTest.java | 101 ++--- .../maps/quests/HatForMonogenesTest.java | 10 +- .../maps/quests/JailedBarbarianTest.java | 7 +- .../maps/quests/LookBookforCerylTest.java | 76 ++-- .../server/maps/quests/PlinksToyTest.java | 24 +- .../server/maps/quests/TrapsForKlaasTest.java | 42 +-- tests/utilities/QuestRunner.java | 1 + .../quest_runner/ChildrensFriendStub.java | 5 +- 27 files changed, 625 insertions(+), 1893 deletions(-) diff --git a/src/games/stendhal/server/core/rp/achievement/factory/FriendAchievementFactory.java b/src/games/stendhal/server/core/rp/achievement/factory/FriendAchievementFactory.java index 542665f2a8c..8d0a322e286 100644 --- a/src/games/stendhal/server/core/rp/achievement/factory/FriendAchievementFactory.java +++ b/src/games/stendhal/server/core/rp/achievement/factory/FriendAchievementFactory.java @@ -69,10 +69,7 @@ public Collection createAchievements() { // Anna, in Ados new QuestCompletedCondition("toys_collector"), // Sally, Orril River - // 'completed' doesn't work for Sally - return player.hasQuest(QUEST_SLOT) && !"start".equals(player.getQuest(QUEST_SLOT)) && !"rejected".equals(player.getQuest(QUEST_SLOT)); - new AndCondition( - new QuestActiveCondition("campfire"), - new QuestNotInStateCondition("campfire", "start")), + new QuestCompletedCondition("campfire"), // Annie, Kalavan city gardens new QuestStateStartsWithCondition("icecream_for_annie","eating;"), // Elisabeth, Kirdneh @@ -86,9 +83,7 @@ public Collection createAchievements() { // Finn Farmer, George new QuestCompletedCondition("coded_message"), // Marianne, Deniran City S - new AndCondition( - new QuestActiveCondition("eggs_for_marianne"), - new QuestNotInStateCondition("eggs_for_marianne", "start")) + new QuestCompletedCondition("eggs_for_marianne") ))); // quests about finding people diff --git a/src/games/stendhal/server/entity/npc/quest/QuestOfferBuilder.java b/src/games/stendhal/server/entity/npc/quest/QuestOfferBuilder.java index 28ee0858b95..e974f272d7b 100644 --- a/src/games/stendhal/server/entity/npc/quest/QuestOfferBuilder.java +++ b/src/games/stendhal/server/entity/npc/quest/QuestOfferBuilder.java @@ -28,6 +28,7 @@ import games.stendhal.server.entity.npc.action.SetQuestAndModifyKarmaAction; import games.stendhal.server.entity.npc.condition.AndCondition; import games.stendhal.server.entity.npc.condition.NotCondition; +import games.stendhal.server.entity.npc.condition.OrCondition; import games.stendhal.server.entity.npc.condition.QuestActiveCondition; import games.stendhal.server.entity.npc.condition.QuestCompletedCondition; import games.stendhal.server.entity.npc.condition.QuestNotStartedCondition; @@ -39,6 +40,7 @@ * @author hendrik */ public class QuestOfferBuilder> { + protected String begOnGreeting = null; protected String respondToRequest = null; protected String respondToUnrepeatableRequest = "Thanks for your help. I have no new task for you."; protected String respondToRepeatedRequest = null; @@ -54,6 +56,12 @@ public class QuestOfferBuilder> { super(); } + @SuppressWarnings("unchecked") + public T begOnGreeting(String begOnGreeting) { + this.begOnGreeting = begOnGreeting; + return (T) this; + } + @SuppressWarnings("unchecked") public T respondToRequest(String respondToRequest) { this.respondToRequest = respondToRequest; @@ -113,7 +121,9 @@ public T rejectionKarmaPenalty(double rejectionKarmaPenalty) { void simulateFirst(String npc, QuestSimulator simulator) { simulator.playerSays("hi"); - simulator.playerSays("quest"); + if (begOnGreeting == null) { + simulator.playerSays("quest"); + } simulator.npcSays(npc, respondToRequest); simulator.playerSays("no"); simulator.npcSays(npc, respondToReject); @@ -121,17 +131,21 @@ void simulateFirst(String npc, QuestSimulator simulator) { simulator.info(""); simulator.playerSays("hi"); - simulator.playerSays("quest"); + if (begOnGreeting == null) { + simulator.playerSays("quest"); + } simulator.npcSays(npc, respondToRequest); simulator.playerSays("yes"); simulator.npcSays(npc, respondToAccept); simulator.playerSays("bye"); simulator.info(""); - simulator.playerSays("hi"); - simulator.playerSays("quest"); - simulator.npcSays(npc, remind); - simulator.info(""); + if (begOnGreeting == null) { + simulator.playerSays("hi"); + simulator.playerSays("quest"); + simulator.npcSays(npc, remind); + simulator.info(""); + } } void simulateNotRepeatable(String npc, QuestSimulator simulator) { @@ -156,6 +170,21 @@ public void build(SpeakerNPC npc, String questSlot, QuestTaskBuilder task, ChatC ChatAction startQuestAction = task.buildStartQuestAction(questSlot); ChatAction rejectQuestAction = task.buildRejectQuestAction(questSlot); + if (begOnGreeting != null) { + npc.add(ConversationStates.IDLE, + ConversationPhrases.GREETING_MESSAGES, + new OrCondition( + new QuestNotStartedCondition(questSlot), + new AndCondition( + new QuestActiveCondition(questSlot), + new NotCondition(questCompletedCondition) + ) + ), + ConversationStates.QUEST_OFFERED, + begOnGreeting, + null); + } + npc.add(ConversationStates.ATTENDING, ConversationPhrases.QUEST_MESSAGES, new QuestNotStartedCondition(questSlot), diff --git a/src/games/stendhal/server/entity/player/UpdateConverter.java b/src/games/stendhal/server/entity/player/UpdateConverter.java index 6b2b19da687..b950f855527 100644 --- a/src/games/stendhal/server/entity/player/UpdateConverter.java +++ b/src/games/stendhal/server/entity/player/UpdateConverter.java @@ -591,6 +591,26 @@ public static void updateQuests(final Player player) { player.setQuest(questSlot, "start;;;" + player.getQuest(questSlot)); } } + + // 1.44: Amazon Princess + questSlot = "amazon_princess"; + if (player.hasQuest(questSlot)) { + final String fsState = player.getQuest(questSlot, 0); + if (fsState.equals("drinking")) { + player.setQuest(questSlot, 0, "done"); + } + } + + // 1.44: Campfire and Eggs for marianne + for (String slot : Arrays.asList("campfire", "eggs_for_marianne")) { + if (player.hasQuest(slot)) { + final String fsState = player.getQuest(slot, 0); + if (!fsState.equals("start") && !fsState.equals("rejected")) { + player.setQuest(slot, 1, fsState); + player.setQuest(slot, 0, "done"); + } + } + } } diff --git a/src/games/stendhal/server/maps/amazon/hut/PrincessNPC.java b/src/games/stendhal/server/maps/amazon/hut/PrincessNPC.java index 2690ef59544..7cdfd1b1035 100644 --- a/src/games/stendhal/server/maps/amazon/hut/PrincessNPC.java +++ b/src/games/stendhal/server/maps/amazon/hut/PrincessNPC.java @@ -63,7 +63,7 @@ protected void createPath() { @Override protected void createDialog() { - addGreeting("Huh, what are you doing here?"); + addGreeting("Huh, what are you doing here?"); addReply("sorry", "Well, so you should be, sneaking up on me like that!"); addReply("look", "You had better not poke around, this is all mine!"); addReply("nothing", "Go away and do this somewhere else but not in my hut!"); diff --git a/src/games/stendhal/server/maps/orril/river/CampingGirlNPC.java b/src/games/stendhal/server/maps/orril/river/CampingGirlNPC.java index 28cd0e520e2..73fb349895e 100644 --- a/src/games/stendhal/server/maps/orril/river/CampingGirlNPC.java +++ b/src/games/stendhal/server/maps/orril/river/CampingGirlNPC.java @@ -45,7 +45,7 @@ protected void createPath() { @Override protected void createDialog() { - //addGreeting(); + addGreeting("Hi, how are you?"); addJob("Work? I'm just a little girl! I'm a scout, you know."); addHelp("You can find lots of useful stuff in the forest; wood and mushrooms, for example. But beware, some mushrooms are poisonous!"); addGoodbye(); diff --git a/src/games/stendhal/server/maps/quests/AmazonPrincess.java b/src/games/stendhal/server/maps/quests/AmazonPrincess.java index 8c8af9906b5..411e8db742a 100644 --- a/src/games/stendhal/server/maps/quests/AmazonPrincess.java +++ b/src/games/stendhal/server/maps/quests/AmazonPrincess.java @@ -1,6 +1,5 @@ -/* $Id$ */ /*************************************************************************** - * (C) Copyright 2003-2011 - Stendhal * + * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** *************************************************************************** * * @@ -12,37 +11,12 @@ ***************************************************************************/ package games.stendhal.server.maps.quests; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import games.stendhal.common.Rand; -import games.stendhal.common.constants.SoundLayer; -import games.stendhal.common.grammar.Grammar; -import games.stendhal.common.parser.Sentence; -import games.stendhal.server.entity.npc.ChatAction; -import games.stendhal.server.entity.npc.ConversationPhrases; -import games.stendhal.server.entity.npc.ConversationStates; -import games.stendhal.server.entity.npc.EventRaiser; -import games.stendhal.server.entity.npc.SpeakerNPC; -import games.stendhal.server.entity.npc.action.DropItemAction; -import games.stendhal.server.entity.npc.action.EquipItemAction; +import games.stendhal.server.entity.npc.action.EquipRandomAmountOfItemAction; +import games.stendhal.server.entity.npc.action.IncreaseKarmaAction; import games.stendhal.server.entity.npc.action.InflictStatusOnNPCAction; -import games.stendhal.server.entity.npc.action.MultipleActions; -import games.stendhal.server.entity.npc.action.SayTimeRemainingAction; -import games.stendhal.server.entity.npc.action.SetQuestAction; -import games.stendhal.server.entity.npc.action.SetQuestAndModifyKarmaAction; -import games.stendhal.server.entity.npc.condition.AndCondition; -import games.stendhal.server.entity.npc.condition.NotCondition; -import games.stendhal.server.entity.npc.condition.PlayerHasItemWithHimCondition; -import games.stendhal.server.entity.npc.condition.QuestCompletedCondition; -import games.stendhal.server.entity.npc.condition.QuestInStateCondition; -import games.stendhal.server.entity.npc.condition.QuestNotInStateCondition; -import games.stendhal.server.entity.npc.condition.QuestNotStartedCondition; -import games.stendhal.server.entity.npc.condition.QuestStateStartsWithCondition; -import games.stendhal.server.entity.npc.condition.TimePassedCondition; -import games.stendhal.server.entity.player.Player; -import games.stendhal.server.events.SoundEvent; +import games.stendhal.server.entity.npc.action.PlaySoundAction; +import games.stendhal.server.entity.npc.quest.BringItemQuestBuilder; +import games.stendhal.server.entity.npc.quest.QuestManuscript; import games.stendhal.server.maps.Region; /** @@ -72,184 +46,53 @@ *
  • You can repeat it once an hour.
  • * */ -public class AmazonPrincess extends AbstractQuest { - - private static final String QUEST_SLOT = "amazon_princess"; - - // The delay between repeating quests is 60 minutes - private static final int REQUIRED_MINUTES = 60; - private static final List triggers = Arrays.asList("drink", "pina colada", "cocktail", "cheers", "pina"); - - - private void offerQuestStep() { - final SpeakerNPC npc = npcs.get("Princess Esclara"); -npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new QuestNotStartedCondition(QUEST_SLOT), - ConversationStates.QUEST_OFFERED, - "I'm looking for a drink, should be an exotic one. Can you bring me one?", - null); -npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new QuestCompletedCondition(QUEST_SLOT), - ConversationStates.ATTENDING, - "I'm drunken now thank you!", - null); - -npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new AndCondition(new TimePassedCondition(QUEST_SLOT, 1, REQUIRED_MINUTES), new QuestStateStartsWithCondition(QUEST_SLOT, "drinking;")), - ConversationStates.QUEST_OFFERED, - "The last cocktail you brought me was so lovely. Will you bring me another?", - null); - -npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new AndCondition(new NotCondition(new TimePassedCondition(QUEST_SLOT, 1, REQUIRED_MINUTES)), new QuestStateStartsWithCondition(QUEST_SLOT, "drinking;")), - ConversationStates.ATTENDING, - null, - new SayTimeRemainingAction(QUEST_SLOT, 1, REQUIRED_MINUTES, "I'm sure I'll be too drunk to have another for at least ")); - - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, null, - ConversationStates.ATTENDING, - "I like these exotic drinks, I forget the name of my favourite one.", - null); - -// Player agrees to get the drink - npc.add(ConversationStates.QUEST_OFFERED, - ConversationPhrases.YES_MESSAGES, null, - ConversationStates.ATTENDING, - "Thank you! If you have found some, say #drink to me so I know you have it. I'll be sure to give you a nice reward.", - new SetQuestAction(QUEST_SLOT, "start")); - - // Player says no, they've lost karma. - npc.add(ConversationStates.QUEST_OFFERED, - ConversationPhrases.NO_MESSAGES, null, ConversationStates.IDLE, - "Oh, never mind. Bye then.", - new SetQuestAndModifyKarmaAction(QUEST_SLOT, "rejected", -10.0)); - } - - /** - * Get Drink Step : - * src/games/stendhal/server/maps/athor/cocktail_bar/BarmanNPC.java he - * serves drinks to all, not just those with the quest - */ - private void bringCocktailStep() { - final SpeakerNPC npc = npcs.get("Princess Esclara"); - npc.add( - ConversationStates.ATTENDING, triggers, - new AndCondition(new QuestInStateCondition(QUEST_SLOT, "start"), new PlayerHasItemWithHimCondition("pina colada")), - ConversationStates.ATTENDING, - null, - new MultipleActions( - new DropItemAction("pina colada"), - new ChatAction() { - @Override - public void fire(final Player player, - final Sentence sentence, - final EventRaiser npc) { - int pieAmount = Rand.roll1D6() + 1; - new EquipItemAction("fish pie", pieAmount, true).fire(player, sentence, npc); - npc.say("Thank you!! Take " + - Grammar.thisthese(pieAmount) + " " + - Grammar.quantityplnoun(pieAmount, "fish pie", "") + - " from my cook, and this kiss, from me."); - npc.addEvent(new SoundEvent("kiss-female-01", SoundLayer.CREATURE_NOISE)); - new SetQuestAndModifyKarmaAction(getSlotName(), "drinking;" - + System.currentTimeMillis(), 15.0).fire(player, sentence, npc); - } - }, - new InflictStatusOnNPCAction("pina colada") - )); - - npc.add( - ConversationStates.ATTENDING, triggers, - new AndCondition(new QuestInStateCondition(QUEST_SLOT, "start"), new NotCondition(new PlayerHasItemWithHimCondition("pina colada"))), - ConversationStates.ATTENDING, - "You don't have any drink I like yet. Go, and you better get an exotic one!", - null); - - npc.add( - ConversationStates.ATTENDING, triggers, - new QuestNotInStateCondition(QUEST_SLOT, "start"), - ConversationStates.ATTENDING, - "Sometime you could do me a #favour ...", null); - - } - - @Override - public void addToWorld() { - fillQuestInfo( - "Amazon Princess", - "A thirsty princess wants a drink.", - true); - offerQuestStep(); - bringCocktailStep(); - } - +public class AmazonPrincess implements QuestManuscript { @Override - public List getHistory(final Player player) { - final List res = new ArrayList(); - if (!player.hasQuest(QUEST_SLOT)) { - return res; - } - res.add("Princess Esclara welcomed me to her home on Amazon Island."); - final String questState = player.getQuest(QUEST_SLOT); - if ("rejected".equals(questState)) { - res.add("She asked me to fetch her a drink but I didn't think she should have one."); - } - if (player.isQuestInState(QUEST_SLOT, "start") || isCompleted(player)) { - res.add("The Princess is thirsty, I promised her an exotic drink, and should tell her 'drink' when I have it."); - } - if ("start".equals(questState) && player.isEquipped("pina colada") || isCompleted(player)) { - res.add("I found a pina colada for the Princess, I think she'd like that."); - } - if (isCompleted(player)) { - if (isRepeatable(player)) { - res.add("I took a pina colada to the Princess, but I'd bet she's ready for another. Maybe I'll get more fish pies."); - } else { - res.add("Princess Esclara loved the pina colada I took her, she's not thirsty now. She gave me fish pies and a kiss!!"); - } - } - return res; + public BringItemQuestBuilder story() { + BringItemQuestBuilder quest = new BringItemQuestBuilder(); + + quest.info() + .name("Amazon Princess") + .description("A thirsty princess wants a drink.") + .internalName("amazon_princess") + .repeatableAfterMinutes(60) + .minLevel(70) + .region(Region.AMAZON_ISLAND) + .questGiverNpc("Princess Esclara"); + + quest.history() + .whenNpcWasMet("Princess Esclara welcomed me to her home on Amazon Island.") + .whenQuestWasRejected("She asked me to fetch her a drink but I didn't think she should have one.") + .whenQuestWasAccepted("The Princess is thirsty, I promised her an exotic drink.") + .whenTaskWasCompleted("I found a pina colada for the Princess, I think she'd like that.") + .whenQuestWasCompleted("Princess Esclara loved the pina colada I gave to her. She gave me fish pies and a kiss!!") + .whenQuestCanBeRepeated("But I'd bet she's ready for another one. Maybe I'll get more fish pies."); + + quest.offer() + .respondToRequest("I'm looking for a drink, should be an exotic one. Can you bring me one?") + .respondToUnrepeatableRequest("I'm sure I'll be too drunk to have another one now.") // TODO: for at least [time_remaining] + .respondToRepeatedRequest("The last cocktail you brought me was so lovely. Will you bring me another?") + .respondToAccept("Thank you! If you have found some, I'll be sure to give you a nice reward.") + .respondToReject("Oh, never mind. Bye then.") + .rejectionKarmaPenalty(10.0) + .remind("I like these exotic drinks, I forget the name of my favourite one."); + + // Get Drink Step : athor/cocktail_bar/BarmanNPC.java he serves drinks to all, not just those with the quest + quest.task() + .requestItem(1, "pina colada"); + + quest.complete() + .greet("Ah, I see, you have a §'pina colada' Is it for me?") + .respondToReject("Well then, hopefully someone else will help.") + .respondToAccept(null) + .rewardWith(new IncreaseKarmaAction(15)) + .rewardWith(new EquipRandomAmountOfItemAction("fish pie", 1, 6, 1, + "Thank you! Take [this_these] [number_item] from my cook, and this kiss from me.")) + .rewardWith(new PlaySoundAction("kiss-female-01")) + .rewardWith(new InflictStatusOnNPCAction("pina colada")); + + return quest; } - @Override - public String getSlotName() { - return QUEST_SLOT; - } - - @Override - public String getName() { - return "AmazonPrincess"; - } - - // Amazon is dangerous below this level - don't hint to go there - @Override - public int getMinLevel() { - return 70; - } - - @Override - public boolean isRepeatable(final Player player) { - return new AndCondition(new QuestStateStartsWithCondition(QUEST_SLOT,"drinking;"), - new TimePassedCondition(QUEST_SLOT, 1, REQUIRED_MINUTES)).fire(player,null, null); - } - - @Override - public boolean isCompleted(final Player player) { - return new QuestStateStartsWithCondition(QUEST_SLOT,"drinking;").fire(player, null, null); - } - - @Override - public String getRegion() { - return Region.AMAZON_ISLAND; - } - - @Override - public String getNPCName() { - return "Princess Esclara"; - } } diff --git a/src/games/stendhal/server/maps/quests/BeerForHayunn.java b/src/games/stendhal/server/maps/quests/BeerForHayunn.java index d9ae09db8bf..14143132618 100644 --- a/src/games/stendhal/server/maps/quests/BeerForHayunn.java +++ b/src/games/stendhal/server/maps/quests/BeerForHayunn.java @@ -1,4 +1,3 @@ -/* $Id$ */ /*************************************************************************** * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** @@ -12,30 +11,12 @@ ***************************************************************************/ package games.stendhal.server.maps.quests; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - import games.stendhal.server.core.engine.SingletonRepository; -import games.stendhal.server.entity.npc.ChatAction; -import games.stendhal.server.entity.npc.ConversationPhrases; -import games.stendhal.server.entity.npc.ConversationStates; -import games.stendhal.server.entity.npc.SpeakerNPC; -import games.stendhal.server.entity.npc.action.DropItemAction; import games.stendhal.server.entity.npc.action.EquipItemAction; import games.stendhal.server.entity.npc.action.IncreaseKarmaAction; import games.stendhal.server.entity.npc.action.IncreaseXPAction; -import games.stendhal.server.entity.npc.action.MultipleActions; -import games.stendhal.server.entity.npc.action.SetQuestAction; -import games.stendhal.server.entity.npc.action.SetQuestAndModifyKarmaAction; -import games.stendhal.server.entity.npc.condition.AndCondition; -import games.stendhal.server.entity.npc.condition.GreetingMatchesNameCondition; -import games.stendhal.server.entity.npc.condition.NotCondition; -import games.stendhal.server.entity.npc.condition.PlayerHasItemWithHimCondition; -import games.stendhal.server.entity.npc.condition.QuestActiveCondition; -import games.stendhal.server.entity.npc.condition.QuestCompletedCondition; -import games.stendhal.server.entity.npc.condition.QuestNotCompletedCondition; -import games.stendhal.server.entity.player.Player; +import games.stendhal.server.entity.npc.quest.BringItemQuestBuilder; +import games.stendhal.server.entity.npc.quest.QuestManuscript; import games.stendhal.server.maps.Region; import games.stendhal.server.maps.semos.guardhouse.RetiredAdventurerNPC; import games.stendhal.server.util.ResetSpeakerNPC; @@ -67,183 +48,61 @@ *
  • None
  • * */ -public class BeerForHayunn extends AbstractQuest { - public static final String QUEST_SLOT = "beer_hayunn"; - private static final String OTHER_QUEST_SLOT = "meet_hayunn"; +public class BeerForHayunn implements QuestManuscript { + public static final String QUEST_SLOT = "beer_hayunn"; @Override - public List getHistory(final Player player) { - final List res = new ArrayList(); - if (!player.hasQuest(QUEST_SLOT)) { - return res; - } - res.add("I have talked to Hayunn."); - final String questState = player.getQuest(QUEST_SLOT); - if ("rejected".equals(questState)) { - res.add("I do not want to make Hayunn drunk."); - } - if (player.isQuestInState(QUEST_SLOT, "start", "done")) { - res.add("I promised to buy him a beer from Margaret in Semos Tavern."); - } - if ("start".equals(questState) && player.isEquipped("beer") - || "done".equals(questState)) { - res.add("I have a bottle of beer."); - } - if ("done".equals(questState)) { - res.add("I gave the beer to Hayunn. He paid me 20 gold coins and I got some experience."); - } - return res; - } - - private void prepareRequestingStep() { - final SpeakerNPC npc = npcs.get("Hayunn Naratha"); - - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - // Don't give the task until the previous is completed to avoid - // confusing Hayunn in a lot of places later. - new AndCondition(new QuestNotCompletedCondition(QUEST_SLOT), - new QuestCompletedCondition(OTHER_QUEST_SLOT)), - ConversationStates.QUEST_OFFERED, - "My mouth is dry, but I can't be seen to abandon this teaching room! Could you bring me some #beer from the #tavern?", - null); - - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new QuestCompletedCondition(QUEST_SLOT), - ConversationStates.ATTENDING, - "Thanks all the same, but I don't want to get too heavily into drinking; I'm still on duty, you know! I'll need my wits about me if a student shows up...", - null); - - npc.add( - ConversationStates.QUEST_OFFERED, - ConversationPhrases.YES_MESSAGES, - null, - ConversationStates.ATTENDING, - "Thanks! I'll be right here, waiting. And guarding, of course.", - new SetQuestAction(QUEST_SLOT, "start")); - - npc.add( - ConversationStates.QUEST_OFFERED, - ConversationPhrases.NO_MESSAGES, - null, - ConversationStates.ATTENDING, - "Oh, well forget it then. I guess I'll just hope for it to start raining, and then stand with my mouth open.", - new SetQuestAndModifyKarmaAction(QUEST_SLOT, "rejected", -5.0)); - - npc.add( - ConversationStates.QUEST_OFFERED, - "tavern", - null, - ConversationStates.QUEST_OFFERED, - "If you don't know where the inn is, you could ask old Monogenes; he's good with directions. Are you going to help?", - null); - - npc.add( - ConversationStates.QUEST_OFFERED, - "beer", - null, - ConversationStates.QUEST_OFFERED, - "A bottle of cool beer from #Margaret will be more than enough. So, will you do it?", - null); - - npc.add( - ConversationStates.QUEST_OFFERED, - "Margaret", - null, - ConversationStates.QUEST_OFFERED, - "Margaret is the pretty maid in the tavern, of course! Quite a looker, too... heh. Will you go for me?", - null); - } - - private void prepareBringingStep() { - final SpeakerNPC npc = npcs.get("Hayunn Naratha"); - - npc.add(ConversationStates.IDLE, ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestActiveCondition(QUEST_SLOT), - new PlayerHasItemWithHimCondition("beer")), - ConversationStates.QUEST_ITEM_BROUGHT, - "Hey! Is that beer for me?", null); - - npc.add(ConversationStates.IDLE, ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestActiveCondition(QUEST_SLOT), - new NotCondition(new PlayerHasItemWithHimCondition("beer"))), - ConversationStates.ATTENDING, - "Hey, I'm still waiting for that beer, remember? Anyway, what can I do for you?", - null); - - final List reward = new LinkedList(); - reward.add(new DropItemAction("beer")); - reward.add(new EquipItemAction("money", 20)); - reward.add(new IncreaseXPAction(50)); - reward.add(new SetQuestAction(QUEST_SLOT, "done")); - reward.add(new IncreaseKarmaAction(10)); - npc.add( - ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.YES_MESSAGES, - new PlayerHasItemWithHimCondition("beer"), - ConversationStates.ATTENDING, - "*glug glug* Ah! That hit the spot. Let me know if you need anything, ok?", - new MultipleActions(reward)); - - npc.add( - ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.NO_MESSAGES, - null, - ConversationStates.ATTENDING, - "Drat! You remembered that I asked you for one, right? I could really use it right now.", - null); + public BringItemQuestBuilder story() { + BringItemQuestBuilder quest = new BringItemQuestBuilder(); + + quest.info() + .name("Beer for Hayunn") + .description("Hayunn Naratha, the great warrior in Semos Guard House, wants a beer.") + .internalName(QUEST_SLOT) + .notRepeatable() + .minLevel(0) + .region(Region.SEMOS_CITY) + .questGiverNpc("Hayunn Naratha"); + + quest.history() + .whenNpcWasMet("I have talked to Hayunn Naratha.") + .whenQuestWasRejected("I do not want to make Hayunn drunk.") + .whenQuestWasAccepted("I promised to buy him a beer from Margaret in Semos Tavern.") + .whenTaskWasCompleted("I have a bottle of beer.") + .whenQuestWasCompleted("I gave the beer to Hayunn. He paid me 20 gold coins and I got some experience."); + + // TODO: new QuestCompletedCondition(OTHER_QUEST_SLOT)), + quest.offer() + .respondToRequest("My mouth is dry, but I can't be seen to abandon this teaching room! Could you bring me some #beer from the #tavern?") + .respondToUnrepeatableRequest("Thanks all the same, but I don't want to get too heavily into drinking; I'm still on duty, you know! I'll need my wits about me if a student shows up...") + .respondToAccept("Thanks! I'll be right here, waiting. And guarding, of course.") + .respondToReject("Oh, well forget it then. I guess I'll just hope for it to start raining, and then stand with my mouth open.") + .rejectionKarmaPenalty(5.0) + .remind("Hey, I'm still waiting for that beer, remember? Anyway, what can I do for you?") + .respondTo("tavern").saying("If you don't know where the inn is, you could ask old Monogenes; he's good with directions. Are you going to help?") + .respondTo("beer").saying("A bottle of cool beer from #Margaret will be more than enough. So, will you do it?") + .respondTo("Margaret").saying("Margaret is the pretty maid in the tavern, of course! Quite a looker, too... heh. Will you go for me?"); + + quest.task() + .requestItem(1, "beer"); + + quest.complete() + .greet("Hey! Is that beer for me?") + .respondToReject("Drat! You remembered that I asked you for one, right? I could really use it right now.") + .respondToAccept("*glug glug* Ah! That hit the spot. Let me know if you need anything, ok?") + .rewardWith(new EquipItemAction("money", 20)) + .rewardWith(new IncreaseXPAction(50)) + .rewardWith(new IncreaseKarmaAction(10)); + return quest; } - @Override - public void addToWorld() { - fillQuestInfo( - "Beer for Hayunn", - "Hayunn Naratha, the great warrior in Semos Guard House, wants a beer.", - false); - prepareRequestingStep(); - prepareBringingStep(); - } - @Override public boolean removeFromWorld() { - final boolean res = ResetSpeakerNPC.reload(new RetiredAdventurerNPC(), getNPCName()); + final boolean res = ResetSpeakerNPC.reload(new RetiredAdventurerNPC(), "Hayunn Naratha"); // reload other associated quests SingletonRepository.getStendhalQuestSystem().reloadQuestSlots("meet_hayunn"); return res; } - - @Override - public String getSlotName() { - return QUEST_SLOT; - } - - @Override - public String getName() { - return "BeerForHayunn"; - } - - public String getTitle() { - - return "Beer for Hayunn"; - } - - @Override - public int getMinLevel() { - return 0; - } - - @Override - public String getRegion() { - return Region.SEMOS_CITY; - } - - @Override - public String getNPCName() { - return "Hayunn Naratha"; - } } diff --git a/src/games/stendhal/server/maps/quests/Campfire.java b/src/games/stendhal/server/maps/quests/Campfire.java index a35fd6d2052..a4dfc3810b6 100644 --- a/src/games/stendhal/server/maps/quests/Campfire.java +++ b/src/games/stendhal/server/maps/quests/Campfire.java @@ -1,6 +1,5 @@ -/* $Id$ */ /*************************************************************************** - * (C) Copyright 2003-2010 - Stendhal * + * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** *************************************************************************** * * @@ -12,38 +11,12 @@ ***************************************************************************/ package games.stendhal.server.maps.quests; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - -import games.stendhal.common.Rand; -import games.stendhal.common.parser.Sentence; -import games.stendhal.server.core.engine.SingletonRepository; -import games.stendhal.server.entity.item.StackableItem; -import games.stendhal.server.entity.npc.ChatAction; -import games.stendhal.server.entity.npc.ConversationPhrases; -import games.stendhal.server.entity.npc.ConversationStates; -import games.stendhal.server.entity.npc.EventRaiser; -import games.stendhal.server.entity.npc.SpeakerNPC; -import games.stendhal.server.entity.npc.action.DropItemAction; import games.stendhal.server.entity.npc.action.EquipItemAction; +import games.stendhal.server.entity.npc.action.EquipRandomItemAction; import games.stendhal.server.entity.npc.action.IncreaseKarmaAction; import games.stendhal.server.entity.npc.action.IncreaseXPAction; -import games.stendhal.server.entity.npc.action.MultipleActions; -import games.stendhal.server.entity.npc.action.SayTimeRemainingAction; -import games.stendhal.server.entity.npc.action.SetQuestAction; -import games.stendhal.server.entity.npc.action.SetQuestAndModifyKarmaAction; -import games.stendhal.server.entity.npc.action.SetQuestToTimeStampAction; -import games.stendhal.server.entity.npc.condition.AndCondition; -import games.stendhal.server.entity.npc.condition.GreetingMatchesNameCondition; -import games.stendhal.server.entity.npc.condition.NotCondition; -import games.stendhal.server.entity.npc.condition.PlayerHasItemWithHimCondition; -import games.stendhal.server.entity.npc.condition.QuestInStateCondition; -import games.stendhal.server.entity.npc.condition.QuestNotInStateCondition; -import games.stendhal.server.entity.npc.condition.QuestNotStartedCondition; -import games.stendhal.server.entity.npc.condition.QuestStartedCondition; -import games.stendhal.server.entity.npc.condition.TimePassedCondition; -import games.stendhal.server.entity.player.Player; +import games.stendhal.server.entity.npc.quest.BringItemQuestBuilder; +import games.stendhal.server.entity.npc.quest.QuestManuscript; import games.stendhal.server.maps.Region; /** @@ -74,222 +47,51 @@ *
  • Unlimited, but 60 minutes of waiting are required between repetitions
  • * */ -public class Campfire extends AbstractQuest { - private static final int REQUIRED_WOOD = 10; - private static final int REWARDS = 10; - - private static final int REQUIRED_MINUTES = 60; - - private static final String QUEST_SLOT = "campfire"; - - @Override - public String getSlotName() { - return QUEST_SLOT; - } - - @Override - public boolean isCompleted(final Player player) { - return player.hasQuest(QUEST_SLOT) && !"start".equals(player.getQuest(QUEST_SLOT)) && !"rejected".equals(player.getQuest(QUEST_SLOT)); - } - - @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); - } - - @Override - public List getHistory(final Player player) { - final List res = new ArrayList(); - if (!player.hasQuest(QUEST_SLOT)) { - return res; - } - res.add("I have met Sally"); - final String questState = player.getQuest(QUEST_SLOT); - if ("rejected".equals(questState)) { - res.add("I do not want to help Sally"); - return res; - } - res.add("I do want to help Sally"); - if (player.isEquipped("wood", REQUIRED_WOOD) || isCompleted(player)) { - res.add("I have found the 10 wood needed to start the fire"); - } - if (isCompleted(player)) { - res.add("I have given Sally the wood. She gave me some food and charcoal in return. I also gained 50 xp"); - } - if(isRepeatable(player)){ - res.add("Sally's fire needs some wood again."); - } - return res; - } - - - - private void prepareRequestingStep() { - final SpeakerNPC npc = npcs.get("Sally"); - - // player returns with the promised wood - npc.add(ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestInStateCondition(QUEST_SLOT, "start"), new PlayerHasItemWithHimCondition("wood", REQUIRED_WOOD)), - ConversationStates.QUEST_ITEM_BROUGHT, - "Hi again! You've got wood, I see; do you have those 10 pieces of wood I asked about earlier?", - null); - - //player returns without promised wood - npc.add(ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestInStateCondition(QUEST_SLOT, "start"), new NotCondition(new PlayerHasItemWithHimCondition("wood", REQUIRED_WOOD))), - ConversationStates.ATTENDING, - "You're back already? Don't forget that you promised to collect ten pieces of wood for me!", - null); - - // first chat of player with sally - npc.add(ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestNotStartedCondition(QUEST_SLOT)), - ConversationStates.ATTENDING, "Hi! I need a little #favor ... ", - null); - - // player who is rejected or 'done' but waiting to start again, returns - npc.add(ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestNotInStateCondition(QUEST_SLOT, "start"), - new QuestStartedCondition(QUEST_SLOT)), - ConversationStates.ATTENDING, - "Hi again!", - null); - - // if they ask for quest while on it, remind them - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new QuestInStateCondition(QUEST_SLOT, "start"), - ConversationStates.ATTENDING, - "You already promised me to bring me some wood! Ten pieces, remember?", - null); - - // first time player asks/ player had rejected - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new QuestNotStartedCondition(QUEST_SLOT), - ConversationStates.QUEST_OFFERED, - "I need more wood to keep my campfire running, But I can't leave it unattended to go get some! Could you please get some from the forest for me? I need ten pieces.", - null); - - // player returns - enough time has passed - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new AndCondition(new QuestNotInStateCondition(QUEST_SLOT, "start"), new QuestStartedCondition(QUEST_SLOT), new TimePassedCondition(QUEST_SLOT,REQUIRED_MINUTES)), - ConversationStates.QUEST_OFFERED, - "My campfire needs wood again, ten pieces of #wood will be enough. Could you please get those #wood pieces from the forest for me? Please say yes!", - null); - - // player returns - enough time has passed - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new AndCondition(new QuestNotInStateCondition(QUEST_SLOT, "start"), new QuestStartedCondition(QUEST_SLOT), new NotCondition(new TimePassedCondition(QUEST_SLOT,REQUIRED_MINUTES))), - ConversationStates.ATTENDING, - null, - new SayTimeRemainingAction(QUEST_SLOT,REQUIRED_MINUTES,"Thanks, but I think the wood you brought already will last me")); - - // player is willing to help - npc.add(ConversationStates.QUEST_OFFERED, - ConversationPhrases.YES_MESSAGES, - null, - ConversationStates.ATTENDING, - "Okay. You can find wood in the forest north of here. Come back when you get ten pieces of wood!", - new SetQuestAction(QUEST_SLOT, "start")); - - // player is not willing to help - npc.add(ConversationStates.QUEST_OFFERED, - ConversationPhrases.NO_MESSAGES, - null, - ConversationStates.ATTENDING, - "Oh dear, how am I going to cook all this meat? Perhaps I'll just have to feed it to the animals...", - new SetQuestAndModifyKarmaAction(QUEST_SLOT, "rejected", -5.0)); - } - - private void prepareBringingStep() { - final SpeakerNPC npc = npcs.get("Sally"); - // player has wood and tells sally, yes, it is for her - - final List reward = new LinkedList(); - reward.add(new DropItemAction("wood", REQUIRED_WOOD)); - reward.add(new EquipItemAction("charcoal", REWARDS)); - reward.add(new IncreaseXPAction(50)); - reward.add(new SetQuestToTimeStampAction(QUEST_SLOT)); - reward.add(new IncreaseKarmaAction(10)); - reward.add(new ChatAction() { - @Override - public void fire(final Player player, final Sentence sentence, final EventRaiser npc) { - String rewardClass; - if (Rand.throwCoin() == 1) { - rewardClass = "meat"; - } else { - rewardClass = "ham"; - } - npc.say("Thank you! Here, take some " + rewardClass + " and charcoal!"); - final StackableItem reward = (StackableItem) SingletonRepository.getEntityManager().getItem(rewardClass); - reward.setQuantity(REWARDS); - player.equipOrPutOnGround(reward); - player.notifyWorldAboutChanges(); - } - }); - - npc.add(ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.YES_MESSAGES, - new PlayerHasItemWithHimCondition("wood", REQUIRED_WOOD), - ConversationStates.ATTENDING, null, - new MultipleActions(reward)); - - //player said the wood was for her but has dropped it from his bag or hands - npc.add(ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.YES_MESSAGES, - new NotCondition(new PlayerHasItemWithHimCondition("wood", REQUIRED_WOOD)), - ConversationStates.ATTENDING, - "Hey! Where did you put the wood?", - null); - - // player had wood but said it is not for sally - npc.add( - ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.NO_MESSAGES, - null, - ConversationStates.ATTENDING, - "Oh... well, I hope you find some quickly; this fire's going to burn out soon!", - null); - } +public class Campfire implements QuestManuscript { @Override - public void addToWorld() { - fillQuestInfo( - "Campfire", - "Sally wants to build a campfire, but she doesn't have any wood.", - true); - prepareRequestingStep(); - prepareBringingStep(); + public BringItemQuestBuilder story() { + BringItemQuestBuilder quest = new BringItemQuestBuilder(); + + quest.info() + .name("Campfire") + .description("Sally wants to build a campfire, but she doesn't have any wood.") + .internalName("campfire") + .repeatableAfterMinutes(60) + .minLevel(0) + .region(Region.ORRIL) + .questGiverNpc("Sally"); + + quest.history() + .whenNpcWasMet("I have met Sally south of Orril Castle.") + .whenQuestWasRejected("But I do not want to help her.") + .whenQuestWasAccepted("She asked me to fetch 10 pieces of wood to keep her fire going.") + .whenTaskWasCompleted("I found the wood needed for the fire.") + .whenQuestWasCompleted("I have given the wood to Sally. She gave me some food and charcoal in return. I also gained 50 xp") + .whenQuestCanBeRepeated("Sally's fire needs some wood again."); + + quest.offer() + .respondToRequest("I need more wood to keep my campfire running, But I can't leave it unattended to go get some! Could you please get some from the forest for me? I need ten pieces.") + .respondToUnrepeatableRequest("Thanks, but I think the wood, you brought, will last [remaining_time].") + .respondToRepeatedRequest("My campfire needs wood again, ten pieces of #wood will be enough. Could you please get those #wood pieces from the forest for me? Please say yes!") + .respondToAccept("Okay. You can find wood in the forest north of here. Come back when you get ten pieces of wood!") + .respondToReject("Oh dear, how am I going to cook all this meat? Perhaps I'll just have to feed it to the animals...") + .rejectionKarmaPenalty(5.0) + .remind("Please don't forget that you promised to collect ten pieces of wood for me!"); + + quest.task() + .requestItem(10, "wood"); + + quest.complete() + .greet("Hi again! You've got wood, I see; do you have those 10 pieces of wood I asked about earlier?") + .respondToReject("Oh... well, I hope you find some quickly; this fire's going to burn out soon!") + .respondToAccept(null) + .rewardWith(new IncreaseXPAction(50)) + .rewardWith(new IncreaseKarmaAction(10)) + .rewardWith(new EquipItemAction("charcoal", 10)) + .rewardWith(new EquipRandomItemAction("meat=10;ham=10", false, "Thank you! Here, take [this_these] [number_item] and charcoal!")); + + return quest; } - @Override - public String getName() { - return "Campfire"; - } - - @Override - public int getMinLevel() { - return 0; - } - - @Override - public String getNPCName() { - return "Sally"; - } - - @Override - public String getRegion() { - return Region.ORRIL; - } } diff --git a/src/games/stendhal/server/maps/quests/EggsForMarianne.java b/src/games/stendhal/server/maps/quests/EggsForMarianne.java index b78dc43c175..1360ed0fc1e 100644 --- a/src/games/stendhal/server/maps/quests/EggsForMarianne.java +++ b/src/games/stendhal/server/maps/quests/EggsForMarianne.java @@ -1,6 +1,5 @@ -/* $Id$ */ /*************************************************************************** - * (C) Copyright 2019 - Stendhal * + * (C) Copyright 2019-2023 - Stendhal * *************************************************************************** *************************************************************************** * * @@ -12,37 +11,11 @@ ***************************************************************************/ package games.stendhal.server.maps.quests; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - -import games.stendhal.common.Rand; -import games.stendhal.common.parser.Sentence; -import games.stendhal.server.core.engine.SingletonRepository; -import games.stendhal.server.entity.item.StackableItem; -import games.stendhal.server.entity.npc.ChatAction; -import games.stendhal.server.entity.npc.ConversationPhrases; -import games.stendhal.server.entity.npc.ConversationStates; -import games.stendhal.server.entity.npc.EventRaiser; -import games.stendhal.server.entity.npc.SpeakerNPC; -import games.stendhal.server.entity.npc.action.DropItemAction; +import games.stendhal.server.entity.npc.action.EquipRandomItemAction; import games.stendhal.server.entity.npc.action.IncreaseKarmaAction; import games.stendhal.server.entity.npc.action.IncreaseXPAction; -import games.stendhal.server.entity.npc.action.MultipleActions; -import games.stendhal.server.entity.npc.action.SayTimeRemainingAction; -import games.stendhal.server.entity.npc.action.SetQuestAction; -import games.stendhal.server.entity.npc.action.SetQuestAndModifyKarmaAction; -import games.stendhal.server.entity.npc.action.SetQuestToTimeStampAction; -import games.stendhal.server.entity.npc.condition.AndCondition; -import games.stendhal.server.entity.npc.condition.GreetingMatchesNameCondition; -import games.stendhal.server.entity.npc.condition.NotCondition; -import games.stendhal.server.entity.npc.condition.PlayerHasItemWithHimCondition; -import games.stendhal.server.entity.npc.condition.QuestInStateCondition; -import games.stendhal.server.entity.npc.condition.QuestNotInStateCondition; -import games.stendhal.server.entity.npc.condition.QuestNotStartedCondition; -import games.stendhal.server.entity.npc.condition.QuestStartedCondition; -import games.stendhal.server.entity.npc.condition.TimePassedCondition; -import games.stendhal.server.entity.player.Player; +import games.stendhal.server.entity.npc.quest.BringItemQuestBuilder; +import games.stendhal.server.entity.npc.quest.QuestManuscript; import games.stendhal.server.maps.Region; /** @@ -73,250 +46,58 @@ *
  • Unlimited, at least 60 minutes have to elapse before repeating
  • * */ -public class EggsForMarianne extends AbstractQuest { - - //a dozen of eggs - private static final int REQUIRED_EGGS = 12; - - //60 minutes before quest can be repeated - private static final int REQUIRED_MINUTES = 60; - - private static final String QUEST_SLOT = "eggs_for_marianne"; - - @Override - public String getSlotName() { - return QUEST_SLOT; - } - - @Override - public boolean isCompleted(final Player player) { - return player.hasQuest(QUEST_SLOT) && !"start".equals(player.getQuest(QUEST_SLOT)) && !"rejected".equals(player.getQuest(QUEST_SLOT)); - } +public class EggsForMarianne implements QuestManuscript { @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); + public BringItemQuestBuilder story() { + BringItemQuestBuilder quest = new BringItemQuestBuilder(); + + quest.info() + .name("Eggs for Marianne") + .description("Marianne's mom is going to make some pancakes and she needs some eggs.") + .internalName("eggs_for_marianne") + .repeatableAfterMinutes(60) + .minLevel(0) + .region(Region.DENIRAN) + .questGiverNpc("Marianne"); + + quest.history() + .whenNpcWasMet("I have met Marianne in Deniran City.") + .whenQuestWasRejected("She asked me to fetch some eggs, but I do not want to help her.") + .whenQuestWasAccepted("She asked me to fetch 12 eggs") + .whenTaskWasCompleted("I have found the eggs for Marianne.") + .whenQuestWasCompleted("I have given Marianne the eggs. She gave me some flowers in return.") + .whenQuestCanBeRepeated("Marianne needs more eggs again."); + + quest.offer() + .respondToRequest( + "I need a dozen of eggs. " + + "My mom asked me to collect eggs and she is going to make me pancakes! " + + "I'm afraid of getting close to those chickens! " + + "Could you please get eggs for me?") + .respondToUnrepeatableRequest("Thanks! I think the eggs you already brought me will be enough for another while...") + .respondToRepeatedRequest("My mom needs eggs again! Could you please get a dozen more for me?") + .respondToAccept( + "Okay. You can find eggs hunting chickens... I am so afraid of getting near those pesky chickens! " + + "Please come back when you found enough eggs for me!") + .respondToReject( + "Oh dear, what am I going to do with all these flowers? " + + "Perhaps I'll just leave them around some graves...") + .rejectionKarmaPenalty(5.0) + .remind("You promised to collect a dozen of eggs for me ... "); + + quest.task() + .requestItem(12, "egg"); + + quest.complete() + .greet("Hi again! You've got several eggs, I see. Do you have 12 eggs for me?") + .respondToReject("Oh... well, I hope you find some quickly. I'm getting hungry!") + .respondToAccept(null) + .rewardWith(new IncreaseXPAction(50)) + .rewardWith(new IncreaseKarmaAction(50)) + .rewardWith(new EquipRandomItemAction("pansy=12;daisies=12", false, "Thank you! Here, take [this_these] [number_item]!")); + + return quest; } - @Override - public List getHistory(final Player player) { - final List res = new ArrayList(); - if (!player.hasQuest(QUEST_SLOT)) { - return res; - } - res.add("I have met Marianne"); - final String questState = player.getQuest(QUEST_SLOT); - if ("rejected".equals(questState)) { - res.add("I do not want to help Marianne"); - return res; - } - res.add("I do want to help Marianne"); - if (player.isEquipped("egg", REQUIRED_EGGS) || isCompleted(player)) { - res.add("I have found some eggs for Marianne"); - } - if (isCompleted(player)) { - res.add("I have given Marianne the eggs. " + - "She gave me some flowers in return. " + - "I also gained some xp!"); - } - if(isRepeatable(player)){ - res.add("Marianne needs more eggs again."); - } - return res; - } - - private void prepareRequestingStep() { - final SpeakerNPC npc = npcs.get("Marianne"); - - // player returns with the promised eggs - npc.add(ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition( - new GreetingMatchesNameCondition(npc.getName()), - new QuestInStateCondition(QUEST_SLOT, "start"), - new PlayerHasItemWithHimCondition("egg", REQUIRED_EGGS)), - ConversationStates.QUEST_ITEM_BROUGHT, - "Hi again! You've got several eggs I see; " + - "Do you have as many eggs as I asked earlier?", - null); - - //player returns without promised eggs - npc.add(ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestInStateCondition(QUEST_SLOT, "start"), - new NotCondition( - new PlayerHasItemWithHimCondition("egg", REQUIRED_EGGS))), - ConversationStates.ATTENDING, - "You're back already? " + - "You promised to collect a dozen of eggs for me ... " + - "But it does not seem that you carry enough eggs with you!", - null); - - // first chat of player with Marianne - npc.add(ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestNotStartedCondition(QUEST_SLOT)), - ConversationStates.ATTENDING, "Hello you ... " + - "I need a little #favor if you please, you look so kind ... ", - null); - - // player who is rejected or 'done' but waiting to start again, returns - npc.add(ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestNotInStateCondition(QUEST_SLOT, "start"), - new QuestStartedCondition(QUEST_SLOT)), - ConversationStates.ATTENDING, - "Hello again, you!", - null); - - // if they ask for quest while on it, remind them - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new QuestInStateCondition(QUEST_SLOT, "start"), - ConversationStates.ATTENDING, - "You already promised me to bring me some eggs, do you not remember?", - null); - - // first time player asks/ player had rejected - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new QuestNotStartedCondition(QUEST_SLOT), - ConversationStates.QUEST_OFFERED, - "I need a dozen of eggs. " + - "My mom asked me to collect eggs and she is going to make me pancakes! " + - "I'm afraid of getting close to those chickens! " + - "Could you please get eggs for me?", - null); - - // player returns - enough time has passed - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new AndCondition( - new QuestNotInStateCondition(QUEST_SLOT, "start"), - new QuestStartedCondition(QUEST_SLOT), - new TimePassedCondition(QUEST_SLOT,REQUIRED_MINUTES)), - ConversationStates.QUEST_OFFERED, - "My mom needs eggs again! " + - "Could you please get a dozen more for me?", - null); - - // player returns - enough time has passed - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new AndCondition(new QuestNotInStateCondition(QUEST_SLOT, "start"), - new QuestStartedCondition(QUEST_SLOT), - new NotCondition(new TimePassedCondition(QUEST_SLOT,REQUIRED_MINUTES))), - ConversationStates.ATTENDING, - null, - new SayTimeRemainingAction(QUEST_SLOT,REQUIRED_MINUTES, - "Thanks! " + - "I think the eggs you already brought me " + - "will be enough for another while ...")); - - // player is willing to help - npc.add(ConversationStates.QUEST_OFFERED, - ConversationPhrases.YES_MESSAGES, - null, - ConversationStates.ATTENDING, - "Okay. " + - "You can find eggs hunting chickens... I am so afraid of getting near those pesky chickens! " + - "Please come back when you found enough eggs for me!", - new SetQuestAction(QUEST_SLOT, "start")); - - // player is not willing to help - npc.add(ConversationStates.QUEST_OFFERED, - ConversationPhrases.NO_MESSAGES, - null, - ConversationStates.ATTENDING, - "Oh dear, what am I going to do with all these flowers? " + - "Perhaps I'll just leave them around some graves...", - new SetQuestAndModifyKarmaAction(QUEST_SLOT, "rejected", -5.0)); - } - - private void prepareBringingStep() { - final SpeakerNPC npc = npcs.get("Marianne"); - // player has eggs and tells Marianne, yes, it is for her - - final List reward = new LinkedList(); - reward.add(new DropItemAction("egg", REQUIRED_EGGS)); - reward.add(new IncreaseXPAction(50)); - reward.add(new SetQuestToTimeStampAction(QUEST_SLOT)); - reward.add(new IncreaseKarmaAction(50)); - reward.add(new ChatAction() { - @Override - public void fire(final Player player, final Sentence sentence, final EventRaiser npc) { - String rewardClass; - if (Rand.throwCoin() == 1) { - rewardClass = "pansy"; - } else { - rewardClass = "daisies"; - } - npc.say("Thank you! Here, take some " + rewardClass + "!"); - final StackableItem reward = (StackableItem) SingletonRepository.getEntityManager().getItem(rewardClass); - reward.setQuantity(REQUIRED_EGGS); - player.equipOrPutOnGround(reward); - player.notifyWorldAboutChanges(); - } - }); - - npc.add(ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.YES_MESSAGES, - new PlayerHasItemWithHimCondition("egg", REQUIRED_EGGS), - ConversationStates.ATTENDING, null, - new MultipleActions(reward)); - - //player said the eggs was for her but has dropped it from his bag or hands - npc.add(ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.YES_MESSAGES, - new NotCondition(new PlayerHasItemWithHimCondition("egg", REQUIRED_EGGS)), - ConversationStates.ATTENDING, - "Hey! Where did you put the eggs?", - null); - - // player had eggs but said it is not for Marianne - npc.add( - ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.NO_MESSAGES, - null, - ConversationStates.ATTENDING, - "Oh... well, I hope you find some quickly;" + - "I'm getting hungry!", - null); - } - - @Override - public void addToWorld() { - fillQuestInfo( - "Eggs for Marianne", - "Marianne's mom is going to make some pancakes and she needs some eggs.", - true); - prepareRequestingStep(); - prepareBringingStep(); - } - - @Override - public String getName() { - return "EggsForMarianne"; - } - - @Override - public int getMinLevel() { - return 0; - } - - @Override - public String getNPCName() { - return "Marianne"; - } - - @Override - public String getRegion() { - return Region.DENIRAN; - } } diff --git a/src/games/stendhal/server/maps/quests/HatForMonogenes.java b/src/games/stendhal/server/maps/quests/HatForMonogenes.java index e6785890194..beb7806c37f 100644 --- a/src/games/stendhal/server/maps/quests/HatForMonogenes.java +++ b/src/games/stendhal/server/maps/quests/HatForMonogenes.java @@ -1,4 +1,3 @@ -/* $Id$ */ /*************************************************************************** * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** @@ -12,29 +11,11 @@ ***************************************************************************/ package games.stendhal.server.maps.quests; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - import games.stendhal.server.core.engine.SingletonRepository; -import games.stendhal.server.entity.npc.ChatAction; -import games.stendhal.server.entity.npc.ConversationPhrases; -import games.stendhal.server.entity.npc.ConversationStates; -import games.stendhal.server.entity.npc.SpeakerNPC; -import games.stendhal.server.entity.npc.action.DropItemAction; import games.stendhal.server.entity.npc.action.IncreaseKarmaAction; import games.stendhal.server.entity.npc.action.IncreaseXPAction; -import games.stendhal.server.entity.npc.action.MultipleActions; -import games.stendhal.server.entity.npc.action.SetQuestAction; -import games.stendhal.server.entity.npc.action.SetQuestAndModifyKarmaAction; -import games.stendhal.server.entity.npc.condition.AndCondition; -import games.stendhal.server.entity.npc.condition.GreetingMatchesNameCondition; -import games.stendhal.server.entity.npc.condition.NotCondition; -import games.stendhal.server.entity.npc.condition.PlayerHasItemWithHimCondition; -import games.stendhal.server.entity.npc.condition.QuestCompletedCondition; -import games.stendhal.server.entity.npc.condition.QuestInStateCondition; -import games.stendhal.server.entity.npc.condition.QuestNotCompletedCondition; -import games.stendhal.server.entity.player.Player; +import games.stendhal.server.entity.npc.quest.BringItemQuestBuilder; +import games.stendhal.server.entity.npc.quest.QuestManuscript; import games.stendhal.server.maps.Region; import games.stendhal.server.maps.semos.city.GreeterNPC; import games.stendhal.server.util.ResetSpeakerNPC; @@ -62,151 +43,55 @@ * * REPETITIONS: - None. */ -public class HatForMonogenes extends AbstractQuest { - private static final String QUEST_SLOT = "hat_monogenes"; - - - @Override - public String getSlotName() { - return QUEST_SLOT; - } - @Override - public List getHistory(final Player player) { - final List res = new ArrayList(); - if (player.hasQuest(QUEST_SLOT)) { - res.add("I have met Monogenes at the spring in Semos village"); - } - if (!player.hasQuest(QUEST_SLOT)) { - return res; - } - res.add("I have to find a hat, something leather to keep his head warm."); - if (player.isQuestInState(QUEST_SLOT, "start") - && player.isEquipped("leather helmet") - || player.isQuestCompleted(QUEST_SLOT)) { - res.add("I have found a hat."); - } - if (player.isQuestCompleted(QUEST_SLOT)) { - res.add("I gave the hat to Monogenes to keep his bald head warm."); - } - return res; - } - - private void createRequestingStep() { - final SpeakerNPC monogenes = npcs.get("Monogenes"); - - monogenes.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new QuestNotCompletedCondition(QUEST_SLOT), - ConversationStates.QUEST_OFFERED, - "Could you bring me a #hat to cover my bald head? Brrrrr! The days here in Semos are really getting colder...", - null); - - monogenes.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new QuestCompletedCondition(QUEST_SLOT), - ConversationStates.ATTENDING, - "Thanks for the offer, good friend, but this hat will last me five winters at least, and it's not like I need more than one.", - null); - - monogenes.add( - ConversationStates.QUEST_OFFERED, - ConversationPhrases.YES_MESSAGES, - null, - ConversationStates.ATTENDING, - "Thanks, my good friend. I'll be waiting here for your return!", - new SetQuestAction(QUEST_SLOT, "start")); - - monogenes.add( - ConversationStates.QUEST_OFFERED, - ConversationPhrases.NO_MESSAGES, - null, - ConversationStates.ATTENDING, - "You surely have more importants things to do, and little time to do them in. I'll just stay here and freeze to death, I guess... *sniff*", - new SetQuestAndModifyKarmaAction(QUEST_SLOT, "rejected", -5.0)); - - monogenes.add( - ConversationStates.QUEST_OFFERED, - "hat", - null, - ConversationStates.QUEST_OFFERED, - "You don't know what a hat is?! Anything light that can cover my head; like leather, for instance. Now, will you do it?", - null); - } - - private void createBringingStep() { - final SpeakerNPC monogenes = npcs.get("Monogenes"); - - monogenes.add(ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(monogenes.getName()), - new QuestInStateCondition(QUEST_SLOT, "start"), - new PlayerHasItemWithHimCondition("leather helmet")), - ConversationStates.QUEST_ITEM_BROUGHT, - "Hey! Is that leather hat for me?", null); - - monogenes.add(ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(monogenes.getName()), - new QuestInStateCondition(QUEST_SLOT, "start"), - new NotCondition(new PlayerHasItemWithHimCondition("leather helmet"))), - ConversationStates.ATTENDING, - "Hey, my good friend, remember that leather hat I asked you about before? It's still pretty chilly here...", - null); - - final List reward = new LinkedList(); - reward.add(new DropItemAction("leather helmet")); - reward.add(new IncreaseXPAction(50)); - reward.add(new IncreaseKarmaAction(10)); - reward.add(new SetQuestAction(QUEST_SLOT, "done")); - - // make sure the player isn't cheating by putting the - // helmet away and then saying "yes" - monogenes.add( - ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.YES_MESSAGES, - new PlayerHasItemWithHimCondition("leather helmet"), - ConversationStates.ATTENDING, - "Bless you, my good friend! Now my head will stay nice and warm.", - new MultipleActions(reward)); - - monogenes.add( - ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.NO_MESSAGES, - null, - ConversationStates.ATTENDING, - "I guess someone more fortunate will get his hat today... *sneeze*", - null); - } +public class HatForMonogenes implements QuestManuscript { @Override - public void addToWorld() { - fillQuestInfo( - "Hat for Monogenes", - "Monogenes wants a hat to help him keep warm during the winter.", - false); - createRequestingStep(); - createBringingStep(); + public BringItemQuestBuilder story() { + BringItemQuestBuilder quest = new BringItemQuestBuilder(); + + quest.info() + .name("Hat for Monogenes") + .description("Monogenes wants a hat to help him keep warm during the winter.") + .internalName("hat_monogenes") + .notRepeatable() + .minLevel(0) + .region(Region.SEMOS_CITY) + .questGiverNpc("Monogenes"); + + quest.history() + .whenNpcWasMet("I have met Monogenes at the spring in Semos village.") + .whenQuestWasRejected("He asked me for a hat, but I don't want to help.") + .whenQuestWasAccepted("I have to find a hat, something leather to keep his head warm.") + .whenTaskWasCompleted("I have found a hat.") + .whenQuestWasCompleted("I gave the hat to Monogenes to keep his bald head warm."); + + quest.offer() + .respondToRequest("Could you bring me a #hat to cover my bald head? Brrrrr! The days here in Semos are really getting colder...") + .respondToUnrepeatableRequest("Thanks for the offer, good friend, but this hat will last me five winters at least, and it's not like I need more than one.") + .respondToAccept("Thanks, my good friend. I'll be waiting here for your return!") + .respondToReject("You surely have more importants things to do, and little time to do them in. I'll just stay here and freeze to death, I guess... *sniff*") + .rejectionKarmaPenalty(5.0) + .remind("Hey, my good friend, remember that leather hat I asked you about before? It's still pretty chilly here...") + .respondTo("hat").saying("You don't know what a hat is?! Anything light that can cover my head; like leather, for instance. Now, will you do it?"); + + quest.task() + .requestItem(1, "leather helmet"); + + quest.complete() + .greet("Hey! Is that leather hat for me?") + .respondToReject("I guess someone more fortunate will get his hat today... *sneeze*") + .respondToAccept("Bless you, my good friend! Now my head will stay nice and warm.") + .rewardWith(new IncreaseXPAction(50)) + .rewardWith(new IncreaseKarmaAction(10)); + + return quest; } - @Override public boolean removeFromWorld() { - final boolean res = ResetSpeakerNPC.reload(new GreeterNPC(), getNPCName()); + final boolean res = ResetSpeakerNPC.reload(new GreeterNPC(), "Monogenes"); // reload other quests associated with Monogenes SingletonRepository.getStendhalQuestSystem().reloadQuestSlots("Monogenes"); return res; } - @Override - public String getName() { - return "HatForMonogenes"; - } - - @Override - public String getRegion() { - return Region.SEMOS_CITY; - } - @Override - public String getNPCName() { - return "Monogenes"; - } } diff --git a/src/games/stendhal/server/maps/quests/LookBookforCeryl.java b/src/games/stendhal/server/maps/quests/LookBookforCeryl.java index 34a65046821..2afb70bdfc4 100644 --- a/src/games/stendhal/server/maps/quests/LookBookforCeryl.java +++ b/src/games/stendhal/server/maps/quests/LookBookforCeryl.java @@ -1,4 +1,3 @@ -/* $Id$ */ /*************************************************************************** * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** @@ -12,30 +11,24 @@ ***************************************************************************/ package games.stendhal.server.maps.quests; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - import games.stendhal.server.core.engine.SingletonRepository; -import games.stendhal.server.entity.npc.ChatAction; import games.stendhal.server.entity.npc.ConversationPhrases; import games.stendhal.server.entity.npc.ConversationStates; +import games.stendhal.server.entity.npc.NPCList; import games.stendhal.server.entity.npc.SpeakerNPC; -import games.stendhal.server.entity.npc.action.DropItemAction; import games.stendhal.server.entity.npc.action.EquipItemAction; import games.stendhal.server.entity.npc.action.IncreaseKarmaAction; import games.stendhal.server.entity.npc.action.IncreaseXPAction; import games.stendhal.server.entity.npc.action.MultipleActions; import games.stendhal.server.entity.npc.action.SetQuestAction; -import games.stendhal.server.entity.npc.action.SetQuestAndModifyKarmaAction; import games.stendhal.server.entity.npc.condition.AndCondition; import games.stendhal.server.entity.npc.condition.GreetingMatchesNameCondition; import games.stendhal.server.entity.npc.condition.NotCondition; import games.stendhal.server.entity.npc.condition.PlayerHasItemWithHimCondition; -import games.stendhal.server.entity.npc.condition.QuestCompletedCondition; import games.stendhal.server.entity.npc.condition.QuestInStateCondition; import games.stendhal.server.entity.npc.condition.QuestNotStartedCondition; -import games.stendhal.server.entity.player.Player; +import games.stendhal.server.entity.npc.quest.BringItemQuestBuilder; +import games.stendhal.server.entity.npc.quest.QuestManuscript; import games.stendhal.server.maps.Region; import games.stendhal.server.maps.orril.magician_house.WitchNPC; import games.stendhal.server.maps.semos.library.LibrarianNPC; @@ -66,84 +59,75 @@ * * REPETITIONS: None */ -public class LookBookforCeryl extends AbstractQuest { - private static final String QUEST_SLOT = "ceryl_book"; - - +public class LookBookforCeryl implements QuestManuscript { + private final static String QUEST_SLOT = "ceryl_book"; @Override - public String getSlotName() { - return QUEST_SLOT; - } - - private void step1LearnAboutQuest() { - - final SpeakerNPC npc = npcs.get("Ceryl"); - - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new QuestNotStartedCondition(QUEST_SLOT), - ConversationStates.ATTENDING, - "I am looking for a very special #book.", null); - - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new QuestCompletedCondition(QUEST_SLOT), - ConversationStates.ATTENDING, - "I have nothing for you now.", null); + public BringItemQuestBuilder story() { + BringItemQuestBuilder quest = new BringItemQuestBuilder(); + + quest.info() + .name("Look for a Book for Ceryl") + .description("Ceryl wants an old book that was checked out.") + .internalName(QUEST_SLOT) + .notRepeatable() + .minLevel(0) + .region(Region.SEMOS_CITY) + .questGiverNpc("Ceryl"); + + quest.history() + .whenNpcWasMet("I have met Ceryl at the library, he's the librarian there.") + .whenQuestWasRejected("I do not want to find the book.") + .whenQuestWasAccepted("I promised to fetch the black book from Jynath.") + .whenTaskWasCompleted("I have talked to Jynath and got the book.") + .whenQuestWasCompleted("I have returned the book to Ceryl and got a little reward."); + + quest.offer() + .respondToRequest("I am looking for a very special book. Could you ask #Jynath to return it? She has had it for months now, and people are looking for it.") + .respondToUnrepeatableRequest("I have nothing for you now.") + .respondToAccept("Great! Please get me it as quickly as possible... there's a huge waiting list!") + .respondTo("jynath").saying("Jynath is the witch who lives south of Or'ril castle, southwest of here. So, will you get me the book?") + .respondToReject("Oh... I suppose I will have to get somebody else to do it, then.") + .rejectionKarmaPenalty(5.0) + .remind("I really need that book now! Go to talk with #Jynath."); + + SpeakerNPC npc = NPCList.get().get("Ceryl"); + npc.addReply("jynath", "Jynath is the witch who lives south of Or'ril castle, southwest of here."); - /** Other conditions not met e.g. quest completed */ - npc.addReply("book","If you want to learn more, chat to my friend Wikipedian in Ados library.", null); + step2getBook(); + quest.task() + .requestItem(1, "black book"); - /** If quest is not started yet, start it. */ - npc.add( - ConversationStates.ATTENDING, - "book", new QuestNotStartedCondition(QUEST_SLOT), - ConversationStates.QUEST_OFFERED, - "Could you ask #Jynath to return her book? She's had it for months now, and people are looking for it.", - null); + quest.complete() + .greet("Hi, did you get the book from Jynath?") + .respondToReject("Oh... I suppose I will have to get somebody else to fetch it, then.") + .respondToAccept("Oh, you got the book back! Phew, thanks!") + .rewardWith(new IncreaseXPAction(100)) + .rewardWith(new IncreaseKarmaAction(10)) + .rewardWith(new EquipItemAction("money", 50)); + // There is no other way to get the book. + // Remove that quest slot so that the player can get + // it again from Jynath + // As the book is both bound and useless outside the + // quest, this is not a problem npc.add( - ConversationStates.QUEST_OFFERED, - ConversationPhrases.YES_MESSAGES, - null, + ConversationStates.IDLE, + ConversationPhrases.GREETING_MESSAGES, + new AndCondition(new GreetingMatchesNameCondition(npc.getName()), + new QuestInStateCondition(QUEST_SLOT, "jynath"), + new NotCondition(new PlayerHasItemWithHimCondition("black book"))), ConversationStates.ATTENDING, - "Great! Please get me it as quickly as possible... there's a huge waiting list!", + "Haven't you got that #book back from #Jynath? Please go look for it, quickly!", new SetQuestAction(QUEST_SLOT, "start")); - npc.add( - ConversationStates.QUEST_OFFERED, - ConversationPhrases.NO_MESSAGES, - null, - ConversationStates.ATTENDING, - "Oh... I suppose I will have to get somebody else to do it, then.", - new SetQuestAndModifyKarmaAction(QUEST_SLOT, "rejected", -5.0)); - - npc.add( - ConversationStates.QUEST_OFFERED, - "jynath", - null, - ConversationStates.QUEST_OFFERED, - "Jynath is the witch who lives south of Or'ril castle, southwest of here. So, will you get me the book?", - null); + return quest; + } - /** Remind player about the quest */ - npc.add(ConversationStates.ATTENDING, "book", - new QuestInStateCondition(QUEST_SLOT, "start"), - ConversationStates.ATTENDING, - "I really need that book now! Go to talk with #Jynath.", null); - npc.add( - ConversationStates.ATTENDING, - "jynath", - null, - ConversationStates.ATTENDING, - "Jynath is the witch who lives south of Or'ril castle, southwest of here.", - null); - } private void step2getBook() { - final SpeakerNPC npc = npcs.get("Jynath"); + final SpeakerNPC npc = NPCList.get().get("Jynath"); /** * If player has quest and is in the correct state, just give him the @@ -182,103 +166,12 @@ private void step2getBook() { null); } - private void step3returnBook() { - final SpeakerNPC npc = npcs.get("Ceryl"); - - /** Complete the quest */ - final List reward = new LinkedList(); - reward.add(new DropItemAction("black book")); - reward.add(new EquipItemAction("money", 50)); - reward.add(new IncreaseXPAction(100)); - reward.add(new IncreaseKarmaAction(10.0)); - reward.add(new SetQuestAction(QUEST_SLOT, "done")); - npc.add( - ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestInStateCondition(QUEST_SLOT, "jynath"), - new PlayerHasItemWithHimCondition("black book")), - ConversationStates.ATTENDING, - "Oh, you got the book back! Phew, thanks!", - new MultipleActions(reward)); - - // There is no other way to get the book. - // Remove that quest slot so that the player can get - // it again from Jynath - // As the book is both bound and useless outside the - // quest, this is not a problem - npc.add( - ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestInStateCondition(QUEST_SLOT, "jynath"), - new NotCondition(new PlayerHasItemWithHimCondition("black book"))), - ConversationStates.ATTENDING, - "Haven't you got that #book back from #Jynath? Please go look for it, quickly!", - new SetQuestAction(QUEST_SLOT, "start")); - } - - - @Override - public List getHistory(final Player player) { - final List res = new ArrayList(); - if (!player.hasQuest(QUEST_SLOT)) { - return res; - } - res.add("I have met Ceryl at the library, he's the librarian there."); - final String questState = player.getQuest(QUEST_SLOT); - if (questState.equals("rejected")) { - res.add("I do not want to find the book."); - } - if (player.isQuestInState(QUEST_SLOT, "start", "jynath", "done")) { - res.add("I promised to fetch the black book from Jynath."); - } - if (questState.equals("jynath") && player.isEquipped("black book") - || questState.equals("done")) { - res.add("I have talked to Jynath, and have the book."); - } - if (questState.equals("jynath") && !player.isEquipped("black book")) { - res.add("I do not have the black book Jynath has."); - } - if (questState.equals("done")) { - res.add("I have returned the book to Ceryl and got a little reward."); - } - return res; - } - - @Override - public void addToWorld() { - fillQuestInfo( - "Look for a Book for Ceryl", - "Ceryl wants an old book that was checked out.", - false); - step1LearnAboutQuest(); - step2getBook(); - step3returnBook(); - } - - @Override public boolean removeFromWorld() { - final boolean res = ResetSpeakerNPC.reload(new LibrarianNPC(), getNPCName()) + final boolean res = ResetSpeakerNPC.reload(new LibrarianNPC(), "Ceryl") && ResetSpeakerNPC.reload(new WitchNPC(), "Jynath"); // reload other quests associated with Ceryl SingletonRepository.getStendhalQuestSystem().reloadQuestSlots("obsidian_knife"); return res; } - - @Override - public String getName() { - return "LookBookforCeryl"; - } - - @Override - public String getRegion() { - return Region.SEMOS_CITY; - } - - @Override - public String getNPCName() { - return "Ceryl"; - } } diff --git a/src/games/stendhal/server/maps/quests/PlinksToy.java b/src/games/stendhal/server/maps/quests/PlinksToy.java index fc6fabd6434..5767c4fb1a0 100644 --- a/src/games/stendhal/server/maps/quests/PlinksToy.java +++ b/src/games/stendhal/server/maps/quests/PlinksToy.java @@ -1,6 +1,5 @@ -/* $Id$ */ /*************************************************************************** - * (C) Copyright 2003-2010 - Stendhal * + * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** *************************************************************************** * * @@ -12,32 +11,17 @@ ***************************************************************************/ package games.stendhal.server.maps.quests; -import java.util.ArrayList; import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; import games.stendhal.server.core.engine.SingletonRepository; import games.stendhal.server.core.engine.StendhalRPZone; import games.stendhal.server.entity.mapstuff.spawner.PassiveEntityRespawnPoint; -import games.stendhal.server.entity.npc.ChatAction; -import games.stendhal.server.entity.npc.ConversationPhrases; -import games.stendhal.server.entity.npc.ConversationStates; +import games.stendhal.server.entity.npc.NPCList; import games.stendhal.server.entity.npc.SpeakerNPC; -import games.stendhal.server.entity.npc.action.DropItemAction; import games.stendhal.server.entity.npc.action.IncreaseKarmaAction; import games.stendhal.server.entity.npc.action.IncreaseXPAction; -import games.stendhal.server.entity.npc.action.MultipleActions; -import games.stendhal.server.entity.npc.action.SetQuestAction; -import games.stendhal.server.entity.npc.condition.AndCondition; -import games.stendhal.server.entity.npc.condition.GreetingMatchesNameCondition; -import games.stendhal.server.entity.npc.condition.NotCondition; -import games.stendhal.server.entity.npc.condition.OrCondition; -import games.stendhal.server.entity.npc.condition.PlayerHasItemWithHimCondition; -import games.stendhal.server.entity.npc.condition.QuestCompletedCondition; -import games.stendhal.server.entity.npc.condition.QuestNotCompletedCondition; -import games.stendhal.server.entity.npc.condition.QuestNotStartedCondition; -import games.stendhal.server.entity.player.Player; +import games.stendhal.server.entity.npc.quest.BringItemQuestBuilder; +import games.stendhal.server.entity.npc.quest.QuestManuscript; import games.stendhal.server.maps.Region; /** @@ -53,85 +37,60 @@ * * REPETITIONS:
    • None.
    */ -public class PlinksToy extends AbstractQuest { - - private static final String QUEST_SLOT = "plinks_toy"; - - @Override - public String getSlotName() { - return QUEST_SLOT; - } +public class PlinksToy implements QuestManuscript { @Override - public List getHistory(final Player player) { - final List res = new ArrayList(); - if (!player.hasQuest(QUEST_SLOT)) { - if (player.isEquipped("teddy")) { - res.add("I found a bear which might belong to someone else."); - } - return res; - } - res.add("I have met Plink"); - final String questState = player.getQuest(QUEST_SLOT); - if (questState.equals("rejected")) { - res.add("I do not want to find Plink's toy bear."); - return res; - } - res.add("Plink begged me to look for his teddy in a garden with lots of wolves."); - if (player.isEquipped("teddy") || isCompleted(player)) { - res.add("I have found Plink's toy bear"); - } - if (isCompleted(player)) { - res.add("I gave Plink his bear."); - } - return res; - } - - private void step_1() { - final SpeakerNPC npc = npcs.get("Plink"); - - npc.add( - ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestNotCompletedCondition(QUEST_SLOT), - new NotCondition(new PlayerHasItemWithHimCondition("teddy"))), - ConversationStates.QUEST_OFFERED, - "*cries* There were wolves in the #park! *sniff* I ran away, but I dropped my #teddy! Please will you get it for me? *sniff* Please?", - null); - - npc.add(ConversationStates.QUEST_OFFERED, - ConversationPhrases.YES_MESSAGES, null, - ConversationStates.IDLE, "*sniff* Thanks a lot! *smile*", - new SetQuestAction(QUEST_SLOT, "start")); - - npc.add(ConversationStates.QUEST_OFFERED, ConversationPhrases.NO_MESSAGES, null, - ConversationStates.QUEST_OFFERED, - "*sniff* But... but... PLEASE! *cries*", null); - - npc.add( - ConversationStates.QUEST_OFFERED, - Arrays.asList("wolf", "wolves"), - null, - ConversationStates.QUEST_OFFERED, - "They came in from the plains, and now they're hanging around the #park over to the east a little ways. I'm not allowed to go near them, they're dangerous.", - null); - - npc.add( - ConversationStates.QUEST_OFFERED, - "park", - null, - ConversationStates.QUEST_OFFERED, - "My parents told me not to go to the park by myself, but I got lost when I was playing... Please don't tell them! Can you bring my #teddy back?", - null); - - npc.add(ConversationStates.QUEST_OFFERED, "teddy", null, - ConversationStates.QUEST_OFFERED, - "Teddy is my favourite toy! Please will you bring him back?", - null); + public BringItemQuestBuilder story() { + BringItemQuestBuilder quest = new BringItemQuestBuilder(); + + quest.info() + .name("Plink's Toy") + .description("Plink is a sweet little boy, and like many little boys, is frightened of wolves") + .internalName("plinks_toy") + .notRepeatable() + .minLevel(0) + .region(Region.SEMOS_SURROUNDS) + .questGiverNpc("Plink"); + + quest.history() + .whenNpcWasMet("I have met Plink.") + .whenQuestWasRejected("I do not want to find Plink's toy bear.") + .whenQuestWasAccepted("Plink begged me to look for his teddy in a garden with lots of wolves.") + .whenTaskWasCompleted("I have found Plink's toy bear.") + .whenQuestWasCompleted("I gave the bear to Plink and he was extremly happy."); + + quest.offer() + .begOnGreeting("*cries* There were wolves in the #park! *sniff* I ran away, but I dropped my #teddy! Please will you get it for me? *sniff* Please?") + .respondToRequest("*cries* There were wolves in the #park! *sniff* I ran away, but I dropped my #teddy! Please will you get it for me? *sniff* Please?") + .respondToUnrepeatableRequest("You found my teddy already near by the wolves! I still squeeze and hug it :)") + .respondToAccept("*sniff* Thanks a lot! *smile*") + .respondToReject("*sniff* But... but... PLEASE! *cries*") + .rejectionKarmaPenalty(10.0) + .remind("I lost my teddy in the #park over east, where all those #wolves are hanging about.") + .respondTo("wolf", "wolves").saying("They came in from the plains, and now they're hanging around the #park over to the east a little ways. I'm not allowed to go near them, they're dangerous.") + .respondTo("park").saying("My parents told me not to go to the park by myself, but I got lost when I was playing... Please don't tell them! Can you bring my #teddy back?") + .respondTo("teddy").saying("Teddy is my favourite toy! Please will you bring him back?"); + + final SpeakerNPC npc = NPCList.get().get("Plink"); + npc.addReply(Arrays.asList("wolf", "wolves"), "They came in from the plains, and now they're hanging around the #park over to the east a little ways. I'm not allowed to go near them, they're dangerous."); + npc.addReply("park", "My parents told me not to go to the park by myself, but I got lost when I was playing... Please don't tell them!"); + npc.addReply("teddy", "Teddy is my favourite toy! Please bring him back to me."); + + quest.task() + .requestItem(1, "teddy"); + step2(); + + quest.complete() + .greet("Ah, I see, you have enough coal to keep my BBQ on! Is it for me?") + .respondToReject("Well then, hopefully someone else will help me before my BBQ goes out.") + .respondToAccept("You found him! *hugs teddy* Thank you, thank you! *smile*") + .rewardWith(new IncreaseXPAction(20)) + .rewardWith(new IncreaseKarmaAction(10)); + + return quest; } - private void step_2() { + private void step2() { final StendhalRPZone zone = SingletonRepository.getRPWorld().getZone("0_semos_plains_n"); final PassiveEntityRespawnPoint teddyRespawner = new PassiveEntityRespawnPoint("teddy", 1500); teddyRespawner.setPosition(107, 84); @@ -140,66 +99,4 @@ private void step_2() { teddyRespawner.setToFullGrowth(); } - - private void step_3() { - final SpeakerNPC npc = npcs.get("Plink"); - - final List reward = new LinkedList(); - reward.add(new DropItemAction("teddy")); - reward.add(new IncreaseXPAction(20)); - reward.add(new SetQuestAction(QUEST_SLOT, "done")); - reward.add(new IncreaseKarmaAction(10)); - - npc.add(ConversationStates.IDLE, ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new OrCondition( - new QuestNotStartedCondition(QUEST_SLOT), - new QuestNotCompletedCondition(QUEST_SLOT)), - new PlayerHasItemWithHimCondition("teddy")), - ConversationStates.ATTENDING, - "You found him! *hugs teddy* Thank you, thank you! *smile*", - new MultipleActions(reward)); - - npc.add( - ConversationStates.ATTENDING, - "teddy", - new AndCondition(new QuestNotCompletedCondition(QUEST_SLOT), new NotCondition(new PlayerHasItemWithHimCondition("teddy"))), - ConversationStates.ATTENDING, - "I lost my teddy in the #park over east, where all those #wolves are hanging about.", - null); - - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestCompletedCondition(QUEST_SLOT)), - ConversationStates.ATTENDING, - "You found my teddy already near by the wolves! I still squeeze and hug it :)", null); - } - - @Override - public void addToWorld() { - fillQuestInfo( - "Plink's Toy", - "Plink is a sweet little boy, and like many little boys, is frightened of wolves.", - false); - step_1(); - step_2(); - step_3(); - } - - @Override - public String getName() { - return "PlinksToy"; - } - - @Override - public String getNPCName() { - return "Plink"; - } - - @Override - public String getRegion() { - return Region.SEMOS_SURROUNDS; - } - } diff --git a/src/games/stendhal/server/maps/quests/TrapsForKlaas.java b/src/games/stendhal/server/maps/quests/TrapsForKlaas.java index 00de47673a8..95a1a09238a 100644 --- a/src/games/stendhal/server/maps/quests/TrapsForKlaas.java +++ b/src/games/stendhal/server/maps/quests/TrapsForKlaas.java @@ -1,5 +1,5 @@ /*************************************************************************** - * (C) Copyright 2003-2010 - Stendhal * + * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** *************************************************************************** * * @@ -11,10 +11,7 @@ ***************************************************************************/ package games.stendhal.server.maps.quests; -import java.util.ArrayList; import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; import games.stendhal.common.parser.Sentence; import games.stendhal.server.core.engine.SingletonRepository; @@ -25,27 +22,24 @@ import games.stendhal.server.entity.npc.ConversationPhrases; import games.stendhal.server.entity.npc.ConversationStates; import games.stendhal.server.entity.npc.EventRaiser; +import games.stendhal.server.entity.npc.NPCList; import games.stendhal.server.entity.npc.SpeakerNPC; -import games.stendhal.server.entity.npc.action.DropItemAction; +import games.stendhal.server.entity.npc.action.ConditionalAction; import games.stendhal.server.entity.npc.action.EquipItemAction; import games.stendhal.server.entity.npc.action.IncreaseKarmaAction; import games.stendhal.server.entity.npc.action.IncreaseXPAction; import games.stendhal.server.entity.npc.action.MultipleActions; -import games.stendhal.server.entity.npc.action.SayTimeRemainingAction; -import games.stendhal.server.entity.npc.action.SetQuestAction; -import games.stendhal.server.entity.npc.action.SetQuestAndModifyKarmaAction; -import games.stendhal.server.entity.npc.action.SetQuestToTimeStampAction; +import games.stendhal.server.entity.npc.action.SayTextAction; import games.stendhal.server.entity.npc.condition.AndCondition; -import games.stendhal.server.entity.npc.condition.GreetingMatchesNameCondition; import games.stendhal.server.entity.npc.condition.NotCondition; import games.stendhal.server.entity.npc.condition.PlayerCanEquipItemCondition; -import games.stendhal.server.entity.npc.condition.PlayerHasItemWithHimCondition; import games.stendhal.server.entity.npc.condition.PlayerHasItemdataItemWithHimCondition; import games.stendhal.server.entity.npc.condition.QuestActiveCondition; import games.stendhal.server.entity.npc.condition.QuestCompletedCondition; import games.stendhal.server.entity.npc.condition.QuestNotStartedCondition; import games.stendhal.server.entity.npc.condition.QuestRegisteredCondition; -import games.stendhal.server.entity.npc.condition.TimePassedCondition; +import games.stendhal.server.entity.npc.quest.BringItemQuestBuilder; +import games.stendhal.server.entity.npc.quest.QuestManuscript; import games.stendhal.server.entity.player.Player; import games.stendhal.server.maps.Region; @@ -75,207 +69,64 @@ *
  • Every 24 hours
  • * */ -public class TrapsForKlaas extends AbstractQuest { - - public final int REQUIRED_TRAPS = 20; - - // Time player must wait to repeat quest (1 day) - private static final int WAIT_TIME = 60 * 24; - - private static final String QUEST_SLOT = "traps_for_klaas"; - private static final String info_string = "note to apothecary"; - +public class TrapsForKlaas implements QuestManuscript { + private final static String QUEST_SLOT = "traps_for_klaas"; @Override - public List getHistory(final Player player) { - final List res = new ArrayList(); - if (!player.hasQuest(QUEST_SLOT)) { - return res; - } - res.add("I have talked to Klaas."); - final String questState = player.getQuest(QUEST_SLOT); - if ("rejected".equals(questState)) { - res.add("I do not care to deal with rodents."); - } - if (player.isQuestInState(QUEST_SLOT, "start", "done")) { - res.add("I promised to gather " + REQUIRED_TRAPS + " rodent traps and bring them to Klaas."); - } - if (player.isQuestInState(QUEST_SLOT, 0, "done")) { - res.add("I gave the rodent traps to Klaas. I got some experience and antidotes."); - } - if (isRepeatable(player)) { - res.add("I should check if Klaas needs my help again."); - } - return res; - } - - private void prepareRequestingStep() { - final SpeakerNPC npc = npcs.get("Klaas"); - - // Player asks for quest - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new AndCondition( - new NotCondition(new QuestActiveCondition(QUEST_SLOT)), - new TimePassedCondition(QUEST_SLOT, 1, WAIT_TIME) - ), - ConversationStates.QUEST_OFFERED, - "The rats down here have been getting into the food storage. Would you help me rid us of the varmints?", - null); - - // Player requests quest before wait period ended - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new NotCondition(new TimePassedCondition(QUEST_SLOT, 1, WAIT_TIME)), - ConversationStates.ATTENDING, - null, - new SayTimeRemainingAction(QUEST_SLOT, 1, WAIT_TIME, "Thanks for the traps. Now the food will be safe. But I may need your help again in")); - - // Player asks for quest after already started - npc.add(ConversationStates.ATTENDING, - ConversationPhrases.QUEST_MESSAGES, - new QuestActiveCondition(QUEST_SLOT), - ConversationStates.ATTENDING, - "I believe I already asked you to get me " + REQUIRED_TRAPS + " rodent traps.", - null); - - // Player accepts quest - npc.add( - ConversationStates.QUEST_OFFERED, - ConversationPhrases.YES_MESSAGES, - null, - ConversationStates.ATTENDING, - "Thanks, I need you to bring me bring me " + REQUIRED_TRAPS + " #rodent #traps. Please hurry! We can't afford to lose anymore food.", - new SetQuestAction(QUEST_SLOT, "start")); - - // Player rejects quest - npc.add( - ConversationStates.QUEST_OFFERED, - ConversationPhrases.NO_MESSAGES, - null, - // Klaas walks away - ConversationStates.IDLE, - "Don't waste my time. I've got to protect the cargo.", - new SetQuestAndModifyKarmaAction(QUEST_SLOT, "rejected", -5.0)); - - // Player asks about rodent traps + public BringItemQuestBuilder story() { + BringItemQuestBuilder quest = new BringItemQuestBuilder(); + + quest.info() + .name("Traps for Klaas") + .description("Klaas, the cargo caretaker on the Athor ferry, is in need of some rodent traps.") + .internalName(QUEST_SLOT) + .repeatableAfterMinutes(24 * 60) + .minLevel(0) + .region(Region.ATHOR_ISLAND) + .questGiverNpc("Klaas"); + + quest.history() + .whenNpcWasMet("I have talked to Klaas on the ship to Athor.") + .whenQuestWasRejected("I do not care about dealing with rodents.") + .whenQuestWasAccepted("I promised to gather 20 rodent traps and bring them to Klaas.") + .whenTaskWasCompleted("I got enough traps.") + .whenQuestWasCompleted("I gave the rodent traps to Klaas. I got some experience and antidotes.") + .whenQuestCanBeRepeated("I should check if Klaas needs my help again."); + + quest.offer() + .respondToRequest("The rats down here have been getting into the food storage. Would you help me rid us of the varmints?") + .respondToUnrepeatableRequest("Thanks for the traps. Now the food will be safe. But I may need your help again soon.") + .respondToRepeatedRequest("The rats down here have been getting into the food storage. Would you help me rid us of the varmints?") + .respondToAccept("Thanks, I need you to bring me bring me 20 #rodent #traps. Please hurry! We can't afford to lose anymore food.") + .respondToReject("Don't waste my time. I've got to protect the cargo.") + .rejectionKarmaPenalty(5.0) + .remind("I believe, I already asked you to get me 20 rodent traps."); + + final SpeakerNPC npc = NPCList.get().get("Klaas"); npc.add( - ConversationStates.ATTENDING, - Arrays.asList("rodent trap", "trap", "rodent traps", "traps"), - new QuestActiveCondition(QUEST_SLOT), - ConversationStates.ATTENDING, - "I don't know of anyone who sells 'em. But I did hear a story once about a fella who killed a large rat and discovered a trap snapped shut on its foot.", - null); - - } - - private void prepareBringingStep() { - final SpeakerNPC npc = npcs.get("Klaas"); - - final ChatCondition giveNoteRewardCondition = new ChatCondition() { - private final String avrQuestSlot = "antivenom_ring"; - - @Override - public boolean fire(final Player player, final Sentence sentence, final Entity npc) { - if (!new QuestRegisteredCondition(avrQuestSlot).fire(player, sentence, npc)) { - return false; - } - - // note has already been given to Jameson & Antivenom Ring quest has already been started or completed - if (player.getQuest(avrQuestSlot) != null) { - return false; - } - - // player already has a note - // FIXME: PlayerOwnsItemIncludingBankCondition currently doesn't support itemdata items - if (player.isEquippedWithItemdata("note", info_string)) { - return false; - } - - return true; - } - }; - - // Reward - final List reward = new LinkedList(); - reward.add(new DropItemAction("rodent trap", 20)); - reward.add(new EquipItemAction("greater antidote", 5)); - reward.add(new IncreaseXPAction(1000)); - reward.add(new IncreaseKarmaAction(10)); - reward.add(new SetQuestAction(QUEST_SLOT, "done")); - reward.add(new SetQuestToTimeStampAction(QUEST_SLOT, 1)); - - // action that gives player note to apothecary - final ChatAction equipNoteAction = new ChatAction() { - @Override - public void fire(final Player player, final Sentence sentence, final EventRaiser npc) { - final Item note = SingletonRepository.getEntityManager().getItem("note"); - note.setItemData(info_string); - note.setDescription("You see a note written to an apothecary. It is a recommendation from Klaas."); - note.setBoundTo(player.getName()); - player.equipOrPutOnGround(note); - } - }; - - // Player has all 20 traps - npc.add(ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestActiveCondition(QUEST_SLOT), - new PlayerHasItemWithHimCondition("rodent trap")), - ConversationStates.QUEST_ITEM_BROUGHT, - "Did you bring any traps?", - null); - - // Player is not carrying any traps - npc.add(ConversationStates.IDLE, - ConversationPhrases.GREETING_MESSAGES, - new AndCondition(new GreetingMatchesNameCondition(npc.getName()), - new QuestActiveCondition(QUEST_SLOT), - new NotCondition(new PlayerHasItemWithHimCondition("rodent trap"))), - ConversationStates.ATTENDING, - "I could really use those #traps. How can I help you?", - null); - - // Player is not carrying 20 traps - npc.add(ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.YES_MESSAGES, - new AndCondition(new PlayerHasItemWithHimCondition("rodent trap"), - new NotCondition(new PlayerHasItemWithHimCondition("rodent trap", 20))), - ConversationStates.ATTENDING, - "I'm sorry but I need 20 #rodent #traps", - null); - - // brings traps & has already started/completed antivenom ring quest - npc.add(ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.YES_MESSAGES, - new AndCondition( - new NotCondition(giveNoteRewardCondition), - new PlayerHasItemWithHimCondition("rodent trap", 20)), ConversationStates.ATTENDING, - "Thanks! I've got to get these set up as quickly as possible. Take these antidotes as a reward.", - new MultipleActions(reward)); - - // brings traps & has not started antivenom ring quest - npc.add(ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.YES_MESSAGES, - new AndCondition( - giveNoteRewardCondition, - new PlayerHasItemWithHimCondition("rodent trap", 20)), + Arrays.asList("rodent trap", "trap", "rodent traps", "traps"), + new QuestActiveCondition("traps_for_klaas"), ConversationStates.ATTENDING, - "Thanks! I've got to get these set up as quickly as possible. Take these antidotes as a reward. I used to know an old #apothecary. Take this note to him. Maybe he can help you out with something.", - new MultipleActions( - new MultipleActions(reward), - equipNoteAction)); - - // Player says did not bring items - npc.add( - ConversationStates.QUEST_ITEM_BROUGHT, - ConversationPhrases.NO_MESSAGES, - null, - ConversationStates.ATTENDING, - "Please hurry! I just found another box of food that's been chewed through.", - null); + "I don't know of anyone who sells 'em. But I did hear a story once about a fella who killed a large rat and discovered a trap snapped shut on its foot.", + null); + + + quest.task() + .requestItem(20, "rodent trap"); + + quest.complete() + .greet("Did you bring any traps?") + .respondToReject("Please hurry! I just found another box of food that's been chewed through.") + .respondToAccept("Thanks! I've got to get these set up as quickly as possible. Take these antidotes as a reward.") + .rewardWith(new IncreaseXPAction(1000)) + .rewardWith(new IncreaseKarmaAction(10)) + .rewardWith(new EquipItemAction("greater antidote", 5)) + .rewardWith(new ConditionalAction( + giveNoteRewardCondition, + new MultipleActions( + equipNoteAction, + new SayTextAction("I used to know an old #apothecary. Take this note to him. Maybe he can help you out with something.")))); // Player has lost note npc.add(ConversationStates.IDLE, @@ -291,6 +142,7 @@ public void fire(final Player player, final Sentence sentence, final EventRaiser + " Remember to ask around about an #apothecary.", equipNoteAction); + // player lost note, but doesn't have room in inventory npc.add(ConversationStates.IDLE, ConversationPhrases.GREETING_MESSAGES, @@ -302,52 +154,46 @@ public void fire(final Player player, final Sentence sentence, final EventRaiser ConversationStates.ATTENDING, "You lost the note? Well, I could write another one. But it doesn't look like you have room to carry it.", null); - } - @Override - public void addToWorld() { - fillQuestInfo( - "Traps for Klaas", - "Klaas, the cargo caretaker on the Athor ferry, is in need of some rodent traps.", - false); - prepareRequestingStep(); - prepareBringingStep(); + return quest; } - @Override - public String getSlotName() { - return QUEST_SLOT; - } - - @Override - public String getName() { - return "TrapsForKlaas"; - } - - public String getTitle() { - - return "TrapsForKlaas"; - } + + // action that gives player note to apothecary + private static final String info_string = "note to apothecary"; + final ChatAction equipNoteAction = new ChatAction() { + @Override + public void fire(final Player player, final Sentence sentence, final EventRaiser npc) { + final Item note = SingletonRepository.getEntityManager().getItem("note"); + note.setItemData(info_string); + note.setDescription("You see a note written to an apothecary. It is a recommendation from Klaas."); + note.setBoundTo(player.getName()); + player.equipOrPutOnGround(note); + } + }; + + final ChatCondition giveNoteRewardCondition = new ChatCondition() { + private final String avrQuestSlot = "antivenom_ring"; + + @Override + public boolean fire(final Player player, final Sentence sentence, final Entity npc) { + if (!new QuestRegisteredCondition(avrQuestSlot).fire(player, sentence, npc)) { + return false; + } - @Override - public int getMinLevel() { - return 0; - } + // note has already been given to Jameson & Antivenom Ring quest has already been started or completed + if (player.getQuest(avrQuestSlot) != null) { + return false; + } - @Override - public String getRegion() { - return Region.ATHOR_ISLAND; - } + // player already has a note + // FIXME: PlayerOwnsItemIncludingBankCondition currently doesn't support itemdata items + if (player.isEquippedWithItemdata("note", info_string)) { + return false; + } - @Override - public String getNPCName() { - return "Klaas"; - } + return true; + } + }; - @Override - public boolean isRepeatable(final Player player) { - return new AndCondition( - new QuestCompletedCondition(QUEST_SLOT), - new TimePassedCondition(QUEST_SLOT, 1, WAIT_TIME)).fire(player, null, null); - } } diff --git a/tests/games/stendhal/server/core/rp/achievement/factory/FriendAchievementFactoryTest.java b/tests/games/stendhal/server/core/rp/achievement/factory/FriendAchievementFactoryTest.java index 7f84e69eaee..643371cf28d 100644 --- a/tests/games/stendhal/server/core/rp/achievement/factory/FriendAchievementFactoryTest.java +++ b/tests/games/stendhal/server/core/rp/achievement/factory/FriendAchievementFactoryTest.java @@ -35,6 +35,7 @@ import games.stendhal.server.entity.npc.NPCList; import games.stendhal.server.entity.npc.SpeakerNPC; import games.stendhal.server.entity.npc.fsm.Engine; +import games.stendhal.server.entity.npc.quest.BuiltQuest; import games.stendhal.server.entity.player.Player; import games.stendhal.server.maps.MockStendlRPWorld; import games.stendhal.server.maps.quests.AGrandfathersWish; @@ -175,7 +176,7 @@ public void testChildrensFriend() { // Plink loadConfigurators(new games.stendhal.server.maps.semos.plains.LittleBoyNPC()); addZones("0_semos_plains_n"); - loadQuests(new PlinksToy()); + loadQuests(new BuiltQuest(new PlinksToy().story())); ChildrensFriendStub.doQuestPlink(player); assertFalse(achievementReached(player, id)); @@ -187,7 +188,7 @@ public void testChildrensFriend() { // Sally loadConfigurators(new games.stendhal.server.maps.orril.river.CampingGirlNPC()); - loadQuests(new Campfire()); + loadQuests(new BuiltQuest(new Campfire().story())); ChildrensFriendStub.doQuestSally(player); assertFalse(achievementReached(player, id)); @@ -233,7 +234,7 @@ public void testChildrensFriend() { // Marianne loadConfigurators(new games.stendhal.server.maps.deniran.cityoutside.LittleGirlNPC()); - loadQuests(new EggsForMarianne()); + loadQuests(new BuiltQuest(new EggsForMarianne().story())); ChildrensFriendStub.doQuestMarianne(player); assertTrue(achievementReached(player, id)); diff --git a/tests/games/stendhal/server/core/rp/achievement/factory/KillBlordroughsAchievementFactoryTest.java b/tests/games/stendhal/server/core/rp/achievement/factory/KillBlordroughsAchievementFactoryTest.java index 90bb80a1307..a5e0b7b501f 100644 --- a/tests/games/stendhal/server/core/rp/achievement/factory/KillBlordroughsAchievementFactoryTest.java +++ b/tests/games/stendhal/server/core/rp/achievement/factory/KillBlordroughsAchievementFactoryTest.java @@ -48,7 +48,6 @@ import utilities.PlayerTestHelper; import utilities.ZonePlayerAndNPCTestImpl; - public class KillBlordroughsAchievementFactoryTest extends ZonePlayerAndNPCTestImpl { private static final Logger logger = Logger.getLogger(KillBlordroughsAchievementFactoryTest.class); diff --git a/tests/games/stendhal/server/core/rp/achievement/factory/QuestAchievementFactoryTest.java b/tests/games/stendhal/server/core/rp/achievement/factory/QuestAchievementFactoryTest.java index c842da4b773..171466d6aa3 100644 --- a/tests/games/stendhal/server/core/rp/achievement/factory/QuestAchievementFactoryTest.java +++ b/tests/games/stendhal/server/core/rp/achievement/factory/QuestAchievementFactoryTest.java @@ -14,6 +14,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static utilities.SpeakerNPCTestHelper.getSpeakerNPC; import static utilities.ZoneAndPlayerTestImpl.setupZone; @@ -21,6 +22,7 @@ import java.util.ArrayList; import java.util.List; +import org.hamcrest.Matchers; import org.junit.After; import org.junit.Before; import org.junit.Ignore; @@ -35,6 +37,7 @@ import games.stendhal.server.entity.npc.fsm.Engine; import games.stendhal.server.entity.npc.quest.BuiltQuest; import games.stendhal.server.entity.player.Player; +import games.stendhal.server.maps.Region; import games.stendhal.server.maps.quests.AbstractQuest; import games.stendhal.server.maps.quests.BalloonForBobby; import games.stendhal.server.maps.quests.BeerForHayunn; @@ -318,9 +321,9 @@ public void testAideToSemosFolk() { final GoodiesForRudolph questRudolph = new GoodiesForRudolph(); loadQuests( new MeetHayunn(), - new BeerForHayunn(), + new BuiltQuest(new BeerForHayunn().story()), new MeetMonogenes(), - new HatForMonogenes(), + new BuiltQuest(new HatForMonogenes().story()), new SheepGrowing(), new MedicineForTad(), new MeetIo(), @@ -328,7 +331,7 @@ public void testAideToSemosFolk() { new NewsFromHackim(), new BowsForOuchit(), new HungryJoshua(), - new LookBookforCeryl(), + new BuiltQuest(new LookBookforCeryl().story()), new MeetKetteh(), new BuiltQuest(new PizzaDelivery().story()), new HerbsForCarmen(), @@ -474,6 +477,7 @@ public void testAideToSemosFolk() { QuestRunner.doQuestGoodiesForRudolph(player); */ + assertThat(SingletonRepository.getStendhalQuestSystem().getIncompleteQuests(player, Region.SEMOS_CITY), Matchers.empty()); assertTrue(achievementReached(player, id)); } diff --git a/tests/games/stendhal/server/maps/quests/AmazonPrincessTest.java b/tests/games/stendhal/server/maps/quests/AmazonPrincessTest.java index 978a49788ae..517792df36c 100644 --- a/tests/games/stendhal/server/maps/quests/AmazonPrincessTest.java +++ b/tests/games/stendhal/server/maps/quests/AmazonPrincessTest.java @@ -1,6 +1,5 @@ -/* $Id$ */ /*************************************************************************** - * (C) Copyright 2003-2010 - Stendhal * + * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** *************************************************************************** * * @@ -28,6 +27,7 @@ import games.stendhal.server.entity.npc.ConversationStates; import games.stendhal.server.entity.npc.SpeakerNPC; import games.stendhal.server.entity.npc.fsm.Engine; +import games.stendhal.server.entity.npc.quest.BuiltQuest; import games.stendhal.server.entity.player.Player; import games.stendhal.server.maps.MockStendlRPWorld; import games.stendhal.server.maps.amazon.hut.PrincessNPC; @@ -40,6 +40,7 @@ public class AmazonPrincessTest { private Player player = null; private SpeakerNPC npc = null; private Engine en = null; + private AbstractQuest quest = null; @BeforeClass public static void setUpBeforeClass() throws Exception { @@ -54,7 +55,7 @@ public void setUp() { npc = SingletonRepository.getNPCList().get("Princess Esclara"); en = npc.getEngine(); - final AbstractQuest quest = new AmazonPrincess(); + quest = new BuiltQuest(new AmazonPrincess().story()); quest.addToWorld(); player = PlayerTestHelper.createPlayer("player"); @@ -69,7 +70,7 @@ public void tearDown() { */ @Test public void testGetSlotname() { - assertEquals("amazon_princess", new AmazonPrincess().getSlotName()); + assertEquals("amazon_princess", quest.getSlotName()); } /** @@ -78,12 +79,12 @@ public void testGetSlotname() { @Test public void testhasRecovered() { en.setCurrentState(ConversationStates.ATTENDING); - player.setQuest(new AmazonPrincess().getSlotName(), "drinking;0"); + player.setQuest(quest.getSlotName(), "done;0"); en.step(player, "task"); assertEquals("The last cocktail you brought me was so lovely. Will you bring me another?", getReply(npc)); assertEquals(ConversationStates.QUEST_OFFERED, en.getCurrentState()); en.step(player, "yes"); - assertEquals("start", player.getQuest(new AmazonPrincess().getSlotName())); + assertEquals("start", player.getQuest(quest.getSlotName(), 0)); } @@ -100,7 +101,7 @@ public void testQuest() { en.step(player, "task"); assertEquals("I'm looking for a drink, should be an exotic one. Can you bring me one?", getReply(npc)); en.step(player, "yes"); - assertEquals("Thank you! If you have found some, say #drink to me so I know you have it. I'll be sure to give you a nice reward.", getReply(npc)); + assertEquals("Thank you! If you have found some, I'll be sure to give you a nice reward.", getReply(npc)); en.step(player, "bye"); assertEquals("Goodbye, and beware of the barbarians.", getReply(npc)); @@ -112,17 +113,8 @@ public void testQuest() { assertEquals("I like these exotic drinks, I forget the name of my favourite one.", getReply(npc)); en.step(player, "help"); assertEquals("Beware of my sisters on the island, they do not like strangers.", getReply(npc)); - en.step(player, "pinacolada"); - assertEquals("You don't have any drink I like yet. Go, and you better get an exotic one!", getReply(npc)); - en.step(player, "exotic drink"); - en.step(player, "pinacolad"); - assertEquals("You don't have any drink I like yet. Go, and you better get an exotic one!", getReply(npc)); - en.step(player, "help"); - assertEquals("Beware of my sisters on the island, they do not like strangers.", getReply(npc)); en.step(player, "favor"); assertEquals("I like these exotic drinks, I forget the name of my favourite one.", getReply(npc)); - en.step(player, "pinacolada"); - assertEquals("You don't have any drink I like yet. Go, and you better get an exotic one!", getReply(npc)); en.step(player, "bye"); assertEquals("Goodbye, and beware of the barbarians.", getReply(npc)); @@ -134,9 +126,6 @@ public void testQuest() { assertEquals("Beware of my sisters on the island, they do not like strangers.", getReply(npc)); en.step(player, "quest"); assertEquals("I like these exotic drinks, I forget the name of my favourite one.", getReply(npc)); - en.step(player, "done"); - en.step(player, "drink"); - assertEquals("You don't have any drink I like yet. Go, and you better get an exotic one!", getReply(npc)); en.step(player, "bye"); assertEquals("Goodbye, and beware of the barbarians.", getReply(npc)); @@ -145,9 +134,9 @@ public void testQuest() { player.getSlot("bag").add(item); en.step(player, "hi"); - assertEquals("Huh, what are you doing here?", getReply(npc)); - en.step(player, "pina colada"); - assertTrue(getReply(npc).startsWith("Thank you!! Take th")); + assertEquals("Ah, I see, you have a §'pina colada' Is it for me?", getReply(npc)); + en.step(player, "yes"); + assertTrue(getReply(npc).startsWith("Thank you! Take th")); assertTrue(player.isEquipped("fish pie")); en.step(player, "bye"); assertEquals("Goodbye, and beware of the barbarians.", getReply(npc)); @@ -157,19 +146,9 @@ public void testQuest() { en.step(player, "hi"); assertEquals("Huh, what are you doing here?", getReply(npc)); en.step(player, "task"); - assertTrue(getReply(npc).startsWith("I'm sure I'll be too drunk to have another for at least")); + assertTrue(getReply(npc).startsWith("I'm sure I'll be too drunk to have another one now.")); en.step(player, "bye"); assertEquals("Goodbye, and beware of the barbarians.", getReply(npc)); - // ----------------------------------------------- - - en.step(player, "hi"); - assertEquals("Huh, what are you doing here?", getReply(npc)); - en.step(player, "pina colada"); - assertEquals("Sometime you could do me a #favour ...", getReply(npc)); - en.step(player, "favour"); - assertTrue(getReply(npc).startsWith("I'm sure I'll be too drunk to have another for at least ")); - en.step(player, "bye"); - assertEquals("Goodbye, and beware of the barbarians.", getReply(npc)); } } diff --git a/tests/games/stendhal/server/maps/quests/AntivenomRingTest.java b/tests/games/stendhal/server/maps/quests/AntivenomRingTest.java index cee21c744a1..a94514f1436 100644 --- a/tests/games/stendhal/server/maps/quests/AntivenomRingTest.java +++ b/tests/games/stendhal/server/maps/quests/AntivenomRingTest.java @@ -1,5 +1,5 @@ /*************************************************************************** - * (C) Copyright 2019 - Arianne * + * (C) Copyright 2019-2023 - Arianne * *************************************************************************** *************************************************************************** * * @@ -139,7 +139,7 @@ public void setUp() throws Exception { new MakeRings(new MarriageQuestInfo()).addToWorld(); // marriage quest new RingMaker().addToWorld(); // Klaas - new TrapsForKlaas().addToWorld(); + new BuiltQuest(new TrapsForKlaas().story()).addToWorld(); // Julius new EmotionCrystals().addToWorld(); // Haizen diff --git a/tests/games/stendhal/server/maps/quests/BeerForHayunnTest.java b/tests/games/stendhal/server/maps/quests/BeerForHayunnTest.java index 59ebe3d7e8b..71f81070818 100644 --- a/tests/games/stendhal/server/maps/quests/BeerForHayunnTest.java +++ b/tests/games/stendhal/server/maps/quests/BeerForHayunnTest.java @@ -1,6 +1,5 @@ -/* $Id$ */ /*************************************************************************** - * (C) Copyright 2003-2010 - Stendhal * + * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** *************************************************************************** * * @@ -29,6 +28,7 @@ import games.stendhal.server.entity.item.StackableItem; import games.stendhal.server.entity.npc.SpeakerNPC; import games.stendhal.server.entity.npc.fsm.Engine; +import games.stendhal.server.entity.npc.quest.BuiltQuest; import games.stendhal.server.entity.player.Player; import games.stendhal.server.maps.MockStendhalRPRuleProcessor; import games.stendhal.server.maps.MockStendlRPWorld; @@ -41,7 +41,7 @@ public class BeerForHayunnTest { private SpeakerNPC hayunn; - private BeerForHayunn bfh; + private AbstractQuest bfh; @BeforeClass public static void setUpBeforeClass() throws Exception { @@ -60,7 +60,7 @@ public void setup() { new RetiredAdventurerNPC().configureZone(zone, null); hayunn = SingletonRepository.getNPCList().get("Hayunn Naratha") ; - bfh = new BeerForHayunn(); + bfh = new BuiltQuest(new BeerForHayunn().story()); bfh.addToWorld(); } @@ -96,7 +96,7 @@ public void quest() { assertEquals(1, player.getNumberOfEquipped("beer")); en.step(player, "hi"); en.step(player, "yes"); - assertEquals("done", player.getQuest("beer_hayunn")); + assertEquals("done", player.getQuest("beer_hayunn", 0)); en.step(player, "bye"); // reject final Player player2 = PlayerTestHelper.createPlayer("player"); @@ -125,10 +125,9 @@ public void quest() { public void testgetHistory() { final Player player = PlayerTestHelper.createPlayer("bob"); assertTrue(bfh.getHistory(player).isEmpty()); - player.setQuest("beer_hayunn", ""); + player.setQuest("beer_hayunn", null); final List history = new LinkedList(); - history.add("I have talked to Hayunn."); - assertEquals(history, bfh.getHistory(player)); + history.add("I have talked to Hayunn Naratha."); player.setQuest("beer_hayunn", "rejected"); history.add("I do not want to make Hayunn drunk."); diff --git a/tests/games/stendhal/server/maps/quests/CampfireTest.java b/tests/games/stendhal/server/maps/quests/CampfireTest.java index 8a523c7ac67..27d796980eb 100644 --- a/tests/games/stendhal/server/maps/quests/CampfireTest.java +++ b/tests/games/stendhal/server/maps/quests/CampfireTest.java @@ -1,6 +1,5 @@ -/* $Id$ */ /*************************************************************************** - * (C) Copyright 2003-2010 - Stendhal * + * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** *************************************************************************** * * @@ -20,7 +19,6 @@ import java.util.Date; import org.junit.After; -import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -33,6 +31,7 @@ import games.stendhal.server.entity.npc.NPCList; import games.stendhal.server.entity.npc.SpeakerNPC; import games.stendhal.server.entity.npc.fsm.Engine; +import games.stendhal.server.entity.npc.quest.BuiltQuest; import games.stendhal.server.entity.player.Player; import games.stendhal.server.maps.MockStendhalRPRuleProcessor; import games.stendhal.server.maps.MockStendlRPWorld; @@ -60,19 +59,14 @@ public static void setUpBeforeClass() throws Exception { MockStendlRPWorld.get(); } - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - @Before public void setUp() { player = PlayerTestHelper.createPlayer("player"); zone = new StendhalRPZone("zone"); new CampingGirlNPC().configureZone(zone, null); npc = NPCList.get().get("Sally"); - final Campfire cf = new Campfire(); - cf.addToWorld(); + final AbstractQuest quest = new BuiltQuest(new Campfire().story()); + quest.addToWorld(); } @After @@ -90,46 +84,30 @@ public void testCanStartQuestNow() { final Engine en = npc.getEngine(); assertTrue(en.step(player, "hi")); - assertEquals("Hi! I need a little #favor ... ", getReply(npc)); + assertEquals("Hi, how are you?", getReply(npc)); assertTrue(en.step(player, "bye")); - player.setQuest(CampfireTest.CAMPFIRE, "start"); + player.setQuest(CampfireTest.CAMPFIRE, 0, "start"); assertTrue(en.step(player, "hi")); assertEquals( - "You're back already? Don't forget that you promised to collect ten pieces of wood for me!", + "Hi, how are you?", getReply(npc)); assertTrue(en.step(player, "bye")); - player.setQuest(CampfireTest.CAMPFIRE, String.valueOf(System.currentTimeMillis())); + player.setQuest(CampfireTest.CAMPFIRE, 1, String.valueOf(System.currentTimeMillis())); en.step(player, "hi"); assertEquals( - "Hi again!", + "Hi, how are you?", getReply(npc)); assertTrue(en.step(player, "bye")); final long SIXMINUTESAGO = System.currentTimeMillis() - 6 * MathHelper.MILLISECONDS_IN_ONE_MINUTE; - player.setQuest(CampfireTest.CAMPFIRE, String.valueOf(SIXMINUTESAGO)); + player.setQuest(CampfireTest.CAMPFIRE, 1, String.valueOf(SIXMINUTESAGO)); en.step(player, "hi"); - assertEquals("delay is 5 minutes, so 6 minutes should be enough", "Hi again!", getReply(npc)); + assertEquals("delay is 5 minutes, so 6 minutes should be enough", "Hi, how are you?", getReply(npc)); assertTrue(en.step(player, "bye")); } - /** - * Tests for hiAndbye. - */ - @Test - public void testHiAndbye() { - - final Engine en = npc.getEngine(); - - assertTrue(en.step(player, "hi")); - assertTrue(npc.isTalking()); - assertEquals("Hi! I need a little #favor ... ", getReply(npc)); - assertTrue(en.step(player, "bye")); - assertFalse(npc.isTalking()); - assertEquals("Bye.", getReply(npc)); - } - /** * Tests for doQuest. */ @@ -140,7 +118,7 @@ public void testDoQuest() { assertTrue(en.step(player, "hi")); assertTrue(npc.isTalking()); - assertEquals("Hi! I need a little #favor ... ", getReply(npc)); + assertEquals("Hi, how are you?", getReply(npc)); assertTrue(en.step(player, "favor")); assertEquals( @@ -164,8 +142,7 @@ public void testDoQuest() { assertTrue(en.step(player, "yes")); assertEquals(0, player.getNumberOfEquipped("wood")); String reply = getReply(npc); - assertTrue("Thank you! Here, take some meat and charcoal!".equals(reply) - || "Thank you! Here, take some ham and charcoal!".equals(reply)); + assertTrue(reply.contains("Thank you! Here, take ")); assertTrue((10 == player.getNumberOfEquipped("meat")) || (10 == player.getNumberOfEquipped("ham"))); assertTrue(en.step(player, "bye")); @@ -174,38 +151,6 @@ public void testDoQuest() { } - /** - * Tests for isRepeatable. - */ - @Test - public void testIsRepeatable() { - player.setQuest(CAMPFIRE, "start"); - assertFalse(new Campfire().isRepeatable(player)); - player.setQuest(CAMPFIRE, "rejected"); - assertFalse(new Campfire().isRepeatable(player)); - player.setQuest(CAMPFIRE, System.currentTimeMillis() + ""); - assertFalse(new Campfire().isRepeatable(player)); - player.setQuest(CAMPFIRE, "1"); - assertTrue(new Campfire().isRepeatable(player)); - } - - /** - * Tests for isCompleted. - */ - @Test - public void testIsCompleted() { - assertFalse(new Campfire().isCompleted(player)); - - player.setQuest(CAMPFIRE, "start"); - assertFalse(new Campfire().isCompleted(player)); - - player.setQuest(CAMPFIRE, "rejected"); - assertFalse(new Campfire().isCompleted(player)); - - player.setQuest(CAMPFIRE, "notStartorRejected"); - assertTrue(new Campfire().isCompleted(player)); - } - /** * Tests for jobAndOffer. */ @@ -215,7 +160,7 @@ public void testJobAndOffer() { assertTrue(en.step(player, "hi")); assertTrue(npc.isTalking()); - assertEquals("Hi! I need a little #favor ... ", getReply(npc)); + assertEquals("Hi, how are you?", getReply(npc)); assertTrue(en.step(player, "job")); assertEquals("Work? I'm just a little girl! I'm a scout, you know.", getReply(npc)); @@ -240,14 +185,15 @@ public void testCanNotRepeatYet() { for (String request : ConversationPhrases.QUEST_MESSAGES) { final Engine en = npc.getEngine(); - player.setQuest(CAMPFIRE, questState); + player.setQuest(CAMPFIRE, 0, "done"); + player.setQuest(CAMPFIRE, 1, questState); en.setCurrentState(ConversationStates.ATTENDING); en.step(player, request); String reply = getReply(npc); - assertTrue("Thanks, but I think the wood you brought already will last me 60 minutes.".equals(reply) || "Thanks, but I think the wood you brought already will last me 1 hour.".equals(reply)); + assertTrue("Thanks, but I think the wood, you brought, will last 60 minutes.".equals(reply) || "Thanks, but I think the wood, you brought, will last 1 hour.".equals(reply)); assertEquals(ConversationStates.ATTENDING, en.getCurrentState()); - assertEquals("quest state unchanged", questState, player.getQuest(CAMPFIRE)); + assertEquals("quest state unchanged", questState, player.getQuest(CAMPFIRE, 1)); } } @@ -259,13 +205,14 @@ public void testRepeatQuest() { final String questState = Long.toString(new Date().getTime() - 61 * 60 * 1000); for (String request : ConversationPhrases.QUEST_MESSAGES) { final Engine en = npc.getEngine(); - player.setQuest(CAMPFIRE, questState); + player.setQuest(CAMPFIRE, 0, "done"); + player.setQuest(CAMPFIRE, 1, questState); en.setCurrentState(ConversationStates.ATTENDING); en.step(player, request); assertEquals("My campfire needs wood again, ten pieces of #wood will be enough. Could you please get those #wood pieces from the forest for me? Please say yes!", getReply(npc)); assertEquals(ConversationStates.QUEST_OFFERED, en.getCurrentState()); - assertEquals("quest state unchanged", questState, player.getQuest(CAMPFIRE)); + assertEquals("quest state unchanged", questState, player.getQuest(CAMPFIRE, 1)); } } @@ -276,13 +223,13 @@ public void testRepeatQuest() { public void testAllowRestartAfterRejecting() { for (String request : ConversationPhrases.QUEST_MESSAGES) { final Engine en = npc.getEngine(); - player.setQuest(CAMPFIRE, "rejected"); + player.setQuest(CAMPFIRE, 0, "rejected"); en.setCurrentState(ConversationStates.ATTENDING); en.step(player, request); assertEquals("I need more wood to keep my campfire running, But I can't leave it unattended to go get some! Could you please get some from the forest for me? I need ten pieces.", getReply(npc)); assertEquals(ConversationStates.QUEST_OFFERED, en.getCurrentState()); - assertEquals("quest state unchanged", "rejected", player.getQuest(CAMPFIRE)); + assertEquals("quest state unchanged", "rejected", player.getQuest(CAMPFIRE, 0)); } } @@ -300,7 +247,7 @@ public void testRefuseQuest() { assertEquals("Oh dear, how am I going to cook all this meat? Perhaps I'll just have to feed it to the animals..." , getReply(npc)); assertEquals(ConversationStates.ATTENDING, en.getCurrentState()); - assertEquals("quest state 'rejected'", "rejected", player.getQuest(CAMPFIRE)); + assertEquals("quest state 'rejected'", "rejected", player.getQuest(CAMPFIRE, 0 )); assertEquals("karma penalty", karma - 5.0, player.getKarma(), 0.01); } } diff --git a/tests/games/stendhal/server/maps/quests/HatForMonogenesTest.java b/tests/games/stendhal/server/maps/quests/HatForMonogenesTest.java index 71bb583ae45..24976338822 100644 --- a/tests/games/stendhal/server/maps/quests/HatForMonogenesTest.java +++ b/tests/games/stendhal/server/maps/quests/HatForMonogenesTest.java @@ -1,4 +1,3 @@ -/* $Id$ */ /*************************************************************************** * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** @@ -30,6 +29,7 @@ import games.stendhal.server.entity.item.Item; import games.stendhal.server.entity.npc.SpeakerNPC; import games.stendhal.server.entity.npc.fsm.Engine; +import games.stendhal.server.entity.npc.quest.BuiltQuest; import games.stendhal.server.entity.player.Player; import games.stendhal.server.maps.semos.city.GreeterNPC; import games.stendhal.server.maps.semos.tavern.TraderNPC; @@ -76,7 +76,7 @@ public void setUp() { quest = new MeetMonogenes(); quest.addToWorld(); - quest = new HatForMonogenes(); + quest = new BuiltQuest(new HatForMonogenes().story()); quest.addToWorld(); } @@ -167,6 +167,10 @@ public void testQuest() { // ----------------------------------------------- en.step(player, "hi"); + assertEquals( + "Hi again, player. How can I #help you this time?", + getReply(npc)); + en.step(player, "quest"); assertEquals( "Hey, my good friend, remember that leather hat I asked you about before? It's still pretty chilly here...", getReply(npc)); @@ -199,7 +203,7 @@ public void testGetHistory() { assertEquals(history, quest.getHistory(player)); player.setQuest("hat_monogenes", ""); - history.add("I have met Monogenes at the spring in Semos village"); + history.add("I have met Monogenes at the spring in Semos village."); history.add("I have to find a hat, something leather to keep his head warm."); assertEquals(history, quest.getHistory(player)); diff --git a/tests/games/stendhal/server/maps/quests/JailedBarbarianTest.java b/tests/games/stendhal/server/maps/quests/JailedBarbarianTest.java index 05898d69e61..86ba2660a4c 100644 --- a/tests/games/stendhal/server/maps/quests/JailedBarbarianTest.java +++ b/tests/games/stendhal/server/maps/quests/JailedBarbarianTest.java @@ -1,6 +1,5 @@ -/* $Id$ */ /*************************************************************************** - * (C) Copyright 2003-2010 - Stendhal * + * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** *************************************************************************** * * @@ -24,6 +23,7 @@ import games.stendhal.server.entity.item.Item; import games.stendhal.server.entity.npc.SpeakerNPC; import games.stendhal.server.entity.npc.fsm.Engine; +import games.stendhal.server.entity.npc.quest.BuiltQuest; import games.stendhal.server.entity.player.Player; import games.stendhal.server.maps.MockStendlRPWorld; import games.stendhal.server.maps.amazon.hut.JailedBarbNPC; @@ -54,7 +54,7 @@ public static void setUpBeforeClass() throws Exception { final AbstractQuest quest = new JailedBarbarian(); // princess Esclara's greeting response is defined in her quest - final AbstractQuest quest2 = new AmazonPrincess(); + final AbstractQuest quest2 = new BuiltQuest(new AmazonPrincess().story()); quest.addToWorld(); quest2.addToWorld(); @@ -119,6 +119,7 @@ public void testQuest() { assertEquals("I'm looking for a drink, should be an exotic one. Can you bring me one?", getReply(npc)); en.step(player, "no"); assertEquals("Oh, never mind. Bye then.", getReply(npc)); + en.step(player, "bye"); en.step(player, "hi"); assertEquals("Huh, what are you doing here?", getReply(npc)); diff --git a/tests/games/stendhal/server/maps/quests/LookBookforCerylTest.java b/tests/games/stendhal/server/maps/quests/LookBookforCerylTest.java index 057bb1582d6..c1eff082e03 100644 --- a/tests/games/stendhal/server/maps/quests/LookBookforCerylTest.java +++ b/tests/games/stendhal/server/maps/quests/LookBookforCerylTest.java @@ -1,6 +1,5 @@ -/* $Id$ */ /*************************************************************************** - * (C) Copyright 2003-2010 - Stendhal * + * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** *************************************************************************** * * @@ -12,9 +11,11 @@ ***************************************************************************/ package games.stendhal.server.maps.quests; +import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static utilities.SpeakerNPCTestHelper.getReply; @@ -31,6 +32,7 @@ import games.stendhal.server.entity.npc.ConversationPhrases; import games.stendhal.server.entity.npc.SpeakerNPC; import games.stendhal.server.entity.npc.fsm.Engine; +import games.stendhal.server.entity.npc.quest.BuiltQuest; import games.stendhal.server.entity.player.Player; import games.stendhal.server.maps.MockStendhalRPRuleProcessor; import games.stendhal.server.maps.MockStendlRPWorld; @@ -70,7 +72,7 @@ public void tearDown() throws Exception { @Test public final void askJynathWithoutQuest() { - final LookBookforCeryl quest = new LookBookforCeryl(); + final AbstractQuest quest = new BuiltQuest(new LookBookforCeryl().story()); quest.addToWorld(); final Player pl = PlayerTestHelper.createPlayer("joe"); @@ -94,7 +96,7 @@ public final void askJynathWithoutQuest() { @Test public final void comeBackFromJynathWithoutBook() { - final LookBookforCeryl quest = new LookBookforCeryl(); + final AbstractQuest quest = new BuiltQuest(new LookBookforCeryl().story()); quest.addToWorld(); final Player pl = PlayerTestHelper.createPlayer("joe"); @@ -112,7 +114,7 @@ public final void comeBackFromJynathWithoutBook() { @Test public void doQuest() throws Exception { - final LookBookforCeryl quest = new LookBookforCeryl(); + final AbstractQuest quest = new BuiltQuest(new LookBookforCeryl().story()); quest.addToWorld(); final Player pl = PlayerTestHelper.createPlayer("player"); @@ -124,12 +126,7 @@ public void doQuest() throws Exception { assertEquals("Greetings! How may I help you?", getReply(ceryl)); cerylEngine.step(pl, ConversationPhrases.QUEST_MESSAGES.get(0)); assertTrue(ceryl.isTalking()); - assertEquals("I am looking for a very special #book.", - getReply(ceryl)); - cerylEngine.step(pl, "book"); - assertTrue(ceryl.isTalking()); - assertEquals( - "Could you ask #Jynath to return her book? She's had it for months now, and people are looking for it.", + assertEquals("I am looking for a very special book. Could you ask #Jynath to return it? She has had it for months now, and people are looking for it.", getReply(ceryl)); cerylEngine.step(pl, ConversationPhrases.YES_MESSAGES.get(0)); assertTrue(ceryl.isTalking()); @@ -137,10 +134,6 @@ public void doQuest() throws Exception { "Great! Please get me it as quickly as possible... there's a huge waiting list!", getReply(ceryl)); assertEquals("start", pl.getQuest(LookBookforCerylTest.CERYL_BOOK)); - cerylEngine.step(pl, "book"); - assertTrue(ceryl.isTalking()); - assertEquals("I really need that book now! Go to talk with #Jynath.", - getReply(ceryl)); cerylEngine.step(pl, ConversationPhrases.GOODBYE_MESSAGES.get(0)); assertFalse(ceryl.isTalking()); final Engine jynathEngine = jynath.getEngine(); @@ -164,8 +157,9 @@ public void doQuest() throws Exception { cerylEngine.step(pl, "Hi"); assertTrue(ceryl.isTalking()); - assertEquals("Oh, you got the book back! Phew, thanks!", - getReply(ceryl)); + assertEquals("Hi, did you get the book from Jynath?", getReply(ceryl)); + cerylEngine.step(pl, "yes"); + assertEquals("Oh, you got the book back! Phew, thanks!", getReply(ceryl)); cerylEngine.step(pl, "bye"); cerylEngine.step(pl, "Hi"); @@ -181,8 +175,7 @@ public void doQuest() throws Exception { */ @Test public final void testAddToWorld() { - LookBookforCeryl quest; - quest = new LookBookforCeryl(); + final AbstractQuest quest = new BuiltQuest(new LookBookforCeryl().story()); quest.addToWorld(); } @@ -192,54 +185,38 @@ public final void testAddToWorld() { @Test public final void testGetHistory() { final Player pl = PlayerTestHelper.createPlayer("player"); - LookBookforCeryl quest; - quest = new LookBookforCeryl(); + final AbstractQuest quest = new BuiltQuest(new LookBookforCeryl().story()); quest.addToWorld(); assertTrue(quest.getHistory(pl).isEmpty()); pl.setQuest(CERYL_BOOK, "rejected"); - assertEquals(2, quest.getHistory(pl).size()); - assertEquals(Arrays.asList( + assertThat(quest.getHistory(pl), equalTo(Arrays.asList( "I have met Ceryl at the library, he's the librarian there.", - "I do not want to find the book."), - quest.getHistory(pl)); + "I do not want to find the book."))); pl.setQuest(CERYL_BOOK, "start"); - assertEquals(2, quest.getHistory(pl).size()); - assertEquals(Arrays.asList( + assertThat(quest.getHistory(pl), equalTo(Arrays.asList( "I have met Ceryl at the library, he's the librarian there.", - "I promised to fetch the black book from Jynath."), - quest.getHistory(pl)); + "I promised to fetch the black book from Jynath."))); pl.setQuest(CERYL_BOOK, "jynath"); - assertEquals(3, quest.getHistory(pl).size()); - assertEquals(Arrays.asList( - "I have met Ceryl at the library, he's the librarian there.", - "I promised to fetch the black book from Jynath.", - "I do not have the black book Jynath has."), - quest.getHistory(pl)); - final Item item = SingletonRepository.getEntityManager().getItem( - "black book"); + final Item item = SingletonRepository.getEntityManager().getItem("black book"); assertNotNull(item); item.setBoundTo(pl.getName()); pl.equipOrPutOnGround(item); - assertEquals(3, quest.getHistory(pl).size()); - assertEquals(Arrays.asList( + assertThat(quest.getHistory(pl), equalTo(Arrays.asList( "I have met Ceryl at the library, he's the librarian there.", "I promised to fetch the black book from Jynath.", - "I have talked to Jynath, and have the book."), - quest.getHistory(pl)); + "I have talked to Jynath and got the book."))); pl.setQuest(CERYL_BOOK, "done"); - assertEquals(4, quest.getHistory(pl).size()); - assertEquals(Arrays.asList( + assertThat(quest.getHistory(pl), equalTo(Arrays.asList( "I have met Ceryl at the library, he's the librarian there.", "I promised to fetch the black book from Jynath.", - "I have talked to Jynath, and have the book.", - "I have returned the book to Ceryl and got a little reward."), - quest.getHistory(pl)); + "I have talked to Jynath and got the book.", + "I have returned the book to Ceryl and got a little reward."))); } /** @@ -247,8 +224,7 @@ public final void testGetHistory() { */ @Test public final void testIsCompleted() { - LookBookforCeryl quest; - quest = new LookBookforCeryl(); + final AbstractQuest quest = new BuiltQuest(new LookBookforCeryl().story()); quest.addToWorld(); final Player pl = PlayerTestHelper.createPlayer("player"); @@ -264,7 +240,7 @@ public final void testIsCompleted() { */ @Test public final void testIsRepeatable() { - final LookBookforCeryl quest = new LookBookforCeryl(); + final AbstractQuest quest = new BuiltQuest(new LookBookforCeryl().story()); assertFalse(quest.isRepeatable(null)); } @@ -273,7 +249,7 @@ public final void testIsRepeatable() { */ @Test public final void testIsStarted() { - final LookBookforCeryl quest = new LookBookforCeryl(); + final AbstractQuest quest = new BuiltQuest(new LookBookforCeryl().story()); final Player bob = PlayerTestHelper.createPlayer("bob"); assertFalse(bob.hasQuest(LookBookforCerylTest.CERYL_BOOK)); diff --git a/tests/games/stendhal/server/maps/quests/PlinksToyTest.java b/tests/games/stendhal/server/maps/quests/PlinksToyTest.java index c76b97a823b..f234897b62c 100644 --- a/tests/games/stendhal/server/maps/quests/PlinksToyTest.java +++ b/tests/games/stendhal/server/maps/quests/PlinksToyTest.java @@ -1,6 +1,5 @@ -/* $Id$ */ /*************************************************************************** - * (C) Copyright 2003-2010 - Stendhal * + * (C) Copyright 2003-2023 - Stendhal * *************************************************************************** *************************************************************************** * * @@ -13,27 +12,22 @@ package games.stendhal.server.maps.quests; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import static utilities.SpeakerNPCTestHelper.getReply; -import java.util.Arrays; - import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import games.stendhal.server.core.engine.SingletonRepository; import games.stendhal.server.core.engine.StendhalRPZone; -import games.stendhal.server.entity.item.Item; import games.stendhal.server.entity.npc.SpeakerNPC; import games.stendhal.server.entity.npc.fsm.Engine; +import games.stendhal.server.entity.npc.quest.BuiltQuest; import games.stendhal.server.entity.player.Player; import games.stendhal.server.maps.MockStendlRPWorld; import games.stendhal.server.maps.semos.plains.LittleBoyNPC; import utilities.PlayerTestHelper; import utilities.QuestHelper; -import utilities.RPClass.ItemTestHelper; import utilities.RPClass.PassiveEntityRespawnPointTestHelper; public class PlinksToyTest { @@ -54,7 +48,7 @@ public void setUp() { MockStendlRPWorld.get().addRPZone(zone); new LittleBoyNPC().configureZone(zone, null); - final PlinksToy quest = new PlinksToy(); + final AbstractQuest quest = new BuiltQuest(new PlinksToy().story()); quest.addToWorld(); player = PlayerTestHelper.createPlayer("player"); @@ -74,6 +68,7 @@ public void testQuest() { assertEquals("My parents told me not to go to the park by myself, but I got lost when I was playing... Please don't tell them! Can you bring my #teddy back?", getReply(npc)); en.step(player, "yes"); assertEquals("*sniff* Thanks a lot! *smile*", getReply(npc)); + en.step(player, "bye"); // ----------------------------------------------- @@ -85,21 +80,17 @@ public void testQuest() { assertEquals("*sniff* But... but... PLEASE! *cries*", getReply(npc)); en.step(player, "teddy bear"); - assertEquals("Teddy is my favourite toy! Please will you bring him back?", getReply(npc)); - en.step(player, "yes"); - assertEquals("*sniff* Thanks a lot! *smile*", getReply(npc)); + assertEquals("Teddy is my favourite toy! Please bring him back to me.", getReply(npc)); + en.step(player, "bye"); // ----------------------------------------------- + /* TODO: Re-implement support for early quest completion final Item teddy = ItemTestHelper.createItem("teddy"); teddy.setEquipableSlots(Arrays.asList("bag")); player.equipToInventoryOnly(teddy); assertTrue(player.isEquipped("teddy")); - System.out.println(player.getSlot("!quests")); - System.out.println(player.getSlot("lhand")); - System.out.println(player.getSlot("rhand")); - en.step(player, "hi"); // [21:25] player earns 10 experience points. assertEquals("You found him! *hugs teddy* Thank you, thank you! *smile*", getReply(npc)); @@ -112,5 +103,6 @@ public void testQuest() { assertEquals("I play all day.", getReply(npc)); en.step(player, "bye"); assertEquals("Bye.", getReply(npc)); + */ } } diff --git a/tests/games/stendhal/server/maps/quests/TrapsForKlaasTest.java b/tests/games/stendhal/server/maps/quests/TrapsForKlaasTest.java index 26f13d605b9..28e2f9d02c7 100644 --- a/tests/games/stendhal/server/maps/quests/TrapsForKlaasTest.java +++ b/tests/games/stendhal/server/maps/quests/TrapsForKlaasTest.java @@ -1,5 +1,5 @@ /*************************************************************************** - * (C) Copyright 2019 - Arianne * + * (C) Copyright 2019-2023 - Arianne * *************************************************************************** *************************************************************************** * * @@ -30,6 +30,7 @@ import games.stendhal.server.entity.npc.ConversationStates; import games.stendhal.server.entity.npc.SpeakerNPC; import games.stendhal.server.entity.npc.fsm.Engine; +import games.stendhal.server.entity.npc.quest.BuiltQuest; import games.stendhal.server.maps.ados.animal_sanctuary.ZoologistNPC; import games.stendhal.server.maps.ados.church.HealerNPC; import games.stendhal.server.maps.ados.magician_house.WizardNPC; @@ -51,7 +52,7 @@ public class TrapsForKlaasTest extends ZonePlayerAndNPCTestImpl { private SpeakerNPC klaas; - private TrapsForKlaas quest; + private AbstractQuest quest; private AntivenomRing avrQuest; private String questName; private String avrQuestName; @@ -91,7 +92,7 @@ public void setUp() throws Exception { klaas = getNPC(npcName); - quest = new TrapsForKlaas(); + quest = new BuiltQuest(new TrapsForKlaas().story()); avrQuest = new AntivenomRing(); questName = quest.getSlotName(); avrQuestName = avrQuest.getSlotName(); @@ -130,7 +131,6 @@ private void testDialogue() { "The rats down here have been getting into the food storage. Would you help me rid us of the varmints?", getReply(klaas)); en.step(player, "no"); - assertEquals(ConversationStates.IDLE, en.getCurrentState()); assertEquals("Don't waste my time. I've got to protect the cargo.", getReply(klaas)); // player loses some karma assertEquals(karma - 5.0, player.getKarma(), 0); @@ -162,33 +162,14 @@ private void testDialogue() { en.step(player, "hi"); assertEquals(ConversationStates.ATTENDING, en.getCurrentState()); - assertEquals("I could really use those #traps. How can I help you?", getReply(klaas)); - en.step(player, "bye"); - assertEquals(ConversationStates.IDLE, en.getCurrentState()); - - // player does not have enough traps - PlayerTestHelper.equipWithStackableItem(player, "rodent trap", 19); - assertTrue(player.isEquipped("rodent trap")); - assertFalse(player.isEquipped("rodent trap", 20)); - - en.step(player, "hi"); - assertEquals(ConversationStates.QUEST_ITEM_BROUGHT, en.getCurrentState()); - assertEquals("Did you bring any traps?", getReply(klaas)); - en.step(player, "no"); - assertEquals(ConversationStates.ATTENDING, en.getCurrentState()); - assertEquals("Please hurry! I just found another box of food that's been chewed through.", getReply(klaas)); - en.step(player, "bye"); - assertEquals(ConversationStates.IDLE, en.getCurrentState()); - en.step(player, "hi"); - assertEquals(ConversationStates.QUEST_ITEM_BROUGHT, en.getCurrentState()); - en.step(player, "yes"); - assertEquals(ConversationStates.ATTENDING, en.getCurrentState()); - assertEquals("I'm sorry but I need 20 #rodent #traps", getReply(klaas)); + assertEquals("Ahoy! Nice to see you in the cargo hold!", getReply(klaas)); + en.step(player, "quest"); + assertEquals("I believe, I already asked you to get me 20 rodent traps.", getReply(klaas)); en.step(player, "bye"); assertEquals(ConversationStates.IDLE, en.getCurrentState()); // player has enough traps - PlayerTestHelper.equipWithStackableItem(player, "rodent trap", 1); + PlayerTestHelper.equipWithStackableItem(player, "rodent trap", 20); assertTrue(player.isEquipped("rodent trap", 20)); en.step(player, "hi"); @@ -214,10 +195,10 @@ private void testDialogue() { // player asks for quest before cooldown period is up en.step(player, "quest"); assertEquals(ConversationStates.ATTENDING, en.getCurrentState()); - assertTrue(getReply(klaas).startsWith("Thanks for the traps. Now the food will be safe. But I may need your help again in")); + assertTrue(getReply(klaas).startsWith("Thanks for the traps. Now the food will be safe. But I may need your help again soon.")); // player asks for quest after cooldown period is up - player.setQuest(questName, "done;0"); + player.setQuest(questName, 1, "0"); en.step(player, "quest"); assertEquals(ConversationStates.QUEST_OFFERED, en.getCurrentState()); assertEquals("The rats down here have been getting into the food storage. Would you help me rid us of the varmints?", getReply(klaas)); @@ -250,8 +231,7 @@ private void testAVRNote(final Engine en) { assertEquals(ConversationStates.QUEST_ITEM_BROUGHT, en.getCurrentState()); assertEquals("Did you bring any traps?", getReply(klaas)); en.step(player, "yes"); - assertEquals("Thanks! I've got to get these set up as quickly as possible. Take these antidotes as a reward." - + " I used to know an old #apothecary. Take this note to him. Maybe he can help you out with something.", + assertEquals("I used to know an old #apothecary. Take this note to him. Maybe he can help you out with something.", getReply(klaas)); assertEquals("done", player.getQuest(questName, 0)); assertFalse(player.isEquipped("rodent trap")); diff --git a/tests/utilities/QuestRunner.java b/tests/utilities/QuestRunner.java index f14f2cdb6ae..88aa62c43b5 100644 --- a/tests/utilities/QuestRunner.java +++ b/tests/utilities/QuestRunner.java @@ -265,6 +265,7 @@ public static void doQuestLookBookforCeryl(final Player player) { en.step(player, "bye"); en = ceryl.getEngine(); en.step(player, "hi"); + en.step(player, "yes"); en.step(player, "bye"); assertEquals("done", player.getQuest(questSlot, 0)); } diff --git a/tests/utilities/quest_runner/ChildrensFriendStub.java b/tests/utilities/quest_runner/ChildrensFriendStub.java index 84caa129411..0bbad7c2f3b 100644 --- a/tests/utilities/quest_runner/ChildrensFriendStub.java +++ b/tests/utilities/quest_runner/ChildrensFriendStub.java @@ -86,13 +86,12 @@ public static void doQuestPlink(final Player player) { en.step(player, "hi"); en.step(player, "yes"); - - // don't need to say "bye" - assertEquals(ConversationStates.IDLE, en.getCurrentState()); + en.step(player, "bye"); equipWithItem(player, "teddy"); en.step(player, "hi"); + en.step(player, "yes"); en.step(player, "bye"); assertEquals("done", player.getQuest(questSlot, 0));