Package iryrwarosh.screens

Source Code of iryrwarosh.screens.PlayScreen

package iryrwarosh.screens;

import iryrwarosh.Creature;
import iryrwarosh.FameHandler;
import iryrwarosh.GainedFame;
import iryrwarosh.SaidOutLoud;
import iryrwarosh.Trait;
import iryrwarosh.Factory;
import iryrwarosh.Handler;
import iryrwarosh.Item;
import iryrwarosh.Killed;
import iryrwarosh.Message;
import iryrwarosh.MessageBus;
import iryrwarosh.Moved;
import iryrwarosh.Note;
import iryrwarosh.Projectile;
import iryrwarosh.Tile;
import iryrwarosh.Common;
import iryrwarosh.World;

import java.awt.Color;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import asciiPanel.AsciiCharacterData;
import asciiPanel.AsciiPanel;
import asciiPanel.TileTransformer;

public class PlayScreen implements Screen, Handler {
  private FameHandler fameHandler;
 
  private World world;
  private Creature player;
  private Factory factory;
 
  private int screenWidth = 80;
  private int screenHeight = 23;
 
  private List<Message> messages = new ArrayList<Message>();
 
  private MessageLogScreen messageLogScreen;
 
  private int turnNumber = 0;
 
  public PlayScreen(World world, Factory factory, Creature player){
    MessageBus.subscribe(this);
    this.fameHandler = new FameHandler();
    this.world = world;
    this.factory = factory;
    this.player = player;
    this.messageLogScreen = new MessageLogScreen(this);
  }
 
  @Override
  public void displayOutput(AsciiPanel terminal) {
    terminal.setDefaultForegroundColor(Common.playScreenForeground);
    terminal.setDefaultBackgroundColor(Common.playScreenBackground);
    displayTiles(terminal);
    displayHud(terminal);
    displayMessages(terminal);
  }

  private void displayHud(AsciiPanel terminal) {
    terminal.clear(' ', 0, 0, 80, 1);
   
    terminal.write("[z] ", 0, 0);
    terminal.write(player.leftHand().name(), player.leftHand().color(), null);
   
    terminal.write("[x] ", 22, 0);
    terminal.write(player.rightHand().name(), player.rightHand().color(), null);

    terminal.write("[?] help", 44, 0);

    terminal.write("evade: " + player.evadePercent(world) + "%", 54, 0, AsciiPanel.yellow, null);

    terminal.write(String.format("%3d" + (char)4, player.rupees()), 64, 0, Common.hsv(60, 25, 75), null);
   
    Item item = world.item(player.position.x, player.position.y);
    if (item != null && item.canBePickedUp()){
      terminal.write("[g] ", 0, 1);
      terminal.write(item.name(), item.color(), null);
      terminal.write(" (at your feet)");
    }

    terminal.setCursorPosition(69, 0);
    Color heartColor = player.isPoisoned() ? AsciiPanel.green : AsciiPanel.red;
    for (int i = 0; i < player.maxHearts(); i++){
      if (i > 0 && (i % 10) == 0)
        terminal.setCursorPosition(69, terminal.getCursorY() + 1);
      terminal.write((char)3, i < player.hearts() ? heartColor : AsciiPanel.brightBlack, null);
    }

    displayFame(terminal);
  }

  private void displayFame(AsciiPanel terminal) {
    List<Creature> people = fameHandler.getFamousPeople();
    int left = 68;
   
    if (people.size() == 0)
      return;
   
    if (getScrollX() == world.width() - screenWidth && getScrollY() == 0)
      terminal.setCursorPosition(left, terminal.getHeightInCharacters() - 7);
    else
      terminal.setCursorPosition(left, terminal.getCursorY() + 2);
   
    terminal.write("-- fame --", AsciiPanel.brightGreen, null);
    terminal.setCursorPosition(left, terminal.getCursorY() + 1);
    for (Creature famousPerson : people){
      terminal.write(" " + (famousPerson.isPlayer() ? "You " : famousPerson.name()), famousPerson.color(), null);
      terminal.write(String.format(" %3d%%", fameHandler.getFame(famousPerson)), AsciiPanel.white, null);
      terminal.setCursorPosition(left, terminal.getCursorY() + 1);
    }
  }
 
