Files
lakebane/src/engine/powers/poweractions/TransferStatPowerAction.java
T

256 lines
11 KiB
Java
Raw Normal View History

2022-04-30 09:41:17 -04:00
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.powers.poweractions;
import engine.gameManager.DispatchManager;
import engine.math.Vector3fImmutable;
import engine.mbEnums;
import engine.mbEnums.ModType;
import engine.mbEnums.SourceType;
2022-04-30 09:41:17 -04:00
import engine.net.AbstractNetMsg;
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;
2024-09-07 15:47:33 -04:00
import engine.wpak.data.PowerAction;
2022-04-30 09:41:17 -04:00
import java.util.HashMap;
import java.util.concurrent.ThreadLocalRandom;
public class TransferStatPowerAction extends AbstractPowerAction {
2023-07-15 09:23:48 -04:00
protected String effectID;
2024-09-12 12:20:23 -04:00
public PowerAction powerAction;
2023-07-15 09:23:48 -04:00
protected boolean transferRampAdd;
protected boolean transferEfficiencyRampAdd;
protected boolean targetToCaster;
protected mbEnums.DamageType damageType;
2023-07-15 09:23:48 -04:00
protected EffectsBase effect;
2024-09-07 15:47:33 -04:00
public TransferStatPowerAction(PowerAction powerAction, HashMap<String, EffectsBase> effects) {
super(powerAction);
2024-09-07 15:49:58 -04:00
2024-09-12 12:20:23 -04:00
this.powerAction = powerAction;
this.effectID = powerAction.effects.get(0).effect_id;
2024-09-07 15:49:58 -04:00
2025-01-19 10:22:59 -06:00
//int flags = powerAction.getInt("flags");
this.transferRampAdd = powerAction.statTransfer.rampCurve != null;
this.transferEfficiencyRampAdd = powerAction.statTransfer.rampCurve != null;
this.targetToCaster = powerAction.statTransfer.isDrain;
2023-07-15 09:23:48 -04:00
this.effect = effects.get(this.effectID);
try {
2025-01-19 10:22:59 -06:00
this.damageType = powerAction.damageType;
2023-07-15 09:23:48 -04:00
} catch (Exception e) {
this.damageType = null;
}
}
public String getEffectID() {
return this.effectID;
}
public EffectsBase getEffect() {
return this.effect;
}
public float getTransferAmount(float trains) {
// if (this.transferRampAdd)
2025-01-19 10:22:59 -06:00
return (float) (this.powerAction.statTransfer.ramp + (this.powerAction.statTransfer.rampCurve.getValue() * trains));
2023-07-15 09:23:48 -04:00
// else
// return this.transferAmount * (1 + (this.transferRamp * trains));
}
public float getTransferEfficiency(float trains) {
2025-01-19 10:22:59 -06:00
return (float) (this.powerAction.statTransfer.efficiency + (this.powerAction.statTransfer.efficiencyCurve.getValue() * trains));
2023-07-15 09:23:48 -04:00
}
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(mbEnums.GameObjectType.PlayerCharacter)) {
2023-07-15 09:23:48 -04:00
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;
// 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)
2024-04-01 09:19:37 -04:00
damage *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None));
2023-07-15 09:23:48 -04:00
//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
2024-09-12 12:20:23 -04:00
float maxDrain = 0;
switch (powerAction.statTransfer.fromStat) {
case HEALTH:
maxDrain = from.getCurrentHitpoints();
break;
case MANA:
maxDrain = from.getMana();
break;
case STAMINA:
maxDrain = from.getStamina();
break;
}
2023-07-15 09:23:48 -04:00
if (toAmount > maxDrain)
toAmount = maxDrain;
//prep messages for transfer
2024-09-12 12:20:23 -04:00
2023-07-15 09:23:48 -04:00
int powerID = pb.getToken();
int effectID = 496519310;
String powerName = pb.getName();
2024-09-12 12:20:23 -04:00
ModifyHealthMsg mhmTo = null;
2023-07-15 09:23:48 -04:00
AbstractNetMsg mhmFrom = null;
//stop if target is immune to drains
2024-09-12 12:20:23 -04:00
2024-04-01 09:19:37 -04:00
if (from.getBonuses().getBool(ModType.ImmuneTo, SourceType.Drain)) {
2023-07-15 09:23:48 -04:00
ModifyHealthMsg mhm = new ModifyHealthMsg(source, to, 0f, 0f, 0f, powerID, powerName, trains, effectID);
mhm.setUnknown03(5); //set target is immune
DispatchManager.sendToAllInRange(from, mhm);
2023-07-15 09:23:48 -04:00
return;
}
2024-09-12 12:20:23 -04:00
switch (powerAction.statTransfer.toStat) {
case HEALTH:
to.modifyHealth(toAmount, source, false);
mhmTo = new ModifyHealthMsg(source, to, toAmount, 0f, 0f, powerID, powerName, trains, effectID);
break;
case MANA:
to.modifyMana(toAmount, source);
mhmTo = new ModifyHealthMsg(source, to, 0f, toAmount, 0f, powerID, powerName, trains, effectID);
break;
case STAMINA:
to.modifyStamina(toAmount, source);
mhmTo = new ModifyHealthMsg(source, to, 0f, 0f, toAmount, powerID, powerName, trains, effectID);
break;
2023-07-15 09:23:48 -04:00
}
//subtract transfer amount
2024-09-12 12:20:23 -04:00
switch (powerAction.statTransfer.fromStat) {
case HEALTH:
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);
break;
case MANA:
from.modifyMana(-fromAmount, source);
mhmFrom = new ModifyHealthMsg(source, from, 0f, -fromAmount, 0f, powerID, powerName, trains, effectID);
break;
case STAMINA:
from.modifyStamina(-fromAmount, source);
mhmFrom = new ModifyHealthMsg(source, from, 0f, 0f, -fromAmount, powerID, powerName, trains, effectID);
break;
2023-07-15 09:23:48 -04:00
}
DispatchManager.sendToAllInRange(to, mhmTo);
DispatchManager.sendToAllInRange(from, mhmFrom);
2023-07-15 09:23:48 -04:00
}
}
@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
}
2022-04-30 09:41:17 -04:00
}