Package iryrwarosh

Source Code of iryrwarosh.Factory

package iryrwarosh;

import iryrwarosh.screens.CastSpellScreen;
import iryrwarosh.screens.DiveScreen;
import iryrwarosh.screens.JumpScreen;
import iryrwarosh.screens.Screen;
import iryrwarosh.screens.SneakScreen;
import iryrwarosh.screens.WorldMapScreen;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import asciiPanel.AsciiPanel;

public class Factory {
  private HashMap<Tile,List<Trait>> monsterTraits;
  private List<Item> minibossLoot;
  private List<Creature> rivals;
  private int defaultHearts;
 
  public Factory(){
    defaultHearts = 15;
    setMonsterTraits();
   
    minibossLoot = new ArrayList<Item>();
    minibossLoot.add(this.ringOfRegeneration());
    minibossLoot.add(this.magicCarpet());
    minibossLoot.add(this.mutationRing());
    minibossLoot.add(this.ringOfEvasion());
    minibossLoot.add(this.darkCloak());
    minibossLoot.add(this.rupeeMachine());
    minibossLoot.add(this.rupeeAmulet());
    minibossLoot.add(this.spikedArmor());
    minibossLoot.add(this.bagOfImps());
    minibossLoot.add(this.magicWand());
    minibossLoot.add(this.bombs());
    Collections.shuffle(minibossLoot);
   
    rivals = new ArrayList<Creature>();
    rivals.add(rival("Lame",   0, knife(), bow(), new RivalAi(0.01, 1.0)));
    rivals.add(rival("Dork"30, staff(), null, new RivalAi(0.00, 1.0)));
    rivals.add(rival("Max" + (char)4, 60, knife(), ringOfEvasion(), new RivalAi(0.005, 0.5)));
    rivals.add(rival("Lulz"90, club(), ringOfRegeneration(), new RivalAi(0.05, 1.0)));
    rivals.add(rival("Link", 120, sword(), shield(), new RivalAi(0.005, 0.1)));
    rivals.add(rival("Bela", 150, spear(), null, new RivalAi(0.01, 0.5)));
    rivals.add(rival("L33t", 180, knife(), club(), new RivalAi(0.01, 0.5)));
    rivals.add(rival("Mr X", 210, darkCloak(), knife(), new RivalAi(0.005, 0.0)));
    rivals.add(rival("Toad", 240, club(), snorkel(), new RivalAi(0.01, 0.5)));
    rivals.add(rival("Tify", 270, spear(), spectacles(), new RivalAi(0.01, 0.5)));
    rivals.add(rival("Muto", 130, staff(), mutationRing(), new RivalAi(0.01, 0.5)));
    rivals.add(rival("Al  ", 330, magicCarpet(), null, new RivalAi(0.01, 0.5)));
    Collections.shuffle(rivals);
  }
 
  private void setMonsterTraits(){
    monsterTraits = new HashMap<Tile,List<Trait>>();
   
    for (Tile biome : new Tile[]{ Tile.GREEN_TREE1, Tile.BROWN_TREE1, Tile.WHITE_TREE1,
        Tile.GREEN_ROCK, Tile.BROWN_ROCK, Tile.WHITE_ROCK, Tile.DESERT_SAND1, Tile.WATER1 }){
     
      List<Trait> traits = new ArrayList<Trait>();
     
      if (biome == Tile.WATER1){
        traits.add(Trait.SWIMMER);
      } else {
        traits.add(Trait.WALKER);
      }
     
      switch ((int)(Math.random() * 4)){
      case 0: traits.add(Trait.POISONOUS); break;
      case 1: traits.add(Trait.AGGRESSIVE); break;
      case 2: traits.add(Trait.DOUBLE_ATTACK); break;
      case 3: traits.add(Trait.DOUBLE_MOVE); break;
      }
     
      while (traits.size() < 4){
        Trait trait = Trait.getRandom();
        if (!traits.contains(trait))
          traits.add(trait);
      }
     
      monsterTraits.put(biome, traits);
    }
  }
 
