Package com.pointcliki.dizgruntled.logic

Source Code of com.pointcliki.dizgruntled.logic.Grunt$MovementMinion

package com.pointcliki.dizgruntled.logic;

import java.util.HashMap;
import java.util.Set;
import java.util.TreeSet;

import org.json.JSONException;
import org.json.JSONObject;
import org.newdawn.slick.Image;
import org.newdawn.slick.Sound;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Vector2f;

import com.pointcliki.core.AnimatedSprite;
import com.pointcliki.core.Entity;
import com.pointcliki.core.Sprite;
import com.pointcliki.dizgruntled.GridLogic;
import com.pointcliki.dizgruntled.GruntzGame;
import com.pointcliki.dizgruntled.LogicProperty;
import com.pointcliki.dizgruntled.StringLogicProperty;
import com.pointcliki.dizgruntled.grunt.GruntState;
import com.pointcliki.dizgruntled.grunt.Task;
import com.pointcliki.dizgruntled.map.Map;
import com.pointcliki.dizgruntled.modifier.AssignModifier;
import com.pointcliki.dizgruntled.modifier.Attribute;
import com.pointcliki.dizgruntled.player.GruntzPlayer;
import com.pointcliki.dizgruntled.player.HumanPlayer;
import com.pointcliki.dizgruntled.rez.MonolithANI;
import com.pointcliki.dizgruntled.rez.MonolithPID;
import com.pointcliki.dizgruntled.rez.MonolithWAV;
import com.pointcliki.dizgruntled.rez.MonolithWWD;
import com.pointcliki.dizgruntled.task.GooSuckTask;
import com.pointcliki.dizgruntled.task.HoleDigTask;
import com.pointcliki.dizgruntled.task.RockBreakTask;
import com.pointcliki.dizgruntled.task.WalkTask;
import com.pointcliki.dizgruntled.task.WalkToActionTask;
import com.pointcliki.dizgruntled.utils.GruntPalette;
import com.pointcliki.event.Dispatcher;
import com.pointcliki.event.FrameEvent;
import com.pointcliki.event.Minion;
import com.pointcliki.event.PeriodicRogue;
import com.pointcliki.event.ProgressEvent;
import com.pointcliki.grid.GridCoordinate;
import com.pointcliki.grid.GridManager.GridEvent;
import com.pointcliki.movement.GridAlignedMovementOld;
import com.pointcliki.net.Player;
import com.pointcliki.transition.LinearLerper;

public class Grunt extends GridLogic {
 
  /**
   * Serial key
   */
  private static final long serialVersionUID = -249620165769083641L;
 
  public static final String[] TOOLS = new String[] {"NORMAL", "BOMB", "BOOMERANG", "BRICK", "CLUB", "GAUNTLETZ", "GLOVEZ", "GOOBER", "GRAVITYBOOTZ", "GUNHAT", "NERFGUN", "ROCK", "SHIELD", "SHOVEL", "SPRING", "SPY", "SWORD", "TIMEBOMB", "TOOB", "WAND", "WARPSTONE", "WELDER", "WINGZ"};
  public static final String[] TOYS = new String[] {"NO TOY", "BABYWALKER", "BEACHBALL", "BIGWHEEL", "GOKART", "JACKINTHEBOX", "JUMPROPE", "POGOSTICK", "SCROLL", "SQUEAKTOY", "YOYO"};
  public static final String[] COLORS = new String[] {"ORANGE", "GREEN", "DKGREEN", "YELLOW", "PURPLE", "PINK", "HOTPINK", "RED", "DKBLUE", "BLUE", "CYAN", "TURQ", "DKRED", "BLACK", "WHITE"};
  public static final String[] AI = new String[] {"NO AI", "DUMB CHASER", "SMART CHASER", "HIT AND RUN", "DEFENDER", "POST GUARD", "OBJECT GUARD", "BOMBER", "BRICK LAYER", "GAUNTLETZ GRUNT", "GOOBERSTRAW GRUNT", "SHOVEL GRUNT", "TIMEBOMB GRUNT", "TOOL THIEF", "TOY THIEF"};
  public static final String[] PLAYERS = new String[] {"human", "enemy 1", "enemy 2", "enemy 3"};
  public static final Rectangle COLLISION_RECT = new Rectangle(5, 16, 22, 16);
 
