Package games.stendhal.server.maps.quests

Source Code of games.stendhal.server.maps.quests.StuffForBaldemar$ItemData

/* $Id: StuffForBaldemar.java,v 1.24 2011/05/01 19:50:05 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;

import games.stendhal.common.MathHelper;
import games.stendhal.common.grammar.Grammar;
import games.stendhal.common.parser.Sentence;
import games.stendhal.server.core.engine.SingletonRepository;
import games.stendhal.server.entity.item.Item;
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.SetQuestAndModifyKarmaAction;
import games.stendhal.server.entity.npc.condition.AndCondition;
import games.stendhal.server.entity.npc.condition.QuestStartedCondition;
import games.stendhal.server.entity.npc.condition.QuestStateStartsWithCondition;
import games.stendhal.server.entity.npc.condition.GreetingMatchesNameCondition;
import games.stendhal.server.entity.player.Player;
import games.stendhal.server.util.TimeUtil;

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

/**
* QUEST: The mithril shield forging.
*
* PARTICIPANTS:
* <ul>
* <li> Baldemar, mithrilbourgh elite wizard, will forge a mithril shield.
* </ul>
*
* STEPS:
* <ul>
* <li> Baldemar tells you about shield.
* <li> He offers to forge a mithril shield for you if you bring him what he
* needs.
* <li> You give him all he asks for.
* <li> Baldemar checks if you have ever killed a black giant alone, or not
* <li> Baldemar forges the shield for you
* </ul>
*
* REWARD:
* <ul>
* <li> mithril shield
* <li>95000 XP
* </ul>
*
*
* REPETITIONS:
* <ul>
* <li> None.
* </ul>
*/
public class StuffForBaldemar extends AbstractQuest {
  private static Map<Integer, ItemData> neededItems = initneededitems();
  private static Map<Integer, ItemData> initneededitems() {
    neededItems = new TreeMap<Integer, ItemData>();
    ItemData data = new ItemData("mithril bar",
                  REQUIRED_MITHRIL_BAR,
                  "I cannot #forge it without the missing ",
                  ". After all, this IS a mithril shield.");
    neededItems.put(1, data);
    data = new ItemData("obsidian",  REQUIRED_OBSIDIAN,
        "I need several gems to grind into dust to mix with the mithril. I need ",
        " still.");
    neededItems.put(2, data);
    data = new ItemData("diamond",  REQUIRED_DIAMOND ,
        "I need several gems to grind into dust to mix with the mithril. I need ",
        " still.");
    neededItems.put(3, data);
   
   
    data = new ItemData("emerald",  REQUIRED_EMERALD ,
        "I need several gems to grind into dust to mix with the mithril. I need ",
        " still.");
    neededItems.put(4, data);
   
    data = new ItemData("carbuncle",  REQUIRED_CARBUNCLE ,
        "I need several gems to grind into dust to mix with the mithril. I need ",
        " still.");
    neededItems.put(5, data);
   
    data = new ItemData("sapphire",  REQUIRED_SAPPHIRE,
        "I need several gems to grind into dust to mix with the mithril. I need ",
        " still.");
    neededItems.put(6, data);
    int i = 7;
    data = new ItemData("black shield",  REQUIRED_BLACK_SHIELD ,
        "I need ",
        " to form the framework for your new shield.");
    neededItems.put(i, data);
   
     i = 8;
    data = new ItemData("magic plate shield",  REQUIRED_MAGIC_PLATE_SHIELD ,
        "I need ",
        " for the pieces and parts for your new shield.");
    neededItems.put(i, data);
 
     i = 9;
      data = new ItemData("gold bar",  REQUIRED_GOLD_BAR ,
          "I need ",
          " to melt down with the mithril and iron.");
      neededItems.put(i, data);

     i = 10;
      data = new ItemData("iron",  REQUIRED_IRON ,
          "I need ",
          " to melt down with the mithril and gold.");
      neededItems.put(i, data);
     i = 11;
      data = new ItemData("black pearl",  REQUIRED_BLACK_PEARL ,
          "I need ",
          " to crush into fine powder to sprinkle onto shield to give it a nice sheen.");
      neededItems.put(i, data);

     i = 12;
      data = new ItemData("shuriken",  REQUIRED_SHURIKEN ,
          "I need ",
          " to melt down with the mithril, gold and iron. It is a 'secret' ingredient that only you and I know about. ;)");
      neededItems.put(i, data);
      i = 13;
      data = new ItemData("marbles",  REQUIRED_MARBLES ,
          "My son wants some new toys. I need ",
          " still.");
      neededItems.put(i, data);

      data = new ItemData("snowglobe",  REQUIRED_SNOWGLOBE,
          "I just LOVE those trinkets from athor. I need ",
          " still.");
      neededItems.put(14, data);
    return neededItems;
  }

 
  protected static final class ItemData {