  public Item knife(){
    Item item = new Item("knife", ')', Tile.WHITE_ROCK.background(), "Melee weapon that attacks when you evade. Can be poisoned."){
      int poisonCounter = 0;
     
      public void update(World world, Creature owner){
        super.update(world, owner);
       
        if (poisonCounter > 0)
          poisonCounter--;
       
        if (poisonCounter == 0 && hasTrait(Trait.POISONOUS)) {
          removeTrait(Trait.POISONOUS);
          if (owner != null)
            MessageBus.publish(new Note(world, owner, "Your knife is no longer poisonous."));
        }
      }

      public Screen use(Screen screen, World world, Creature owner){
        if (owner.rupees() + owner.hearts() <= 1) {
          MessageBus.publish(new Note(world, owner, "You need more than 1 rupee or heart to poison your knife."));
          return screen;
        }
       
        if (!hasTrait(Trait.POISONOUS))
          addTrait(Trait.POISONOUS);

        owner.loseRupees(world, 1);
        poisonCounter += 3;
        MessageBus.publish(new Note(world, owner, "Your knife is now poisonous for " + poisonCounter + " turns."));
       
        return screen;
      }
    };
    item.addTrait(Trait.EVADE_ATTACK);
    item.addTrait(Trait.STRONG_ATTACK);
    return item;
  }
 
  public Item club(){
    Item item = new Item("club", ')', Tile.BROWN_ROCK.background(), "Melee weapon with knockback. Can do a circle attack."){
      public Screen use(Screen screen, World world, Creature owner){
        if (owner.rupees() + owner.hearts() <= 1) {
          MessageBus.publish(new Note(world, owner, "You need more than 1 rupee or heart to do a circle attack."));
          return screen;
        }
       
        for (Point p : owner.position.neighbors()){
          Creature other = world.creature(p.x, p.y);
          if (other == null)
            continue;
         
          owner.attack(world, other, "with a wide swing");
        }
        owner.loseRupees(world, 1);
        return screen;
      }
    };
    item.addTrait(Trait.KNOCKBACK);
    item.addTrait(Trait.STRONG_ATTACK);
    return item;
  }
 
  public Item sword(){
    Item item = new Item("sword", ')', AsciiPanel.white, "Simple melee weapon. Can also shoot at no cost to you."){
      private Projectile last;
     
      public Screen use(Screen screen, World world, Creature owner){
        if (last != null && !last.isDone())
          return screen;
       
        Point dir = owner.lastMovedDirection();
        if (dir.x == 0 && dir.y == 0)
          dir = new Point(0, 1);
       
        char glyph = 9;
        if (dir.x == -1 && dir.y == -1 || dir.x == 1 && dir.y == 1)
          glyph = '\\';
        else if (dir.x == 1 && dir.y == -1 || dir.x == -1 && dir.y == 1)
          glyph = '/';
        else if (dir.x == 0 && (dir.y == -1 || dir.y == 1))
          glyph = 179;
        else if ((dir.x == -1 || dir.x == 1) && dir.y == 0)
          glyph = 196;
       
        last = new Projectile("sword", owner, glyph, AsciiPanel.brightWhite, 1, owner.position.copy(), dir){
          public boolean canEnter(Tile tile){
            return tile.isGround() || tile.isWater();
          }
        };
        world.add(last);
        return screen;
      }
    };
    item.addTrait(Trait.STRONG_ATTACK);
    return item;
  }
 
  public Item spear(){
    Item item = new Item("spear", ')', Tile.BROWN_ROCK.background(), "Long melee weapon that auto-attacks near you. Can be thrown."){
      public Screen use(Screen screen, World world, Creature owner){
        if (owner.rupees() + owner.hearts() <= 2) {
          MessageBus.publish(new Note(world, owner, "You need more than 2 rupees or hearts to throw a spear."));
          return screen;
        }

        Point dir = owner.lastMovedDirection();
        if (dir.x == 0 && dir.y == 0)
          dir = new Point(0, 1);
       
        char glyph = 9;
        if (dir.x == -1 && dir.y == -1 || dir.x == 1 && dir.y == 1)
          glyph = '\\';
        else if (dir.x == 1 && dir.y == -1 || dir.x == -1 && dir.y == 1)
          glyph = '/';
        else if (dir.x == 0 && (dir.y == -1 || dir.y == 1))
          glyph = 179;
        else if ((dir.x == -1 || dir.x == 1) && dir.y == 0)
          glyph = 196;
       
        world.add(new Projectile("arrow", owner, glyph, AsciiPanel.white, 1, owner.position.copy(), owner.lastMovedDirection()));
        owner.loseRupees(world, 1);
        return screen;
      }
    };
    item.addTrait(Trait.REACH_ATTACK);
    item.addTrait(Trait.STRONG_ATTACK);
    return item;
  }
 