  private GruntzPlayer fPlayer;
  private int fPlayerValue;
  private String fTool;
  private String fToy;
  private String fColor;
  private String fAI;
  private GruntPalette fPalette;
  private String fAnimationName = "";
  private AnimatedSprite fAnimation;
  private AnimatedSprite fCursor;
  private String fDir = "SOUTH";
  private Sound fVoice;
  private GridAlignedMovementOld<Grunt> fMovement;
  private GruntState fState;
  private Task fTask;
  private Sprite fHealthSprite;
  private Sprite fStaminaSprite;
  private PeriodicRogue<Grunt> fHurter;
  private PeriodicRogue<Grunt> fStaminater;
 
  private Minion<GridEvent> fTileWatcher;
   
  private HashMap<String, Attribute<?>> fAttributes;
  private static AssignModifier<Boolean> sFalseStateAttribute = new AssignModifier<Boolean>(0, false);
  private AssignModifier<Integer> fHealth = new AssignModifier<Integer>(0, 20);
  private AssignModifier<Integer> fStamina = new AssignModifier<Integer>(0, 20);

  @Override
  public void importFromWWD(String logic, String image, String animation,  byte[] data) {
    fSnapToGrid = true;
    super.importFromWWD(logic, image, animation, data);
   
    fTool = TOOLS[MonolithWWD.readPowerup(data)];
    fToy = "NONE";
    fColor = COLORS[MonolithWWD.readPoints(data)];
    fAI = AI[MonolithWWD.readPoints(data)];   
    fPlayerValue = MonolithWWD.readSmarts(data);
   
    setup();
  }

  @Override
  public byte[] exportToWWD() {
    return null;
  }

  @Override
  public void importFromJSON(JSONObject object) {
    fSnapToGrid = true;
    super.importFromJSON(object);
   
    fTool = object.optString("tool");
    fToy = object.optString("toy");
    fColor = object.optString("color");
    fAI = object.optString("ai");
    fPlayerValue = object.optInt("player");
   
    setup();
  }

  @Override
  public JSONObject exportToJSON() throws JSONException {
    JSONObject o = super.exportToJSON();
    o.put("tool", fTool);
    o.put("toy", fToy);
    o.put("color", fColor);
    o.put("ai", fAI);
    o.put("player", fPlayerValue);
    return o;
  }
 