    private int neededAmount;
    private final String itemName;
    private final String itemPrefix;
    private final String itemSuffix;
    private final int requiredAmount;

    public ItemData(final String name, final int needed, final String prefix, final String suffix) {
      this.requiredAmount = needed;
      this.neededAmount = needed;
      this.itemName = name;
      this.itemPrefix = prefix;
      this.itemSuffix = suffix;
    }

    public int getStillNeeded() {
      return neededAmount;
    }

    public void setAmount(final int needed) {
      neededAmount = needed;
     
    }

    public String getName() {
      return itemName;
    }

    public String getPrefix() {
      return itemPrefix;
    }

    public String getSuffix() {
      return itemSuffix;
    }

    public void subAmount(final String string) {
      subAmount(Integer.parseInt(string));
     
    }

    String getAnswer() {
      return itemPrefix
        + Grammar.quantityplnoun(
            neededAmount, itemName, "a")
        + itemSuffix;
    }

    public int getRequired() {
      return requiredAmount;
    }

    public int getAlreadyBrought() {
      return requiredAmount - neededAmount;
    }

    public void subAmount(final int amount) {
      neededAmount -= amount;
     
    }

    public void resetAmount() {
      neededAmount = requiredAmount;
     
    }
  }

  private static final int REQUIRED_MITHRIL_BAR = 20;

  private static final int REQUIRED_OBSIDIAN = 1;

  private static final int REQUIRED_DIAMOND = 1;

  private static final int REQUIRED_EMERALD = 5;
 
  private static final int REQUIRED_CARBUNCLE = 10;

  private static final int REQUIRED_SAPPHIRE = 10;

  private static final int REQUIRED_BLACK_SHIELD = 1;

  private static final int REQUIRED_MAGIC_PLATE_SHIELD = 1;

  private static final int REQUIRED_GOLD_BAR = 10;

  private static final int REQUIRED_IRON = 20;

  private static final int REQUIRED_BLACK_PEARL = 10;

  private static final int REQUIRED_SHURIKEN = 20;
 
  private static final int REQUIRED_MARBLES = 15;

  private static final int REQUIRED_SNOWGLOBE = 1;

  private static final String I_WILL_NEED_MANY_THINGS = "I will need many, many things: "
              + REQUIRED_MITHRIL_BAR
              + " mithril bars, "
              + REQUIRED_OBSIDIAN
              + " obsidian, "
              + REQUIRED_DIAMOND
              + " diamond, "
              + REQUIRED_EMERALD
              + " emeralds,"
              + REQUIRED_CARBUNCLE
              + " carbuncles, "
              + REQUIRED_SAPPHIRE
              + " sapphires, "
              + REQUIRED_BLACK_SHIELD
              + " black shield, "
              + REQUIRED_MAGIC_PLATE_SHIELD
              + " magic plate shield, "
              + REQUIRED_GOLD_BAR
              + " gold bars, "
              + REQUIRED_IRON
              + " iron bars, "
              + REQUIRED_BLACK_PEARL
              + " black pearls, "
              + REQUIRED_SHURIKEN
              + " shuriken, "
              + REQUIRED_MARBLES
              + " marbles and "
              + REQUIRED_SNOWGLOBE
              + " snowglobe. Come back when you have them in the same #exact order!";
 
  private static final int REQUIRED_MINUTES = 10;

  private static final String QUEST_SLOT = "mithrilshield_quest";

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

    npc.add(ConversationStates.ATTENDING,
      ConversationPhrases.QUEST_MESSAGES, null,
      ConversationStates.QUEST_OFFERED, null,
      new ChatAction() {
        public void fire(final Player player, final Sentence sentence, final EventRaiser raiser) {
          if (!player.hasQuest(QUEST_SLOT) || "rejected".equals(player.getQuest(QUEST_SLOT))) {
            raiser.say("I can forge a shield made from mithril along with several other items. Would you like me to do that?");
          } else if (player.isQuestCompleted(QUEST_SLOT)) {
            raiser.say("I would prefer you left me to my entertainment.");
            raiser.setCurrentState(ConversationStates.ATTENDING);
          } else {
            raiser.say("Why are you bothering me when you haven't completed your quest yet?");
            raiser.setCurrentState(ConversationStates.ATTENDING);
          }
        }
      });

    npc.add(ConversationStates.QUEST_OFFERED,
      ConversationPhrases.YES_MESSAGES, null,
      ConversationStates.ATTENDING, null,
      new ChatAction() {
        public void fire(final Player player, final Sentence sentence, final EventRaiser raiser) {
          raiser.say(I_WILL_NEED_MANY_THINGS);
          player.setQuest(QUEST_SLOT, "start;0;0;0;0;0;0;0;0;0;0;0;0;0;0");
          player.addKarma(10);

        }
      });

