package data.scripts.plugins;
//import com.fs.starfarer.api.combat.BeamAPI;
import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.combat.CombatEngineAPI;
import com.fs.starfarer.api.combat.CombatEntityAPI;
import com.fs.starfarer.api.combat.DamageType;
import com.fs.starfarer.api.combat.DamagingProjectileAPI;
import com.fs.starfarer.api.combat.MissileAPI;
import com.fs.starfarer.api.combat.MutableStat.StatMod;
import com.fs.starfarer.api.combat.ShipAPI;
import com.fs.starfarer.api.combat.WeaponAPI;
import com.fs.starfarer.api.combat.WeaponAPI.WeaponSize;
import java.awt.Color;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import org.lazywizard.lazylib.MathUtils;
public class OnHitCritical {
private float CRITPERCENT = 0.05f;
private float CRITMULT = 2f;
private CombatEngineAPI engine = null;
private DamagingProjectileAPI proj = null;
private MissileAPI missile = null;
private WeaponAPI weapon = null;
// private BeamAPI beam;
private ShipAPI owner = null;
private CombatEntityAPI target = null;
// Sound on High Explosive explosion
private static final Map SOUND_IDS_HE = new HashMap();
static
{
SOUND_IDS_HE.put("isFrigate", "explosion_ship");
SOUND_IDS_HE.put("isDestroyer", "explosion_ship");
SOUND_IDS_HE.put("isCruiser", "explosion_ship");
SOUND_IDS_HE.put("isCapital", "explosion_ship");
}
// Sound on Energy explosion
private static final Map SOUND_IDS_ENERGY = new HashMap();
static
{
SOUND_IDS_ENERGY.put("isFrigate", "explosion_ship");
SOUND_IDS_ENERGY.put("isDestroyer", "explosion_ship");
SOUND_IDS_ENERGY.put("isCruiser", "explosion_ship");
SOUND_IDS_ENERGY.put("isCapital", "explosion_ship");
}
public OnHitCritical(DamagingProjectileAPI proj, ShipAPI owner, CombatEngineAPI engine, CombatEntityAPI target)
{
this.proj = proj;
this.owner = owner;
this.weapon = this.proj.getWeapon();
this.engine = engine;
this.target = target;
}//OnHitCritical(DamagingProjectileAPI proj, ShipAPI owner, CombatEngineAPI engine, CombatEntityAPI target)
public OnHitCritical(MissileAPI missile, ShipAPI owner, CombatEngineAPI engine, CombatEntityAPI target)
{
this.missile = missile;
this.owner = owner;
this.weapon = this.missile.getWeapon();
this.engine = engine;
this.target = target;
}//OnHitCritical(MissileAPI missile, ShipAPI owner, CombatEngineAPI engine, CombatEntityAPI target)
// public onHitCritical(BeamAPI beam, ShipAPI owner, CombatEngineAPI engine, CombatEntityAPI target)
// {
// this.beam = beam;
// this.owner = owner;
// this.engine = engine;
// this.target = target;
// }//onHitCritical(BeamAPI beam, ShipAPI owner, CombatEngineAPI engine, CombatEntityAPI target)
public void initCritSystem()
{
//does the ship exist?
if(owner != null)
{
//Check, is this for Projectiles?
if(proj != null)
{
if(isCrit())
{
this.CritSystem(proj);
}
}//IF
//IF not then its for Missiles.
else
{
if(isCrit())
{
this.CritSystem(missile);
}
}//ELSE
}//IF
}//initCritSystem()
private float getCritChance()
{
if(weapon.getDamageType().equals(DamageType.FRAGMENTATION) ||
weapon.getDamageType().equals(DamageType.KINETIC) ||
weapon.getDamageType().equals(DamageType.OTHER))
{
return 0f;
}
float weaponRoF = weapon.getDerivedStats().getRoF();
StatMod crewBonus;
crewBonus = owner.getMutableStats().getAutofireAimAccuracy().getFlatStatMod("crew skill bonus");
float currentCR = owner.getCurrentCR();
// Green crew don't grant a bonus
float crewMaxXP = 0f;
if (crewBonus != null)
{
//Goes from 0f to 1f - thanks Alex and Lazy for the help
crewMaxXP = crewBonus.getValue();
}
//slower shooting weapons should not surpass limit of 5%
if (weaponRoF < 1f)
{
weaponRoF = 1f;
}
//This means that, if the crew is elite and the current CR is 100 its ((0.05f * 1) \ 1) * 1 that means 5%,
//if the crew is actually lower skilled, the current CR is lower and the weapon's RoF is higher the chances get lower.
return ((CRITPERCENT * crewMaxXP) / weaponRoF) * currentCR;
}//getCritChance()
public void addCritPercent(float addvalue)
{
this.CRITPERCENT += addvalue;
}//addCritPercent(float addvalue)
public void addCritMult(float addvalue)
{
this.CRITMULT += addvalue;
}//addCritMult(float addvalue)
private boolean isCrit()
{
Random r = new Random();
float CritChance = r.nextFloat();
if(CritChance <= getCritChance())
{
return true;
}//IF
else
{
return false;
}//ELSE
}//isCrit()
public void CritSystem (DamagingProjectileAPI proj)
{
float explosionSize = 0f;
ShipAPI enemyShip = (ShipAPI)this.target;
float weaponRoF = weapon.getDerivedStats().getRoF();
//Lets make sure we dont get a REALLY HUGE Crit text
if (weaponRoF < 1f)
{
weaponRoF = 1f;
}
if(weapon.getSize().equals(WeaponSize.SMALL))
{
explosionSize = MathUtils.getRandomNumberInRange(20f, 30f) / weaponRoF;
}
else if(weapon.getSize().equals(WeaponSize.MEDIUM))
{
explosionSize = MathUtils.getRandomNumberInRange(30f, 40f) / weaponRoF;
}
else if(weapon.getSize().equals(WeaponSize.LARGE))
{
explosionSize = MathUtils.getRandomNumberInRange(40f, 50f) / weaponRoF;
}
engine.addFloatingText(proj.getLocation(), "CRITICAL HIT", explosionSize, Color.RED, proj.getDamageTarget(), 0f, 0f);
if(weapon.getDamageType().equals(DamageType.HIGH_EXPLOSIVE))
{
if(enemyShip.isFrigate()) {
CritSystemEffects(enemyShip,
proj,
weapon.getDamageType(),
SOUND_IDS_HE.get("isFrigate").toString(),
explosionSize);
}
else if(enemyShip.isDestroyer()) {
CritSystemEffects(enemyShip,
proj,
weapon.getDamageType(),
SOUND_IDS_HE.get("isDestroyer").toString(),
explosionSize);
}
else if(enemyShip.isCruiser()) {
CritSystemEffects(enemyShip,
proj,
weapon.getDamageType(),
SOUND_IDS_HE.get("isCruiser").toString(),
explosionSize);
}
else if(enemyShip.isCapital()) {
CritSystemEffects(enemyShip,
proj,
weapon.getDamageType(),
SOUND_IDS_HE.get("isCapital").toString(),
explosionSize);
}
}
else if(weapon.getDamageType().equals(DamageType.ENERGY))
{
if(enemyShip.isFrigate()) {
CritSystemEffects(enemyShip,
proj,
weapon.getDamageType(),
SOUND_IDS_ENERGY.get("isFrigate").toString(),
explosionSize);
}
else if(enemyShip.isDestroyer()) {
CritSystemEffects(enemyShip,
proj,
weapon.getDamageType(),
SOUND_IDS_ENERGY.get("isDestroyer").toString(),
explosionSize);
}
else if(enemyShip.isCruiser()) {
CritSystemEffects(enemyShip,
proj,
weapon.getDamageType(),
SOUND_IDS_ENERGY.get("isCruiser").toString(),
explosionSize);
}
else if(enemyShip.isCapital()) {
CritSystemEffects(enemyShip,
proj,
weapon.getDamageType(),
SOUND_IDS_ENERGY.get("isCapital").toString(),
explosionSize);
}
}
}//CritSystem (DamagingProjectileAPI proj)
public void CritSystem(MissileAPI missile)
{
float explosionSize = 0f;
ShipAPI enemyShip = (ShipAPI)this.target;
float weaponRoF = weapon.getDerivedStats().getRoF();
//Lets make sure we dont get a REALLY HUGE Crit text
if (weaponRoF < 1f)
{
weaponRoF = 1f;
}
if(weapon.getSize().equals(WeaponSize.SMALL))
{
explosionSize = MathUtils.getRandomNumberInRange(20f, 30f) / weaponRoF;
}
else if(weapon.getSize().equals(WeaponSize.MEDIUM))
{
explosionSize = MathUtils.getRandomNumberInRange(30f, 40f) / weaponRoF;
}
else if(weapon.getSize().equals(WeaponSize.LARGE))
{
explosionSize = MathUtils.getRandomNumberInRange(40f, 50f) / weaponRoF;
}
engine.addFloatingText(missile.getLocation(), "CRITICAL HIT", explosionSize, Color.RED, missile.getDamageTarget(), 0f, 0f);
if(weapon.getDamageType().equals(DamageType.HIGH_EXPLOSIVE))
{
if(enemyShip.isFrigate()) {
CritSystemEffects(enemyShip,
missile,
weapon.getDamageType(),
SOUND_IDS_HE.get("isFrigate").toString(),
explosionSize);
}
else if(enemyShip.isDestroyer()) {
CritSystemEffects(enemyShip,
missile,
weapon.getDamageType(),
SOUND_IDS_HE.get("isDestroyer").toString(),
explosionSize);
}
else if(enemyShip.isCruiser()) {
CritSystemEffects(enemyShip,
missile,
weapon.getDamageType(),
SOUND_IDS_HE.get("isCruiser").toString(),
explosionSize);
}
else if(enemyShip.isCapital()) {
CritSystemEffects(enemyShip,
missile,
weapon.getDamageType(),
SOUND_IDS_HE.get("isCapital").toString(),
explosionSize);
}
}
else if(weapon.getDamageType().equals(DamageType.ENERGY))
{
if(enemyShip.isFrigate()) {
CritSystemEffects(enemyShip,
missile,
weapon.getDamageType(),
SOUND_IDS_ENERGY.get("isFrigate").toString(),
explosionSize);
}
else if(enemyShip.isDestroyer()) {
CritSystemEffects(enemyShip,
missile,
weapon.getDamageType(),
SOUND_IDS_ENERGY.get("isDestroyer").toString(),
explosionSize);
}
else if(enemyShip.isCruiser()) {
CritSystemEffects(enemyShip,
missile,
weapon.getDamageType(),
SOUND_IDS_ENERGY.get("isCruiser").toString(),
explosionSize);
}
else if(enemyShip.isCapital()) {
CritSystemEffects(enemyShip,
missile,
weapon.getDamageType(),
SOUND_IDS_ENERGY.get("isCapital").toString(),
explosionSize);
}
}
}//CritSystem(MissileAPI missile)
public void CritSystemEffects(ShipAPI ship, DamagingProjectileAPI proj, DamageType dmgtype, String ExplosionSoundID, float explosionSize)
{
if(weapon.getDamageType().equals(DamageType.HIGH_EXPLOSIVE))
{
float damage = proj.getDamageAmount() * CRITMULT;
float emp = proj.getEmpAmount() * CRITMULT;
// Apply damage and slow the projectile
// Note: BALLISTIC_AS_BEAM projectiles won't be slowed!
engine.applyDamage(owner,
proj.getLocation(),
damage,
proj.getDamageType(),
emp,
true,
true,
proj.getSource());
proj.getVelocity().scale(1.5f - 1.0f);
engine.spawnExplosion(
proj.getLocation(),
ship.getVelocity(),
Color.ORANGE,
1f,
1.5f);
// Play Explosion sound
Global.getSoundPlayer().playSound(ExplosionSoundID,
1f,
1f,
proj.getLocation(),
ship.getVelocity());
}
else if(weapon.getDamageType().equals(DamageType.ENERGY))
{
float damage = proj.getDamageAmount() * CRITMULT;
float emp = proj.getEmpAmount() * CRITMULT;
// Apply damage and slow the projectile
// Note: BALLISTIC_AS_BEAM projectiles won't be slowed!
engine.applyDamage(ship,
proj.getLocation(),
damage,
proj.getDamageType(),
emp,
true,
true,
proj.getSource());
proj.getVelocity().scale(1.5f - 1.0f);
engine.spawnExplosion(
proj.getLocation(),
ship.getVelocity(),
Color.blue,
1f,
1.5f);
// Play Crit Explosion
Global.getSoundPlayer().playSound(ExplosionSoundID,
1f,
1f,
proj.getLocation(),
ship.getVelocity());
}
}//CritSystemEffects(ShipAPI ship, DamagingProjectileAPI proj, DamageType dmgtype, String ExplosionSoundID, float explosionSize)
public void CritSystemEffects(ShipAPI ship, MissileAPI missile, DamageType dmgtype, String ExplosionSoundID, float explosionSize)
{
if(weapon.getDamageType().equals(DamageType.HIGH_EXPLOSIVE))
{
float damage = missile.getDamageAmount() * CRITMULT;
float emp = missile.getEmpAmount() * CRITMULT;
// Apply damage and slow the projectile
// Note: BALLISTIC_AS_BEAM projectiles won't be slowed!
engine.applyDamage(owner,
missile.getLocation(),
damage,
missile.getDamageType(),
emp,
true,
true,
missile.getSource());
missile.getVelocity().scale(1.5f - 1.0f);
engine.spawnExplosion(
missile.getLocation(),
ship.getVelocity(),
Color.ORANGE,
1f,
1.5f);
// Play Explosion sound
Global.getSoundPlayer().playSound(ExplosionSoundID,
1f,
1f,
missile.getLocation(),
ship.getVelocity());
}
else if(weapon.getDamageType().equals(DamageType.ENERGY))
{
float damage = missile.getDamageAmount() * CRITMULT;
float emp = missile.getEmpAmount() * CRITMULT;
// Apply damage and slow the projectile
// Note: BALLISTIC_AS_BEAM projectiles won't be slowed!
engine.applyDamage(ship,
missile.getLocation(),
damage,
missile.getDamageType(),
emp,
true,
true,
missile.getSource());
missile.getVelocity().scale(1.5f - 1.0f);
engine.spawnExplosion(
missile.getLocation(),
ship.getVelocity(),
Color.blue,
1f,
1.5f);
// Play Crit Explosion
Global.getSoundPlayer().playSound(ExplosionSoundID,
1f,
1f,
missile.getLocation(),
ship.getVelocity());
}
}//CritSystemEffects(ShipAPI ship, MissileAPI missile, DamageType dmgtype, String ExplosionSoundID, float explosionSize)
public float getCRITPERCENT()
{
return this.CRITPERCENT;
}
public void increaseCRITPERCENT(float amount)
{
this.CRITPERCENT += amount;
}
public float getCRITMULT()
{
return this.CRITMULT;
}
public void changeCRITMULT(float amount)
{
this.CRITMULT = amount;
}
}//CLASS