  private void setup() {
    // Give AI correct tools
    if (fAI.equals("GAUNTLETZ GRUNT")) fTool = "GAUNTLETZ";
    else if (fAI.equals("SHOVEL GRUNT")) fTool = "SHOVEL";
    else if (fAI.equals("GOOBERSTRAW GRUNT")) fTool = "GOOBER";
    else if (fAI.equals("TIMEBOMB GRUNT")) fTool = "TIMEBOMB";
    else if (fAI.equals("BRICKLAYER GRUNT")) fTool = "BRICK";
   
    // Setup attributes
    fAttributes = new HashMap<String, Attribute<?>>();
    fAttributes.put("selectable", new Attribute<Boolean>(true));
    fAttributes.put("controllable", new Attribute<Boolean>(true));
    fAttributes.put("walkable", new Attribute<Boolean>(true));
    fAttributes.put("hurtable", new Attribute<Boolean>(true));
    fAttributes.put("health", new Attribute<Integer>(20).addModifier(fHealth));
    fAttributes.put("stamina", new Attribute<Integer>(20).addModifier(fStamina));
   
    // Create the grunt body
    fPalette = new GruntPalette(fColor, GruntzGame.resourceManager().rez().file("GRUNTZ/PALETTEZ/" + fColor + "TOOL", "pal"));
    animate("IDLE1", "IDLE");
    fCursor = new MonolithANI(GruntzGame.resourceManager().rez().file("GAME/ANIZ/GRUNTSELECTEDSPRITE", "ani"), "GAME/IMAGEZ/GRUNTSELECTEDSPRITE").sprite();
   
    // Health
    fHealthSprite = new Sprite(new MonolithPID(GruntzGame.resourceManager().rez().file("GAME/IMAGEZ/GRUNTHEALTHSPRITE/FRAME001", "pid")).image());
    fHealthSprite.position(new Vector2f(-12, -26));
   
    fStaminaSprite = new Sprite(new MonolithPID(GruntzGame.resourceManager().rez().file("GAME/IMAGEZ/GRUNTSTAMINASPRITE/FRAME001", "pid")).image());
    fStaminaSprite.position(new Vector2f(-12, -32));
   
    // Setup the grunt movement
    fMovement = new GridAlignedMovementOld<Grunt>(this, new MovementMinion(), 0, 0) {

      /**
       * Serial key
       */
      private static final long serialVersionUID = -3074929548144342979L;

      @Override
      public boolean canMove(GridCoordinate target) {
        TreeSet<String> traits = fMap.traits(target);
        return (!traits.contains("solid") && !traits.contains("nogo") && !traits.contains("water") && gridManager().getFirstEntityOfTypeAt(target, Grunt.class, Grunt.this) == null);
      }
    };
    fMovement.setup(500, new LinearLerper());
   
    // Setup the tile watcher
    fTileWatcher = new Minion<GridEvent>() {
      public long run(com.pointcliki.event.Dispatcher<GridEvent> dispatcher, String type, GridEvent event) {
        checkTile();
        return Minion.CONTINUE;
      };
    };
   
    fHurter = new PeriodicRogue<Grunt>(this, null, 40, 0) {
     
      /**
       * Serial key
       */
      private static final long serialVersionUID = 6455636894570231644L;

      @Override
      public void run(Grunt entity, long currentFrame) {
        if (attributeAsBoolean("hurtable")) setStateHealth(fHealth.value() - 2);
      }
    };
    fStaminater = new PeriodicRogue<Grunt>(this, null, 4, 0) {
      /**
       * Serial key
       */
      private static final long serialVersionUID = 6455636894570231644L;

      @Override
      public void run(Grunt entity, long currentFrame) {
        fStamina.assign(fStamina.value() + 1);
        int val = Math.max(0, attributeAsInteger("stamina"));
       
        String s = (21 - val) + "";
        while (s.length() < 3) s = "0" + s;
        fStaminaSprite.image(new MonolithPID(GruntzGame.resourceManager().rez().file("GAME/IMAGEZ/GRUNTSTAMINASPRITE/FRAME" + s, "pid")).image());
       
        if ((fStamina).value() == 20) {
          removeChild(fStaminaSprite);
          cancel();
        }
      }
    };
  }
 
  private void setStateHealth(int h) {
    fHealth.assign(h);
    int val = Math.max(0, attributeAsInteger("health"));
   
    String s = (21 - val) + "";
    while (s.length() < 3) s = "0" + s;
   
    fHealthSprite.image(new MonolithPID(GruntzGame.resourceManager().rez().file("GAME/IMAGEZ/GRUNTHEALTHSPRITE/FRAME" + s, "pid")).image());
  }
 
  public void depleteStamina(int rate) {
    if (fStaminater.isRunning()) fStaminater.cancel();
   
    addChild(fStaminaSprite, 101);
   
    fStamina.assign(0);
    int val = Math.max(0, attributeAsInteger("stamina"));
   
    String s = (21 - val) + "";
    while (s.length() < 3) s = "0" + s;
    fStaminaSprite.image(new MonolithPID(GruntzGame.resourceManager().rez().file("GAME/IMAGEZ/GRUNTSTAMINASPRITE/FRAME" + s, "pid")).image());
   
    fStaminater.period(rate);
    fStaminater.begin();
  }
 
  public boolean attributeAsBoolean(String s) {
    return (Boolean) fAttributes.get(s).value();
  }
 
  public int attributeAsInteger(String s) {
    return (Integer) fAttributes.get(s).value();
  }
 
  @SuppressWarnings("unchecked")
  public Attribute<Boolean> attributeBoolean(String s) {
    return (Attribute<Boolean>) fAttributes.get(s);
  }

  @SuppressWarnings("unchecked")
  public Attribute<Integer> attributeInteger(String s) {
    return (Attribute<Integer>) fAttributes.get(s);
  }
   
  public void rawAnimate(String ani, String graphics) {
    // Get ani first in case it causes an exception
    AnimatedSprite sprite = new MonolithANI(GruntzGame.resourceManager().rez().file("GRUNTZ/ANIZ/" + ani, "ani"), "GRUNTZ/IMAGEZ/" + graphics).sprite(fPalette);
    if (fAnimation != null) fAnimation.cleanup();
    fAnimation = sprite;
    fAnimationName = "";
    addChild(fAnimation, 50);
    fSpan = fAnimation.span();
    if (fMap != null) fAnimation.start();
  }
 
