You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
299 lines
11 KiB
299 lines
11 KiB
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . |
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· |
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ |
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ |
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ |
|
// Magicbane Emulator Project © 2013 - 2022 |
|
// www.magicbane.com |
|
|
|
|
|
package engine.powers.poweractions; |
|
|
|
import engine.Enum; |
|
import engine.Enum.DamageType; |
|
import engine.Enum.ModType; |
|
import engine.Enum.SourceType; |
|
import engine.gameManager.ChatManager; |
|
import engine.math.Vector3fImmutable; |
|
import engine.net.AbstractNetMsg; |
|
import engine.net.DispatchMessage; |
|
import engine.net.client.msg.ModifyHealthKillMsg; |
|
import engine.net.client.msg.ModifyHealthMsg; |
|
import engine.objects.*; |
|
import engine.powers.ActionsBase; |
|
import engine.powers.EffectsBase; |
|
import engine.powers.PowersBase; |
|
import engine.powers.effectmodifiers.HealthEffectModifier; |
|
|
|
import java.sql.ResultSet; |
|
import java.sql.SQLException; |
|
import java.util.HashMap; |
|
import java.util.concurrent.ThreadLocalRandom; |
|
|
|
public class TransferStatPowerAction extends AbstractPowerAction { |
|
|
|
protected String effectID; |
|
protected boolean transferFromHealth = false; |
|
protected boolean transferFromMana = false; |
|
protected boolean transferFromStamina = false; |
|
protected boolean transferToHealth = false; |
|
protected boolean transferToMana = false; |
|
protected boolean transferToStamina = false; |
|
protected float transferAmount; |
|
protected float transferRamp; |
|
protected boolean transferRampAdd; |
|
protected float transferEfficiency; |
|
protected float transferEfficiencyRamp; |
|
protected boolean transferEfficiencyRampAdd; |
|
protected boolean targetToCaster; |
|
protected DamageType damageType; |
|
protected EffectsBase effect; |
|
|
|
public TransferStatPowerAction(ResultSet rs, HashMap<String, EffectsBase> effects) throws SQLException { |
|
super(rs); |
|
this.effectID = rs.getString("effectID"); |
|
String st = rs.getString("transferFromType"); |
|
if (st.equals("HEALTH")) |
|
this.transferFromHealth = true; |
|
else if (st.equals("MANA")) |
|
this.transferFromMana = true; |
|
else |
|
this.transferFromStamina = true; |
|
st = rs.getString("transferToType"); |
|
if (st.equals("HEALTH")) |
|
this.transferToHealth = true; |
|
else if (st.equals("MANA")) |
|
this.transferToMana = true; |
|
else |
|
this.transferToStamina = true; |
|
this.transferAmount = rs.getFloat("transferAmount"); |
|
this.transferRamp = rs.getFloat("transferRamp"); |
|
this.transferEfficiency = rs.getFloat("transferEfficiency"); |
|
this.transferEfficiencyRamp = rs.getFloat("transferEfficiencyRamp"); |
|
int flags = rs.getInt("flags"); |
|
this.transferRampAdd = ((flags & 4096) != 0) ? true : false; |
|
this.transferEfficiencyRampAdd = ((flags & 8192) != 0) ? true : false; |
|
this.targetToCaster = ((flags & 16384) != 0) ? true : false; |
|
this.effect = effects.get(this.effectID); |
|
try { |
|
String damageString = rs.getString("damageType"); |
|
// Damage type can sometimes be null in the DB. |
|
|
|
if (damageString.isEmpty() == false) |
|
this.damageType = DamageType.valueOf(damageString); |
|
} catch (Exception e) { |
|
this.damageType = null; |
|
} |
|
} |
|
|
|
public String getEffectID() { |
|
return this.effectID; |
|
} |
|
|
|
public boolean transferFromHealth() { |
|
return this.transferFromHealth; |
|
} |
|
|
|
public boolean transferFromMana() { |
|
return this.transferFromMana; |
|
} |
|
|
|
public boolean transferFromStamina() { |
|
return this.transferFromStamina; |
|
} |
|
|
|
public boolean transferToHealth() { |
|
return this.transferToHealth; |
|
} |
|
|
|
public boolean transferToMana() { |
|
return this.transferToMana; |
|
} |
|
|
|
public boolean transferToStamina() { |
|
return this.transferToStamina; |
|
} |
|
|
|
public EffectsBase getEffect() { |
|
return this.effect; |
|
} |
|
|
|
public float getTransferAmount(float trains) { |
|
// if (this.transferRampAdd) |
|
return this.transferAmount + (this.transferRamp * trains); |
|
// else |
|
// return this.transferAmount * (1 + (this.transferRamp * trains)); |
|
} |
|
|
|
public float getTransferEfficiency(float trains) { |
|
return this.transferEfficiency + (this.transferEfficiencyRamp * trains); |
|
} |
|
|
|
public boolean targetToCaster() { |
|
return this.targetToCaster; |
|
} |
|
|
|
@Override |
|
protected void _startAction(AbstractCharacter source, AbstractWorldObject awo, Vector3fImmutable targetLoc, int trains, ActionsBase ab, PowersBase pb) { |
|
this.__startAction(source, awo, trains, ab, pb); |
|
} |
|
|
|
//Added for dependancy check on TransferStatOTPowerAction |
|
protected void __startAction(AbstractCharacter source, AbstractWorldObject awo, int trains, ActionsBase ab, PowersBase pb) { |
|
this.runAction(source, awo, trains, ab, pb); |
|
} |
|
|
|
public void runAction(AbstractCharacter source, AbstractWorldObject awo, int trains, ActionsBase ab, PowersBase pb) { |
|
if (source == null || awo == null || ab == null || pb == null) |
|
return; |
|
|
|
if (!source.isAlive() || !awo.isAlive()) |
|
return; |
|
|
|
AbstractWorldObject fromAwo; |
|
AbstractWorldObject toAwo; |
|
if (this.targetToCaster) { |
|
fromAwo = awo; |
|
toAwo = source; |
|
} else { |
|
fromAwo = source; |
|
toAwo = awo; |
|
} |
|
|
|
|
|
|
|
if (AbstractWorldObject.IsAbstractCharacter(fromAwo) && AbstractWorldObject.IsAbstractCharacter(toAwo)) { |
|
AbstractCharacter from = (AbstractCharacter) fromAwo; |
|
AbstractCharacter to = (AbstractCharacter) toAwo; |
|
|
|
//get amount to drain |
|
float fromAmount = getTransferAmount(trains); |
|
|
|
//modify for resists if needed |
|
if (this.damageType != null) { |
|
Resists resists = from.getResists(); |
|
if (resists != null) |
|
fromAmount = resists.getResistedDamage(to, from, this.damageType, fromAmount * -1, trains) * -1; |
|
} |
|
|
|
float min = fromAmount;// * (getTransferEfficiency(trains) / 100); |
|
float max = min; |
|
float damage = 0f; |
|
|
|
if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { |
|
PlayerCharacter pc = (PlayerCharacter) source; |
|
float focus; |
|
CharacterSkill skill = pc.getSkills().get(pb.getSkillName()); |
|
if (skill == null) |
|
focus = CharacterSkill.getQuickMastery(pc, pb.getSkillName()); |
|
else |
|
focus = skill.getModifiedAmount(); |
|
|
|
//TODO fix this formula later |
|
float intt = (pc.getStatIntCurrent() >= 1) ? (float)pc.getStatIntCurrent() : 1f; |
|
float spi = (pc.getStatSpiCurrent() >= 1) ? (float)pc.getStatSpiCurrent() : 1f; |
|
// min *= (intt * 0.0045 + 0.055 * (float)Math.sqrt(intt - 0.5) + spi * 0.006 + 0.07 * (float)Math.sqrt(spi - 0.5) + 0.02 * (int)focus); |
|
// max *= (intt * 0.0117 + 0.13 * (float)Math.sqrt(intt - 0.5) + spi * 0.0024 + (float)Math.sqrt(spi - 0.5) * 0.021 + 0.015 * (int)focus); |
|
// min *= (0.62 + 0.0192 * pc.getStatSpiCurrent() + 0.00415 * pc.getStatIntCurrent() + 0.015 * focus) / 2; |
|
// max *= (0.62 + 0.0192 * pc.getStatIntCurrent() + 0.00415 * pc.getStatSpiCurrent() + 0.015 * focus) / 2; |
|
min = HealthEffectModifier.getMinDamage(min, intt, spi, focus); |
|
max = HealthEffectModifier.getMaxDamage(max, intt, spi, focus); |
|
|
|
// get range between min and max |
|
float range = max - min; |
|
|
|
//debug for spell damage and atr |
|
if (pc.getDebug(16)) { |
|
String smsg = "Damage: " + (int)Math.abs(min) + " - " + (int)Math.abs(max); |
|
ChatManager.chatSystemInfo(pc, smsg); |
|
} |
|
|
|
// Damage is calculated twice to average a more central point |
|
damage = ThreadLocalRandom.current().nextFloat() * range; |
|
damage = (damage + (ThreadLocalRandom.current().nextFloat() * range)) / 2; |
|
|
|
// put it back between min and max |
|
damage += min; |
|
} |
|
|
|
// Apply any power effect modifiers (such as stances) |
|
PlayerBonuses bonus = source.getBonuses(); |
|
if (bonus != null) |
|
damage *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None)); |
|
|
|
//get amount to transfer |
|
fromAmount = damage; |
|
float toAmount = fromAmount * (getTransferEfficiency(trains) / 100); |
|
|
|
//get max amount to transfer, don't give more then the target has |
|
float maxDrain; |
|
if (this.transferFromHealth) |
|
maxDrain = from.getCurrentHitpoints(); |
|
else if (this.transferFromMana) |
|
maxDrain = from.getMana(); |
|
else |
|
maxDrain = from.getStamina(); |
|
if (toAmount > maxDrain) |
|
toAmount = maxDrain; |
|
|
|
//prep messages for transfer |
|
int powerID = pb.getToken(); |
|
int effectID = 496519310; |
|
String powerName = pb.getName(); |
|
ModifyHealthMsg mhmTo; |
|
// ModifyHealthMsg mhmFrom; |
|
AbstractNetMsg mhmFrom = null; |
|
|
|
//stop if target is immune to drains |
|
if ( from.getBonuses().getBool(ModType.ImmuneTo, SourceType.Drain)) { |
|
ModifyHealthMsg mhm = new ModifyHealthMsg(source, to, 0f, 0f, 0f, powerID, powerName, trains, effectID); |
|
mhm.setUnknown03(5); //set target is immune |
|
DispatchMessage.sendToAllInRange(from, mhm); |
|
return; |
|
} |
|
|
|
//apply transfer bonus |
|
if (this.transferToHealth) { |
|
to.modifyHealth(toAmount, source, false); |
|
mhmTo = new ModifyHealthMsg(source, to, toAmount, 0f, 0f, powerID, powerName, trains, effectID); |
|
} else if (this.transferToMana) { |
|
to.modifyMana(toAmount, source); |
|
mhmTo = new ModifyHealthMsg(source, to, 0f, toAmount, 0f, powerID, powerName, trains, effectID); |
|
} else { |
|
to.modifyStamina(toAmount, source); |
|
mhmTo = new ModifyHealthMsg(source, to, 0f, 0f, toAmount, powerID, powerName, trains, effectID); |
|
} |
|
|
|
//subtract transfer amount |
|
if (this.transferFromHealth) { |
|
float modFrom = from.modifyHealth(-fromAmount, source, false); |
|
float cur = from.getHealth(); |
|
if (cur < 0 && modFrom != 0) |
|
mhmFrom = new ModifyHealthKillMsg(source, from, -fromAmount, 0f, 0f, powerID, powerName, trains, effectID); |
|
else |
|
mhmFrom = new ModifyHealthMsg(source, from, -fromAmount, 0f, 0f, powerID, powerName, trains, effectID); |
|
} else if (this.transferFromMana) { |
|
from.modifyMana(-fromAmount, source); |
|
mhmFrom = new ModifyHealthMsg(source, from, 0f, -fromAmount, 0f, powerID, powerName, trains, effectID); |
|
} else { |
|
from.modifyStamina(-fromAmount, source); |
|
mhmFrom = new ModifyHealthMsg(source, from, 0f, 0f, -fromAmount, powerID, powerName, trains, effectID); |
|
} |
|
|
|
DispatchMessage.sendToAllInRange(to, mhmTo); |
|
DispatchMessage.sendToAllInRange(from, mhmFrom); |
|
|
|
} |
|
} |
|
|
|
@Override |
|
protected void _handleChant(AbstractCharacter source, AbstractWorldObject target, Vector3fImmutable targetLoc, int trains, ActionsBase ab, PowersBase pb) { |
|
} |
|
|
|
@Override |
|
protected void _startAction(AbstractCharacter source, AbstractWorldObject awo, Vector3fImmutable targetLoc, |
|
int numTrains, ActionsBase ab, PowersBase pb, int duration) { |
|
// TODO Auto-generated method stub |
|
|
|
} |
|
}
|
|
|