// ---------------------------------------------------------------------- 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; } }
// ---------------------------------------------------------------------- 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); } }
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); } } }