  public void rawAnimate(String ani, String graphics, int frames) {
    // Get ani first in case it causes an exception
    AnimatedSprite sprite = new MonolithANI(GruntzGame.resourceManager().rez().file("GRUNTZ/ANIZ/" + ani, "ani"), "GRUNTZ/IMAGEZ/" + graphics).sprite(fPalette);
    sprite.splice(0, frames);
    if (fAnimation != null) fAnimation.cleanup();
    fAnimation = sprite;
    fAnimationName = "";
    addChild(fAnimation, 50);
    fSpan = fAnimation.span();
    if (fMap != null) fAnimation.start();
  }
 
  public void animate(String ani, String graphics) {
    rawAnimate(fTool + "GRUNT/" + ani, fTool + "GRUNT/" + fDir + "/" + graphics);
    fAnimationName = ani;
  }
 
  public void animate(String ani, String graphics, GridCoordinate dir) {   
    String direction = dir.toName();       
    // Check we're not already doing this animation
    if (fAnimationName.equals(ani) && direction.equals(fDir)) return;
   
    fDir = direction;   
    animate(ani, graphics);
  }

  @Override
  public void init(Map map) {
    super.init(map);
    fAnimation.start();
    // Put in grid manager
    if (!map.editing() && fPlayerValue == 0) {
      fPlayer = levelScene().player("human");
      fPlayer.add(this);
    }
    enable();
  }
 
  @Override
  public void select() {
    boolean again = fSelected;
    if (!fMap.editing()) {
     
      // Decide on a sound
      String sound;
     
      if (!attributeAsBoolean("selectable")) return;
   
      // Select the grunt
      if (fPlayer instanceof HumanPlayer) {
        ((HumanPlayer) fPlayer).selectGrunt(this);
        if (!again) {
          addChild(fCursor, 0);
          addChild(fHealthSprite, 100);
          if (fStamina.value() < 20) addChild(fStaminaSprite, 101);
          fCursor.start();
        }
     
        sound = "ACKNOWLEDGE/SELECTGRUNT1" + ((char) ((int) Math.floor(Math.random() * 11) + 65));
      } else {
        int r = (int) Math.floor(Math.random() * 11) + 65;
        sound = "ENEMYSELECT/SELECTGRUNT" + (char) r;
      }
      MonolithWAV wav = new MonolithWAV(GruntzGame.resourceManager().voicez().file("VOICES/" + sound, "wav"));
      speak(wav.sound());
    }
    super.select();
  }
 
  @Override
  public void deselect() {
    if (!fSelected) return;
    super.deselect();
    fCursor.stop();
    removeChild(fCursor);
    removeChild(fHealthSprite);
    removeChild(fStaminaSprite);
  }
 
  public void speak(Sound s) {
    if (fVoice != null) fVoice.stop();
    fVoice = s;
    if (!GruntzGame.instance().mute() && fVoice != null) fVoice.play(1, 0.2f);
  }
 
  public void speak(String s) {
    MonolithWAV wav = new MonolithWAV(GruntzGame.resourceManager().voicez().file("VOICES/" + s, "wav"));
    speak(wav.sound());
  }
 
  public void move(GridCoordinate xy) {
    // Check whether the grunt is accepting commands
    if (!attributeAsBoolean("controllable")) return;
   
    state(GruntState.MOVING);
 
    // Start a path find
    if (fTask != null) fTask.cancel();
    fTask = new WalkTask(this, xy);
    boolean okay = fTask.start();
   
    if (okay) {
      speak("ACKNOWLEDGE/GOODCOMMAND" + ((char) ((int) Math.floor(Math.random() * 10) + 65)));
      // Check we can walk
      if (!fMovement.isRunning() && attributeAsBoolean("walkable")) fTask.next();
    } else {
      speak("ACKNOWLEDGE/BADCOMMAND" + ((char) ((int) Math.floor(Math.random() * 11) + 65)));
      fTask = null;
    }
  }
 