  public Item staff(){
    Item item = new Item("long staff", ')', Tile.BROWN_ROCK.background(), "Long melee weapon that can also parry and counter attack.");
    item.addTrait(Trait.COUNTER_ATTACK);
    item.addTrait(Trait.REACH_ATTACK);
    item.addTrait(Trait.DEFLECT_MELEE);
    item.addTrait(Trait.STRONG_ATTACK);
    return item;
  }

  public Item weapon() {
    switch ((int)(Math.random() * 5)){
    case 0: return knife();
    case 1: return club();
    case 2: return sword();
    case 3: return spear();
    default: return staff();
    }
  }
 
  public Creature miniboss(World world, int sx, int sy){
    char[] glyphs = { 130, 131, 132, 133, 134, 136, 137, 138, 139, 140, 141,
                  147, 148, 149, 150, 151, 152, 160, 161, 162, 163 };
   
    char glyph = glyphs[(int)(Math.random() * glyphs.length)];
   
    int hue = (int)(Math.random() * 360);
    int hp = defaultHearts / 2 + (int)(Math.random() * defaultHearts / 2);
   
    List<Trait> traits = new ArrayList<Trait>();
    traits.add(Trait.WALKER);
    traits.add(Trait.TERRITORIAL);
    traits.add(Trait.HUNTER);
    traits.add(Trait.REGENERATES);
    traits.add(Trait.MYSTERIOUS);
   
    while (traits.size() < 8){
      Trait trait = Trait.getRandom();
      if (!traits.contains(trait))
        traits.add(trait);
    }
   
    Creature boss = new Creature(makeMinibossName(traits), glyph, Common.hsv(hue, 33, 66), hp){
      public void update(World world){
        super.update(world);
        wander(world);
      }
    };

    for (Trait trait : traits)
      boss.addTrait(trait);
   
    boss.setIsMiniboss(true);
   
    world.addToScreen(boss, sx, sy);
   
    if (Math.random() < 0.25)
      boss.swapLeftHand(world, weapon());
    if (Math.random() < 0.25)
      boss.swapRightHand(world, weapon());
   
    if (minibossLoot.size() > 0)
      boss.setLoot(minibossLoot.remove(0));
    else {
      switch ((int)(Math.random() * 4)){
      case 0: boss.setLoot(heartContainer()); break;
      case 1: boss.setLoot(bigMoney()); break;
      case 2: boss.setLoot(evasionPotion()); break;
      case 3: boss.setLoot(this.lostArtifact()); break;
      }
    }
   
    return boss;
  }

  private String makeMinibossName(List<Trait> traits) {
   
    String[] first = { "giant", "ugly", "malformed", "putrid", "rotten", "infested", "ancient", "crazed", "wild", "hated" };

    String[] second = { "spider", "squid", "jellyfish", "bird", "urchin", "demon", "scorpion", "insect", "blob",
        "evil", "best", "serpent", "monster" };
   
    String name = first[(int)(Math.random() * first.length)]
                + " " + second[(int)(Math.random() * second.length)];
   
    return name;
  }
 
  public Creature goblin(final World world){
    int hue = 30 + (int)(Math.random() * 90);
    Creature goblin = new Creature("goblin", 'g', Common.hsv(hue, 50, 50), 3){
      public void update(World world){
        super.update(world);
        wander(world);
      }
    };
    goblin.addTrait(Trait.WALKER);
    goblin.addTrait(Trait.HUNTER);
   
    world.add(goblin);
    goblin.swapLeftHand(world, weapon());
    return goblin;
  }
 