  private void displayTiles(AsciiPanel terminal){
    for (int x = 0; x < screenWidth; x++)
    for (int y = 0; y < screenHeight; y++){
      Tile t = world.tile(x + getScrollX(), y + getScrollY());
      Item item = world.item(x + getScrollX(), y + getScrollY());
     
      if (item == null) {
        terminal.write(
            t.glyph(),
            x, y+1,
            t.color(),
            t.background());
      } else {
        terminal.write(
            item.glyph(),
            x, y+1,
            item.color(),
            t.background());
      }
    }
   
    for (Creature c : world.creatures()){
      int x = c.position.x - getScrollX();
      int y = c.position.y - getScrollY();
     
      if (x < 0 || x >= screenWidth || y < 0 || y >= screenHeight)
        continue;
     
      Color color = c.color();
      if (c.hasTrait(Trait.CAMOUFLAGED)){
        switch (player.position.distanceTo(c.position)){
        case 0:
        case 1:
        case 2:
        case 3:
          break;
        case 4:
          if (!player.hasTrait(Trait.DETECT_CAMOUFLAGED))
            color = color.darker();
          break;
        case 5:
          if (!player.hasTrait(Trait.DETECT_CAMOUFLAGED))
            color = color.darker().darker();
          break;
        default:
          if (!player.hasTrait(Trait.DETECT_CAMOUFLAGED))
            color = null;
          else
            color = color.darker();
        }
      }
     
      if (color != null)
        terminal.write(c.glyph(),
          x, y+1,
          color,
          world.tile(c.position.x, c.position.y).background());
    }

    for (Projectile p : world.projectiles()){
      int x = p.position.x - getScrollX();
      int y = p.position.y - getScrollY();
     
      if (x < 0 || x >= screenWidth || y < 0 || y >= screenHeight)
        continue;
     
      terminal.write(p.glyph(),
        x, y+1,
        p.color(),
        world.tile(p.position.x, p.position.y).background());
    }
   
    fadeIn(terminal);
    turnNumber++;
  }

  private void fadeIn(AsciiPanel terminal) {
    if (turnNumber == 0)
      terminal.withEachTile(new TileTransformer(){
        @Override
        public void transformTile(int x, int y, AsciiCharacterData data) {
          if (y== 0)
            return;
          if (data.character == '@' && data.foregroundColor == AsciiPanel.brightWhite)
            return;
         
          data.foregroundColor = data.foregroundColor.darker().darker();
          data.backgroundColor = data.backgroundColor.darker().darker();
        }
      });
    else if (turnNumber == 1)
      terminal.withEachTile(new TileTransformer(){
        @Override
        public void transformTile(int x, int y, AsciiCharacterData data) {
          if (y== 0)
            return;
          if (data.character == '@' && data.foregroundColor == AsciiPanel.brightWhite)
            return;
         
          data.foregroundColor = data.foregroundColor.darker();
          data.backgroundColor = data.backgroundColor.darker();
        }
      });
  }

  private void displayMessages(AsciiPanel terminal) {
    int i = terminal.getHeightInCharacters() - messages.size();
    for (Message m : messages){
      Color color = (GainedFame.class.isAssignableFrom(m.getClass())) ? AsciiPanel.brightYellow : null;

      if (SaidOutLoud.class.isAssignableFrom(m.getClass()))
        color = ((SaidOutLoud)m).creature.color();
     
      terminal.writeCenter(clean(m.text()), i++, color, AsciiPanel.black);
    }
    messages.clear();
  }
 
  private String clean(String text){
    return text.replace("player has", "player have")
               .replace("The player's", "Your").replace("the player's", "your").replace("player's", "your")
             .replace("The player", "You").replace("the player", "you").replace("player", "you");
  }
 
  public int getScrollX() {
        return Math.max(0, Math.min(player.position.x - screenWidth / 2, world.width() - screenWidth));
    }
   
    public int getScrollY() {
        return Math.max(0, Math.min(player.position.y - screenHeight / 2, world.height() - screenHeight));
    }
   
  private void moveBy(int x, int y){
    player.moveBy(world, x, y);
  }
 