  public void useTool(GridCoordinate xy) {
    // Check whether the grunt is accepting commands
    if (!attributeAsBoolean("controllable")) return;
   
    if (!canUseToolAt(xy)) return;
   
    state(GruntState.MOVING);
   
    if (fTask != null) fTask.cancel();
    fTask = new WalkToActionTask(this, xy);
    boolean okay = fTask.start();
   
    if (okay) {
      speak("ACKNOWLEDGE/GOODCOMMAND" + ((char) ((int) Math.floor(Math.random() * 10) + 65)));
      // Check we can walk
      if (!fMovement.isRunning() && attributeAsBoolean("walkable")) fTask.next();
    } else {
      speak("ACKNOWLEDGE/BADCOMMAND" + ((char) ((int) Math.floor(Math.random() * 11) + 65)));
      fTask = null;
    }
  }
 
  public boolean canUseToolAt(GridCoordinate xy) {
    TreeSet<String> traits = map().traits(xy);
    if (fTool.equals("GAUNTLETZ") && traits.contains("break")) return true;
    else if (fTool.equals("SHOVEL") && traits.contains("dig")) return true;
    else if (fTool.equals("GOOBER") && gridManager().getEntitiesOfTypeAt(xy, GruntPuddle.class).size() > 0) return true;
   
    return false;
  }
 
  public void performAction(final GridCoordinate xy) {
   
    fMovement.stop();
   
    // Check we can still use the tool
    if (!canUseToolAt(xy) || fStamina.value() < 20) {
      if (fTask != null) fTask.cancel();
      fTask = null;
      animate("IDLE1", "IDLE");
      state(GruntState.IDLE);
      return;
    }
   
    Task t = null;
   
    if (fTool.equals("GAUNTLETZ")) t = new RockBreakTask(this, xy);
    else if (fTool.equals("SHOVEL")) t = new HoleDigTask(this, xy);
    else if (fTool.equals("GOOBER")) t = new GooSuckTask(this, xy);
   
    if (t != null) {
      boolean okay = t.start();
      if (okay) {
        fTask = t;
        t.next();
        state(GruntState.ACTING);
        animate("ITEM", "ITEM", xy.subtract(fTile));
       
      } else {
        if (fTask != null) fTask.cancel();
        fTask = null;
        animate("IDLE1", "IDLE");
        state(GruntState.IDLE);
      }
    } else {
      if (fTask != null) fTask.cancel();
      fTask = null;
      animate("IDLE1", "IDLE");
      state(GruntState.IDLE);
    }
  }
 
  public void finishAction() {
    fTask = null;
    checkTile();
  }

  public void win() {
    rawAnimate("EXITZ/ONE", "EXITZ", 196);
    doDie();
  }
 
  public void squash() {
    if (state() != GruntState.DYING) {
      doSquashDeath();
      doDie();
    }
  }

  @Override
  public void cleanup() {
    if (fPlayer != null) fPlayer.remove(this);
    gridManager().dispatcher().removeGridMinion(fTile, "tilechange", fTileWatcher);
    fTileWatcher = null;
    if (fTask != null) fTask.cancel();
    fTask = null;
    fPlayer = null;
    fTile = null;
    fDir = null;
    fPalette = null;
    fMovement = null;
    fState = null;
    fAttributes = null;
    super.cleanup();
    fAnimation = null;
    fHealthSprite = null;
    fStaminaSprite = null;
    fHurter.cleanup();
    fStaminater.cleanup();
  }
 
  private class MovementMinion extends Minion<ProgressEvent<Grunt>> {
    @Override
    public long run(Dispatcher<ProgressEvent<Grunt>> dispatcher, String type, ProgressEvent<Grunt> event) {
      if (type.equals(GridAlignedMovementOld.ON_BEGIN)) {
        pressureManager().tileDepressure(fTile);
       
      } else if (type.equals(GridAlignedMovementOld.ON_END)) {
        // Allow walking again, for example if we've been folling an arrow
        attributeBoolean("walkable").removeModifier(sFalseStateAttribute);
       
        pressureManager().tilePressure(fTile);
        checkTile();
       
      } else if (type.equals(GridAlignedMovementOld.PROGRESS_LAST_STOP)) {
        if (fState == GruntState.MOVING) {
          animate("IDLE1", "IDLE");
          state(GruntState.WAITING_TO_MOVE);
        }
        gridManager().dispatcher().addGridMinion(fTile, "tilechange", fTileWatcher);
       
      } else if (type.equals(GridAlignedMovementOld.PROGRESS_FIRST_START)) {
        gridManager().dispatcher().removeGridMinion(fTile, "tilechange", fTileWatcher);
      }
      return Minion.CONTINUE;
    }
  }
 
