SheepBuyerNPC.java :  » Game » Arianne-RPG-0.83 » games » stendhal » server » maps » semos » city » Java Open Source

Java Open Source » Game » Arianne RPG 0.83 
Arianne RPG 0.83 » games » stendhal » server » maps » semos » city » SheepBuyerNPC.java
  package games.stendhal.server.maps.semos.city;

import games.stendhal.common.Rand;
import games.stendhal.server.core.engine.StendhalRPZone;
import games.stendhal.server.core.rp.StendhalRPAction;
import games.stendhal.server.entity.RPEntity;
import games.stendhal.server.entity.creature.Creature;
import games.stendhal.server.entity.creature.Sheep;
import games.stendhal.server.entity.npc.SpeakerNPC;
import games.stendhal.server.entity.npc.SpeakerNPCFactory;
import games.stendhal.server.entity.npc.behaviour.adder.BuyerAdder;
import games.stendhal.server.entity.npc.behaviour.impl.BuyerBehaviour;
import games.stendhal.server.entity.player.Player;
import games.stendhal.server.maps.semos.village.SheepSellerNPC;
import games.stendhal.server.util.Area;

import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import marauroa.common.game.RPObject;

/**
 * A merchant (original name: Sato) who buys sheep from players.
 */
public class SheepBuyerNPC extends SpeakerNPCFactory {
  // The sheep pen where Sato moves what he buys
  /** Left X coordinate of the sheep pen */ 
  private static final int SHEEP_PEN_X = 39;
  /** Top Y coordinate of the sheep pen */
  private static final int SHEEP_PEN_Y = 24;
  /** Width of the sheep pen */
  private static final int SHEEP_PEN_WIDTH = 16;
  /** Height of the sheep pen */
  private static final int SHEEP_PEN_HEIGHT = 6;
  /** 
   * The maximum number of sheep Sato keeps in his sheep pen.
   */ 
  private static final int MAX_SHEEP_IN_PEN = 10;
  /** The area covering the sheep pen in Semos */
  private Area pen;
  

  @Override
  public void createDialog(final SpeakerNPC npc) {
    class SheepBuyerBehaviour extends BuyerBehaviour {
      SheepBuyerBehaviour(final Map<String, Integer> items) {
        super(items);
      }

      private int getValue(final Sheep sheep) {
        return Math.round(getUnitPrice(chosenItemName) * ((float) sheep.getWeight() / (float) sheep.MAX_WEIGHT));
      }

      @Override
      public int getCharge(final SpeakerNPC seller, final Player player) {
        if (player.hasSheep()) {
          final Sheep sheep = player.getSheep();
          return getValue(sheep);
        } else {
          // npc's answer was moved to BuyerAdder. 
          return 0;
        }
      }
      
      /**
       * Get the area of the sheep pen where bought sheep 
       * should be moved.
       * 
       * @param zone the zone of the sheep pen
       * @return area of the sheep pen
       */
      private Area getPen(StendhalRPZone zone) {
        if (pen == null) {
          Rectangle2D rect = new Rectangle2D.Double();
          rect.setRect(SHEEP_PEN_X, SHEEP_PEN_Y, SHEEP_PEN_WIDTH, SHEEP_PEN_HEIGHT);
          pen = new Area(zone, rect);
        }
        
        return pen;
      }
      
      /**
       * Try to get rid of the big bad wolf that could have spawned in the pen,
       * but miss it sometimes.
       *  
       * @param zone the zone to check
       */
      private void killWolves(StendhalRPZone zone) {
        if (Rand.throwCoin() == 1) { 
          for (RPObject obj : zone) {
            if (obj instanceof Creature) {
              Creature wolf = (Creature) obj;
              
              if ("wolf".equals(wolf.get("subclass")) && getPen(zone).contains(wolf)) {
                  wolf.delayedDamage(wolf.getHP(), "Sato");
                  return;
              }
            }
          }
        }
      }
      
      /**
       * Get a list of the sheep in the pen.
       * 
       * @param zone the zone to check
       * @return list of sheep in the pen
       */
      private List<Sheep> sheepInPen(StendhalRPZone zone) {
        List<Sheep> sheep = new LinkedList<Sheep>();
        Area pen = getPen(zone);
        
        for (RPEntity entity : zone.getPlayerAndFriends()) {
          if (entity instanceof Sheep) {
            if (pen.contains(entity)) {
              sheep.add((Sheep) entity);
            }
          }
        }
        
        return sheep;
      }
      
      /**
       * Move a bought sheep to the den if there's space, or remove it 
       * from the zone otherwise. Remove old sheep if there'd be more
       * than <code>MAX_SHEEP_IN_PEN</code> after the addition.
       * 
       * @param sheep the sheep to be moved
       */
      private void moveSheep(Sheep sheep) {
        // The area of the sheed den.
        int x = Rand.randUniform(SHEEP_PEN_X, SHEEP_PEN_X + SHEEP_PEN_WIDTH - 1);
        int y = Rand.randUniform(SHEEP_PEN_Y, SHEEP_PEN_Y + SHEEP_PEN_HEIGHT - 1);
        StendhalRPZone zone = sheep.getZone();
        List<Sheep> oldSheep = sheepInPen(zone);
        
        killWolves(zone);
        /*
         * Keep the amount of sheep reasonable. Sato's
         * a business man and letting the sheep starve 
         * would be bad for busines.
         */
        if (oldSheep.size() >= MAX_SHEEP_IN_PEN) {
          // Sato sells the oldest sheep
          zone.remove(oldSheep.get(0));
        }
        
        if (!StendhalRPAction.placeat(zone, sheep, x, y)) {
          // there was no room for the sheep. Simply eat it
          sheep.getZone().remove(sheep);  
        }
      }

      @Override
      public boolean transactAgreedDeal(final SpeakerNPC seller, final Player player) {
        // amount is currently ignored.

        final Sheep sheep = player.getSheep();

        if (sheep != null) {
          if (seller.squaredDistance(sheep) > 5 * 5) {
            seller.say("I can't see that sheep from here! Bring it over so I can assess it properly.");
          } else if (getValue(sheep) < SheepSellerNPC.BUYING_PRICE) {
            // prevent newbies from selling their sheep too early
            seller.say("Nah, that sheep looks too skinny. Feed it with red berries, and come back when it has become fatter.");
          } else {
            seller.say("Thanks! Here is your money.");
            payPlayer(seller, player);
            player.removeSheep(sheep);

            player.notifyWorldAboutChanges();
            moveSheep(sheep);

            return true;
          }
        } else {
          seller.say("You don't have any sheep, " + player.getTitle() + "! What are you trying to pull?");
        }

        return false;
      }
    }

    final Map<String, Integer> buyitems = new HashMap<String, Integer>();
    buyitems.put("sheep", 150);

    npc.addGreeting();
    npc.addJob("I buy sheep here in Semos, then I send them up to Ados where they are exported.");
    npc.addHelp("I purchase sheep, at what I think is a fairly reasonable price. Just say if you want to #sell #sheep, and I will set up a deal!");
    new BuyerAdder().add(npc, new SheepBuyerBehaviour(buyitems), true);
    npc.addGoodbye();
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.