Package games.stendhal.server.maps.quests.logic

Source Code of games.stendhal.server.maps.quests.logic.BringListOfItemsQuestLogic

/* $Id: BringListOfItemsQuestLogic.java,v 1.41 2011/05/01 19:50:10 martinfuchs Exp $ */
/***************************************************************************
*                   (C) Copyright 2003-2010 - 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.logic;

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.action.DecreaseKarmaAction;
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.QuestActiveCondition;
import games.stendhal.server.entity.npc.condition.QuestCompletedCondition;
import games.stendhal.server.entity.npc.condition.QuestNotStartedCondition;
import games.stendhal.server.entity.npc.condition.TriggerInListCondition;
import games.stendhal.server.entity.player.Player;

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

/**
* An abstract quest which is based on bringing a list of items to an NPC.
* The NPC keeps track of the items already brought to him.
*/
public class BringListOfItemsQuestLogic {
  /** The concrete quest information (which items?, which npc?, what does it say?). */
  protected BringListOfItemsQuest concreteQuest;

  /**
   * Creates a new BringItems quest.
   *
   * @param concreteQuest the real quest
   */
  public BringListOfItemsQuestLogic(final BringListOfItemsQuest concreteQuest) {
    this.concreteQuest = concreteQuest;
  }

  public List<String> getHistory(final Player player) {
    final List<String> res = new ArrayList<String>();
    if (!player.hasQuest(concreteQuest.getSlotName())) {
      return res;
    }
    final String npcName = concreteQuest.getNPC().getName();
    final String questState = player.getQuest(concreteQuest.getSlotName());
    if (!"done".equals(questState)) {
      res.add("I need to collect " + Grammar.enumerateCollection(getListOfStillMissingItems(player, false)) " for " + npcName + ".");
    } else {
      res.add("I collected everything that " +  npcName + " needed!");
    }
    return res;
  }
 
  /**
   * Returns a list of the names of all items that the given player still
   * has to bring to fulfil the quest.
   *
   * @param player The player doing the quest
   * @param hash If true, sets a # character in front of every name and puts it in quotes
   * @return A list of item names
   */
  protected List<String> getListOfStillMissingItems(final Player player, final boolean hash) {
    final List<String> result = new LinkedList<String>();

    String doneText = player.getQuest(concreteQuest.getSlotName());
    if (doneText == null) {
      doneText = "";
    }

    final List<String> done = Arrays.asList(doneText.split(";"));
    for (String item : concreteQuest.getNeededItems()) {
      if (!done.contains(item)) {
        if (hash) {
          item = "#" + item;
        }
        result.add(item);
      }
    }

    return result;
  }

  /**
   * player says 'hi' before starting the quest.
   */
  protected void welcomeNewPlayer() {
    concreteQuest.getNPC().add(
      ConversationStates.IDLE,
      ConversationPhrases.GREETING_MESSAGES,
      new AndCondition(new GreetingMatchesNameCondition(concreteQuest.getNPC().getName()),
          new QuestNotStartedCondition(concreteQuest.getSlotName())),
      ConversationStates.ATTENDING,
      concreteQuest.welcomeBeforeStartingQuest(),
      null);
  }

  /**
   * Player asks about quest.
   */
  protected void tellAboutQuest() {
     final List<String> questTrigger = new LinkedList<String>(ConversationPhrases.QUEST_MESSAGES);
    final List<String> additionalTrigger = concreteQuest.getAdditionalTriggerPhraseForQuest();
    if (additionalTrigger != null) {
      questTrigger.addAll(additionalTrigger);
    }
    concreteQuest.getNPC().add(ConversationStates.ATTENDING,
      questTrigger,
      new QuestNotStartedCondition(concreteQuest.getSlotName()),
      ConversationStates.QUEST_OFFERED,
      concreteQuest.respondToQuest()null);
  }