  protected void checkTile() {
    TreeSet<String> traits = fMap.traits(fTile);
    boolean done = false;
   
    // Check we're still alive
    if (state() == GruntState.DYING) return;
   
    done = checkForDamage(traits);
    if (!done) done = checkForWin(traits);
    if (!done) done = checkForDeath(traits);
    if (!done) done = checkForHelpBook();
    if (!done) done = checkForPickup();
    if (!done) done = checkForArrows(traits);
    if (!done) {
      if (fTask != null) done = fTask.next();
      if (!done) {
        fMovement.stop();
        animate("IDLE1", "IDLE");
        state(GruntState.IDLE);
      }
    }
  }
 
  private boolean checkForWin(TreeSet<String> traits) {
    if (!fTool.equals("WARPSTONE")) return false;
    if (gridManager().getFirstEntityOfTypeAt(fTile, Fort.class) != null) {
      if (fPlayer != null) fPlayer.win();
      speak("EXITZ/ONEA");
      return true;
    }
    return false;
  }

  protected boolean checkForDeath(Set<String> traits) {
    boolean die = false;
   
    if (traits.contains("hole")) {
      die = true;
      doHoleDeath();
    }
   
    if (traits.contains("solid") || traits.contains("nogo")) {
      die = true;
      doFlyUpDeath();
    }
   
    if (traits.contains("water")) {
      die = true;
      doSinkDeath();
    }
   
    if (traits.contains("death")) {
      die = true;
      doSinkDeath();
    }
   
    if (attributeAsInteger("health") == 0) {
      die = true;
      doHealthDeath();
    }
   
    if (die) {
      doDie();     
      return true;
    }
    return false;
  }

  protected boolean checkForDamage(Set<String> traits) {
    if (traits.contains("pain")) {
      if (!fHurter.isRunning()) fHurter.begin();
    } else {
      if (fHurter.isRunning()) fHurter.cancel();
    }
    return false;
  }
 
  protected boolean checkForHelpBook() {
    final HelpBook book = gridManager().getFirstEntityOfTypeAt(fTile, HelpBook.class);
    if (book != null) {
     
      state(GruntState.PICKUP);
      attributeBoolean("walkable").addModifier(sFalseStateAttribute);
     
      fMovement.stop();
     
      rawAnimate("PICKUPS/HELPBOX", "PICKUPS");
      GruntzGame.resourceManager().playSound("GAME/SOUNDZ/HELPBOOK");
      speak("PICKUPZ/HELPBOOKPICKUPA");
     
      book.cleanup();
     
      // Clean up the grunt after the read animation ends
      frameManager().queue(new Minion<FrameEvent>() {
       
        public long run(Dispatcher<FrameEvent> dispatcher, String type, FrameEvent event) {
          levelScene().hud().showText(book.text());
          return Minion.FINISH;
        };
       
      }, fAnimation.frameDuration() - 1);
     
      // Clean up the grunt after the read animation ends
      frameManager().queue(new Minion<FrameEvent>() {
       
        public long run(Dispatcher<FrameEvent> dispatcher, String type, FrameEvent event) {
         
          // Allow walking again
          attributeBoolean("walkable").removeModifier(sFalseStateAttribute);
         
          Grunt.this.checkTile();
          return Minion.FINISH;
        };
       
      }, fAnimation.frameDuration());
      return true;
    }
    return false;
  }
 
