示例#1
0
public class AbilityPanel extends TilePanel {
  private final GlyphLayout layout = new GlyphLayout();
  private BitmapFont font;
  private TextureRegion white;
  private TextureRegion passiveTileBorder;

  public AbilityPanel(Skin skin, Stage stage) {
    super(
        skin,
        stage,
        AssetManager.loadSprite("GUI/TileBackground"),
        AssetManager.loadSprite("GUI/TileBorder"),
        1,
        Global.NUM_ABILITY_SLOTS,
        48,
        false);

    drawHorizontalBackground = false;
    font = skin.getFont("default");
    padding = 10;

    this.white = AssetManager.loadTextureRegion("Sprites/white.png");
    passiveTileBorder = AssetManager.loadTextureRegion("Sprites/GUI/PassiveTileBorder.png");
  }

  @Override
  public void populateTileData() {
    tileData.clear();

    for (AbilityTree a : Global.CurrentLevel.player.slottedAbilities) {
      if (a != null) {
        tileData.add(a);
      } else {
        tileData.add(tileData.size);
      }
    }

    while (tileData.size < Global.NUM_ABILITY_SLOTS) {
      tileData.add(tileData.size);
    }
  }

  @Override
  public Sprite getSpriteForData(Object data) {
    if (data == null || data instanceof Integer) {
      return null;
    }

    return ((AbilityTree) data).current.current.getIcon();
  }

  @Override
  public void handleDataClicked(final Object data, InputEvent event, float x, float y) {
    {
      if (GameScreen.Instance.abilityToEquip != null) {
        int index = 0;
        if (data instanceof Integer) {
          index = (Integer) data;
        } else {
          index = Global.CurrentLevel.player.slottedAbilities.indexOf((AbilityTree) data, true);
        }

        while (Global.CurrentLevel.player.slottedAbilities.size <= index) {
          Global.CurrentLevel.player.slottedAbilities.add(null);
        }

        Global.CurrentLevel.player.slottedAbilities.removeIndex(index);
        Global.CurrentLevel.player.slottedAbilities.insert(
            index, GameScreen.Instance.abilityToEquip);
        GameScreen.Instance.abilityToEquip = null;

        if (data instanceof AbilityTree) {
          Item item = new Item();
          item.ability = (AbilityTree) data;

          Global.CurrentLevel.player.tile[0][0].items.add(item);
        }

        GameScreen.Instance.lockContextMenu = false;
        GameScreen.Instance.clearContextMenu();
      } else {
        if (data instanceof AbilityTree
            && ((AbilityTree) data).current.current instanceof ActiveAbility) {
          ActiveAbility aa = (ActiveAbility) ((AbilityTree) data).current.current;

          if (GameScreen.Instance.preparedAbility == aa) {
            GameScreen.Instance.prepareAbility(null);
          } else if (aa.isAvailable()) {
            GameScreen.Instance.prepareAbility(aa);
          }
        }
      }
    }
  }

  @Override
  public Table getToolTipForData(Object data) {
    if (data == null || data instanceof Integer) {
      return null;
    }

    return ((AbilityTree) data).current.current.createTable(skin, Global.CurrentLevel.player);
  }

  @Override
  public Color getColourForData(Object data) {
    if (data == null || data instanceof Integer) {
      return Color.DARK_GRAY;
    }

    if (((AbilityTree) data).current.current == GameScreen.Instance.preparedAbility) {
      return Color.CYAN;
    }

    return null;
  }

  @Override
  public void onDrawItemBackground(Object data, Batch batch, int x, int y, int width, int height) {
    if (GameScreen.Instance.abilityToEquip != null) {
      batch.setColor(Color.GOLD);
      tileBackground.render(batch, x, y, width, height);
    }
  }

  @Override
  public void onDrawItem(Object data, Batch batch, int x, int y, int width, int height) {
    if (data instanceof AbilityTree
        && ((AbilityTree) data).current.current instanceof ActiveAbility) {
      ActiveAbility aa = (ActiveAbility) ((AbilityTree) data).current.current;

      if (!aa.isAvailable()) {
        batch.setColor(0.1f, 0.1f, 0.1f, 0.75f);
        batch.draw(white, x, y, width, height);
        batch.setColor(Color.WHITE);

        int cooldown = (int) Math.ceil(aa.cooldownAccumulator);

        if (cooldown > 0) {
          String text = aa.cooldownType.text + "\n" + cooldown;
          layout.setText(font, text, Color.WHITE, 0, Align.center, false);

          font.draw(batch, layout, x + width / 2, y + height / 2 + layout.height / 2);
        }
      }
    }
  }

