Package games.stendhal.server.maps.quests

Source Code of games.stendhal.server.maps.quests.ElfPrincess

/* $Id: ElfPrincess.java,v 1.46 2011/05/01 19:50:05 martinfuchs Exp $ */
/***************************************************************************
*                   (C) Copyright 2003-2011 - Stendhal                    *
***************************************************************************
***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/
package games.stendhal.server.maps.quests;

import games.stendhal.common.MathHelper;
import games.stendhal.common.Rand;
import games.stendhal.common.grammar.Grammar;
import games.stendhal.common.parser.Sentence;
import games.stendhal.server.core.engine.SingletonRepository;
import games.stendhal.server.entity.Entity;
import games.stendhal.server.entity.item.StackableItem;
import games.stendhal.server.entity.npc.ChatAction;
import games.stendhal.server.entity.npc.ChatCondition;
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.DecreaseKarmaAction;
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.IncrementQuestAction;
import games.stendhal.server.entity.npc.action.MultipleActions;
import games.stendhal.server.entity.npc.action.SetQuestAction;
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.OrCondition;
import games.stendhal.server.entity.npc.condition.PlayerCanEquipItemCondition;
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.TimePassedCondition;
import games.stendhal.server.entity.player.Player;
import games.stendhal.server.maps.Region;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
* QUEST: The Elf Princess
*
* PARTICIPANTS:
* <ul>
* <li>Tywysoga, the Elf Princess in Nalwor Tower</li>
* <li>Rose Leigh, the wandering flower seller.</li>
* </ul>
*
* STEPS:
* <ul>
* <li>The princess asks you for a rare flower</li>
* <li>Find the wandering flower seller</li>
* <li>You are given the flower, provided you've already been asked to fetch it</li>
* <li>Take flower back to princess</li>
* <li>Princess gives you a reward</li>
* </ul>
*
* REWARD:
* <ul>
* <li>5000 XP</li>
* <li>Some gold bars, random between 5,10,15,20,25,30.</li>
* <li>Karma: 15</li>
* </ul>
*
* REPETITIONS:
* <ul>
* <li>Unlimited, provided you've activated the quest by asking the princess
* for a task again</li>
* </ul>
*/
public class ElfPrincess extends AbstractQuest {

    /* delay in minutes */
  private static final int DELAY = 5;
  private static final String QUEST_SLOT = "elf_princess";


  @Override
  public String getSlotName() {
    return QUEST_SLOT;
  }
  private void offerQuestStep() {
    final SpeakerNPC npc = npcs.get("Tywysoga");

    npc.add(ConversationStates.ATTENDING,
      ConversationPhrases.QUEST_MESSAGES,
      new OrCondition(new QuestNotStartedCondition(QUEST_SLOT), new QuestInStateCondition(QUEST_SLOT, 0, "rejected")),
      ConversationStates.QUEST_OFFERED,
      "Will you find the wandering flower seller, Rose Leigh, and get from her my favourite flower, the Rhosyd?",
      null);

        // shouldn't happen: is a repeatable quest
    npc.add(ConversationStates.ATTENDING,
      ConversationPhrases.QUEST_MESSAGES,
      new QuestCompletedCondition("QUEST_SLOT"),
      ConversationStates.ATTENDING,
      "I have plenty of blooms now thank you.", null);
   
    npc.add(ConversationStates.ATTENDING,
      ConversationPhrases.QUEST_MESSAGES,
      new QuestInStateCondition(QUEST_SLOT, 0, "flower_brought"),
      ConversationStates.QUEST_OFFERED,
      "The last Rhosyd you brought me was so lovely. Will you find me another from Rose Leigh?",
      null);

    npc.add(ConversationStates.ATTENDING,
      ConversationPhrases.QUEST_MESSAGES,
      new OrCondition(new QuestInStateCondition(QUEST_SLOT, 0, "start"), new QuestInStateCondition(QUEST_SLOT, 0, "got_flower")),
      ConversationStates.ATTENDING,
      "I do so love those pretty flowers from Rose Leigh ...",
      null);

    // Player agrees to collect flower
    npc.add(ConversationStates.QUEST_OFFERED,
      ConversationPhrases.YES_MESSAGES, null,
      ConversationStates.ATTENDING,
      "Thank you! Once you find it, say #flower to me so I know you have it. I'll be sure to give you a nice reward.",
      new MultipleActions(new SetQuestAction(QUEST_SLOT, 0, "start"),
                new IncreaseKarmaAction(10.0)));

    // Player says no, they've lost karma.
    npc.add(ConversationStates.QUEST_OFFERED,
      ConversationPhrases.NO_MESSAGES, null, ConversationStates.IDLE,
      "Oh, never mind. Bye then.",
      new MultipleActions(new SetQuestAction(QUEST_SLOT, 0, "rejected"),
          new DecreaseKarmaAction(10.0)));
  }