  protected boolean checkForPickup() {
    final Pickup pickup = gridManager().getFirstEntityOfTypeAt(fTile, Pickup.class);
    if (pickup != null) {
      GruntzGame.resourceManager().playSound("GAME/SOUNDZ/TREASURE");
      pickup.cleanup();
     
      state(GruntState.PICKUP);
      attributeBoolean("walkable").addModifier(sFalseStateAttribute);
     
      try {
        rawAnimate("PICKUPS/" + pickup.item(), "PICKUPS");
      } catch (NullPointerException e) {
        try {
          rawAnimate("PICKUPS/" + pickup.item().substring(0, pickup.item().length() - 1), "PICKUPS");
        } catch (NullPointerException e2) {
          rawAnimate("PICKUPS/" + pickup.item().substring(0, pickup.item().length() - 2), "PICKUPS");
        }
      }
      fMovement.stop();
     
      // Carry on after animation has ended
      frameManager().queue(new Minion<FrameEvent>() {
       
        public long run(Dispatcher<FrameEvent> dispatcher, String type, FrameEvent event) {
          if (pickup.type().equals("TOOL")) {
            fTool = pickup.item();
            // Check for warpstone
            if (fTool.startsWith("WARPSTONE")) fTool = "WARPSTONE";
            // Remove Z if not required
            if (fTool.endsWith("Z") && !fTool.equals("GAUNTLETZ") && !fTool.equals("GLOVEZ") && !fTool.equals("GRAVITYBOOTZ") && !fTool.equals("WINGZ")) fTool = fTool.substring(0, fTool.length() - 1);
           
          } else if (pickup.type().equals("TOY")) fToy = pickup.item();
         
          // Allow walking again
          attributeBoolean("walkable").removeModifier(sFalseStateAttribute);
         
          Grunt.this.checkTile();
          return Minion.FINISH;
        };
       
      }, fAnimation.frameDuration());
     
      return true;
    }
    return false;
  }
 
  protected boolean checkForArrows(Set<String> traits) {
   
    if (traits.contains("arrow")) {
      fTask = null;

      if (traits.contains("downArrow")) {
        fMovement.move(GridCoordinate.SOUTH);
        animate("WALK", "WALK", GridCoordinate.SOUTH);
       
      } else if (traits.contains("leftArrow")) {
        fMovement.move(GridCoordinate.WEST);
        animate("WALK", "WALK", GridCoordinate.WEST);
       
      } else if (traits.contains("rightArrow")) {
        fMovement.move(GridCoordinate.EAST);
        animate("WALK", "WALK", GridCoordinate.EAST);
       
      } else if (traits.contains("upArrow")) {
        fMovement.move(GridCoordinate.NORTH);
        animate("WALK", "WALK", GridCoordinate.NORTH);
       
      }
      fTask = null;
      state(GruntState.MOVING);
      attributeBoolean("walkable").addModifier(sFalseStateAttribute);
      return true;
    }
    return false;
  }
 
  protected void doDie() {
    state(GruntState.DYING);
    attributeBoolean("selectable").addModifier(sFalseStateAttribute);
    attributeBoolean("controllable").addModifier(sFalseStateAttribute);
    attributeBoolean("walkable").addModifier(sFalseStateAttribute);
    fMovement.pause();
    if (fTask != null) fTask.cancel();
    fTask = null;
    deselect();
    gridManager().removeObject(fTile, Grunt.this);
    // Clean up the grunt after the death animation ends
    frameManager().queue(new Minion<FrameEvent>() {
     
      public long run(Dispatcher<FrameEvent> dispatcher, String type, FrameEvent event) {
        Grunt.this.cleanup();
        return Minion.FINISH;
      };
     
    }, fAnimation.frameDuration());
  }
 
  protected void doHoleDeath() {
    rawAnimate("DEATHZ/HOLE", "DEATHZ/HOLE");
    GruntzGame.resourceManager().playSound("GRUNTZ/SOUNDZ/DEATHZ/DEATHZHOLEZ1A");
    frameManager().queue(new Minion<FrameEvent>() {
     
      public long run(Dispatcher<FrameEvent> dispatcher, String type, FrameEvent event) {
        GruntzGame.resourceManager().playSound("GRUNTZ/SOUNDZ/DEATHZ/DEATHZHOLEZ1B");
        return Minion.FINISH;
      };
     
    }, 40);
  }
 
  protected void doSquashDeath() {
    rawAnimate("DEATHZ/SQUASH", "DEATHZ/SQUASH");
    order(-1000);
    GruntzGame.resourceManager().playSound("GRUNTZ/SOUNDZ/DEATHZ/DEATHZSQUASH1A");
    speak(new MonolithWAV(GruntzGame.resourceManager().voicez().file("VOICES/DEATHZ/EXPLODEA", "wav")).sound());
  }
 
  protected void doHealthDeath() {
    rawAnimate(fTool + "GRUNT/DEATH", fTool + "GRUNT/DEATH");
  }
 