  private int monstersCreated = 0;
  public Creature monster(final World world, Tile biome){
    Color color = null;
    List<Point> candidates = new ArrayList<Point>();
    Point candidate = null;
    String name = null;
   
    switch (biome) {
    case GREEN_TREE1:
      name = "green forest monster";
      color = biome.color().brighter();
      candidates.addAll(world.screensOfType(Tile.GREEN_TREE1));
      candidates.addAll(world.screensOfType(Tile.PINE_TREE1));
      if (candidates.size() == 0)
        return null;
      candidate = candidates.get((int)(Math.random() * candidates.size()));
      break;
    case BROWN_TREE1:
      name = "brown forest monster";
      color = biome.color().brighter();
      candidates.addAll(world.screensOfType(Tile.BROWN_TREE1));
      candidates.addAll(world.screensOfType(Tile.BROWN_TREE4));
      if (candidates.size() == 0)
        return null;
      candidate = candidates.get((int)(Math.random() * candidates.size()));
      break;
    case WHITE_TREE1:
      name = "white forest monster";
      color = biome.color().brighter();
      candidates.addAll(world.screensOfType(Tile.WHITE_TREE1));
      if (candidates.size() == 0)
        return null;
      candidate = candidates.get((int)(Math.random() * candidates.size()));
      break;
    case GREEN_ROCK:
      name = "green hill monster";
      color = biome.background().darker();
      candidates.addAll(world.screensOfType(Tile.GREEN_ROCK));
      if (candidates.size() == 0)
        return null;
      candidate = candidates.get((int)(Math.random() * candidates.size()));
      break;
    case BROWN_ROCK:
      name = "brown mountain monster";
      color = biome.background().darker();
      candidates.addAll(world.screensOfType(Tile.BROWN_ROCK));
      if (candidates.size() == 0)
        return null;
      candidate = candidates.get((int)(Math.random() * candidates.size()));
      break;
    case WHITE_ROCK:
      name = "white mountain monster";
      color = biome.background().darker();
      candidates.addAll(world.screensOfType(Tile.WHITE_ROCK));
      if (candidates.size() == 0)
        return null;
      candidate = candidates.get((int)(Math.random() * candidates.size()));
      break;
    case DESERT_SAND1:
      name = "desert monster";
      color = biome.color();
      candidates.addAll(world.screensOfType(Tile.DESERT_SAND1));
      if (candidates.size() == 0)
        return null;
      candidate = candidates.get((int)(Math.random() * candidates.size()));
      break;
    case WATER1:
      name = "water monster";
      color = biome.color();
      break;
    }
   
    boolean isBigMonster = Math.random() * 1000 < (monstersCreated - 300);
   
    if (isBigMonster)
      name = "giant " + name;
   
    Creature monster = new Creature(name, isBigMonster ? 'M' : 'm', color, isBigMonster ? 7 : 3){
      public void update(World world){
        super.update(world);
        wander(world);
      }
    };
   
    for (Trait trait : monsterTraits.get(biome))
      monster.addTrait(trait);
   
    if (isBigMonster){
      Trait trait = Trait.getRandom();
      while (monster.hasTrait(trait))
        trait = Trait.getRandom();
      monster.addTrait(trait);
    }
   
    if (candidate == null)
      world.add(monster);
    else
      world.addToScreen(monster, candidate.x, candidate.y);
   
    monstersCreated++;
   
    return monster;
  }

  public Creature player(World world) {
    Creature player = new Creature("player", '@', AsciiPanel.brightWhite, defaultHearts);
    player.addTrait(Trait.WALKER);
    player.addTrait(Trait.LOOTLESS);
    world.add(player);
    return player;
  }
 
  public Creature zora(World world){
    Creature zora = new Creature("zora", 'z', Tile.WATER1.color(), 1);
    zora.addTrait(Trait.SWIMMER);
    zora.addTrait(Trait.HIDER);
    zora.addTrait(Trait.TERRITORIAL);
    zora.addTrait(Trait.ROCK_SPITTER);
    world.add(zora);
    return zora;
  }

  public Creature rival(World world){
    Creature rival = rivals.remove(0);
    world.add(rival);
   
    return rival;
  }
 
  public Creature rival(String name, int hue, Item item1, Item item2, final RivalAi ai){
    Creature rival = new Creature(name, '@', Common.hsv(hue, 80, 80), defaultHearts){
      public void update(World world){
        super.update(world);
        ai.update(world, this);
      }
    };
   
    rival.addTrait(Trait.WALKER);

    if (item1 != null)
      rival.swapLeftHand(null, item1);
   
    if (item2 != null)
      rival.swapRightHand(null, item2);
   
    if (Math.random() < 0.5)
      rival.setLoot(heartContainer());
    else
      rival.setLoot(bigMoney());
   
    return rival;
  }