  private void getFlowerStep() {
    final SpeakerNPC rose = npcs.get("Rose Leigh");

        // give the flower if it's at least 5 minutes since the flower was last given, and set the time slot again
    rose.add(ConversationStates.IDLE,
      ConversationPhrases.GREETING_MESSAGES,
      new AndCondition(new GreetingMatchesNameCondition(rose.getName()),
               new QuestInStateCondition(QUEST_SLOT, 0, "start"),
               new PlayerCanEquipItemCondition("rhosyd"),
                             new TimePassedCondition(QUEST_SLOT, 1, DELAY)),
      ConversationStates.IDLE,
      "Hello dearie. My far sight tells me you need a pretty flower for some fair maiden. Here ye arr, bye now.",
      new MultipleActions(new EquipItemAction("rhosyd", 1, true),
                                new SetQuestAction(QUEST_SLOT, 0, "got_flower"),
                                new SetQuestToTimeStampAction(QUEST_SLOT, 1)));

    // don't put the flower on the ground - if player has no space, tell them
    rose.add(ConversationStates.IDLE,
        ConversationPhrases.GREETING_MESSAGES,
        new AndCondition(new GreetingMatchesNameCondition(rose.getName()),
                 new QuestInStateCondition(QUEST_SLOT, 0, "start"),
                                 new TimePassedCondition(QUEST_SLOT, 1, DELAY),
                 new NotCondition(new PlayerCanEquipItemCondition("rhosyd"))),
        ConversationStates.IDLE,
        "Shame you don't have space to take a pretty flower from me. Come back when you can carry my precious blooms without damaging a petal.",
        null);
   
        // don't give the flower if one was given within the last 5 minutes
        rose.add(ConversationStates.IDLE,
        ConversationPhrases.GREETING_MESSAGES,
        new AndCondition(new GreetingMatchesNameCondition(rose.getName()),
                 new QuestInStateCondition(QUEST_SLOT, 0, "start"),
                                 new NotCondition(new TimePassedCondition(QUEST_SLOT, 1, DELAY))),
        ConversationStates.IDLE,
        "I gave you a flower not five minutes past! Her Royal Highness can enjoy that one for a while.",
        null);
     
      final ChatCondition lostFlowerCondition = new AndCondition(new GreetingMatchesNameCondition(rose.getName()),
         // had got the flower before and was supposed to take it to the princess next
           new QuestInStateCondition(QUEST_SLOT, 0, "got_flower"),
         // check chest and so on first - maybe the player does still have it (though we can't check house chests or the floor)
         new ChatCondition() {
             public boolean fire(final Player player, final Sentence sentence, final Entity entity) {
               return player.getTotalNumberOf("rhosyd") == 0;
             }
         },
        // just to check there is space
        new PlayerCanEquipItemCondition("rhosyd"),
        // note: older quest slots will pass this automatically, but they are old now.
                new TimePassedCondition(QUEST_SLOT, 1, 12*MathHelper.MINUTES_IN_ONE_WEEK));
          
      // if the player never had a timestamp stored (older quest) we have now added timestamp 1.
      // but that was a while ago that we changed it (November 2010?)
    rose.add(ConversationStates.IDLE,
      ConversationPhrases.GREETING_MESSAGES,
      lostFlowerCondition,
      ConversationStates.QUESTION_1,
      "Hello dearie. Did you lose the flower I gave you last? If you need another say #yes but it's bad luck for me to have to give you it again, so you better be sure!",
      null);
   
    rose.add(ConversationStates.QUESTION_1,
        ConversationPhrases.YES_MESSAGES,
        lostFlowerCondition,
        ConversationStates.IDLE,
        "Heres a new flower to take the pretty lady, but mind you don't lose that one.",
        new MultipleActions(new EquipItemAction("rhosyd", 1, true),
                        new SetQuestAction(QUEST_SLOT, 0, "got_flower"),
                        // dock some karma for losing the flower
                        new IncreaseKarmaAction(-20.0),
                        new SetQuestToTimeStampAction(QUEST_SLOT, 1)));
   
    rose.add(ConversationStates.QUESTION_1,
        ConversationPhrases.NO_MESSAGES,
        lostFlowerCondition,
        ConversationStates.IDLE,
        "No worries dearie, you probably got it somewhere!",
        null);
   
        // don't give the flower if the quest state isn't start
        // unless it's been over 12 weeks and are in state got_flower?
      rose.add(ConversationStates.IDLE,
          ConversationPhrases.GREETING_MESSAGES,
          new AndCondition(new GreetingMatchesNameCondition(rose.getName()),
                   new QuestNotInStateCondition(QUEST_SLOT, 0, "start"),
                   new NotCondition(lostFlowerCondition)),
          ConversationStates.IDLE,
          "I've got nothing for you today, sorry dearie. I'll be on my way now, bye.",
          null);
  }