  protected void doFlyUpDeath() {
    rawAnimate("DEATHZ/FLYUP", "DEATHZ/FLYUP", 15);
    GruntzGame.resourceManager().playSound("GRUNTZ/SOUNDZ/DEATHZ/DEATHZEXPLODE1A");
  }
 
  protected void doSinkDeath() {
    rawAnimate("DEATHZ/SINK", "DEATHZ/SINK");
    GruntzGame.resourceManager().playSound("GRUNTZ/SOUNDZ/DEATHZ/DEATHZSINK1B");
  }
 
  @Override
  public Entity position(Vector2f position) {
    order((int) position.y - 40);
    return super.position(position);
  }
 
  public GruntzPlayer player() {
    return fPlayer;
  }

  public GridAlignedMovementOld<Grunt> movement() {
    return fMovement;
  }
 
  public void state(GruntState s) {
    fState = s;
  }
 
  public GruntState state() {
    return fState;
  }
 
  @Override
  public String toString() {
    return "[Grunt #" + fID + " " + fTool + " " + fToy + "]";
  }

  @Override
  public void initProperties() {
    fProperties = new LogicProperty[] {
      new StringLogicProperty("tool") {
       
        @Override
        public String description() {
          return "The tool the grunt starts with";
        }
       
        @Override
        public String value() {
          return fTool;
        }
       
        @Override
        public String[] choices() {
          return TOOLS;
        }

        @Override
        public void choice(int i) {
          fTool = TOOLS[i];
          animate("IDLE1", "IDLE");
        }
      },
      new StringLogicProperty("toy") {
       
        @Override
        public String description() {
          return "The toy the grunt starts with";
        }
       
        @Override
        public String value() {
          return fToy;
        }
       
        @Override
        public String[] choices() {
          return TOYS;
        }

        @Override
        public void choice(int i) {
          fToy = TOYS[i];
        }
      },
      new StringLogicProperty("color") {
       
        @Override
        public String description() {
          return "The color of the grunt";
        }
       
        @Override
        public String value() {
          return fColor;
        }
       
        @Override
        public String[] choices() {
          return COLORS;
        }

        @Override
        public void choice(int i) {
          fColor = COLORS[i];
          fPalette = new GruntPalette(fColor, GruntzGame.resourceManager().rez().file("GRUNTZ/PALETTEZ/" + fColor + "TOOL", "pal"));
          animate("IDLE1", "IDLE");
        }
      },
      new StringLogicProperty("player") {
       
        @Override
        public String description() {
          return "The player of the grunt";
        }
       
        @Override
        public String value() {
          return PLAYERS[fPlayerValue];
        }
       
        @Override
        public String[] choices() {
          return PLAYERS;
        }

        @Override
        public void choice(int i) {
          fPlayerValue = i;
        }
      },
      new StringLogicProperty("ai") {
       
        @Override
        public String description() {
          return "The AI type of the grunt";
        }
       
        @Override
        public String value() {
          return fAI;
        }
       
        @Override
        public String[] choices() {
          return AI;
        }

        @Override
        public void choice(int i) {
          fAI = AI[i];
        }
      }
    };
  }

  @Override
  public String name() {
    return "Grunt";
  }
 
  public int toolID() {
    for (int i = 0; i < TOOLS.length; i++) if (TOOLS[i].equals(fTool)) return i;
    return 0;
  }
 
  public int toyID() {
    for (int i = 0; i < TOYS.length; i++) if (TOYS[i].equals(fToy)) return i;
    return 0;
  }
 
  public static AnimatedSprite editorIcon(JSONObject object) throws JSONException {
    GruntPalette pal = new GruntPalette(object.getString("color"), GruntzGame.resourceManager().rez().file("GRUNTZ/PALETTEZ/" + object.getString("color") + "TOOL", "pal"));
    MonolithPID pid = GruntzGame.resourceManager().pid("GRUNTZ/IMAGEZ/" + object.getString("tool") + "GRUNT/SOUTH/IDLE/FRAME001", pal);
    return new AnimatedSprite(new Image[] {pid.image()}, new Vector2f[] {pid.offset()});
  }
}
TOP

Related Classes of com.pointcliki.dizgruntled.logic.Grunt$MovementMinion

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.