  public Item heavyArmor() {
    Item item = new Item("heavy armor", '[', AsciiPanel.yellow, -2, "Reduces damage from heavy hitters.");
    item.addTrait(Trait.EXTRA_DEFENSE);
    return item;
  }
 
  public Item spikedArmor() {
    Item item = new Item("spiked armor", '[', AsciiPanel.yellow, -2, "Reduces damage from heavy hitters. Also covered in spikes.");
    item.addTrait(Trait.EXTRA_DEFENSE);
    item.addTrait(Trait.SPIKED);
    return item;
  }

  public Item shield() {
    Item item = new Item("large shield", '[', AsciiPanel.yellow, -1, "Deflects projectiles. Can be used to scare others nearby."){
      public Screen use(Screen screen, World world, Creature player) {
        if (player.rupees() + player.hearts() <= 1){
          MessageBus.publish(new Note(world, player, "You need more than 1 rupee or heart to intimidate others."));
          return screen;
        }

        int number = 0;
       
        for (Creature c : world.creaturesNear(player)){
          if (c.isFriendlyTo(player) || c.isMiniboss())
            continue;
         
          number++;
          c.fleeFrom(player);
          player.loseRupees(world, 1);
        }
       
        switch(number){
        case 0:
          MessageBus.publish(new Note(world, player, "You swing wildly but didn't scare anyone away."));
          break;
        case 1:
          MessageBus.publish(new Note(world, player, "You swing wildly and scare 1 nearby creature."));
          break;
        default:
          MessageBus.publish(new Note(world, player, "You swing wildly and scare " + number + " nearby creatures."));
          break;
        }
        return screen;
      }
    };
    item.addTrait(Trait.DEFLECT_RANGED);
    return item;
  }

  public Item spectacles() {
    Item item = new Item("spectacles", '/', Common.hsv(220, 15, 50), "Allows you to see camouflaged creatures. Use to see far away."){
      public Screen use(Screen screen, World world, Creature player) {
        if (player.rupees() + player.hearts() <= 1){
          MessageBus.publish(new Note(world, player, "You need more than 1 rupee or heart to look far away."));
          return screen;
        }
       
        player.loseRupees(world, 1);
        return new WorldMapScreen(screen, world.map(), player.position, true);
      }
    };
    item.addTrait(Trait.DETECT_CAMOUFLAGED);
    return item;
  }

  public Item bow() {
    Item item = new Item("bow", ')', Common.hsv(45, 50, 50), "Shoots deady arrows."){
      public Screen use(Screen screen, World world, Creature owner){
        if (owner.rupees() + owner.hearts() <= 1){
          MessageBus.publish(new Note(world, owner, "You need more than 1 rupee or heart to shoot arrows."));
          return screen;
        }
       
        Point dir = owner.lastMovedDirection();
        if (dir.x == 0 && dir.y == 0)
          dir = new Point(0, 1);
       
        char glyph = 9;
        if (dir.x == -1 && dir.y == -1 || dir.x == 1 && dir.y == 1)
          glyph = '\\';
        else if (dir.x == 1 && dir.y == -1 || dir.x == -1 && dir.y == 1)
          glyph = '/';
        else if (dir.x == 0 && (dir.y == -1 || dir.y == 1))
          glyph = 179;
        else if ((dir.x == -1 || dir.x == 1) && dir.y == 0)
          glyph = 196;
       
        world.add(new Projectile("arrow", owner, glyph, AsciiPanel.white, 3, owner.position.copy(), owner.lastMovedDirection()));
        owner.loseRupees(world, 1);
        return screen;
      }
    };
    return item;
  }

  public Item bombs() {
    Item item = new Item("bombs", ')', Common.hsv(220, 75, 75), "Pay 3" + (char)4 + " to place a bomb."){
      public Screen use(Screen screen, World world, Creature owner){
        if (owner.rupees() + owner.hearts() <= 3){
          MessageBus.publish(new Note(world, owner, "You need more than 3 rupees and hearts to place a bomb."));
          return screen;
        }
       
        Point where = owner.position;
       
        world.add(bomb(owner, where.x, where.y), where.x, where.y);
        owner.loseRupees(world, 1);
        return screen;
      }
    };
    return item;
  }
 