  @Override
  public void onDrawItemForeground(Object data, Batch batch, int x, int y, int width, int height) {
    if (data instanceof AbilityTree) {
      AbilityTree tree = (AbilityTree) data;

      if (((AbilityTree) data).current.current instanceof PassiveAbility) {
        batch.draw(passiveTileBorder, x, y, width, height);
      }

      if (tree.current.needsLevelAnim) {
        Sprite sprite = AssetManager.loadSprite("EffectSprites/Heal/Heal", 0.1f);

        GameScreen.Instance.addSpriteAction(sprite, x + width / 2, y + height / 2, width, height);
        Global.CurrentLevel.player.pendingMessages.add(
            new Message(
                tree.current.current.getName()
                    + " levelled up! (Level "
                    + tree.current.current.getLevel()
                    + ")",
                Color.GOLD));

        levelUpSound.play(Global.CurrentLevel.player.tile[0][0]);

        tree.current.needsLevelAnim = false;
      }
    }
  }

  public static final SoundInstance levelUpSound = SoundInstance.getSound("LevelUp");
}
示例#2
0
  private void doAttack(Array<GameTile> hitTiles, final GameEntity entity, Item weapon) {
    final GameTile source = entity.tile[0][0];

    // Get all the attacked tiles
    Array<GameTile> attackedTiles = new Array<GameTile>();

    if (weapon == null
        || weapon.wepDef == null
        || weapon.wepDef.hitType == Item.WeaponDefinition.HitType.ALL) {
      attackedTiles.addAll(hitTiles);
    } else if (weapon.wepDef.hitType == Item.WeaponDefinition.HitType.CLOSEST) {
      int num = weapon.wepDef.hitData != null ? Integer.parseInt(weapon.wepDef.hitData) : 1;

      Array<GameTile> validEntityTiles = new Array<GameTile>();
      Array<GameTile> validEnvironmentTiles = new Array<GameTile>();

      // Get tiles valid to hit
      for (GameTile tile : hitTiles) {
        if (tile.entity != null && !tile.entity.isAllies(entity)) {
          validEntityTiles.add(tile);
        } else if (tile.environmentEntity != null && tile.environmentEntity.canTakeDamage) {
          validEnvironmentTiles.add(tile);
        }
      }

      Comparator<GameTile> comp =
          new Comparator<GameTile>() {
            @Override
            public int compare(GameTile o1, GameTile o2) {
              int dist1 = Math.abs(o1.x - source.x) + Math.abs(o1.y - source.y);
              int dist2 = Math.abs(o2.x - source.x) + Math.abs(o2.y - source.y);

              return dist1 - dist2;
            }
          };

      // sort by distance
      validEntityTiles.sort(comp);
      validEnvironmentTiles.sort(comp);

      for (int i = 0; i < num && i < validEntityTiles.size; i++) {
        attackedTiles.add(validEntityTiles.get(i));
      }

      for (int i = 0; i < num - validEntityTiles.size && i < validEnvironmentTiles.size; i++) {
        attackedTiles.add(validEnvironmentTiles.get(i));
      }
    } else if (weapon.wepDef.hitType == Item.WeaponDefinition.HitType.RANDOM) {
      int num = weapon.wepDef.hitData != null ? Integer.parseInt(weapon.wepDef.hitData) : 1;

      Array<GameTile> validEntityTiles = new Array<GameTile>();
      Array<GameTile> validEnvironmentTiles = new Array<GameTile>();

      // Get tiles valid to hit
      for (GameTile tile : hitTiles) {
        if (tile.entity != null && !tile.entity.isAllies(entity)) {
          validEntityTiles.add(tile);
        } else if (tile.environmentEntity != null && tile.environmentEntity.canTakeDamage) {
          validEnvironmentTiles.add(tile);
        }
      }

      if (validEntityTiles.size > 0) {
        for (int i = 0; i < num; i++) {
          attackedTiles.add(validEntityTiles.random());
        }
      } else if (validEnvironmentTiles.size > 0) {
        for (int i = 0; i < num; i++) {
          attackedTiles.add(validEnvironmentTiles.random());
        }
      }
    }

    Sprite hitEffect = null;
    if (weapon == null) {
      hitEffect = entity.defaultHitEffect;
    } else {
      hitEffect = weapon.getWeaponHitEffect();
    }

    Point minPoint = Global.PointPool.obtain().set(Integer.MAX_VALUE, Integer.MAX_VALUE);
    Point maxPoint = Global.PointPool.obtain().set(0, 0);

    int hitCount = weapon != null && weapon.wepDef != null ? weapon.wepDef.hitCount : 1;
    float animdelay = 0;

    for (int i = 0; i < hitCount; i++) {
      // Do the attack
      for (GameTile tile : attackedTiles) {
        // do misses
        int hitPercent = weapon != null && weapon.wepDef != null ? weapon.wepDef.hitPercent : 100;
        if (hitPercent < 100) {
          if (MathUtils.random(100) > hitPercent) {
            // Argh! a miss! Hit a random surrounding tile

            Direction dir = Direction.values()[MathUtils.random(Direction.values().length - 1)];
            GameTile newTile = tile.level.getGameTile(tile.x + dir.getX(), tile.y + dir.getY());
            if (newTile != null) {
              tile = newTile;
            }
          }
        }

        if (weapon == null
            || weapon.wepDef == null
            || weapon.wepDef.hitType != Item.WeaponDefinition.HitType.ALL) {
          int[] diff = tile.getPosDiff(source);

          Sprite sprite = hitEffect.copy();

          if (sprite.spriteAnimation != null) {
            int distMoved = (Math.abs(diff[0]) + Math.abs(diff[1])) / Global.TileSize;
            sprite.spriteAnimation.set(0.05f * distMoved, diff);
          }

          Vector2 vec = new Vector2(diff[0] * -1, diff[1] * -1);
          vec.nor();
          float x = vec.x;
          float y = vec.y;
          double dot = 0 * x + 1 * y; // dot product
          double det = 0 * y - 1 * x; // determinant
          float angle = (float) Math.atan2(det, dot) * MathUtils.radiansToDegrees;
          sprite.rotation = angle;

          sprite.renderDelay = animdelay;
          animdelay += 0.1f;

          boolean isMoving =
              sprite.spriteAnimation != null && sprite.spriteAnimation instanceof MoveAnimation;
          final SoundInstance sound = hitEffect.sound;

          final GameTile hitTile = tile;
          final GameEntity hitEntity = hitTile.entity;
          final EnvironmentEntity hitEnvEntity = hitTile.environmentEntity;

          sprite.spriteAction =
              new SpriteAction(
                  isMoving ? SpriteAction.FirePoint.End : SpriteAction.FirePoint.Start) {
                @Override
                public void evaluate() {
                  // do on hit
                  for (GameEventHandler handler : entity.getAllHandlers()) {
                    handler.onHit(entity, hitTile);
                  }

                  if (hitEntity != null && !hitEntity.isAllies(entity)) {
                    entity.attack(hitEntity, dir);
                  } else if (hitEnvEntity != null
                      && !hitEnvEntity.passableBy.intersect(entity.getTravelType())) {
                    entity.attack(hitEnvEntity, dir);
                  }

                  if (sound != null) {
                    sound.play(hitTile);
                  }
                }
              };

          SpriteEffect effect =
              new SpriteEffect(
                  sprite,
                  Direction.CENTER,
                  weapon != null && weapon.light != null ? weapon.light.copyNoFlag() : null);
          tile.spriteEffects.add(effect);
        } else {
          // do on hit
          for (GameEventHandler handler : entity.getAllHandlers()) {
            handler.onHit(entity, tile);
          }

          if (tile.entity != null && !tile.entity.isAllies(entity)) {
            entity.attack(tile.entity, dir);
          } else if (tile.environmentEntity != null
              && !tile.environmentEntity.passableBy.intersect(entity.getTravelType())) {
            entity.attack(tile.environmentEntity, dir);
          }

          if (tile.x < minPoint.x) {
            minPoint.x = tile.x;
          }
          if (tile.x > maxPoint.x) {
            maxPoint.x = tile.x;
          }
          if (tile.y < minPoint.y) {
            minPoint.y = tile.y;
          }
          if (tile.y > maxPoint.y) {
            maxPoint.y = tile.y;
          }
        }
      }
    }

    if (weapon != null
        && weapon.wepDef != null
        && weapon.wepDef.hitType == Item.WeaponDefinition.HitType.ALL) {
      // Use a joined sprite

      Sprite sprite = hitEffect.copy();

      sprite.rotation = dir.getAngle();
      sprite.baseScale[0] = (maxPoint.x - minPoint.x) + 1;
      sprite.baseScale[1] = (maxPoint.y - minPoint.y) + 1;

      if (dir == Direction.WEST || dir == Direction.EAST) {
        float temp = sprite.baseScale[0];
        sprite.baseScale[0] = sprite.baseScale[1];
        sprite.baseScale[1] = temp;
      }

      SpriteEffect effect =
          new SpriteEffect(
              sprite,
              Direction.CENTER,
              weapon != null && weapon.light != null ? weapon.light.copyNoFlag() : null);

      int px = minPoint.x;
      int py = minPoint.y;

      float dx = (maxPoint.x - minPoint.x) / 2.0f;
      float dy = (maxPoint.y - minPoint.y) / 2.0f;

      px += dir.getX() < 0 ? Math.ceil(dx) : Math.floor(dx);
      py += dir.getY() < 0 ? Math.ceil(dy) : Math.floor(dy);

      GameTile tile = attackedTiles.first().level.getGameTile(px, py);

      tile.spriteEffects.add(effect);

      SoundInstance sound = hitEffect.sound;
      if (sound != null) {
        sound.play(tile);
      }
    }
  }