  private void bringFlowerStep() {
    final SpeakerNPC npc = npcs.get("Tywysoga");
    ChatAction addRandomNumberOfItemsAction = new ChatAction() {
      public void fire(final Player player, final Sentence sentence, final EventRaiser npc) {
        //add random number of goldbars
        final StackableItem goldbars = (StackableItem) SingletonRepository.getEntityManager()
            .getItem("gold bar");
        int goldamount;
        goldamount = 5 * Rand.roll1D6();
        goldbars.setQuantity(goldamount);
        // goldbars.setBoundTo(player.getName()); <- not sure
        // if these should get bound or not.
        player.equipOrPutOnGround(goldbars);
        npc.say("Thank you! Take these " + Integer.toString(goldamount) + " gold bars, I have plenty. And, listen: If you'd ever like to get me another, be sure to ask me first. Rose Leigh is superstitious, she won't give the bloom unless she senses you need it.");
      }
    };
    npc.add(ConversationStates.ATTENDING,
        Arrays.asList("flower", "Rhosyd"),
        new AndCondition(new QuestInStateCondition(QUEST_SLOT, 0, "got_flower"), new PlayerHasItemWithHimCondition("rhosyd")),
        ConversationStates.ATTENDING, null,
        new MultipleActions(new DropItemAction("rhosyd"),
                                    new IncreaseXPAction(5000),
                                    new IncreaseKarmaAction(15),
                  addRandomNumberOfItemsAction,
                  new SetQuestAction(QUEST_SLOT, 0, "flower_brought"),
                  new IncrementQuestAction(QUEST_SLOT, 2, 1)));

    npc.add(ConversationStates.ATTENDING,
      Arrays.asList("flower", "Rhosyd"),
      new NotCondition(new PlayerHasItemWithHimCondition("rhosyd")),
      ConversationStates.ATTENDING,
      "You don't seem to have a rhosyd bloom with you. But Rose Leigh wanders all over the island, I'm sure you'll find her one day!",
      null);

  }

  @Override
  public void addToWorld() {
    super.addToWorld();
    fillQuestInfo(
        "Rhosyd for Elf Princess",
        "Tywysoga, the Elf Princess in Nalwor Tower, wants to fill her room with precious rhosyds.",
        false);
    offerQuestStep();
    getFlowerStep();
    bringFlowerStep();
  }

  @Override
  public List<String> getHistory(final Player player) {
    final List<String> res = new ArrayList<String>();
    if (!player.hasQuest(QUEST_SLOT)) {
      return res;
    }
    res.add("I bravely fought my way to the top of Nalwor Tower to meet Princess Tywysoga.");
        // todo split on ; to put the 0th part in questState   
        final String questStateFull = player.getQuest(QUEST_SLOT);
        final String[] parts = questStateFull.split(";");
        final String questState = parts[0];
    if ("rejected".equals(questState)) {
      res.add("The Elf Princess asked for a pretty flower, but I can't be bothered with that. I'm gonna kill some orcs!");
    }
    if ("start".equals(questState) || "got_flower".equals(questState) || isCompleted(player)) {
      res.add("The Princess requested I find the wandering flower seller Rose Leigh to get a precious rhosyd from her.");
    }
    if ("got_flower".equals(questState) || isCompleted(player)) {
      res.add("I found Rose Leigh and got the flower to take Princess Tywysoga.");
    }
        if (isRepeatable(player)) {
            res.add("I took the flower to the Princess and she gave me gold bars. If I want to make her happy again, I can ask her for another task.");
        }
    final int repetitions = player.getNumberOfRepetitions(getSlotName(), 2);
    if (repetitions > 0) {
      res.add("I've already taken Princess Tywysoga " + Grammar.quantityplnoun(repetitions, "precious flower", "one") + ".");
    }
    return res;
  }
 
  @Override
  public String getName() {
    return "ElfPrincess";
  }
 
  @Override
  public int getMinLevel() {
    return 60;
  }
 
  @Override
  public boolean isRepeatable(final Player player) {
    return new QuestInStateCondition(QUEST_SLOT,0,"flower_brought").fire(player,null, null);
  }
 
  // The quest may have been completed a few times already and then re-opened as it's repeatable
  // since this method is used to separate open quests from completed quests, we'll say that being completed
  // means it's done and not re-opened
  @Override
  public boolean isCompleted(final Player player) {
    return new QuestInStateCondition(QUEST_SLOT,0,"flower_brought").fire(player,null, null);
  }
 
  @Override
  public String getRegion() {
    return Region.NALWOR_CITY;
  }
}
TOP

Related Classes of games.stendhal.server.maps.quests.ElfPrincess

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.