  private Item bomb(final Creature owner, final int x, final int y) {
    Item item = new Item("bomb", 248, Common.hsv(220, 75, 75), "Stand back!"){
      int countdown = 3;
     
      public void update(World world, Creature owner){
        if (countdown-- == 0)
          explode(world);
      }
     
      private void explode(World world){
        Creature here = world.creature(x, y);
        if (here != null)
          here.loseHearts(world, owner, 5, "with a bomb", "You have been blown up by one of " + owner.name() + "'s bomb");
       
        for (Point p : new Point(x, y).neighbors()){
          here = world.creature(p.x, p.y);
          if (here != null)
            here.loseHearts(world, owner, 2, "with a bomb", "You have been blown up by one of " + owner.name() + "'s bomb");
        }
        world.removeItem(x, y);
        world.add(smoke(x, y), x, y);
        for (Point p : new Point(x, y).neighbors()){
          world.removeItem(p.x, p.y);
          world.add(smoke(p.x, p.y), p.x, p.y);
        }
      }
    };
    item.setCanBePickedUp(false);
    return item;
  }
 
  private Item smoke(final int x, final int y) {
    Item item = new Item("smoke", '*', Common.hsv(220, 0, 75), "Smoke from a bomb"){
     
      public void update(World world, Creature owner){
        world.removeItem(x, y);
      }
    };
    item.setCanBePickedUp(false);
    return item;
  }
 
  public Item snorkel() {
    Item item = new Item("snorkel", '/', Tile.WATER2.color(), "Allows you to swim. Can be used to swim underwater."){
      public Screen use(Screen screen, World world, Creature owner){
        if (owner.rupees() + owner.hearts() <= 1){
          MessageBus.publish(new Note(world, owner, "You need more than 1 rupee or heart to dive underwater."));
          return screen;
        } if (!world.tile(owner.position.x, owner.position.y).isSwimmable()){
          MessageBus.publish(new Note(world, owner, "You must be on a bridge or water to dive underwater."));
          return screen;
        }
       
        return new DiveScreen(screen, world, owner);
      }
    };
    item.addTrait(Trait.SWIMMER);
    return item;
  }

  public Item firstAidKit() {
    Item item = new Item("first aid kit", '+', Common.hsv(20, 50, 50), "Use to cure poison or recover health."){
      public Screen use(Screen screen, World world, Creature owner){
        if (owner.rupees() < 5){
          MessageBus.publish(new Note(world, owner, "You need at least 5 rupees to cure poison or heal yourself."));
          return screen;
        }
       
        if (owner.isPoisoned()){
          owner.curePoison();
          owner.loseRupees(world, 5);
        } else {
          int amount = Math.min(owner.rupees() / 5, owner.maxHearts() - owner.hearts());
          owner.recoverHearts(amount);
          owner.loseRupees(world, amount * 5);
        }
        return screen;
      }
    };
    return item;
  }
 
  public Item ringOfRegeneration() {
    Item item = new Item("ring of regeneration", '=', Tile.LAVA1.color(), "Automatically recover health.");
    item.addTrait(Trait.REGENERATES);
    return item;
  }

  public Item rupeeMachine() {
    Item item = new Item("rupee machine", '/', Common.hsv(210, 25, 90), "Automatically creates rupees."){
      public void update(World world, Creature owner){
        super.update(world, owner);
       
        if (owner != null && Math.random() < 0.1)
          owner.gainRupees(1);
      }
    };
    return item;
  }
 
  public Item rupeeAmulet() {
    Item item = new Item("rupee amulet", '=', Common.hsv(210, 25, 90), "Can be used to convert your hearts into rupees."){
      public Screen use(Screen screen, World world, Creature owner){
        owner.loseHearts(world, owner, 1, null, "You turned the last of your hearts into rupees");
        owner.gainRupees(20);
        return screen;
      }
    };
    return item;
  }
 