  /**
   * Player is willing to help.
   */
  protected void acceptQuest() {
    concreteQuest.getNPC().add(ConversationStates.QUEST_OFFERED,
      ConversationPhrases.YES_MESSAGES, null,
      ConversationStates.IDLE, concreteQuest.respondToQuestAcception(),
      new SetQuestAndModifyKarmaAction(concreteQuest.getSlotName(), "", concreteQuest.getKarmaDiffForQuestResponse()));
  }

  /**
   * Player is not willing to help.
   */
  protected void rejectQuest() {
    concreteQuest.getNPC().add(ConversationStates.QUEST_OFFERED, ConversationPhrases.NO_MESSAGES, null,
      ConversationStates.IDLE,
      concreteQuest.respondToQuestRefusal(),
      new DecreaseKarmaAction(concreteQuest.getKarmaDiffForQuestResponse()));
  }

  /**
   * Player asks what exactly is missing.
   */
  protected void listMissingItemsDuringQuestOffer() {
    if (concreteQuest.getTriggerPhraseToEnumerateMissingItems() != ConversationPhrases.EMPTY) {
      concreteQuest.getNPC().add(ConversationStates.QUEST_OFFERED,
        concreteQuest.getTriggerPhraseToEnumerateMissingItems(),
        null, ConversationStates.QUEST_OFFERED, null,
        new ChatAction() {
          public void fire(final Player player, final Sentence sentence, final EventRaiser raiser) {
            final List<String> missingItems = getListOfStillMissingItems(player, false);
            raiser.say(concreteQuest.firstAskForMissingItems(missingItems));
          }

          @Override
          public String toString() {
            return "list items";
          }
        });
    }
  }

  /**
   * Player asks what exactly is missing.
   */
  protected void listMissingItems() {
    // List missing items at the beginning of the conversation and during
    // the "giving items" states. Unless the trigger phrase list is empty
    // In this case it is ignored during the "giving items" state because
    // there is already a yes-trigger defined elsewhere.
    ConversationStates[] states;
    if (concreteQuest.getTriggerPhraseToEnumerateMissingItems() != ConversationPhrases.EMPTY) {
      states = new ConversationStates[] {ConversationStates.ATTENDING, ConversationStates.QUESTION_1};
    } else {
      states = new ConversationStates[] {ConversationStates.ATTENDING};
    }

    concreteQuest.getNPC().add(states,
      concreteQuest.getTriggerPhraseToEnumerateMissingItems(),
      new QuestActiveCondition(concreteQuest.getSlotName()),
      ConversationStates.QUESTION_1, null,
      new ChatAction() {
        public void fire(final Player player, final Sentence sentence, final EventRaiser raiser) {
          final List<String> missingItems = getListOfStillMissingItems(player, true);
          raiser.say(concreteQuest.askForMissingItems(missingItems));
        }

        @Override
        public String toString() {
          return "list items as triggers";
        }
      });
  }

  /**
   * Player says he doesn't have required items with him.
   */
  protected void playerDoesNotWantToGiveItems() {
      final ConversationStates[] states = new ConversationStates[] {ConversationStates.ATTENDING, ConversationStates.QUESTION_1};
    concreteQuest.getNPC().add(states, ConversationPhrases.NO_MESSAGES, null,
      ConversationStates.IDLE, null, new ChatAction() {
        public void fire(final Player player, final Sentence sentence, final EventRaiser raiser) {
          final List<String> missingItems = getListOfStillMissingItems(player, false);
          raiser.say(concreteQuest.respondToPlayerSayingHeHasNoItems(missingItems));
        }

        @Override
        public String toString() {
          return "respond to player not wanting to give any items";
        }
      });
  }

  /**
   * Player says he has a required item with him.
   */
  protected void playerWantsToGiveItems() {
    final ConversationStates[] states = new ConversationStates[] {ConversationStates.ATTENDING, ConversationStates.QUESTION_1};
    concreteQuest.getNPC().add(states,
      ConversationPhrases.YES_MESSAGES,
      new QuestActiveCondition(concreteQuest.getSlotName()),
      ConversationStates.QUESTION_1, concreteQuest.askForItemsAfterPlayerSaidHeHasItems(),
      null);
  }