    npc.add(
      ConversationStates.QUEST_OFFERED,
      ConversationPhrases.NO_MESSAGES,
      null,
      ConversationStates.IDLE,
      "I can't believe you are going to pass up this opportunity! You must be daft!!!",
      new SetQuestAndModifyKarmaAction(QUEST_SLOT, "rejected", -10.0));

    npc.addReply("exact",
      "As I have listed them here, you must provide them in that order.");
  }

  private void step_2() {
    /* Get the stuff. */
  }

  private void step_3() {
    final SpeakerNPC npc = npcs.get("Baldemar");

    npc.add(ConversationStates.IDLE, ConversationPhrases.GREETING_MESSAGES,
      new AndCondition(new GreetingMatchesNameCondition(npc.getName()),
          new QuestStateStartsWithCondition(QUEST_SLOT, "start")),
      ConversationStates.ATTENDING, null,
      new ChatAction() {
        public void fire(final Player player, final Sentence sentence, final EventRaiser raiser) {
          final String[] tokens = player.getQuest(QUEST_SLOT).split(";");
         
          int idx1 = 1;
          for (ItemData itemdata : neededItems.values()) {
              itemdata.resetAmount();
              itemdata.subAmount(tokens[idx1]);
              idx1++;
          }

          boolean missingSomething = false;

          int size = neededItems.size();
          for (int idx = 1; !missingSomething && idx <= size; idx++) {
            ItemData itemData = neededItems.get(idx);
            missingSomething = proceedItem(player, raiser,
                itemData);
          }
         
          if (player.hasKilledSolo("black giant") && !missingSomething) {
            raiser.say("You've brought everything I need to forge the shield. Come back in "
              + REQUIRED_MINUTES
              + " minutes and it will be ready.");
            player.setQuest(QUEST_SLOT, "forging;" + System.currentTimeMillis());
          } else {
            if (!player.hasKilledSolo("black giant") && !missingSomething) {
              raiser.say("This shield can only be given to those who have killed a black giant, and without the help of others.");
            }

            StringBuilder sb = new StringBuilder(30);
            sb.append("start");
            for (ItemData id : neededItems.values()) {
              sb.append(";");
              sb.append(id.getAlreadyBrought());
            }
            player.setQuest(QUEST_SLOT, sb.toString());
             
          }
        }

 
        private boolean proceedItem(final Player player,
            final EventRaiser engine, final ItemData itemData) {
          if (itemData.getStillNeeded() > 0) {
           
            if (player.isEquipped(itemData.getName(), itemData.getStillNeeded())) {
              player.drop(itemData.getName(), itemData.getStillNeeded());
              itemData.setAmount(0);
            } else {
              final int amount = player.getNumberOfEquipped(itemData.getName());
              if (amount > 0) {
                player.drop(itemData.getName(), amount);
                itemData.subAmount(amount);
              }

              engine.say(itemData.getAnswer());
              return true;
            }
          }
          return false;
        }
      });

    npc.add(ConversationStates.IDLE, ConversationPhrases.GREETING_MESSAGES,
        new AndCondition(new GreetingMatchesNameCondition(npc.getName()),
            new QuestStateStartsWithCondition(QUEST_SLOT, "forging;")),
        ConversationStates.IDLE, null, new ChatAction() {
        public void fire(final Player player, final Sentence sentence, final EventRaiser raiser) {

          final String[] tokens = player.getQuest(QUEST_SLOT).split(";");
         
          final long delay = REQUIRED_MINUTES * MathHelper.MILLISECONDS_IN_ONE_MINUTE;
          final long timeRemaining = (Long.parseLong(tokens[1]) + delay)
              - System.currentTimeMillis();

          if (timeRemaining > 0L) {
            raiser.say("I haven't finished forging your shield. Please check back in "
              + TimeUtil.approxTimeUntil((int) (timeRemaining / 1000L))
              + ".");
            return;
          }

          raiser.say("I have finished forging your new mithril shield. Enjoy. Now I will see what Trillium has stored behind the counter for me. ;)");
          player.addXP(95000);
          player.addKarma(25);
          final Item mithrilshield = SingletonRepository.getEntityManager().getItem("mithril shield");
          mithrilshield.setBoundTo(player.getName());
          player.equipOrPutOnGround(mithrilshield);
          player.notifyWorldAboutChanges();
          player.setQuest(QUEST_SLOT, "done");
        }
      });

    npc.add(ConversationStates.ATTENDING,
      Arrays.asList("forge", "missing"),
      new QuestStartedCondition(QUEST_SLOT),
      ConversationStates.ATTENDING,
      null,
      new ChatAction() {
        public void fire(final Player player, final Sentence sentence, final EventRaiser raiser) {
          final String[] tokens = player.getQuest(QUEST_SLOT).split(";");

          final int neededMithrilBar = REQUIRED_MITHRIL_BAR
              - Integer.parseInt(tokens[1]);
          final int neededObsidian = REQUIRED_OBSIDIAN
              - Integer.parseInt(tokens[2]);
          final int neededDiamond = REQUIRED_DIAMOND
              - Integer.parseInt(tokens[3]);
          final int neededEmerald = REQUIRED_EMERALD
              - Integer.parseInt(tokens[4]);
          final int neededCarbuncle = REQUIRED_CARBUNCLE
              - Integer.parseInt(tokens[5]);
          final int neededSapphire = REQUIRED_SAPPHIRE
              - Integer.parseInt(tokens[6]);
          final int neededBlackShield = REQUIRED_BLACK_SHIELD
              - Integer.parseInt(tokens[7]);
          final int neededMagicPlateShield = REQUIRED_MAGIC_PLATE_SHIELD
              - Integer.parseInt(tokens[8]);
          final int neededGoldBars = REQUIRED_GOLD_BAR
              - Integer.parseInt(tokens[9]);
          final int neededIron = REQUIRED_IRON
              - Integer.parseInt(tokens[10]);
          final int neededBlackPearl = REQUIRED_BLACK_PEARL
              - Integer.parseInt(tokens[11]);
          final int neededShuriken = REQUIRED_SHURIKEN
              - Integer.parseInt(tokens[12]);
          final int neededMarbles = REQUIRED_MARBLES
              - Integer.parseInt(tokens[13]);
          final int neededSnowglobe = REQUIRED_SNOWGLOBE
              - Integer.parseInt(tokens[14]);
         
          raiser.say("I will need " + neededMithrilBar + " mithril bars, "
              + neededObsidian + " obsidian, "
              + neededDiamond + " diamond, "
              + neededEmerald + " emeralds, "
              + neededCarbuncle + " carbuncles, "
              + neededSapphire + " sapphires, "
              + neededBlackShield + " black shield, "
              + neededMagicPlateShield + " magic plate shield, "
              + neededGoldBars + " gold bars, "
              + neededIron + " iron bars, "
              + neededBlackPearl + " black pearls, "
              + neededShuriken + " shuriken, "
              + neededMarbles + " marbles and "
              + neededSnowglobe + " snowglobe");
        }
      });

  }

  @Override
  public void addToWorld() {
    super.addToWorld();
    fillQuestInfo(
        "Stuff for Baldemar",
        "Baldemar, a friendly mithrilbourgh elite wizard, will forge a special shield.",
        false);
    step_1();
    step_2();
    step_3();
  }

  @Override
  public String getName() {
    return "StuffForBaldemar";
  }
 
  @Override
  public List<String> getHistory(final Player player) {
      final List<String> res = new ArrayList<String>();
      if (!player.hasQuest(QUEST_SLOT)) {
        return res;
      }     
      final String questState = player.getQuest(QUEST_SLOT);
      res.add("I met Baldemar in the magic theater.");
      if (questState.equals("rejected")) {
        res.add("I'm not interested in his ideas about shields made from mithril.");
        return res;
      }
      res.add("Baldemar told me: " + I_WILL_NEED_MANY_THINGS);
      // yes, yes. this is the most horrible quest code and so you get a horrible quest history.
      if(questState.startsWith("start") && !"start;20;1;1;5;10;10;1;1;10;20;10;20;15;1".equals(questState)){
        res.add("I haven't brought everything yet. Baldemar will tell me what I need to take next.");
      } else if ("start;20;1;1;5;10;10;1;1;10;20;10;20;15;1".equals(questState) || !questState.startsWith("start")) {
        res.add("I took all the special items to Baldemar.");
      }
      if("start;20;1;1;5;10;10;1;1;10;20;10;20;15;1".equals(questState) && !player.hasKilledSolo("black giant")){
        res.add("I will need to bravely face a black giant alone, before I am worthy of this shield.");
      }
      if (questState.startsWith("forging")) {
        res.add("Baldemar is forging my mithril shield!");
      }
      if (isCompleted(player)) {
        res.add("I brought Baldemar many items, killed a black giant solo, and he forged me a mithril shield.");
      }
      return res;
  }
 
  @Override
  public int getMinLevel() {
    return 100;
  }
}
TOP

Related Classes of games.stendhal.server.maps.quests.StuffForBaldemar$ItemData

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.