  public Item spellBook() {
    Item item = new Item("spellbook", '+', Common.hsv(200, 50, 50), "Used to cast one of 3 basic spells."){
      public Screen use(Screen screen, World world, Creature owner){
        return new CastSpellScreen(screen, world, owner);
      }
    };
    return item;
  }
 
  public Item magicCarpet() {
    Item item = new Item("magic carpet", Tile.WATER1.glyph(), AsciiPanel.red, +1, "You can fly on this.");
    item.addTrait(Trait.FLIER);
    return item;
  }
 
  public Item heartContainer(){
    Item item = new Item("heart container", 3, AsciiPanel.brightRed, "Increases your max hearts."){
      public void onCollide(World world, Creature collider){
        if (!collider.isHuman())
          return;
       
        collider.increaseMaxHearts(1);
        collider.recoverHearts(10);
        world.removeItem(collider.position.x, collider.position.y);
      }
    };
    item.collectableValue(15);
    return item;
  }
 
  public Item bigMoney(){
    Item item = new Item("rupees", 4, Common.hsv(210, 25, 90), "Rupees are used for special actions."){
      public void onCollide(World world, Creature collider){
        if (!collider.isHuman())
          return;
       
        world.removeItem(collider.position.x, collider.position.y);
        collider.gainRupees(50);
      }
    };
    item.collectableValue(5);
    return item;
  }

  public Item evasionPotion(){
    Item item = new Item("evasion potion", '!', Common.hsv(90, 33, 66), "Permanently boost your evasion."){
      public void onCollide(World world, Creature collider){
        if (!collider.isHuman())
          return;
       
        world.removeItem(collider.position.x, collider.position.y);
        collider.modifyEvasion(1);
      }
    };
    item.collectableValue(5);
    return item;
  }

  public Item lostArtifact(){
    String[] first = { "ancient", "historic", "old", "lost", "antique", "famous", "missing", "forgotten", "stolen" };
    String[] second = { "heirloom", "artifact", "treasure", "item" };
   
    String name = first[(int)(Math.random() * first.length)]
                + " " + second[(int)(Math.random() * second.length)];
   
    int hue = (int)(Math.random() * 360);
    Item item = new Item(name, '?', Common.hsv(hue, 33, 66), "A " + name + " from the past."){
      public void onCollide(World world, Creature collider){
        if (!collider.isHuman())
          return;
       
        world.removeItem(collider.position.x, collider.position.y);
        MessageBus.publish(new DiscoveredLostArtifact(world, collider, this));
      }
    };
    item.collectableValue(10);
    return item;
  }
 
  public Item jumpingBoots() {
    Item item = new Item("jumping boots", '[', Common.hsv(180, 50, 50), "Makes you more evasive and can be used to jump."){
      public Screen use(Screen screen, World world, Creature owner){
        return new JumpScreen(screen, world, owner);
      }
    };
    return item;
  }

  public Item ringOfEvasion() {
    Item item = new Item("ring of evasion", '=', Common.hsv(90, 33, 66), +5, "Makes you much more evasive.");
    return item;
  }
 
  public Item darkCloak() {
    Item item = new Item("dark cloak", '[', Common.hsv(180, 5, 25), +2, "Makes you harder to hit and see. Can be used to sneak."){
      public Screen use(Screen screen, World world, Creature owner){
        if (owner.rupees() < 5){
          MessageBus.publish(new Note(world, owner, "You need at least 5 rupees to sneak."));
          return screen;
        }
       
        return new SneakScreen(screen, world, owner);
      }
    };
    item.addTrait(Trait.CAMOUFLAGED);
    return item;
  }
 
  public Item bagOfImps() {
    Item item = new Item("bag of imps", '+', Common.hsv(350, 90, 75), "Costs 5" + (char)4 + " to pull an imp out."){
      public Screen use(Screen previous, World world, Creature owner){
        if (owner.rupees() + owner.hearts() <= 5){
          MessageBus.publish(new Note(world, owner, "You need more than 5 rupees and hearts to summon an imp."));
          return previous;
        }
       
        summonImp(world, owner);
        owner.loseRupees(world, 5);
        return previous;
      }
    };
    return item;
  }
 