  /**
   * Player offers an item.
   */
  protected void offerItem() {
    for(final String itemName : concreteQuest.getNeededItems()) {
      concreteQuest.getNPC().add(ConversationStates.QUESTION_1, itemName, null,
        ConversationStates.QUESTION_1, null,
        new ChatAction() {
          public void fire(final Player player, final Sentence sentence, final EventRaiser raiser) {
            List<String> missing = getListOfStillMissingItems(player, false);

            if (missing.contains(itemName)) {
                if (!player.drop(itemName)) {
                    raiser.say(concreteQuest.respondToOfferOfNotExistingItem(itemName));
                    return;
                }

                // register item as done
                final String doneText = player.getQuest(concreteQuest.getSlotName());
                player.setQuest(concreteQuest.getSlotName(), doneText + ";" + itemName);

                // check if the player has brought all items
                missing = getListOfStillMissingItems(player, false);

                if (!missing.isEmpty()) {
                    raiser.say(concreteQuest.respondToItemBrought());
                } else {
                    concreteQuest.rewardPlayer(player);
                    player.notifyWorldAboutChanges();
                    raiser.say(concreteQuest.respondToLastItemBrought());
                    player.setQuest(concreteQuest.getSlotName(), "done");
                    raiser.setCurrentState(ConversationStates.ATTENDING);
                }
            } else {
                raiser.say(concreteQuest.respondToOfferOfNotMissingItem());
            }
          }

            @Override
          public String toString() {
              return "accept or reject offered item";
            }
        }
      );
    }
  }

    /**
     * player tries to offer an unwanted item
    */
    protected void offerNotNeededItem() {
  concreteQuest.getNPC().add(ConversationStates.QUESTION_1, "",  
           new NotCondition(new TriggerInListCondition(concreteQuest.getNeededItems())),
           ConversationStates.QUESTION_1,
           concreteQuest.respondToOfferOfNotNeededItem(),
           null);
    }

    /**
     * player tries to say bye
    */
    // allow to say goodbye while listening for items
    protected void sayByeWhileInQuestion1() {
  concreteQuest.getNPC().add(ConversationStates.QUESTION_1, ConversationPhrases.GOODBYE_MESSAGES, null,
    ConversationStates.IDLE, "Bye.", null);
    }
 
    /**
   * Player returns while quest is still active.
   */
  protected void welcomeKnownPlayer() {
    concreteQuest.getNPC().add(
      ConversationStates.IDLE,
      ConversationPhrases.GREETING_MESSAGES,
      new AndCondition(new GreetingMatchesNameCondition(concreteQuest.getNPC().getName()),
          new QuestActiveCondition(concreteQuest.getSlotName())),
      ConversationStates.ATTENDING,
      concreteQuest.welcomeDuringActiveQuest(),
      null);
  }

  /**
   * Player returns after finishing the quest.
   */
  protected void welcomePlayerAfterQuest() {
    if (concreteQuest.shouldWelcomeAfterQuestIsCompleted()) {
      concreteQuest.getNPC().add(ConversationStates.IDLE,
        ConversationPhrases.GREETING_MESSAGES,
        new AndCondition(new GreetingMatchesNameCondition(concreteQuest.getNPC().getName()),
            new QuestCompletedCondition(concreteQuest.getSlotName())),
        ConversationStates.ATTENDING,
        concreteQuest.welcomeAfterQuestIsCompleted(),
        null);
    }
  }

  /**
   * Adds the quest to the world.
   */
  public void addToWorld() {

    // talk about quest
    welcomeNewPlayer();
    tellAboutQuest();
    listMissingItemsDuringQuestOffer();
    acceptQuest();
    rejectQuest();

    // accept items
    welcomeKnownPlayer();
    listMissingItems();
    playerDoesNotWantToGiveItems();
    playerWantsToGiveItems();
    offerItem();

          offerNotNeededItem();
    sayByeWhileInQuestion1();
    welcomePlayerAfterQuest();
  }
}
TOP

Related Classes of games.stendhal.server.maps.quests.logic.BringListOfItemsQuestLogic

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.