  @Override
  public Screen respondToUserInput(KeyEvent key) {
    if (player.hearts() < 1) {
      MessageBus.unsubscribe(this);
      return new DeadScreen(this, player.causeOfDeath());
    }
   
    switch (key.getKeyCode()){
        case KeyEvent.VK_LEFT:
        case KeyEvent.VK_NUMPAD4:
        case KeyEvent.VK_H: moveBy(-1, 0); break;
        case KeyEvent.VK_RIGHT:
        case KeyEvent.VK_NUMPAD6:
        case KeyEvent.VK_L: moveBy( 1, 0); break;
        case KeyEvent.VK_UP:
        case KeyEvent.VK_NUMPAD8:
        case KeyEvent.VK_K: moveBy( 0,-1); break;
        case KeyEvent.VK_DOWN:
        case KeyEvent.VK_NUMPAD2:
        case KeyEvent.VK_J: moveBy( 0, 1); break;
        case KeyEvent.VK_NUMPAD7:
        case KeyEvent.VK_Y: moveBy(-1,-1); break;
        case KeyEvent.VK_NUMPAD9:
        case KeyEvent.VK_U: moveBy( 1,-1); break;
        case KeyEvent.VK_NUMPAD1:
        case KeyEvent.VK_B: moveBy(-1, 1); break;
        case KeyEvent.VK_NUMPAD3:
        case KeyEvent.VK_N: moveBy( 1, 1); break;
        case KeyEvent.VK_PERIOD: moveBy( 0, 0); break;
        case KeyEvent.VK_Z:
          Screen lhs = player.leftHand().use(this, world, player);
          if (lhs != this)
            return lhs;
          break;
        case KeyEvent.VK_X:
          Screen rhs = player.rightHand().use(this, world, player);
          if (rhs != this)
            return rhs;
          break;
        case KeyEvent.VK_G:
        case KeyEvent.VK_COMMA:
          Item item = world.item(player.position.x, player.position.y);
            if (item == null || !item.canBePickedUp()) {
                MessageBus.publish(new Note(world, player, "Nothing to pick up here"));
                return this; //Don't spend an action when nothing to pick up
            } else {
                return new PickupItemScreen(this, world, player);
            }
    case KeyEvent.VK_M: return new WorldMapScreen(this, world.map(), player.position);
    case KeyEvent.VK_SPACE: return new LookAtScreen(this, world, player, getScrollX(), getScrollY());
    case KeyEvent.VK_Q:
    case KeyEvent.VK_ESCAPE:
      return new ConfirmationScreen(this, new ChooseStartingItemsScreen(), "Are you sure you'd like to quit?");
    case KeyEvent.VK_QUOTEDBL:
    case KeyEvent.VK_QUOTE:
      messageLogScreen.scrollToEnd();
      return messageLogScreen;
    default:
      if (key.getKeyChar() == '?')
        return new HelpScreen(this);
     
      return this;
    }
   
    world.update();
   
    if (player.hearts() < 1) {
      MessageBus.unsubscribe(this);
      return new DeadScreen(this, player.causeOfDeath());
    } else if (fameHandler.getFame(player) > 99){
      MessageBus.unsubscribe(this);
      return new VictoryScreen(this);
    } else {
      for (Creature creature : fameHandler.getFamousPeople()){
        if (fameHandler.getFame(creature) > 99){
          MessageBus.unsubscribe(this);
          return new LostScreen(this);
        }
      }
    }
   
    return this;
  }

  @Override
  public void handle(Message message) {
    fameHandler.handle(message);
   
    if (message.involves(player) && !Moved.class.isAssignableFrom(message.getClass())){
      messages.add(message);
      messageLogScreen.record(message);
    }
   
    if (Killed.class.isAssignableFrom(message.getClass()))
      addRandomBadGuy();
  }

  private void addRandomBadGuy() {
    if (Math.random() < 0.25){
      factory.goblin(world);
    } else {
      Tile[] biomes = { Tile.GREEN_TREE1, Tile.BROWN_TREE1, Tile.WHITE_TREE1, Tile.GREEN_TREE1, Tile.BROWN_TREE1,
        Tile.GREEN_ROCK, Tile.BROWN_ROCK, Tile.WHITE_ROCK, Tile.DESERT_SAND1, Tile.WATER1 };
      Tile biome = biomes[(int)(Math.random() * biomes.length)];
      factory.monster(world, biome);
    }
  }
}
TOP

Related Classes of iryrwarosh.screens.PlayScreen

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.