  private void summonImp(World world, final Creature master) {
    Creature imp = new Creature("imp", (char)139, Common.hsv(350, 90, 75), 5){
      public void update(World world){
        super.update(world);
        if (position.distanceTo(master.position) > 3){
          int dx = 0;
          int dy = 0;
          if (master.position.x < position.x)
            dx = -1;
          else if (master.position.x > position.x)
            dx = 1;
         
          if (master.position.y < position.y)
            dy = -1;
          else if (master.position.y > position.y)
            dy = 1;
         
          moveBy(world, dx, dy);
        } else {
          wander(world);
        }
      }
     
      public boolean isFriendlyTo(Creature other){
        return other == master || other.name().equals(name());
      }
    };
    imp.addTrait(Trait.AGGRESSIVE);
    imp.addTrait(Trait.HUNTER);
    imp.addTrait(Trait.FLIER);
    imp.addTrait(Trait.REGENERATES);
    world.add(imp);
    Point dir = master.lastMovedDirection();
    imp.position = master.position.plus(dir.x, dir.y).plus(dir.x, dir.y);
  }
 
  public Item magicWand() {
    Item item = new Item("Magic Missile wand", '/', Common.hsv(0, 0, 75), "Use to shoot 8 weak magic missiles."){
      public Screen use(Screen previous, World world, Creature owner){
        magicMissiles(world, owner);
        owner.loseRupees(world, 8);
        return previous;
      }
    };
    return item;
  }
 
  private void magicMissiles(World world, Creature caster) {
    world.add(new Projectile("magic missile", caster, 7, Common.hsv(210, 33, 66), 2, caster.position.plus(1, 0), new Point( 1, 0)));
    world.add(new Projectile("magic missile", caster, 7, Common.hsv(210, 33, 66), 2, caster.position.plus(-1, 0), new Point(-1, 0)));
    world.add(new Projectile("magic missile", caster, 7, Common.hsv(210, 33, 66), 2, caster.position.plus(0, 1), new Point( 0, 1)));
    world.add(new Projectile("magic missile", caster, 7, Common.hsv(210, 33, 66), 2, caster.position.plus(0,-1), new Point( 0,-1)));
    world.add(new Projectile("magic missile", caster, 7, Common.hsv(210, 33, 66), 2, caster.position.plus(-1,-1), new Point(-1,-1)));
    world.add(new Projectile("magic missile", caster, 7, Common.hsv(210, 33, 66), 2, caster.position.plus(-1, 1), new Point(-1, 1)));
    world.add(new Projectile("magic missile", caster, 7, Common.hsv(210, 33, 66), 2, caster.position.plus(1,-1), new Point( 1,-1)));
    world.add(new Projectile("magic missile", caster, 7, Common.hsv(210, 33, 66), 2, caster.position.plus(1, 1), new Point( 1, 1)));
  }

  public Item mutationRing() {
    Item item = new Item("mutation ring", '=', Common.hsv(60, 33, 90), "A slight chance of random mutations when wearing this."){
      public void update(World world, Creature owner){
        super.update(null, owner);
       
        if (owner != null && Math.random() < 0.005)
          mutateSelf(world, owner);
      }
    };
    return item;
  }
 
  private void mutateSelf(World world, Creature self) {
    Trait[] traits = {
        Trait.CAMOUFLAGED, Trait.COUNTER_ATTACK, Trait.DEFLECT_MELEE, Trait.DEFLECT_RANGED, Trait.DETECT_CAMOUFLAGED,
        Trait.EVADE_ATTACK, Trait.EXTRA_DEFENSE, Trait.EXTRA_EVADE, Trait.EXTRA_HP, Trait.FLIER, Trait.KNOCKBACK,
        Trait.POISONOUS, Trait.REACH_ATTACK, Trait.REGENERATES, Trait.SLOWING_ATTACK, Trait.SPIKED, Trait.STRONG_ATTACK,
        Trait.SWIMMER
    };
   
    int tries = 0;
    while (tries++ < 100){
      Trait trait = traits[(int)(Math.random() * traits.length)];
      if (self.hasTrait(trait))
        continue;
     
      self.addTrait(trait);
      MessageBus.publish(new Note(null, self, "You have gained the trait \"" + trait.description() + "\""));
      self.loseRupees(world, 10);
      break;
    }
  }
}
TOP

Related Classes of iryrwarosh.Factory

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.