package Roguelike.Ability.ActiveAbility.EffectType;
import Roguelike.Ability.ActiveAbility.ActiveAbility;
import Roguelike.Entity.Entity;
import Roguelike.Entity.EnvironmentEntity;
import Roguelike.Entity.GameEntity;
import Roguelike.Global;
import Roguelike.Global.Statistic;
import Roguelike.Tiles.GameTile;
import Roguelike.Util.FastEnumMap;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.XmlReader.Element;
import exp4j.Helpers.EquationHelper;
import net.objecthunter.exp4j.Expression;
import net.objecthunter.exp4j.ExpressionBuilder;
import java.util.HashMap;
public class EffectTypeDamage extends AbstractEffectType
{
private boolean directDamage = false;
private FastEnumMap<Statistic, String> equations = new FastEnumMap<Statistic, String>( Statistic.class );
private String[] reliesOn;
@Override
public void update( ActiveAbility aa, float time, GameTile tile, GameEntity entity, EnvironmentEntity envEntity )
{
if ( entity != null || envEntity != null )
{
HashMap<String, Integer> variableMap = calculateVariableMap( aa );
if ( entity != null )
{
applyToEntity( entity, aa, variableMap );
}
if ( envEntity != null )
{
applyToEntity( envEntity, aa, variableMap );
}
}
}
@Override
public void parse( Element xml )
{
reliesOn = xml.getAttribute( "ReliesOn", "" ).toLowerCase().split( "," );
directDamage = xml.getBooleanAttribute( "DirectDamage", false );
for ( int i = 0; i < xml.getChildCount(); i++ )
{
Element sEl = xml.getChild( i );
Statistic stat = Statistic.valueOf( sEl.getName().toUpperCase() );
equations.put( stat, sEl.getText().toLowerCase() );
}
}
@Override
public AbstractEffectType copy()
{
EffectTypeDamage e = new EffectTypeDamage();
e.directDamage = directDamage;
e.equations = equations;
e.reliesOn = reliesOn;
return e;
}
@Override
public Array<String> toString( ActiveAbility aa )
{
HashMap<String, Integer> variableMap = calculateVariableMap( aa );
Array<String> lines = new Array<String>();
float damage = Global.calculateScaledAttack( variableMap, aa.getVariableMap() );
damage /= 100.0f;
damage *= aa.getCaster().getVariable( Statistic.ATTACK );
lines.add( "Total Damage: " + (int)damage );
lines.add( "---" );
lines.add( "Weapon Damage: " + variableMap.get( Statistic.ATTACK.toString().toLowerCase() ) + "%" );
int pen = variableMap.get( Statistic.PENETRATION.toString().toLowerCase() );
if ( pen > 0 )
{
lines.add( "Weapon Penetration: " + pen );
}
lines.add( "---" );
lines.add( "Scales By:" );
for ( Statistic stat : Statistic.ModifierValues )
{
int val = variableMap.get( stat.toString().toLowerCase() );
if ( val > 0 )
{
Global.ScaleLevel scale = Global.ScaleLevel.values()[val-1];
lines.add( Global.capitalizeString( stat.toString() ) + " : " + scale );
}
}
return lines;
}
private void applyToEntity( Entity target, ActiveAbility aa, HashMap<String, Integer> variableMap )
{
float damage = Global.calculateScaledAttack( variableMap, aa.getVariableMap() );
if (!directDamage)
{
damage /= 100.0f;
damage *= aa.getCaster().getVariable( Statistic.ATTACK );
}
int pen = variableMap.get( Statistic.PENETRATION.toString().toLowerCase() );
Global.calculateDamage( aa.getCaster(), target, (int)damage, target.getVariable( Statistic.DEFENSE ), pen, true );
}
private HashMap<String, Integer> calculateVariableMap( ActiveAbility aa )
{
HashMap<String, Integer> variableMap = aa.getVariableMap();
for ( String name : reliesOn )
{
if ( !variableMap.containsKey( name ) )
{
variableMap.put( name, 0 );
}
}
FastEnumMap<Statistic, Integer> stats = Statistic.getStatisticsBlock();
for ( Statistic stat : Statistic.values() )
{
if ( equations.containsKey( stat ) )
{
String eqn = equations.get( stat );
int raw = EquationHelper.evaluate( eqn, variableMap );
stats.put( stat, raw );
}
}
variableMap = Statistic.statsBlockToVariableBlock( stats );
return variableMap;
}
}