Пример #1
0
  // ----------------------------------------------------------------------
  public void applyDamage(int dam, Entity damager) {
    if (!canTakeDamage || HP == 0) {
      return;
    }

    HP = Math.max(HP - dam, 0);

    if (HP == 0) {
      for (GameEventHandler handler : getAllHandlers()) {
        handler.onDeath(this, damager);
      }
    }

    damageAccumulator += dam;
    hasDamage = true;
    extraUIHP += dam;

    if (HP + extraUIHP > getMaxHP()) {
      extraUIHP = getMaxHP() - HP;
    }

    if (dam != 0) {
      isVariableMapDirty = true;
    }
  }
Пример #2
0
  // ----------------------------------------------------------------------
  protected void calculateVariableMap() {
    variableMap.clear();

    for (Statistic s : Statistic.values()) {
      variableMap.put(s.toString().toLowerCase(), statistics.get(s));
    }

    for (GameEventHandler handler : getAllHandlers()) {
      for (Statistic s : Statistic.values()) {
        String key = s.toString().toLowerCase();
        variableMap.put(key, variableMap.get(key) + handler.getStatistic(baseVariableMap, s));
      }
    }

    variableMap.put("hp", HP);

    for (EquipmentSlot slot : EquipmentSlot.values()) {
      Item equipped = inventory.getEquip(slot);
      if (equipped != null && equipped.type != null) {
        variableMap.put(equipped.type, 1);
      }
    }

    for (StatusEffectStack s : stacks) {
      variableMap.put(s.effect.name.toLowerCase(), s.count);
    }

    for (Statistic s : Statistic.values()) {
      variableMap.put(s.toString().toLowerCase(), getStatistic(s));
    }

    variableMap.put("maxhp", variableMap.get(Statistic.CONSTITUTION.toString().toLowerCase()) * 10);

    if (inventory.getEquip(EquipmentSlot.WEAPON) != null) {
      Item wep = inventory.getEquip(EquipmentSlot.WEAPON);

      int atk =
          Global.calculateScaledAttack(
              Statistic.statsBlockToVariableBlock(wep.getStatistics(variableMap)), variableMap);

      String key = Statistic.ATTACK.toString().toLowerCase();
      variableMap.put(key, variableMap.get(key) + atk);
    }
  }
Пример #3
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);
      }
    }
  }