forked from MagicBane/Server
Compare commits
140 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5142a87b60 | |||
| 9b7568b576 | |||
| 7bec57e77d | |||
| 28bccdd3d8 | |||
| cca342e99d | |||
| e41c79e6d7 | |||
| 7dfb0da862 | |||
| c2d4e0c1dd | |||
| 512621981a | |||
| 81c9a84edf | |||
| c099444464 | |||
| 94afb7f40f | |||
| d43f87b295 | |||
| d5b787430e | |||
| 3af6cab92e | |||
| 106e7be1ac | |||
| 0d8f1f7252 | |||
| 330344f55b | |||
| 7a5f138c78 | |||
| 6a9ca26d81 | |||
| 32c28e8f54 | |||
| 99dcfbb4a2 | |||
| 16dffee0e3 | |||
| a5cb785587 | |||
| 7bcd75719c | |||
| d96993576a | |||
| 17afaf6720 | |||
| 3e9f38c857 | |||
| a36dbc6539 | |||
| 7d3ff49796 | |||
| d2ac62e320 | |||
| 4b83311a89 | |||
| 7fd55bb6f3 | |||
| a40025bca1 | |||
| d58ba67cc2 | |||
| 3d4a9e18d0 | |||
| 7e5fe56bc0 | |||
| 4cf3b0929f | |||
| 98a6d268d0 | |||
| a9a4b36121 | |||
| 75a4a69036 | |||
| 982a35bb4f | |||
| 27c3fe515c | |||
| 29d82d9e81 | |||
| 81427e6911 | |||
| 296a7012b0 | |||
| b9b88449ed | |||
| 6585248eb8 | |||
| feebddd495 | |||
| 3e510a487c | |||
| 5277fbbe56 | |||
| 1a64272801 | |||
| fc7b7eb915 | |||
| 1e3249561c | |||
| 1ac76ae4d3 | |||
| 56cea25e06 | |||
| 2c33ff5a2a | |||
| 3cdf848e33 | |||
| 7ed291860f | |||
| e3e8fae90c | |||
| 0a2e487a76 | |||
| 6018be3c72 | |||
| 486141ce0b | |||
| cc96d68974 | |||
| 6740896244 | |||
| 811eb42e47 | |||
| 1633b5d0dd | |||
| 808eb989ea | |||
| 6879a8dccf | |||
| 8cf17e3abd | |||
| 0711c8f05b | |||
| b0ad37dbf8 | |||
| 2c3d5a3fcf | |||
| 78e8aab808 | |||
| 2bc033170f | |||
| 556eb30ab0 | |||
| 4f74d43081 | |||
| 80c4dcc082 | |||
| 9cd30d5299 | |||
| b148ea5f6e | |||
| 3612232788 | |||
| 99acc4736f | |||
| fac426a09c | |||
| c75a153c92 | |||
| ce5611aafd | |||
| 9e6b50d264 | |||
| f5801e0837 | |||
| 79864713b5 | |||
| 42daf1c049 | |||
| 1784ac1e5d | |||
| 137a547d3d | |||
| d9738c39a5 | |||
| 45bd3159ce | |||
| acd1246a87 | |||
| 1e64108b56 | |||
| 1481cc7ac0 | |||
| c0b75564c2 | |||
| 4958165603 | |||
| 35258f6ab5 | |||
| 3913201eed | |||
| 37bedcf919 | |||
| 11e40d7e57 | |||
| 0cdd8a75dc | |||
| 2e45d8548f | |||
| 61f8c210ae | |||
| acc5c04810 | |||
| 8030ecb800 | |||
| 12b350580a | |||
| 78dd409fa8 | |||
| 0727175cb2 | |||
| 7c3a3fb84c | |||
| 5781737afc | |||
| 75e1dddd08 | |||
| 1e78442910 | |||
| de6158842d | |||
| 0c07586927 | |||
| cfca585ab5 | |||
| db2a168229 | |||
| 040121f7cd | |||
| 570a22f0cb | |||
| 1ebc5d5e00 | |||
| 4b1d7ea718 | |||
| 402f608f7a | |||
| b9b6b37505 | |||
| 3be5236ba8 | |||
| 4cbe9fc236 | |||
| 6ac05d3db2 | |||
| 2531041d7c | |||
| 77e5866351 | |||
| 22e80e1ef4 | |||
| a86e07a89f | |||
| 5f277c3cff | |||
| ef234beeb7 | |||
| 69c5c5da92 | |||
| 7ed5431c99 | |||
| 627255ce3d | |||
| 0d1c9e8b8b | |||
| 5fa79fbac6 | |||
| 45b4ae9e3e | |||
| f410fc5482 |
@@ -1,156 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.devcmd.cmds;
|
||||
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.mbEnums.PowerActionType;
|
||||
import engine.objects.AbstractGameObject;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.powers.ActionsBase;
|
||||
import engine.powers.PowersBase;
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
import engine.util.ThreadUtils;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class ApplyBonusCmd extends AbstractDevCmd {
|
||||
|
||||
public ApplyBonusCmd() {
|
||||
super("applybonus");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _doCmd(PlayerCharacter pcSender, String[] words,
|
||||
AbstractGameObject target) {
|
||||
|
||||
String action = words[0];
|
||||
|
||||
PowerActionType actionType = null;
|
||||
|
||||
HashMap<String, HashSet<String>> appliedMods = new HashMap<>();
|
||||
|
||||
try {
|
||||
|
||||
if (action.equals("all") == false)
|
||||
for (PowerActionType powerActionType : PowerActionType.values()) {
|
||||
if (powerActionType.name().equalsIgnoreCase(action) == false)
|
||||
continue;
|
||||
actionType = powerActionType;
|
||||
break;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
this.throwbackError(pcSender, "Invalid power Action type for " + action);
|
||||
this.throwbackInfo(pcSender, "Valid Types : " + this.getActionTypes());
|
||||
return;
|
||||
}
|
||||
if (action.equals("all") == false)
|
||||
if (actionType == null) {
|
||||
this.throwbackError(pcSender, "Invalid power Action type for " + action);
|
||||
this.throwbackInfo(pcSender, "Valid Types : " + this.getActionTypes());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (PowersBase pb : PowersManager.powersBaseByIDString.values()) {
|
||||
if (pb.getActions() == null || pb.getActions().isEmpty())
|
||||
continue;
|
||||
|
||||
for (ActionsBase ab : pb.getActions()) {
|
||||
if (ab.getPowerAction() == null)
|
||||
continue;
|
||||
if (action.equals("all") == false)
|
||||
if (ab.getPowerAction().getType().equalsIgnoreCase(action) == false)
|
||||
continue;
|
||||
String effect1 = "";
|
||||
String effect2 = "";
|
||||
ChatManager.chatSystemInfo(pcSender, "Applying Power " + pb.getName() + " : " + pb.getDescription());
|
||||
if (ab.getPowerAction().getEffectsBase() == null) {
|
||||
|
||||
try {
|
||||
PowersManager.runPowerAction(pcSender, pcSender, pcSender.getLoc(), ab, 1, pb);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
ThreadUtils.sleep(500);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (ab.getPowerAction().getEffectsBase().getModifiers() == null || ab.getPowerAction().getEffectsBase().getModifiers().isEmpty()) {
|
||||
try {
|
||||
PowersManager.runPowerAction(pcSender, pcSender, pcSender.getLoc(), ab, 1, pb);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean run = true;
|
||||
for (AbstractEffectModifier mod : ab.getPowerAction().getEffectsBase().getModifiers()) {
|
||||
if (appliedMods.containsKey(mod.modType.name()) == false) {
|
||||
appliedMods.put(mod.modType.name(), new HashSet<>());
|
||||
}
|
||||
|
||||
// if (appliedMods.get(mod.modType.name()).contains(mod.sourceType.name())){
|
||||
// continue;
|
||||
// }
|
||||
|
||||
appliedMods.get(mod.modType.name()).add(mod.sourceType.name());
|
||||
try {
|
||||
try {
|
||||
PowersManager.runPowerAction(pcSender, pcSender, pcSender.getLoc(), ab, 1, pb);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String _getUsageString() {
|
||||
return "' /bounds'";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String _getHelpString() {
|
||||
return "Audits all the mobs in a zone.";
|
||||
|
||||
}
|
||||
|
||||
private String getActionTypes() {
|
||||
String output = "";
|
||||
|
||||
for (PowerActionType actionType : PowerActionType.values()) {
|
||||
output += actionType.name() + " | ";
|
||||
|
||||
}
|
||||
|
||||
return output.substring(0, output.length() - 3);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -122,7 +122,6 @@ public enum DevCmdManager {
|
||||
DevCmdManager.registerDevCmd(new SetNpcNameCmd());
|
||||
DevCmdManager.registerDevCmd(new BoundsCmd());
|
||||
DevCmdManager.registerDevCmd(new RegionCmd());
|
||||
DevCmdManager.registerDevCmd(new ApplyBonusCmd());
|
||||
DevCmdManager.registerDevCmd(new SlotTestCmd());
|
||||
}
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@ import engine.server.MBServerStatics;
|
||||
import engine.wpak.EffectsParser;
|
||||
import engine.wpak.PowerActionParser;
|
||||
import engine.wpak.PowersParser;
|
||||
import engine.wpak.WpakPowerManager;
|
||||
import engine.wpak.data.Effect;
|
||||
import engine.wpak.data.PowerAction;
|
||||
import engine.wpakpowers.WpakPowerManager;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -64,10 +64,12 @@ public enum PowersManager {
|
||||
|
||||
public static void initPowersManager(boolean fullPowersLoad) {
|
||||
|
||||
if (fullPowersLoad)
|
||||
PowersManager.InitializePowers();
|
||||
else
|
||||
if (fullPowersLoad) {
|
||||
//PowersManager.InitializePowers();
|
||||
WpakPowerManager.init();
|
||||
}else {
|
||||
PowersManager.InitializeLoginPowers();
|
||||
}
|
||||
|
||||
PowersManager.js = JobScheduler.getInstance();
|
||||
|
||||
@@ -119,7 +121,7 @@ public enum PowersManager {
|
||||
// Add EffectsBase
|
||||
ArrayList<EffectsBase> effectList = new ArrayList<>();
|
||||
|
||||
for (Effect entry : WpakPowerManager.effect_data.values()) {
|
||||
for (Effect entry : WpakPowerManager._effectsLookup.values()) {
|
||||
EffectsBase effectBase = new EffectsBase(entry);
|
||||
effectList.add(effectBase);
|
||||
PowersManager.effectsBaseByToken.put(effectBase.getToken(), effectBase);
|
||||
@@ -134,9 +136,9 @@ public enum PowersManager {
|
||||
|
||||
HashMap<String, EffectsBase> effects = PowersManager.effectsBaseByIDString;
|
||||
|
||||
for (PowerAction powerAction : WpakPowerManager.power_actions.values()) {
|
||||
for (PowerAction powerAction : WpakPowerManager._powerActionLookup.values()) {
|
||||
AbstractPowerAction apa;
|
||||
String type = powerAction.action_type;
|
||||
PowerActionType type = powerAction.action_type;
|
||||
String IDString = powerAction.action_id;
|
||||
int token = DbManager.hasher.SBStringHash(IDString);
|
||||
//cache token, used for applying effects.
|
||||
@@ -146,102 +148,90 @@ public enum PowersManager {
|
||||
default:
|
||||
Logger.error("valid type not found for poweraction of ID" + IDString);
|
||||
break;
|
||||
case "ApplyEffect":
|
||||
case ApplyEffect:
|
||||
apa = new ApplyEffectPowerAction(powerAction, effects);
|
||||
break;
|
||||
case "ApplyEffects":
|
||||
case ApplyEffects:
|
||||
apa = new ApplyEffectsPowerAction(powerAction, effects);
|
||||
break;
|
||||
case "DeferredPower":
|
||||
case DeferredPower:
|
||||
apa = new DeferredPowerPowerAction(powerAction, effects);
|
||||
break;
|
||||
case "DamageOverTime":
|
||||
case DamageOverTime:
|
||||
apa = new DamageOverTimePowerAction(powerAction, effects);
|
||||
break;
|
||||
case "Peek":
|
||||
case Peek:
|
||||
apa = new PeekPowerAction(powerAction);
|
||||
break;
|
||||
case "Charm":
|
||||
case Charm:
|
||||
apa = new CharmPowerAction(powerAction);
|
||||
break;
|
||||
case "Fear":
|
||||
apa = new FearPowerAction(powerAction);
|
||||
break;
|
||||
case "Confusion":
|
||||
apa = new ConfusionPowerAction(powerAction);
|
||||
break;
|
||||
case "RemoveEffect":
|
||||
case RemoveEffect:
|
||||
apa = new RemoveEffectPowerAction(powerAction);
|
||||
break;
|
||||
case "Track":
|
||||
case Track:
|
||||
apa = new TrackPowerAction(powerAction, effects);
|
||||
break;
|
||||
case "DirectDamage":
|
||||
case DirectDamage:
|
||||
apa = new DirectDamagePowerAction(powerAction, effects);
|
||||
break;
|
||||
case "Transform":
|
||||
case Transform:
|
||||
apa = new TransformPowerAction(powerAction, effects);
|
||||
break;
|
||||
case "CreateMob":
|
||||
case CreateMob:
|
||||
apa = new CreateMobPowerAction(powerAction);
|
||||
break;
|
||||
case "Invis":
|
||||
case Invis:
|
||||
apa = new InvisPowerAction(powerAction, effects);
|
||||
break;
|
||||
case "ClearNearbyAggro":
|
||||
case ClearNearbyAggro:
|
||||
apa = new ClearNearbyAggroPowerAction(powerAction);
|
||||
break;
|
||||
case "MobRecall":
|
||||
case MobRecall:
|
||||
apa = new MobRecallPowerAction(powerAction);
|
||||
break;
|
||||
case "SetItemFlag":
|
||||
case SetItemFlag:
|
||||
apa = new SetItemFlagPowerAction(powerAction);
|
||||
break;
|
||||
case "SimpleDamage":
|
||||
case SimpleDamage:
|
||||
apa = new SimpleDamagePowerAction(powerAction);
|
||||
break;
|
||||
case "TransferStatOT":
|
||||
case TransferStatOT:
|
||||
apa = new TransferStatOTPowerAction(powerAction, effects);
|
||||
break;
|
||||
case "TransferStat":
|
||||
case TransferStat:
|
||||
apa = new TransferStatPowerAction(powerAction, effects);
|
||||
break;
|
||||
case "Teleport":
|
||||
case Teleport:
|
||||
apa = new TeleportPowerAction(powerAction);
|
||||
break;
|
||||
case "TreeChoke":
|
||||
case TreeChoke:
|
||||
apa = new TreeChokePowerAction(powerAction);
|
||||
break;
|
||||
case "Block":
|
||||
case Block:
|
||||
apa = new BlockPowerAction(powerAction);
|
||||
break;
|
||||
case "Resurrect":
|
||||
case Resurrect:
|
||||
apa = new ResurrectPowerAction(powerAction);
|
||||
break;
|
||||
case "ClearAggro":
|
||||
apa = new ClearAggroPowerAction(powerAction);
|
||||
break;
|
||||
case "ClaimMine":
|
||||
case ClaimMine:
|
||||
apa = new ClaimMinePowerAction(powerAction);
|
||||
break;
|
||||
case "Recall":
|
||||
case Recall:
|
||||
apa = new RecallPowerAction(powerAction);
|
||||
break;
|
||||
case "SpireDisable":
|
||||
case SpireDisable:
|
||||
apa = new SpireDisablePowerAction(powerAction);
|
||||
break;
|
||||
case "Steal":
|
||||
case Steal:
|
||||
apa = new StealPowerAction(powerAction);
|
||||
break;
|
||||
case "Summon":
|
||||
case Summon:
|
||||
apa = new SummonPowerAction(powerAction);
|
||||
break;
|
||||
case "RunegateTeleport":
|
||||
case RunegateTeleport:
|
||||
apa = new RunegateTeleportPowerAction(powerAction);
|
||||
break;
|
||||
case "OpenGate":
|
||||
apa = new OpenGatePowerAction(powerAction);
|
||||
break;
|
||||
}
|
||||
PowersManager.powerActionsByIDString.put(IDString, apa);
|
||||
}
|
||||
|
||||
@@ -14,9 +14,7 @@ import engine.job.AbstractScheduleJob;
|
||||
import engine.net.client.msg.PerformActionMsg;
|
||||
import engine.objects.AbstractWorldObject;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.powers.PowersBase;
|
||||
import engine.wpak.WpakPowerManager;
|
||||
import engine.wpak.data.Power;
|
||||
import engine.wpakpowers.WpakPowerManager;
|
||||
|
||||
public class WpakUsePowerJob extends AbstractScheduleJob {
|
||||
|
||||
|
||||
+535
-452
File diff suppressed because it is too large
Load Diff
@@ -8,10 +8,10 @@
|
||||
|
||||
package engine.net.client.handlers;
|
||||
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.ClientNetMsg;
|
||||
import engine.net.client.msg.PerformActionMsg;
|
||||
import engine.wpakpowers.WpakPowerManager;
|
||||
|
||||
public class PerformActionMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
@@ -23,7 +23,8 @@ public class PerformActionMsgHandler extends AbstractClientMsgHandler {
|
||||
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
|
||||
|
||||
PerformActionMsg msg = (PerformActionMsg) baseMsg;
|
||||
PowersManager.usePower(msg, origin, false); // Wtf ?
|
||||
//PowersManager.beginCast(msg, origin, false); // Wtf ?
|
||||
WpakPowerManager.beginCast(msg, origin, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,10 @@ import engine.net.client.msg.PerformActionMsg;
|
||||
import engine.net.client.msg.SendSummonsMsg;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.wpakpowers.WpakPowerManager;
|
||||
|
||||
import static engine.gameManager.PowersManager.*;
|
||||
import static engine.gameManager.PowersManager.sendPowerMsg;
|
||||
import static engine.gameManager.PowersManager.sendRecyclePower;
|
||||
|
||||
public class SendSummonsMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
@@ -81,7 +83,8 @@ public class SendSummonsMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
// Client removes 200 mana on summon use.. so don't send message to self
|
||||
target.addSummoner(playerCharacter.getObjectUUID(), System.currentTimeMillis() + MBServerStatics.FOURTYFIVE_SECONDS);
|
||||
usePower(pam, origin, false);
|
||||
//beginCast(pam, origin, false);
|
||||
WpakPowerManager.beginCast(pam, origin, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.UpdateEffectsMsg;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.wpakpowers.AppliedEffect;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
@@ -60,6 +61,10 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
|
||||
private int objectTypeMask = 0;
|
||||
private Bounds bounds;
|
||||
|
||||
// Effects collection for wpak power manager
|
||||
|
||||
public ConcurrentHashMap<engine.wpak.data.Effect, AppliedEffect> _effects = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* No Id Constructor
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,10 @@ import engine.mbEnums.PowerFailCondition;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.ApplyEffectMsg;
|
||||
import engine.objects.*;
|
||||
import engine.objects.AbstractCharacter;
|
||||
import engine.objects.AbstractWorldObject;
|
||||
import engine.objects.Item;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.powers.effectmodifiers.*;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.util.Hasher;
|
||||
@@ -31,6 +34,7 @@ import engine.wpak.data.ConditionEntry;
|
||||
import engine.wpak.data.Effect;
|
||||
import engine.wpak.data.ModifierEntry;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashSet;
|
||||
@@ -148,8 +152,8 @@ public class EffectsBase {
|
||||
|
||||
|
||||
eb.amount = entry.arg;
|
||||
eb.amountRamp = (float) entry.curveType.getValue();
|
||||
eb.useRampAdd = (float) entry.curveType.getValue() != 0;
|
||||
eb.amountRamp = (float) entry.curveType.value;
|
||||
eb.useRampAdd = (float) entry.curveType.value != 0;
|
||||
break;
|
||||
case Attack:
|
||||
eb.cancelOnAttack = true;
|
||||
|
||||
@@ -20,7 +20,6 @@ import engine.powers.EffectsBase;
|
||||
import engine.wpak.data.ModifierEntry;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
public abstract class AbstractEffectModifier {
|
||||
@@ -52,9 +51,9 @@ public abstract class AbstractEffectModifier {
|
||||
this.sourceType = SourceType.GetSourceType(this.type.replace(" ", "").replace("-", ""));
|
||||
this.minMod = mod.min;
|
||||
this.maxMod = mod.max;
|
||||
this.percentMod = mod.value;
|
||||
this.ramp = (float)mod.compoundCurveType.getValue();
|
||||
this.useRampAdd = (float)mod.compoundCurveType.getValue() != 0;
|
||||
this.percentMod = mod.percentage;
|
||||
this.ramp = (float) mod.compoundCurveType.value;
|
||||
this.useRampAdd = (float) mod.compoundCurveType.value != 0;
|
||||
|
||||
this.string1 = mod.arg1;
|
||||
this.string2 = mod.arg2;
|
||||
|
||||
@@ -42,7 +42,7 @@ public class BlockedPowerTypeEffectModifier extends AbstractEffectModifier {
|
||||
|
||||
for (String effect : ac.getEffects().keySet()) {
|
||||
Effect eff = ac.getEffects().get(effect);
|
||||
ModType toBlock = ModType.None;
|
||||
ModType toBlock = null;
|
||||
|
||||
switch (this.sourceType) {
|
||||
case Invisible:
|
||||
@@ -50,6 +50,10 @@ public class BlockedPowerTypeEffectModifier extends AbstractEffectModifier {
|
||||
break;
|
||||
}
|
||||
|
||||
if (toBlock == null)
|
||||
return;
|
||||
;
|
||||
|
||||
HashSet<AbstractEffectModifier> aemList = eff.getEffectModifiers();
|
||||
for (AbstractEffectModifier aem : aemList) {
|
||||
if (aem.modType.equals(toBlock)) {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
package engine.powers.poweractions;
|
||||
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.AbstractCharacter;
|
||||
import engine.objects.AbstractWorldObject;
|
||||
import engine.objects.Item;
|
||||
@@ -24,7 +25,7 @@ public abstract class AbstractPowerAction {
|
||||
protected PowersBase parent;
|
||||
protected int UUID;
|
||||
protected String IDString;
|
||||
protected String type;
|
||||
protected mbEnums.PowerActionType type;
|
||||
protected boolean isAggressive;
|
||||
protected long validItemFlags;
|
||||
|
||||
@@ -46,7 +47,7 @@ public abstract class AbstractPowerAction {
|
||||
this.isAggressive = powerAction.isAggressive;
|
||||
}
|
||||
|
||||
public AbstractPowerAction(int uUID, String iDString, String type, boolean isAggressive,
|
||||
public AbstractPowerAction(int uUID, String iDString, mbEnums.PowerActionType type, boolean isAggressive,
|
||||
long validItemFlags) {
|
||||
super();
|
||||
UUID = uUID;
|
||||
@@ -130,7 +131,7 @@ public abstract class AbstractPowerAction {
|
||||
return this.validItemFlags;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
public mbEnums.PowerActionType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ public class CharmPowerAction extends AbstractPowerAction {
|
||||
public CharmPowerAction(PowerAction powerAction) {
|
||||
super(powerAction);
|
||||
this.levelCap = powerAction.levelCap;
|
||||
this.levelCapRamp = powerAction.levelCurve.ordinal();
|
||||
this.levelCapRamp = powerAction.levelCapCurve.ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -30,7 +30,7 @@ public class FearPowerAction extends AbstractPowerAction {
|
||||
public FearPowerAction(PowerAction powerAction) {
|
||||
super(powerAction);
|
||||
this.levelCap = powerAction.levelCap;
|
||||
this.levelCapRamp = powerAction.levelCurve.ordinal();
|
||||
this.levelCapRamp = powerAction.levelCapCurve.ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -30,7 +30,7 @@ public class OpenGatePowerAction extends AbstractPowerAction {
|
||||
super(powerAction);
|
||||
}
|
||||
|
||||
public OpenGatePowerAction(int uUID, String iDString, String type, boolean isAggressive, long validItemFlags) {
|
||||
public OpenGatePowerAction(int uUID, String iDString, mbEnums.PowerActionType type, boolean isAggressive, long validItemFlags) {
|
||||
super(uUID, iDString, type, isAggressive, validItemFlags);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@@ -44,17 +44,13 @@ public class TransferStatPowerAction extends AbstractPowerAction {
|
||||
this.powerAction = powerAction;
|
||||
this.effectID = powerAction.effects.get(0).effect_id;
|
||||
|
||||
int flags = powerAction.getInt("flags");
|
||||
this.transferRampAdd = ((flags & 4096) != 0) ? true : false;
|
||||
this.transferEfficiencyRampAdd = ((flags & 8192) != 0) ? true : false;
|
||||
this.targetToCaster = ((flags & 16384) != 0) ? true : false;
|
||||
//int flags = powerAction.getInt("flags");
|
||||
this.transferRampAdd = powerAction.statTransfer.rampCurve != null;
|
||||
this.transferEfficiencyRampAdd = powerAction.statTransfer.rampCurve != null;
|
||||
this.targetToCaster = powerAction.statTransfer.isDrain;
|
||||
this.effect = effects.get(this.effectID);
|
||||
try {
|
||||
String damageString = powerAction.getString("damageType");
|
||||
// Damage type can sometimes be null in the DB.
|
||||
|
||||
if (damageString.isEmpty() == false)
|
||||
this.damageType = mbEnums.DamageType.getDamageType(damageString);
|
||||
this.damageType = powerAction.damageType;
|
||||
} catch (Exception e) {
|
||||
this.damageType = null;
|
||||
}
|
||||
@@ -71,13 +67,13 @@ public class TransferStatPowerAction extends AbstractPowerAction {
|
||||
|
||||
public float getTransferAmount(float trains) {
|
||||
// if (this.transferRampAdd)
|
||||
return this.powerAction.statTransfer.fromStatValue + (this.transferRamp * trains);
|
||||
return (float) (this.powerAction.statTransfer.ramp + (this.powerAction.statTransfer.rampCurve.value * trains));
|
||||
// else
|
||||
// return this.transferAmount * (1 + (this.transferRamp * trains));
|
||||
}
|
||||
|
||||
public float getTransferEfficiency(float trains) {
|
||||
return this.transferEfficiency + (this.transferEfficiencyRamp * trains);
|
||||
return (float) (this.powerAction.statTransfer.efficiency + (this.powerAction.statTransfer.efficiencyCurve.value * trains));
|
||||
}
|
||||
|
||||
public boolean targetToCaster() {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2024
|
||||
// www.magicbane.com
|
||||
|
||||
package engine.util;
|
||||
|
||||
public class Pair<A, B> {
|
||||
public A first;
|
||||
public B second;
|
||||
|
||||
public Pair(A first, B second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Pair{" + "first=" + first + ", second=" + second + '}';
|
||||
}
|
||||
}
|
||||
@@ -13,12 +13,16 @@ import engine.mbEnums;
|
||||
import engine.wpak.data.ConditionEntry;
|
||||
import engine.wpak.data.Effect;
|
||||
import engine.wpak.data.ModifierEntry;
|
||||
import engine.wpakpowers.WpakPowerManager;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -50,8 +54,12 @@ public class EffectsParser {
|
||||
Matcher matcher = EFFECT_REGEX.matcher(fileContents);
|
||||
|
||||
while (matcher.find()) {
|
||||
Effect effect = parseEffectEntry(matcher.group());
|
||||
WpakPowerManager.effect_data.put(effect.effect_id, effect);
|
||||
try {
|
||||
Effect effect = parseEffectEntry(matcher.group());
|
||||
WpakPowerManager._effectsLookup.put(effect.effect_id, effect);
|
||||
}catch(Exception e){
|
||||
Logger.error("EFFECT PARSE FAILED: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,8 +181,8 @@ public class EffectsParser {
|
||||
case Stamina:
|
||||
modifierEntry.min = Float.parseFloat(modValues.get(1).trim());
|
||||
modifierEntry.max = Float.parseFloat(modValues.get(2).trim());
|
||||
modifierEntry.value = Float.parseFloat(modValues.get(3).trim());
|
||||
// Parameter 4 is always 0.
|
||||
modifierEntry.percentage = Float.parseFloat(modValues.get(3).trim());
|
||||
modifierEntry.value = Float.parseFloat(modValues.get(4).trim()); // Always zero
|
||||
modifierEntry.compoundCurveType = mbEnums.CompoundCurveType.valueOf(modValues.get(5).trim());
|
||||
modifierEntry.arg1 = modValues.get(6).trim();
|
||||
break;
|
||||
|
||||
@@ -15,6 +15,7 @@ import engine.wpak.data.Effect;
|
||||
import engine.wpak.data.PowerAction;
|
||||
import engine.wpak.data.StatTransfer;
|
||||
import engine.wpak.data.TrackEntry;
|
||||
import engine.wpakpowers.WpakPowerManager;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -53,7 +54,7 @@ public class PowerActionParser {
|
||||
while (matcher.find()) {
|
||||
|
||||
PowerAction powerAction = parsePowerActionEntry(matcher.group().trim());
|
||||
WpakPowerManager.power_actions.put(Hasher.SBStringHash(powerAction.action_id),powerAction);
|
||||
WpakPowerManager._powerActionLookup.put(Hasher.SBStringHash(powerAction.action_id), powerAction);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,26 +84,26 @@ public class PowerActionParser {
|
||||
|
||||
Iterator<String> headerIterator = headerData.iterator();
|
||||
powerAction.action_id = headerIterator.next();
|
||||
powerAction.action_type = headerIterator.next();
|
||||
powerAction.action_type = mbEnums.PowerActionType.valueOf(headerIterator.next());
|
||||
|
||||
switch (powerAction.action_type) {
|
||||
case "RemoveEffect":
|
||||
case RemoveEffect:
|
||||
effect = new Effect();
|
||||
effect.effect_id = headerIterator.next();
|
||||
powerAction.effects.add(effect);
|
||||
break;
|
||||
case "CreateMob":
|
||||
case CreateMob:
|
||||
powerAction.petRace = Integer.parseInt(headerIterator.next());
|
||||
powerAction.petLevel = Integer.parseInt(headerIterator.next());
|
||||
break;
|
||||
case "DamageOverTime":
|
||||
case DamageOverTime:
|
||||
effect = new Effect();
|
||||
effect.effect_id = headerIterator.next();
|
||||
effect.cycleDuration = Integer.parseInt(headerIterator.next());
|
||||
effect.cycleDelay = Integer.parseInt(headerIterator.next());
|
||||
powerAction.effects.add(effect);
|
||||
break;
|
||||
case "ApplyEffects":
|
||||
case ApplyEffects:
|
||||
int level = Integer.parseInt(headerIterator.next());
|
||||
|
||||
while (headerIterator.hasNext()) {
|
||||
@@ -112,12 +113,12 @@ public class PowerActionParser {
|
||||
powerAction.effects.add(effect);
|
||||
}
|
||||
break;
|
||||
case "Transform":
|
||||
case "Invis":
|
||||
case "ApplyEffect":
|
||||
case "DeferredPower":
|
||||
case "DirectDamage":
|
||||
case "SpireDisable":
|
||||
case Transform:
|
||||
case Invis:
|
||||
case ApplyEffect:
|
||||
case DeferredPower:
|
||||
case DirectDamage:
|
||||
case SpireDisable:
|
||||
while (headerIterator.hasNext()) {
|
||||
effect = new Effect();
|
||||
effect.effect_id = headerIterator.next();
|
||||
@@ -130,52 +131,52 @@ public class PowerActionParser {
|
||||
powerAction.effects.add(effect);
|
||||
}
|
||||
break;
|
||||
case "TransferStat":
|
||||
case TransferStat:
|
||||
statTransfer = new StatTransfer();
|
||||
statTransfer.fromStat = mbEnums.CostType.valueOf(headerIterator.next());
|
||||
statTransfer.toStat = mbEnums.CostType.valueOf(headerIterator.next());
|
||||
statTransfer.fromStatValue = Float.parseFloat(headerIterator.next());
|
||||
statTransfer.fromCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
|
||||
statTransfer.toStatValue = Float.parseFloat(headerIterator.next());
|
||||
statTransfer.toCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
|
||||
statTransfer.ramp = Float.parseFloat(headerIterator.next());
|
||||
statTransfer.rampCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
|
||||
statTransfer.efficiency = Float.parseFloat(headerIterator.next());
|
||||
statTransfer.efficiencyCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
|
||||
statTransfer.fromStatBool = Boolean.parseBoolean(headerIterator.next());
|
||||
statTransfer.toStatBool = Boolean.parseBoolean(headerIterator.next());
|
||||
statTransfer.isDrain = Boolean.parseBoolean(headerIterator.next());
|
||||
powerAction.statTransfer = statTransfer;
|
||||
break;
|
||||
case "TransferStatOT":
|
||||
case TransferStatOT:
|
||||
statTransfer = new StatTransfer();
|
||||
statTransfer.fromStat = mbEnums.CostType.valueOf(headerIterator.next());
|
||||
statTransfer.toStat = mbEnums.CostType.valueOf(headerIterator.next());
|
||||
statTransfer.fromStatValue = Float.parseFloat(headerIterator.next());
|
||||
statTransfer.fromCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
|
||||
statTransfer.toStatValue = Float.parseFloat(headerIterator.next());
|
||||
statTransfer.toCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
|
||||
statTransfer.ramp = Float.parseFloat(headerIterator.next());
|
||||
statTransfer.rampCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
|
||||
statTransfer.efficiency = Float.parseFloat(headerIterator.next());
|
||||
statTransfer.efficiencyCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
|
||||
statTransfer.fromStatBool = Boolean.parseBoolean(headerIterator.next());
|
||||
statTransfer.toStatBool = Boolean.parseBoolean(headerIterator.next());
|
||||
statTransfer.isDrain = Boolean.parseBoolean(headerIterator.next());
|
||||
statTransfer.transfer_action = headerIterator.next();
|
||||
statTransfer.transfer_ticks = Integer.parseInt(headerIterator.next());
|
||||
powerAction.statTransfer = statTransfer;
|
||||
break;
|
||||
case "Charm":
|
||||
case Charm:
|
||||
effect = new Effect();
|
||||
effect.effect_id = headerIterator.next();
|
||||
effect.level = Integer.parseInt(headerIterator.next());
|
||||
effect.type = headerIterator.next();
|
||||
powerAction.effects.add(effect);
|
||||
break;
|
||||
case "Block":
|
||||
case Block:
|
||||
effect = new Effect();
|
||||
effect.effect_id = headerIterator.next();
|
||||
effect.level = Integer.parseInt(headerIterator.next());
|
||||
powerAction.effects.add(effect);
|
||||
break;
|
||||
case "Resurrect":
|
||||
case Resurrect:
|
||||
powerAction.levelCap = Integer.parseInt(headerIterator.next());
|
||||
break;
|
||||
case "SetItemFlag":
|
||||
case SetItemFlag:
|
||||
powerAction.itemFlag = mbEnums.ItemFlags.valueOf(headerIterator.next());
|
||||
break;
|
||||
case "Track":
|
||||
case Track:
|
||||
trackEntry = new TrackEntry();
|
||||
trackEntry.action_id = headerIterator.next();
|
||||
trackEntry.trackPlayer = Boolean.parseBoolean(headerIterator.next());
|
||||
@@ -185,21 +186,21 @@ public class PowerActionParser {
|
||||
trackEntry.max = Integer.parseInt(headerIterator.next());
|
||||
powerAction.trackEntry = trackEntry;
|
||||
break;
|
||||
case "Teleport":
|
||||
case Teleport:
|
||||
if (headerIterator.hasNext())
|
||||
powerAction.ignoreNoTeleSpire = Boolean.parseBoolean(headerIterator.next());
|
||||
break;
|
||||
case "Recall": // No arguments for these tags or not parsed
|
||||
case "Summon":
|
||||
case "TreeChoke":
|
||||
case "SimpleDamage":
|
||||
case "MobRecall": // One argument always zero
|
||||
case "ClearAggro":
|
||||
case "ClearNearbyAggro":
|
||||
case "Peek":
|
||||
case "ClaimMine":
|
||||
case "RunegateTeleport":
|
||||
case "Steal":
|
||||
case Recall: // No arguments for these tags or not parsed
|
||||
case Summon:
|
||||
case TreeChoke:
|
||||
case SimpleDamage:
|
||||
case MobRecall: // One argument always zero
|
||||
case ClearAggro:
|
||||
case ClearNearbyAggro:
|
||||
case Peek:
|
||||
case ClaimMine:
|
||||
case RunegateTeleport:
|
||||
case Steal:
|
||||
break;
|
||||
default:
|
||||
Logger.error("Unhandled type " + powerAction.action_type + " for Pow4erAction: " + powerAction.action_id);
|
||||
@@ -273,7 +274,7 @@ public class PowerActionParser {
|
||||
powerAction.levelCap = Integer.parseInt(arguments.get(0));
|
||||
|
||||
if (arguments.size() > 1) // Not all level caps have a curve
|
||||
powerAction.levelCurve = mbEnums.CompoundCurveType.valueOf(arguments.get(1));
|
||||
powerAction.levelCapCurve = mbEnums.CompoundCurveType.valueOf(arguments.get(1));
|
||||
break;
|
||||
case "CLEARAGGRO":
|
||||
powerAction.clearAggro = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
|
||||
+143
-137
@@ -12,6 +12,7 @@ import engine.gameManager.ConfigManager;
|
||||
import engine.mbEnums;
|
||||
import engine.util.Hasher;
|
||||
import engine.wpak.data.*;
|
||||
import engine.wpakpowers.WpakPowerManager;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -51,7 +52,7 @@ public class PowersParser {
|
||||
while (matcher.find()) {
|
||||
|
||||
Power power = parsePowerEntry(matcher.group().trim());
|
||||
WpakPowerManager.powers.put(Hasher.SBStringHash(power.power_id),power);
|
||||
WpakPowerManager._powersLookup.put(Hasher.SBStringHash(power.power_id), power);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +106,7 @@ public class PowersParser {
|
||||
PowerEntry power = new PowerEntry();
|
||||
power.power_type = mbEnums.PowerType.valueOf(iterator.next());
|
||||
power.icon = Integer.parseInt(iterator.next());
|
||||
power.powerBase = iterator.next().replaceAll("\"", "");
|
||||
power.focusLine = iterator.next().replaceAll("\"", "");
|
||||
powerEntry.powers.add(power);
|
||||
|
||||
String nextValue = iterator.next();
|
||||
@@ -116,7 +117,7 @@ public class PowersParser {
|
||||
power = new PowerEntry();
|
||||
power.power_type = mbEnums.PowerType.valueOf(nextValue);
|
||||
power.icon = Integer.parseInt(iterator.next());
|
||||
power.powerBase = iterator.next().replaceAll("\"", "");
|
||||
power.focusLine = iterator.next().replaceAll("\"", "");
|
||||
powerEntry.powers.add(power);
|
||||
powerEntry.target_type = mbEnums.PowerTargetType.valueOf(iterator.next());
|
||||
} else
|
||||
@@ -154,147 +155,152 @@ public class PowersParser {
|
||||
List<String> arguments;
|
||||
Matcher argumentMatcher;
|
||||
|
||||
switch (key) {
|
||||
case "ACTION":
|
||||
actionEntry = new ActionEntry();
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
actionEntry.effect_id = arguments.get(0);
|
||||
actionEntry.minTrains = Integer.parseInt(arguments.get(1));
|
||||
actionEntry.maxTrains = Integer.parseInt(arguments.get(2));
|
||||
actionEntry.duration = Float.parseFloat(arguments.get(3));
|
||||
actionEntry.curve = mbEnums.CompoundCurveType.valueOf(arguments.get(4));
|
||||
actionEntry.stackingCategory = arguments.get(5);
|
||||
actionEntry.stackingPriority = Integer.parseInt(arguments.get(6));
|
||||
actionEntry.categoryToPower = mbEnums.CategoryToPowerType.valueOf(arguments.get(7));
|
||||
powerEntry.actionEntries.add(actionEntry);
|
||||
break;
|
||||
case "MaxLevel":
|
||||
powerEntry.maxLevel = Integer.parseInt(lineValues.get(1).trim());
|
||||
break;
|
||||
case "HateValue":
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
powerEntry.hateValue = Integer.parseInt(arguments.get(0));
|
||||
switch (key) {
|
||||
case "ACTION":
|
||||
actionEntry = new ActionEntry();
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
actionEntry.action_id = arguments.get(0);
|
||||
actionEntry.minTrains = Integer.parseInt(arguments.get(1));
|
||||
actionEntry.maxTrains = Integer.parseInt(arguments.get(2));
|
||||
actionEntry.duration = Float.parseFloat(arguments.get(3));
|
||||
actionEntry.curve = mbEnums.CompoundCurveType.valueOf(arguments.get(4));
|
||||
actionEntry.stackingCategory = arguments.get(5);
|
||||
actionEntry.stackingPriority = Integer.parseInt(arguments.get(6));
|
||||
actionEntry.categoryToPower = mbEnums.CategoryToPowerType.valueOf(arguments.get(7));
|
||||
powerEntry.actionEntries.add(actionEntry);
|
||||
break;
|
||||
case "MaxLevel":
|
||||
powerEntry.maxLevel = Integer.parseInt(lineValues.get(1).trim());
|
||||
break;
|
||||
case "HateValue":
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
powerEntry.hateValue = Integer.parseInt(arguments.get(0));
|
||||
|
||||
// Not all entries have a curve. Defaults to DefaultFlat;
|
||||
// Not all entries have a curve. Defaults to DefaultFlat;
|
||||
|
||||
if (arguments.size() > 1)
|
||||
powerEntry.hateCurve = mbEnums.CompoundCurveType.valueOf(arguments.get(1));
|
||||
break;
|
||||
case "LOOPANIMID":
|
||||
powerEntry.loopAnimID = Integer.parseInt(lineValues.get(1).trim());
|
||||
break;
|
||||
case "GRANTOVERRIDEVAR":
|
||||
powerEntry.grantOverrideVar = lineValues.get(1).trim();
|
||||
break;
|
||||
case "DESCRIPTION":
|
||||
powerEntry.description.add(lineValues.get(1).trim());
|
||||
break;
|
||||
case "CATEGORY":
|
||||
powerEntry.category = lineValues.get(1).trim();
|
||||
break;
|
||||
case "CURVE":
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
powerEntry.curves.put(arguments.get(0), mbEnums.CompoundCurveType.valueOf(arguments.get(1)));
|
||||
break;
|
||||
case "EQPREREQ":
|
||||
argumentMatcher = STRSPLIT_REGEX.matcher(lineValues.get(1).trim());
|
||||
arguments = new ArrayList<>();
|
||||
if (arguments.size() > 1)
|
||||
powerEntry.hateCurve = mbEnums.CompoundCurveType.valueOf(arguments.get(1));
|
||||
break;
|
||||
case "LOOPANIMID":
|
||||
powerEntry.loopAnimID = Integer.parseInt(lineValues.get(1).trim());
|
||||
break;
|
||||
case "GRANTOVERRIDEVAR":
|
||||
powerEntry.grantOverrideVar = lineValues.get(1).trim();
|
||||
break;
|
||||
case "DESCRIPTION":
|
||||
powerEntry.description.add(lineValues.get(1).trim());
|
||||
break;
|
||||
case "CATEGORY":
|
||||
powerEntry.category = mbEnums.PowerCategoryType.valueOf(lineValues.get(1).trim());
|
||||
break;
|
||||
case "CURVE":
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
powerEntry.curves.put(arguments.get(0), mbEnums.CompoundCurveType.valueOf(arguments.get(1)));
|
||||
break;
|
||||
case "EQPREREQ":
|
||||
argumentMatcher = STRSPLIT_REGEX.matcher(lineValues.get(1).trim());
|
||||
arguments = new ArrayList<>();
|
||||
|
||||
while (argumentMatcher.find())
|
||||
arguments.add(argumentMatcher.group().trim());
|
||||
while (argumentMatcher.find())
|
||||
arguments.add(argumentMatcher.group().trim());
|
||||
|
||||
argumentIterator = arguments.iterator();
|
||||
argumentIterator = arguments.iterator();
|
||||
|
||||
while (argumentIterator.hasNext()) {
|
||||
EquipmentPreReq equipmentPreReq = new EquipmentPreReq();
|
||||
equipmentPreReq.slot = mbEnums.EquipSlotType.valueOf(arguments.get(0));
|
||||
equipmentPreReq.skill = arguments.get(1).replaceAll("\"", "");
|
||||
equipmentPreReq.required = Integer.parseInt(arguments.get(2));
|
||||
powerEntry.equipmentPreReq.add(equipmentPreReq);
|
||||
}
|
||||
break;
|
||||
case "CANCASTWHILEMOVING":
|
||||
powerEntry.canCastWhileMoving = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "CANCASTWHILEFLYING":
|
||||
powerEntry.canCastWhileFlying = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "BLADETRAILS":
|
||||
powerEntry.bladeTrails = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "EFFECTPREREQ":
|
||||
Effect effectPreReq = new Effect();
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
effectPreReq.effect_id = arguments.get(9);
|
||||
effectPreReq.level = Integer.parseInt(arguments.get(1));
|
||||
effectPreReq.message = arguments.get(2);
|
||||
powerEntry.effectPreReqs.add(effectPreReq);
|
||||
break;
|
||||
case "MONSTERTYPERESTRICTS":
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
while (argumentIterator.hasNext()) {
|
||||
EquipmentPreReq equipmentPreReq = new EquipmentPreReq();
|
||||
equipmentPreReq.slot = mbEnums.EquipSlotType.valueOf(argumentIterator.next());
|
||||
equipmentPreReq.skill = argumentIterator.next().replaceAll("\"", "");
|
||||
|
||||
for (String restriction : arguments)
|
||||
powerEntry.monsterRestricts.add(mbEnums.MonsterType.valueOf(restriction.trim()));
|
||||
break;
|
||||
case "MONSTERTYPEPREREQS":
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
if (argumentIterator.hasNext())
|
||||
equipmentPreReq.required = Integer.parseInt(argumentIterator.next());
|
||||
else
|
||||
equipmentPreReq.required = 0;
|
||||
|
||||
for (String restriction : arguments)
|
||||
powerEntry.monsterPrereqs.add(mbEnums.MonsterType.valueOf(restriction.trim()));
|
||||
break;
|
||||
case "SHOULDCHECKPATH":
|
||||
powerEntry.shouldCheckPath = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "STICKY":
|
||||
powerEntry.sticky = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "PULSEINFO":
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
powerEntry.pulseCycle = Integer.parseInt(arguments.get(0));
|
||||
powerEntry.pulseDuration = Integer.parseInt(arguments.get(1));
|
||||
break;
|
||||
case "MAXNUMMOBTARGETS":
|
||||
powerEntry.maxMobTargets = Integer.parseInt(lineValues.get(1).trim());
|
||||
break;
|
||||
case "MAXNUMPLAYERTARGETS":
|
||||
powerEntry.maxPlayerTargets = Integer.parseInt(lineValues.get(1).trim());
|
||||
break;
|
||||
case "ISADMINPOWER":
|
||||
powerEntry.isAdminPower = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "ISPROJECTILE":
|
||||
powerEntry.isProjectile = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "CASTERSPULSEPARTICLE":
|
||||
powerEntry.casterPulseParticle = Integer.parseInt(lineValues.get(1).trim());
|
||||
break;
|
||||
case "TARGETEFFECTPREREQS_ORED":
|
||||
Effect preReq = new Effect();
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
preReq.effect_id = arguments.get(0);
|
||||
preReq.level = Integer.parseInt(arguments.get(1));
|
||||
powerEntry.targetEffectPrereqs.add(preReq);
|
||||
break;
|
||||
case "SOUNDS": // Values not parsed
|
||||
case "APPLYDAMAGESELF":
|
||||
case "APPLYDAMAGECASTER":
|
||||
case "APPLYDAMAGEOTHER":
|
||||
case "APPLYDAMAGETARGET":
|
||||
case "APPLYEFFECTSELF":
|
||||
case "APPLYEFFECTOTHER":
|
||||
case "APPLYEFFECTCASTER":
|
||||
case "APPLYEFFECTTARGET":
|
||||
case "FIZZLEOTHER":
|
||||
case "FIZZLESELF":
|
||||
case "INITSTRING":
|
||||
case "SUCCESSOTHER":
|
||||
case "SUCCESSSELF":
|
||||
case "WEAROFFEFFECTOTHER":
|
||||
case "WEAROFFEFFECTSELF":
|
||||
break;
|
||||
default:
|
||||
Logger.error("Unhandled variable type:" + key + " for power: " + powerEntry.power_id);
|
||||
}
|
||||
powerEntry.equipmentPreReq.add(equipmentPreReq);
|
||||
}
|
||||
break;
|
||||
case "CANCASTWHILEMOVING":
|
||||
powerEntry.canCastWhileMoving = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "CANCASTWHILEFLYING":
|
||||
powerEntry.canCastWhileFlying = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "BLADETRAILS":
|
||||
powerEntry.bladeTrails = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "EFFECTPREREQ":
|
||||
Effect effectPreReq = new Effect();
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
effectPreReq.effect_id = arguments.get(9);
|
||||
effectPreReq.level = Integer.parseInt(arguments.get(1));
|
||||
effectPreReq.message = arguments.get(2);
|
||||
powerEntry.effectPreReqs.add(effectPreReq);
|
||||
break;
|
||||
case "MONSTERTYPERESTRICTS":
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
|
||||
for (String restriction : arguments)
|
||||
powerEntry.monsterRestricts.add(mbEnums.MonsterType.valueOf(restriction.trim()));
|
||||
break;
|
||||
case "MONSTERTYPEPREREQS":
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
|
||||
for (String restriction : arguments)
|
||||
powerEntry.monsterPrereqs.add(mbEnums.MonsterType.valueOf(restriction.trim()));
|
||||
break;
|
||||
case "SHOULDCHECKPATH":
|
||||
powerEntry.shouldCheckPath = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "STICKY":
|
||||
powerEntry.sticky = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "PULSEINFO":
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
powerEntry.pulseCycle = Integer.parseInt(arguments.get(0));
|
||||
powerEntry.pulseDuration = Integer.parseInt(arguments.get(1));
|
||||
break;
|
||||
case "MAXNUMMOBTARGETS":
|
||||
powerEntry.maxMobTargets = Integer.parseInt(lineValues.get(1).trim());
|
||||
break;
|
||||
case "MAXNUMPLAYERTARGETS":
|
||||
powerEntry.maxPlayerTargets = Integer.parseInt(lineValues.get(1).trim());
|
||||
break;
|
||||
case "ISADMINPOWER":
|
||||
powerEntry.isAdminPower = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "ISPROJECTILE":
|
||||
powerEntry.isProjectile = Boolean.parseBoolean(lineValues.get(1).trim());
|
||||
break;
|
||||
case "CASTERSPULSEPARTICLE":
|
||||
powerEntry.casterPulseParticle = Integer.parseInt(lineValues.get(1).trim());
|
||||
break;
|
||||
case "TARGETEFFECTPREREQS_ORED":
|
||||
Effect preReq = new Effect();
|
||||
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
|
||||
preReq.effect_id = arguments.get(0);
|
||||
preReq.level = Integer.parseInt(arguments.get(1));
|
||||
powerEntry.targetEffectPrereqs.add(preReq);
|
||||
break;
|
||||
case "SOUNDS": // Values not parsed
|
||||
case "APPLYDAMAGESELF":
|
||||
case "APPLYDAMAGECASTER":
|
||||
case "APPLYDAMAGEOTHER":
|
||||
case "APPLYDAMAGETARGET":
|
||||
case "APPLYEFFECTSELF":
|
||||
case "APPLYEFFECTOTHER":
|
||||
case "APPLYEFFECTCASTER":
|
||||
case "APPLYEFFECTTARGET":
|
||||
case "FIZZLEOTHER":
|
||||
case "FIZZLESELF":
|
||||
case "INITSTRING":
|
||||
case "SUCCESSOTHER":
|
||||
case "SUCCESSSELF":
|
||||
case "WEAROFFEFFECTOTHER":
|
||||
case "WEAROFFEFFECTSELF":
|
||||
break;
|
||||
default:
|
||||
Logger.error("Unhandled variable type:" + key + " for power: " + powerEntry.power_id);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse power conditions
|
||||
|
||||
@@ -1,376 +0,0 @@
|
||||
package engine.wpak;
|
||||
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.gameManager.*;
|
||||
import engine.job.JobContainer;
|
||||
import engine.job.JobScheduler;
|
||||
import engine.jobs.FinishRecycleTimeJob;
|
||||
import engine.jobs.UsePowerJob;
|
||||
import engine.jobs.WpakUsePowerJob;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.mbEnums;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.ModifyHealthMsg;
|
||||
import engine.net.client.msg.PerformActionMsg;
|
||||
import engine.net.client.msg.RecyclePowerMsg;
|
||||
import engine.net.client.msg.UpdateStateMsg;
|
||||
import engine.objects.*;
|
||||
import engine.powers.PowersBase;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.util.Hasher;
|
||||
import engine.wpak.data.*;
|
||||
import engine.wpak.data.Effect;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static engine.math.FastMath.sqr;
|
||||
|
||||
public class WpakPowerManager {
|
||||
public static HashMap<String, Effect> effect_data = new HashMap<>();
|
||||
public static HashMap<Integer, PowerAction> power_actions= new HashMap<>();
|
||||
public static HashMap<Integer, Power> powers= new HashMap<>();
|
||||
|
||||
private static JobScheduler js;
|
||||
|
||||
public static void usePower(final PerformActionMsg msg, ClientConnection origin, boolean sendCastToSelf) {
|
||||
|
||||
if (ConfigManager.MB_RULESET.getValue().equals("LORE")) {
|
||||
PowersBase pb = PowersManager.powersBaseByToken.get(msg.getPowerUsedID());
|
||||
PlayerCharacter caster = origin.getPlayerCharacter();
|
||||
PlayerCharacter target = PlayerCharacter.getFromCache(msg.getTargetID());
|
||||
if (pb != null && pb.enforceLore()) {
|
||||
//if (caster.guild.equals(Guild.getErrantGuild()))
|
||||
// return;
|
||||
|
||||
if (target != null && caster.guild.getGuildType().equals(target.guild.getGuildType()) == false && target.getObjectType().equals(mbEnums.GameObjectType.Building) == false) {
|
||||
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
|
||||
Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), recyclePowerMsg);
|
||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
|
||||
|
||||
// Send Fail to cast message
|
||||
PlayerCharacter pc = SessionManager
|
||||
.getPlayerCharacter(origin);
|
||||
|
||||
if (pc != null) {
|
||||
sendPowerMsg(pc, 2, msg);
|
||||
if (pc.isCasting()) {
|
||||
pc.update();
|
||||
}
|
||||
|
||||
pc.setIsCasting(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (castPower(msg, origin, sendCastToSelf)) {
|
||||
// Cast failed for some reason, reset timer
|
||||
|
||||
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
|
||||
Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), recyclePowerMsg);
|
||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
|
||||
|
||||
// Send Fail to cast message
|
||||
PlayerCharacter pc = SessionManager
|
||||
.getPlayerCharacter(origin);
|
||||
|
||||
if (pc != null) {
|
||||
sendPowerMsg(pc, 2, msg);
|
||||
if (pc.isCasting()) {
|
||||
pc.update();
|
||||
}
|
||||
|
||||
pc.setIsCasting(false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean castPower(final PerformActionMsg msg, ClientConnection origin, boolean sendCastToSelf) {
|
||||
|
||||
//check to see if the caster is valid
|
||||
PlayerCharacter playerCharacter = SessionManager.getPlayerCharacter(origin);
|
||||
if (playerCharacter == null)
|
||||
return false;
|
||||
|
||||
//make sure player is still alive
|
||||
if (!playerCharacter.isAlive() && msg.getPowerUsedID() != 428589216) { //succor
|
||||
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
|
||||
Dispatch dispatch = Dispatch.borrow(playerCharacter, recyclePowerMsg);
|
||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
|
||||
return false;
|
||||
}
|
||||
|
||||
//make sure the recycle timer has actually elapsed
|
||||
if (playerCharacter.getRecycleTimers().containsKey(msg.getPowerUsedID())) {
|
||||
Logger.warn("usePowerA(): Cheat attempted? '" + msg.getPowerUsedID() + "' recycle timer not finished " + playerCharacter.getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
//lookup the power that was cast
|
||||
Power powerCast = powers.get(msg.getPowerUsedID());
|
||||
if (powerCast == null) {
|
||||
ChatManager.chatSayInfo(playerCharacter, "This power is not implemented yet.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (playerCharacter.getLastPower() != null)
|
||||
return true;
|
||||
|
||||
// get numTrains for power
|
||||
int trains = msg.getNumTrains();
|
||||
|
||||
if (trains > powerCast.maxLevel) {
|
||||
trains = powerCast.maxLevel;
|
||||
msg.setNumTrains(trains);
|
||||
}
|
||||
|
||||
//sanity check for amount of trains in spell cast
|
||||
if (playerCharacter.getPowers() != null && playerCharacter.getPowers().containsKey(msg.getPowerUsedID())) {
|
||||
CharacterPower cp = playerCharacter.getPowers().get(msg.getPowerUsedID());
|
||||
if (cp != null) {
|
||||
int tot = cp.getTotalTrains();
|
||||
if (tot == 0)
|
||||
return false;
|
||||
if (trains != tot) {
|
||||
trains = tot;
|
||||
msg.setNumTrains(trains);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//get casting time
|
||||
int time = powerCast.getRecycleTime(trains);
|
||||
|
||||
//combat mode sanity check
|
||||
if (playerCharacter.isCombat()) {
|
||||
if (!powerCast.allowedInCombat())
|
||||
return true;
|
||||
} else if (!powerCast.allowedOutOfCombat())
|
||||
return true;
|
||||
|
||||
//stunned check
|
||||
PlayerBonuses bonus = playerCharacter.getBonuses();
|
||||
mbEnums.SourceType sourceType = mbEnums.SourceType.GetSourceType(powerCast.category);
|
||||
if (bonus != null && (bonus.getBool(mbEnums.ModType.Stunned, mbEnums.SourceType.None) || bonus.getBool(mbEnums.ModType.CannotCast, mbEnums.SourceType.None) || bonus.getBool(mbEnums.ModType.BlockedPowerType, sourceType)))
|
||||
return true;
|
||||
|
||||
//sanity check for casting while moving
|
||||
Vector3fImmutable endLoc = playerCharacter.getEndLoc();
|
||||
|
||||
if (!powerCast.canCastWhileMoving)
|
||||
if (playerCharacter.isMoving()) {
|
||||
float distanceLeftSquared = endLoc.distanceSquared2D(playerCharacter.getLoc());
|
||||
if (distanceLeftSquared > sqr(playerCharacter.getSpeed()))
|
||||
return true;
|
||||
}
|
||||
|
||||
//get the actual target form the message
|
||||
int type = msg.getTargetType();
|
||||
int UUID = msg.getTargetID();
|
||||
|
||||
if (type == -1 || type == 0 || UUID == -1 || UUID == 0)
|
||||
return true;
|
||||
|
||||
AbstractWorldObject target = (AbstractWorldObject) DbManager.getObject(mbEnums.GameObjectType.values()[type], UUID);
|
||||
|
||||
//check to make sure power can be cast on building if target is a building
|
||||
if (target != null && target.getObjectType() == mbEnums.GameObjectType.Building && !powerCast.target_type.equals(mbEnums.PowerTargetType.BUILDING)) {
|
||||
PowersManager.sendPowerMsg(playerCharacter, 9, new PerformActionMsg(msg));
|
||||
return true;
|
||||
}
|
||||
|
||||
//validate casting range
|
||||
if (playerCharacter.getLoc().distanceSquared2D(msg.getTargetLoc()) > (powerCast.range * powerCast.range))
|
||||
return true;
|
||||
|
||||
//validate prereqs for power cast
|
||||
//equipment prereqs
|
||||
if (!powerCast.equipmentPreReq.isEmpty()) {
|
||||
for (EquipmentPreReq prereq : powerCast.equipmentPreReq) {
|
||||
String requiredSkill = prereq.skill;
|
||||
if (playerCharacter.charItemManager.equipped.get(prereq.slot) != null) {
|
||||
Item equippedItem = playerCharacter.charItemManager.equipped.get(prereq.slot);
|
||||
if (!equippedItem.template.item_skill_mastery_used.equals(requiredSkill) && !equippedItem.template.item_skill_used.equals(requiredSkill))
|
||||
return true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//effect prereqs
|
||||
if (!powerCast.effectPreReqs.isEmpty()) {
|
||||
for (Effect prereq : powerCast.effectPreReqs) {
|
||||
if (!playerCharacter.effects.contains(prereq.effect_id) && !playerCharacter.effects.contains(prereq.effect_name))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
float cost = powerCast.getCost(trains);
|
||||
if (bonus != null)
|
||||
cost *= (1 + bonus.getFloatPercentAll(mbEnums.ModType.PowerCost, mbEnums.SourceType.None));
|
||||
|
||||
if (playerCharacter.getAltitude() > 0)
|
||||
cost *= 1.5f;
|
||||
|
||||
if (cost > 0)
|
||||
if ((playerCharacter.getObjectTypeMask() & MBServerStatics.MASK_UNDEAD) != 0)
|
||||
if (playerCharacter.getHealth() <= cost)
|
||||
return true;
|
||||
else {
|
||||
playerCharacter.modifyHealth(-cost, playerCharacter, true);
|
||||
ModifyHealthMsg mhm = new ModifyHealthMsg(playerCharacter, playerCharacter, -cost,
|
||||
0f, 0f, 0, null,
|
||||
9999, 0);
|
||||
mhm.setOmitFromChat(1);
|
||||
DispatchManager.dispatchMsgToInterestArea(playerCharacter, mhm, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
|
||||
}
|
||||
else if (powerCast.costType.name().equals("MANA"))
|
||||
if (playerCharacter.getMana() < cost)
|
||||
return true;
|
||||
else
|
||||
playerCharacter.modifyMana(-cost, playerCharacter, true);
|
||||
else if (powerCast.costType.name().equals("STAMINA"))
|
||||
if (playerCharacter.getStamina() < cost)
|
||||
return true;
|
||||
else
|
||||
playerCharacter.modifyStamina(-cost, playerCharacter, true);
|
||||
else if (playerCharacter.getHealth() <= cost)
|
||||
return true;
|
||||
else
|
||||
playerCharacter.modifyHealth(-cost, playerCharacter, true);
|
||||
|
||||
if (time > 0) {
|
||||
FinishRecycleTimeJob frtj = new FinishRecycleTimeJob(playerCharacter, msg);
|
||||
playerCharacter.getRecycleTimers().put(msg.getPowerUsedID(), js.scheduleJob(frtj, time));
|
||||
} else {
|
||||
// else send recycle message to unlock power
|
||||
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
|
||||
Dispatch dispatch = Dispatch.borrow(playerCharacter, recyclePowerMsg);
|
||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
|
||||
}
|
||||
int tr = msg.getNumTrains();
|
||||
DispatchManager.dispatchMsgToInterestArea(playerCharacter, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, sendCastToSelf, false);
|
||||
|
||||
//Make new msg..
|
||||
PerformActionMsg copyMsg = new PerformActionMsg(msg);
|
||||
copyMsg.setNumTrains(tr);
|
||||
|
||||
// make person casting stand up if spell (unless they're casting a chant which does not make them stand up)
|
||||
if (powerCast.isSpell() && !powerCast.isChant() && playerCharacter.isSit()) {
|
||||
playerCharacter.update();
|
||||
playerCharacter.setSit(false);
|
||||
UpdateStateMsg updateStateMsg = new UpdateStateMsg(playerCharacter);
|
||||
DispatchManager.dispatchMsgToInterestArea(playerCharacter, updateStateMsg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
|
||||
|
||||
}
|
||||
|
||||
// update cast (use skill) fail condition
|
||||
playerCharacter.cancelOnCast();
|
||||
|
||||
// update castSpell (use spell) fail condition if spell
|
||||
if (powerCast.isSpell())
|
||||
playerCharacter.cancelOnSpell();
|
||||
|
||||
// get cast time in ms.
|
||||
time = powerCast.getCastTime(trains);
|
||||
|
||||
// set player is casting for regens
|
||||
|
||||
|
||||
if (time > 100) {
|
||||
playerCharacter.update();
|
||||
playerCharacter.setIsCasting(true);
|
||||
}
|
||||
|
||||
|
||||
playerCharacter.setLastMovementState(playerCharacter.getMovementState());
|
||||
|
||||
// run timer job to end cast
|
||||
if (time < 1) // run immediately
|
||||
finishUsePower(copyMsg, playerCharacter, target);
|
||||
else {
|
||||
WpakUsePowerJob upj = new WpakUsePowerJob(playerCharacter, copyMsg, target);
|
||||
JobContainer jc = js.scheduleJob(upj, time);
|
||||
|
||||
// make lastPower
|
||||
playerCharacter.setLastPower(jc);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void finishUsePower(PerformActionMsg msg, PlayerCharacter caster, AbstractWorldObject target){
|
||||
Power powerUsed = powers.get(msg.getPowerUsedID());
|
||||
if(powerUsed == null)
|
||||
return;
|
||||
if(powerUsed.maxMobTargets > 1 || powerUsed.maxPlayerTargets > 1){
|
||||
AoeHandler(caster, target, powerUsed);
|
||||
}else{
|
||||
applyAllPowerEffects(powerUsed, target);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AoeHandler(PlayerCharacter caster, AbstractWorldObject target, Power powerUsed){
|
||||
HashSet<AbstractWorldObject> mobTargets = new HashSet<>();
|
||||
HashSet<AbstractWorldObject> pcTargets = new HashSet<>();
|
||||
if(powerUsed.maxMobTargets > 0)
|
||||
mobTargets = WorldGrid.getObjectsInRangePartial(target.loc,powerUsed.areaRange, MBServerStatics.MASK_MOB);
|
||||
if(powerUsed.maxPlayerTargets > 0)
|
||||
pcTargets = WorldGrid.getObjectsInRangePartial(target.loc,powerUsed.areaRange, MBServerStatics.MASK_PLAYER);
|
||||
int count = 1;
|
||||
for(AbstractWorldObject mob : mobTargets){
|
||||
if(count < powerUsed.maxMobTargets + 1){
|
||||
applyAllPowerEffects(powerUsed,mob);
|
||||
count ++;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
count = 1;
|
||||
for(AbstractWorldObject pc : pcTargets){
|
||||
if(count < powerUsed.maxPlayerTargets + 1){
|
||||
applyAllPowerEffects(powerUsed,pc);
|
||||
count ++;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void applyAllPowerEffects(Power power, AbstractWorldObject target){
|
||||
for(ActionEntry powerAction: power.actionEntries){
|
||||
Effect eff = effect_data.get(Hasher.SBStringHash(powerAction.effect_id));
|
||||
if(eff == null)
|
||||
continue;
|
||||
//TODO add in effect application
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendPowerMsg(PlayerCharacter playerCharacter, int type, PerformActionMsg msg) {
|
||||
|
||||
if (playerCharacter == null)
|
||||
return;
|
||||
|
||||
msg.setUnknown05(type);
|
||||
|
||||
switch (type) {
|
||||
case 3:
|
||||
case 4:
|
||||
msg.setUnknown04(2);
|
||||
DispatchManager.dispatchMsgToInterestArea(playerCharacter, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
|
||||
break;
|
||||
default:
|
||||
msg.setUnknown04(1);
|
||||
Dispatch dispatch = Dispatch.borrow(playerCharacter, msg);
|
||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import engine.mbEnums;
|
||||
|
||||
public class ActionEntry {
|
||||
|
||||
public String effect_id;
|
||||
public String action_id;
|
||||
public int minTrains;
|
||||
public int maxTrains;
|
||||
public float duration;
|
||||
|
||||
@@ -8,10 +8,9 @@
|
||||
|
||||
package engine.wpak.data;
|
||||
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Effect {
|
||||
public String effect_id;
|
||||
@@ -34,4 +33,19 @@ public class Effect {
|
||||
public String message;
|
||||
public int cycleDuration;
|
||||
public int cycleDelay;
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
Effect effect = (Effect) o;
|
||||
return Objects.equals(effect_id, effect.effect_id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return effect_id.hashCode(); // Use only the id field for hashCode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ public class ModifierEntry {
|
||||
public mbEnums.ModType type;
|
||||
public float min;
|
||||
public float max;
|
||||
public float percentage;
|
||||
public float value;
|
||||
public mbEnums.CompoundCurveType compoundCurveType;
|
||||
public String arg1; // ItemName "Masterwork" ""
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
package engine.wpak.data;
|
||||
|
||||
import engine.mbEnums;
|
||||
import engine.objects.AbstractWorldObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Power {
|
||||
public String power_id;
|
||||
@@ -47,7 +47,7 @@ public class Power {
|
||||
public String grantOverrideVar;
|
||||
public ArrayList<String> description = new ArrayList<>();
|
||||
public HashMap<String, mbEnums.CompoundCurveType> curves = new HashMap<>();
|
||||
public String category;
|
||||
public mbEnums.PowerCategoryType category;
|
||||
public boolean canCastWhileMoving = false;
|
||||
public boolean bladeTrails = false;
|
||||
public ArrayList<Effect> effectPreReqs = new ArrayList<>();
|
||||
@@ -67,55 +67,28 @@ public class Power {
|
||||
public boolean isProjectile = false;
|
||||
public HashMap<String, Float> conditions = new HashMap<>();
|
||||
|
||||
public int getRecycleTime(int trains) { // returns cast time in ms
|
||||
if (this.curves.get("RECYCLETIME") != null)
|
||||
return (int) (((this.recycle_time + (this.curves.get("RECYCLETIME").getValue() * trains)) * 1000) + getCastTime(trains));
|
||||
else
|
||||
return (int) (((this.recycle_time * (1 + (this.curves.get("RECYCLETIME").getValue() * trains))) * 1000) + getCastTime(trains));
|
||||
}
|
||||
public int getCastTime(int trains) { // returns cast time in ms
|
||||
if (this.curves.get("INITTIME") != null)
|
||||
return (int) ((this.init_time + (this.curves.get("INITTIME").getValue() * trains)) * 1000);
|
||||
else
|
||||
return (int) ((this.init_time * (1 + (this.curves.get("INITTIME").getValue() * trains))) * 1000);
|
||||
}
|
||||
|
||||
public boolean allowedInCombat() {
|
||||
switch(castingMode.name()){
|
||||
case "NONE":
|
||||
case "BOTH":
|
||||
case "COMBAT":
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean allowedOutOfCombat() {
|
||||
switch(castingMode.name()){
|
||||
case "NONE":
|
||||
case "BOTH":
|
||||
case "NONCOMBAT":
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public float getCost(int trains) {
|
||||
if (this.curves.get("COSTAMT") != null)
|
||||
return this.cost + (float)(this.curves.get("COSTAMT").getValue() * trains);
|
||||
else
|
||||
return this.cost * (1 + (float)(this.curves.get("COSTAMT").getValue() * trains));
|
||||
|
||||
}
|
||||
|
||||
public boolean isSpell(){
|
||||
return true;
|
||||
}
|
||||
public boolean isSkill(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isChant(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
Power power = (Power) o;
|
||||
return Objects.equals(power_id, power.power_id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return power_id.hashCode(); // Use only the id field for hashCode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,19 +11,20 @@ package engine.wpak.data;
|
||||
import engine.mbEnums;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
|
||||
public class PowerAction {
|
||||
|
||||
// Header values
|
||||
|
||||
public String action_id;
|
||||
public String action_type;
|
||||
public mbEnums.PowerActionType action_type;
|
||||
public ArrayList<Effect> effects = new ArrayList<>();
|
||||
public int petLevel;
|
||||
public int petRace;
|
||||
public StatTransfer statTransfer;
|
||||
public int levelCap;
|
||||
public mbEnums.CompoundCurveType levelCurve;
|
||||
public mbEnums.CompoundCurveType levelCapCurve;
|
||||
public TrackEntry trackEntry;
|
||||
|
||||
// Additional variables after header go here.
|
||||
@@ -50,5 +51,18 @@ public class PowerAction {
|
||||
public int splashDamageMax;
|
||||
public boolean ignoreNoTeleSpire = false;
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
PowerAction powerAction = (PowerAction) o;
|
||||
return Objects.equals(action_id, powerAction.action_id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return action_id.hashCode(); // Use only the id field for hashCode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,5 +13,5 @@ import engine.mbEnums;
|
||||
public class PowerEntry {
|
||||
public mbEnums.PowerType power_type;
|
||||
public int icon;
|
||||
public String powerBase;
|
||||
public String focusLine;
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@ import engine.mbEnums;
|
||||
|
||||
public class StatTransfer {
|
||||
public mbEnums.CostType fromStat;
|
||||
public float fromStatValue;
|
||||
public mbEnums.CompoundCurveType fromCurve;
|
||||
public float ramp;
|
||||
public mbEnums.CompoundCurveType rampCurve;
|
||||
public mbEnums.CostType toStat;
|
||||
public float toStatValue;
|
||||
public mbEnums.CompoundCurveType toCurve;
|
||||
public float efficiency;
|
||||
public mbEnums.CompoundCurveType efficiencyCurve;
|
||||
public boolean fromStatBool;
|
||||
public boolean toStatBool;
|
||||
public boolean isDrain;
|
||||
public String transfer_action;
|
||||
public int transfer_ticks;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2024
|
||||
// www.magicbane.com
|
||||
|
||||
package engine.wpakpowers;
|
||||
|
||||
import engine.objects.AbstractCharacter;
|
||||
import engine.objects.AbstractWorldObject;
|
||||
import engine.wpak.data.Effect;
|
||||
import engine.wpak.data.ModifierEntry;
|
||||
import engine.wpak.data.Power;
|
||||
import engine.wpak.data.PowerAction;
|
||||
|
||||
public class Actions {
|
||||
|
||||
public static void ApplyEffects(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
|
||||
// Iterate effects for this powerAction and apply
|
||||
|
||||
for (Effect effect : powerAction.effects) {
|
||||
|
||||
// Create pojo to hold effect/modifiers stored in AWO
|
||||
|
||||
AppliedEffect appliedEffect = new AppliedEffect();
|
||||
appliedEffect.effect = effect;
|
||||
appliedEffect.rank = rank;
|
||||
|
||||
// Add modifier objects from behaviours to pojo.
|
||||
// Anything from a float to an array can be returned
|
||||
// based on the needs of the behaviour.
|
||||
|
||||
for (ModifierEntry modifierEntry : effect.mods) {
|
||||
Object modifier = modifierEntry.type.behaviorType.apply(caster, power, rank, target,
|
||||
powerAction, effect, modifierEntry);
|
||||
appliedEffect.modifiers.put(modifierEntry.type, modifier);
|
||||
}
|
||||
|
||||
// Add this power effect to the target
|
||||
// or overwrite the old value
|
||||
|
||||
target._effects.put(effect, appliedEffect);
|
||||
}
|
||||
// target.updateBonuses() here?
|
||||
}
|
||||
|
||||
public static void Block(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void Charm(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void ClaimMine(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void ClearAggro(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void ClearNearbyAggro(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void Confusion(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void CreateMob(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void DamageOverTime(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void DeferredPower(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void DirectDamage(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void Invis(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void MobRecall(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void Peek(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void Recall(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void RemoveEffect(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void Resurrect(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void RunegateTeleport(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void SetItemFlag(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void SimpleDamage(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void SpireDisable(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void Steal(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void Summon(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void Teleport(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void Track(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void TransferStat(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void TransferStatOT(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void Transform(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
|
||||
public static void TreeChoke(AbstractCharacter caster, Power power,
|
||||
Integer rank, AbstractWorldObject target, PowerAction powerAction) {
|
||||
System.out.println("PowerAction method called");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2024
|
||||
// www.magicbane.com
|
||||
|
||||
package engine.wpakpowers;
|
||||
|
||||
import engine.mbEnums;
|
||||
import engine.wpak.data.Effect;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class AppliedEffect {
|
||||
|
||||
public Effect effect;
|
||||
public int rank;
|
||||
public ConcurrentHashMap<mbEnums.ModType, Object> modifiers = new ConcurrentHashMap<>();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2024
|
||||
// www.magicbane.com
|
||||
|
||||
package engine.wpakpowers;
|
||||
|
||||
import engine.mbEnums;
|
||||
import engine.objects.AbstractCharacter;
|
||||
import engine.objects.AbstractWorldObject;
|
||||
import engine.util.Pair;
|
||||
import engine.wpak.data.Effect;
|
||||
import engine.wpak.data.ModifierEntry;
|
||||
import engine.wpak.data.Power;
|
||||
import engine.wpak.data.PowerAction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Behaviours {
|
||||
|
||||
public static Object Flag(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Object MapIntToInts(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
return powerAction.attackAnimations.clone();
|
||||
}
|
||||
|
||||
public static Object Standard(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
|
||||
return WpakPowerManager.getModifierValues(modifierEntry, rank).first;
|
||||
}
|
||||
|
||||
public static Object FPSubTypeAttr(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
return WpakPowerManager.getModifierValues(modifierEntry, rank).first;
|
||||
}
|
||||
|
||||
public static Object SubTypeSourceType(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
|
||||
return mbEnums.SourceType.valueOf(modifierEntry.arg1);
|
||||
}
|
||||
|
||||
public static Object SubTypePowerType(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
return modifierEntry.arg1;
|
||||
}
|
||||
|
||||
public static Object SubTypeSkill(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
return null; // Unused in data
|
||||
}
|
||||
|
||||
public static Object FPSubTypeDmg(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
String key = modifierEntry.arg1;
|
||||
float modifierValue = WpakPowerManager.getModifierValues(modifierEntry, rank).first;
|
||||
return new Pair<>(key, modifierValue);
|
||||
}
|
||||
|
||||
public static Object DD(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
WpakPowerManager.DirectDamageHandler(caster,target,power,rank,modifierEntry);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object StringBehaviour(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
return new Pair<>(modifierEntry.arg1, modifierEntry.arg2); // We should filter this. No purpose.
|
||||
}
|
||||
|
||||
public static Object SubTypeMod(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
|
||||
mbEnums.ModType noMod = mbEnums.ModType.valueOf(modifierEntry.arg1);
|
||||
ArrayList<Effect> removeList = new ArrayList<>();
|
||||
|
||||
// Iterate through effects on target slating to remove
|
||||
// all which match the intended modType
|
||||
|
||||
for (AppliedEffect appliedEffect : target._effects.values())
|
||||
if (appliedEffect.modifiers.containsKey(noMod))
|
||||
removeList.add(appliedEffect.effect);
|
||||
|
||||
for (Effect effectEntry : removeList)
|
||||
target._effects.remove(effectEntry); // wpakPowerManager.removeEffect() instead?
|
||||
|
||||
// target.updateBonuses?
|
||||
return noMod;
|
||||
}
|
||||
|
||||
public static Object SubTypePower(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
return power.category;
|
||||
}
|
||||
|
||||
public static Object SubTypeDmg(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
return power.category;
|
||||
}
|
||||
|
||||
public static Object FPSubTypeSkill(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
return WpakPowerManager.getModifierValues(modifierEntry, rank);
|
||||
}
|
||||
|
||||
public static Object FPSubTypeMonster(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
System.out.println("Behavior method called");
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object ProcInfo(AbstractCharacter caster, Power power, Integer rank, AbstractWorldObject target,
|
||||
PowerAction powerAction, Effect effect, ModifierEntry modifierEntry) {
|
||||
System.out.println("Behavior method called");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,537 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2024
|
||||
// www.magicbane.com
|
||||
|
||||
package engine.wpakpowers;
|
||||
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.DispatchManager;
|
||||
import engine.gameManager.SessionManager;
|
||||
import engine.job.JobContainer;
|
||||
import engine.job.JobScheduler;
|
||||
import engine.jobs.FinishRecycleTimeJob;
|
||||
import engine.jobs.WpakUsePowerJob;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.mbEnums;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.ModifyHealthMsg;
|
||||
import engine.net.client.msg.PerformActionMsg;
|
||||
import engine.net.client.msg.RecyclePowerMsg;
|
||||
import engine.net.client.msg.UpdateStateMsg;
|
||||
import engine.objects.*;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.util.Hasher;
|
||||
import engine.util.Pair;
|
||||
import engine.wpak.EffectsParser;
|
||||
import engine.wpak.PowerActionParser;
|
||||
import engine.wpak.PowersParser;
|
||||
import engine.wpak.data.Effect;
|
||||
import engine.wpak.data.*;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static engine.math.FastMath.sqr;
|
||||
|
||||
public class WpakPowerManager {
|
||||
public static HashMap<String, Effect> _effectsLookup = new HashMap<>();
|
||||
public static HashMap<Integer, PowerAction> _powerActionLookup = new HashMap<>();
|
||||
public static HashMap<Integer, Power> _powersLookup = new HashMap<>();
|
||||
|
||||
private static JobScheduler js;
|
||||
|
||||
public static void init() {
|
||||
EffectsParser.parseWpakFile();
|
||||
PowersParser.parseWpakFile();
|
||||
PowerActionParser.parseWpakFile();
|
||||
}
|
||||
|
||||
public static void beginCast(final PerformActionMsg msg, ClientConnection origin, boolean sendCastToSelf) {
|
||||
|
||||
if (executePower(msg, origin, sendCastToSelf)) {
|
||||
// Cast failed for some reason, reset timer
|
||||
|
||||
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
|
||||
Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), recyclePowerMsg);
|
||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
|
||||
|
||||
// Send Fail to cast message
|
||||
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
|
||||
|
||||
if (pc != null) {
|
||||
sendPowerMsg(pc, 2, msg);
|
||||
if (pc.isCasting()) {
|
||||
pc.update();
|
||||
}
|
||||
|
||||
pc.setIsCasting(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean executePower(final PerformActionMsg msg, ClientConnection origin, boolean sendCastToSelf) {
|
||||
|
||||
//check to see if the caster is valid
|
||||
PlayerCharacter playerCharacter = SessionManager.getPlayerCharacter(origin);
|
||||
if (playerCharacter == null)
|
||||
return false;
|
||||
|
||||
//make sure player is still alive
|
||||
if (!playerCharacter.isAlive() && msg.getPowerUsedID() != 428589216) { //succor
|
||||
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
|
||||
Dispatch dispatch = Dispatch.borrow(playerCharacter, recyclePowerMsg);
|
||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
|
||||
return false;
|
||||
}
|
||||
|
||||
//make sure the recycle timer has actually elapsed
|
||||
if (playerCharacter.getRecycleTimers().containsKey(msg.getPowerUsedID())) {
|
||||
Logger.warn("usePowerA(): Cheat attempted? '" + msg.getPowerUsedID() + "' recycle timer not finished " + playerCharacter.getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
//lookup the power that was cast
|
||||
Power powerCast = _powersLookup.get(msg.getPowerUsedID());
|
||||
if (powerCast == null) {
|
||||
ChatManager.chatSayInfo(playerCharacter, "This power is not implemented yet.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (playerCharacter.getLastPower() != null)
|
||||
return true;
|
||||
|
||||
// get numTrains for power
|
||||
int trains = msg.getNumTrains();
|
||||
|
||||
if (trains > powerCast.maxLevel) {
|
||||
trains = powerCast.maxLevel;
|
||||
msg.setNumTrains(trains);
|
||||
}
|
||||
|
||||
//sanity check for amount of trains in spell cast
|
||||
if (playerCharacter.getPowers() != null && playerCharacter.getPowers().containsKey(msg.getPowerUsedID())) {
|
||||
CharacterPower cp = playerCharacter.getPowers().get(msg.getPowerUsedID());
|
||||
if (cp != null) {
|
||||
int tot = cp.getTotalTrains();
|
||||
if (tot == 0)
|
||||
return false;
|
||||
if (trains != tot) {
|
||||
trains = tot;
|
||||
msg.setNumTrains(trains);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//get casting time
|
||||
int time = getRecycleTime(powerCast, trains);
|
||||
|
||||
//combat mode sanity check
|
||||
if (playerCharacter.isCombat()) {
|
||||
if (!allowedInCombat(powerCast))
|
||||
return true;
|
||||
} else if (!allowedOutOfCombat(powerCast))
|
||||
return true;
|
||||
|
||||
//stunned check
|
||||
PlayerBonuses bonus = playerCharacter.getBonuses();
|
||||
// mbEnums.SourceType sourceType = mbEnums.SourceType.GetSourceType(powerCast.category);
|
||||
|
||||
// if (bonus != null && (bonus.getBool(mbEnums.ModType.Stunned, mbEnums.SourceType.None) || bonus.getBool(mbEnums.ModType.CannotCast, mbEnums.SourceType.None) || bonus.getBool(mbEnums.ModType.BlockedPowerType, sourceType)))
|
||||
// return true;
|
||||
|
||||
//sanity check for casting while moving
|
||||
Vector3fImmutable endLoc = playerCharacter.getEndLoc();
|
||||
|
||||
if (!powerCast.canCastWhileMoving)
|
||||
if (playerCharacter.isMoving()) {
|
||||
float distanceLeftSquared = endLoc.distanceSquared2D(playerCharacter.getLoc());
|
||||
if (distanceLeftSquared > sqr(playerCharacter.getSpeed()))
|
||||
return true;
|
||||
}
|
||||
|
||||
//get the actual target form the message
|
||||
int type = msg.getTargetType();
|
||||
int UUID = msg.getTargetID();
|
||||
|
||||
if (type == -1 || type == 0 || UUID == -1 || UUID == 0)
|
||||
return true;
|
||||
|
||||
AbstractWorldObject target = (AbstractWorldObject) DbManager.getObject(mbEnums.GameObjectType.values()[type], UUID);
|
||||
|
||||
//check to make sure power can be cast on building if target is a building
|
||||
if (target != null && target.getObjectType() == mbEnums.GameObjectType.Building && !powerCast.target_type.equals(mbEnums.PowerTargetType.BUILDING)) {
|
||||
sendPowerMsg(playerCharacter, 9, new PerformActionMsg(msg));
|
||||
return true;
|
||||
}
|
||||
|
||||
//validate casting range
|
||||
if (playerCharacter.getLoc().distanceSquared2D(msg.getTargetLoc()) > (powerCast.range * powerCast.range))
|
||||
return true;
|
||||
|
||||
//validate prereqs for power cast
|
||||
//equipment prereqs
|
||||
if (!powerCast.equipmentPreReq.isEmpty())
|
||||
for (EquipmentPreReq prereq : powerCast.equipmentPreReq) {
|
||||
String requiredSkill = prereq.skill;
|
||||
|
||||
if (playerCharacter.charItemManager.equipped.get(prereq.slot) != null) {
|
||||
Item equippedItem = playerCharacter.charItemManager.equipped.get(prereq.slot);
|
||||
if (!equippedItem.template.item_skill_mastery_used.equals(requiredSkill) && !equippedItem.template.item_skill_used.equals(requiredSkill))
|
||||
return true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//effect prereqs
|
||||
if (!powerCast.effectPreReqs.isEmpty()) {
|
||||
for (Effect prereq : powerCast.effectPreReqs) {
|
||||
if (!playerCharacter.effects.contains(prereq.effect_id) && !playerCharacter.effects.contains(prereq.effect_name))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
float cost = getCost(powerCast, trains);
|
||||
if (bonus != null)
|
||||
cost *= (1 + bonus.getFloatPercentAll(mbEnums.ModType.PowerCost, mbEnums.SourceType.None));
|
||||
|
||||
if (playerCharacter.getAltitude() > 0)
|
||||
cost *= 1.5f;
|
||||
|
||||
if (cost > 0)
|
||||
if ((playerCharacter.getObjectTypeMask() & MBServerStatics.MASK_UNDEAD) != 0)
|
||||
if (playerCharacter.getHealth() <= cost)
|
||||
return true;
|
||||
else {
|
||||
playerCharacter.modifyHealth(-cost, playerCharacter, true);
|
||||
ModifyHealthMsg mhm = new ModifyHealthMsg(playerCharacter, playerCharacter, -cost, 0f, 0f, 0, null, 9999, 0);
|
||||
mhm.setOmitFromChat(1);
|
||||
DispatchManager.dispatchMsgToInterestArea(playerCharacter, mhm, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
|
||||
}
|
||||
else if (powerCast.costType.name().equals("MANA"))
|
||||
if (playerCharacter.getMana() < cost)
|
||||
return true;
|
||||
else
|
||||
playerCharacter.modifyMana(-cost, playerCharacter, true);
|
||||
else if (powerCast.costType.name().equals("STAMINA"))
|
||||
if (playerCharacter.getStamina() < cost)
|
||||
return true;
|
||||
else
|
||||
playerCharacter.modifyStamina(-cost, playerCharacter, true);
|
||||
else if (playerCharacter.getHealth() <= cost)
|
||||
return true;
|
||||
else
|
||||
playerCharacter.modifyHealth(-cost, playerCharacter, true);
|
||||
|
||||
if (time > 0) {
|
||||
FinishRecycleTimeJob frtj = new FinishRecycleTimeJob(playerCharacter, msg);
|
||||
playerCharacter.getRecycleTimers().put(msg.getPowerUsedID(), js.scheduleJob(frtj, time));
|
||||
} else {
|
||||
// else send recycle message to unlock power
|
||||
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
|
||||
Dispatch dispatch = Dispatch.borrow(playerCharacter, recyclePowerMsg);
|
||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
|
||||
}
|
||||
|
||||
int tr = msg.getNumTrains();
|
||||
DispatchManager.dispatchMsgToInterestArea(playerCharacter, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, sendCastToSelf, false);
|
||||
|
||||
//Make new msg..
|
||||
PerformActionMsg copyMsg = new PerformActionMsg(msg);
|
||||
copyMsg.setNumTrains(tr);
|
||||
|
||||
// make person casting stand up if spell (unless they're casting a chant which does not make them stand up)
|
||||
if (powerCast.isSpell() && !powerCast.isChant() && playerCharacter.isSit()) {
|
||||
playerCharacter.update();
|
||||
playerCharacter.setSit(false);
|
||||
UpdateStateMsg updateStateMsg = new UpdateStateMsg(playerCharacter);
|
||||
DispatchManager.dispatchMsgToInterestArea(playerCharacter, updateStateMsg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
|
||||
}
|
||||
|
||||
// update cast (use skill) fail condition
|
||||
playerCharacter.cancelOnCast();
|
||||
|
||||
// update castSpell (use spell) fail condition if spell
|
||||
if (powerCast.isSpell())
|
||||
playerCharacter.cancelOnSpell();
|
||||
|
||||
// get cast time in ms.
|
||||
time = getCastTime(powerCast, trains);
|
||||
|
||||
// set player is casting for regens
|
||||
|
||||
if (time > 100) {
|
||||
playerCharacter.update();
|
||||
playerCharacter.setIsCasting(true);
|
||||
}
|
||||
|
||||
playerCharacter.setLastMovementState(playerCharacter.getMovementState());
|
||||
|
||||
// run timer job to end cast
|
||||
if (time < 1) // run immediately
|
||||
finishUsePower(copyMsg, playerCharacter, target);
|
||||
else {
|
||||
WpakUsePowerJob upj = new WpakUsePowerJob(playerCharacter, copyMsg, target);
|
||||
JobContainer jc = js.scheduleJob(upj, time);
|
||||
|
||||
// make lastPower
|
||||
playerCharacter.setLastPower(jc);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void finishUsePower(PerformActionMsg msg, PlayerCharacter caster, AbstractWorldObject target) {
|
||||
|
||||
Power powerUsed = _powersLookup.get(msg.getPowerUsedID());
|
||||
|
||||
if (powerUsed == null) {
|
||||
Logger.error("Invalid power: " + msg.getPowerUsedID());
|
||||
return;
|
||||
}
|
||||
|
||||
if (powerUsed.maxMobTargets > 1 || powerUsed.maxPlayerTargets > 1)
|
||||
AoeHandler(caster, target, powerUsed, msg.getNumTrains());
|
||||
else
|
||||
executeActionsForPower(caster, powerUsed, msg.getNumTrains(), target);
|
||||
}
|
||||
|
||||
private static void AoeHandler(PlayerCharacter caster, AbstractWorldObject target, Power powerUsed, int rank) {
|
||||
|
||||
HashSet<AbstractWorldObject> mobTargets = new HashSet<>();
|
||||
HashSet<AbstractWorldObject> pcTargets = new HashSet<>();
|
||||
int count = 1;
|
||||
|
||||
if (powerUsed.maxMobTargets > 0)
|
||||
mobTargets = WorldGrid.getObjectsInRangePartial(target.loc, powerUsed.areaRange, MBServerStatics.MASK_MOB);
|
||||
|
||||
if (powerUsed.maxPlayerTargets > 0)
|
||||
pcTargets = WorldGrid.getObjectsInRangePartial(target.loc, powerUsed.areaRange, MBServerStatics.MASK_PLAYER);
|
||||
|
||||
for (AbstractWorldObject mob : mobTargets) {
|
||||
if (count < powerUsed.maxMobTargets + 1) {
|
||||
executeActionsForPower(caster, powerUsed, rank, mob);
|
||||
count++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
count = 1;
|
||||
for (AbstractWorldObject pc : pcTargets) {
|
||||
if (count < powerUsed.maxPlayerTargets + 1) {
|
||||
executeActionsForPower(caster, powerUsed, rank, pc);
|
||||
count++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void executeActionsForPower(AbstractCharacter caster, Power power, int rank, AbstractWorldObject target) {
|
||||
|
||||
// Iterate through the poweractions for this power
|
||||
// and execute them according to PowerActionType.
|
||||
|
||||
for (ActionEntry actionEntry : power.actionEntries) {
|
||||
|
||||
PowerAction powerAction = _powerActionLookup.get(Hasher.SBStringHash(actionEntry.action_id));
|
||||
|
||||
if (powerAction == null) {
|
||||
Logger.error("Null PowerAction for " + actionEntry.action_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
powerAction.action_type.execute(caster, power, rank, target,
|
||||
powerAction);
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendPowerMsg(PlayerCharacter playerCharacter, int type, PerformActionMsg msg) {
|
||||
|
||||
if (playerCharacter == null)
|
||||
return;
|
||||
|
||||
msg.setUnknown05(type);
|
||||
|
||||
switch (type) {
|
||||
case 3:
|
||||
case 4:
|
||||
msg.setUnknown04(2);
|
||||
DispatchManager.dispatchMsgToInterestArea(playerCharacter, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
|
||||
break;
|
||||
default:
|
||||
msg.setUnknown04(1);
|
||||
Dispatch dispatch = Dispatch.borrow(playerCharacter, msg);
|
||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getRecycleTime(Power power, int trains) { // returns cast time in ms
|
||||
if (power.curves.get("RECYCLETIME") != null) {
|
||||
mbEnums.CompoundCurveType compoundCurveType = power.curves.get("RECYCLETIME");
|
||||
return (int) (((power.recycle_time + (compoundCurveType.value * trains)) * 1000) + getCastTime(power, trains));
|
||||
} else {
|
||||
mbEnums.CompoundCurveType compoundCurveType = power.curves.get("RECYCLETIME");
|
||||
return (int) (((power.recycle_time * (1 + (compoundCurveType.value * trains))) * 1000) + getCastTime(power, trains));
|
||||
}
|
||||
}
|
||||
|
||||
public static int getCastTime(Power power, int trains) { // returns cast time in ms
|
||||
if (power.curves.get("INITTIME") != null) {
|
||||
mbEnums.CompoundCurveType compoundCurveType = power.curves.get("INITTIME");
|
||||
return (int) ((power.init_time + (compoundCurveType.value * trains)) * 1000);
|
||||
} else {
|
||||
mbEnums.CompoundCurveType compoundCurveType = power.curves.get("INITTIME");
|
||||
return (int) ((power.init_time * (1 + (compoundCurveType.value * trains))) * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
public static float getCost(Power power, int trains) {
|
||||
if (power.curves.get("COSTAMT") != null) {
|
||||
mbEnums.CompoundCurveType compoundCurveType = power.curves.get("COSTAMT");
|
||||
return power.cost + (compoundCurveType.value * trains);
|
||||
} else {
|
||||
mbEnums.CompoundCurveType compoundCurveType = power.curves.get("COSTAMT");
|
||||
return power.cost * (1 + (compoundCurveType.value * trains));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean allowedInCombat(Power power) {
|
||||
return power.castingMode.equals(mbEnums.CastingModeType.NONCOMBAT) == false;
|
||||
}
|
||||
|
||||
public static boolean allowedOutOfCombat(Power power) {
|
||||
|
||||
return power.castingMode.equals(mbEnums.CastingModeType.COMBAT) == false;
|
||||
|
||||
}
|
||||
|
||||
public static Pair<Float, Float> getModifierValues(ModifierEntry modifierEntry, int rank) {
|
||||
|
||||
Pair<Float, Float> outData = new Pair<>(0f, 0f);
|
||||
|
||||
if (modifierEntry.percentage != 0f) {
|
||||
outData.first = modifierEntry.percentage + (modifierEntry.compoundCurveType.value * rank);
|
||||
outData.first = outData.first * 0.01f;
|
||||
return outData;
|
||||
}
|
||||
|
||||
// As there is a min/max we return both as a pair enabling
|
||||
// use in the DD modifier.
|
||||
|
||||
// MB Dev Note:
|
||||
// A subset of health/mana/stam modifiers are multiplicative.
|
||||
// These all have "SIVL" in the curve name suggesting
|
||||
// interpolation between min max. Not something currently done.
|
||||
|
||||
outData.first = modifierEntry.compoundCurveType.type.equals(mbEnums.ModificationType.MULTIPLY) ?
|
||||
modifierEntry.min * (1 + (modifierEntry.compoundCurveType.value * rank)) :
|
||||
modifierEntry.min + (modifierEntry.compoundCurveType.value * rank);
|
||||
|
||||
if (modifierEntry.max != 0)
|
||||
outData.second = modifierEntry.compoundCurveType.type.equals(mbEnums.ModificationType.MULTIPLY) ?
|
||||
modifierEntry.max * (1 + (modifierEntry.compoundCurveType.value * rank)) :
|
||||
modifierEntry.max + (modifierEntry.compoundCurveType.value * rank);
|
||||
|
||||
return outData;
|
||||
}
|
||||
|
||||
public static void DirectDamageHandler(AbstractCharacter caster, AbstractWorldObject target,Power power, Integer rank, ModifierEntry modEntry){
|
||||
if(caster == null || !caster.isAlive())
|
||||
return;
|
||||
|
||||
if(target == null || !target.isAlive())
|
||||
return;
|
||||
|
||||
mbEnums.DamageType damageType = mbEnums.DamageType.getDamageType(modEntry.arg1);
|
||||
|
||||
float focus;
|
||||
CharacterSkill skill = caster.getSkills().get(power.powers.get(0).focusLine);
|
||||
if (skill == null)
|
||||
focus = CharacterSkill.getQuickMastery(caster, power.powers.get(0).focusLine);
|
||||
else
|
||||
focus = skill.getModifiedAmount();
|
||||
|
||||
float min;
|
||||
float max;
|
||||
float percent;
|
||||
|
||||
float damage;
|
||||
if(modEntry.percentage != 0){
|
||||
//handle percentage damage
|
||||
percent = getModifierValues(modEntry,rank).first;
|
||||
damage = target.healthMax * percent;
|
||||
}else{
|
||||
//flat damage range
|
||||
min = getMinDamage(getModifierValues(modEntry,rank).first,caster.getStatIntCurrent(),caster.getStatSpiCurrent(),focus);
|
||||
max = getMaxDamage(getModifierValues(modEntry,rank).second,caster.getStatIntCurrent(),caster.getStatSpiCurrent(),focus);
|
||||
damage = ThreadLocalRandom.current().nextInt((int) min, (int) (max) + 1);
|
||||
}
|
||||
|
||||
//apply power damage modifier values
|
||||
for(AppliedEffect appliedEffect: caster._effects.values()){
|
||||
if(appliedEffect.modifiers.containsKey(mbEnums.ModType.PowerDamageModifier)){
|
||||
damage *= 1 + (float)appliedEffect.modifiers.get(mbEnums.ModType.PowerDamageModifier);
|
||||
}
|
||||
}
|
||||
|
||||
if(AbstractCharacter.IsAbstractCharacter(target)) {
|
||||
AbstractCharacter absChar = (AbstractCharacter)target;
|
||||
damage = (int) absChar.resists.getResistedDamage(caster,absChar,damageType,damage,rank);
|
||||
float newStatValue;
|
||||
switch(modEntry.type){
|
||||
case Health:
|
||||
//damage health
|
||||
newStatValue = absChar.getHealth() - damage;
|
||||
if(newStatValue < 0)
|
||||
newStatValue = 0;
|
||||
absChar.setHealth(newStatValue);
|
||||
break;
|
||||
case Stamina:
|
||||
//damage stamina
|
||||
newStatValue = absChar.getStamina() - damage;
|
||||
if(newStatValue < 0)
|
||||
newStatValue = 0;
|
||||
absChar.setStamina(newStatValue,caster);
|
||||
break;
|
||||
case Mana:
|
||||
//damage mana
|
||||
newStatValue = absChar.getMana() - damage;
|
||||
if(newStatValue < 0)
|
||||
newStatValue = 0;
|
||||
absChar.setMana(newStatValue,caster);
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
//target is building
|
||||
float newStatValue = target.getHealth() - damage;
|
||||
if(newStatValue < 0)
|
||||
newStatValue = 0;
|
||||
target.setHealth(newStatValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static float getMinDamage(float baseMin, float intelligence, float spirit, float focus) {
|
||||
float min = baseMin * (((float) Math.pow(intelligence, 0.75f) * 0.0311f) + (0.02f * (int) focus) + ((float) Math.pow(spirit, 0.75f) * 0.0416f));
|
||||
return (float) ((int) (min + 0.5f)); //round to nearest whole number
|
||||
}
|
||||
|
||||
public static float getMaxDamage(float baseMax, float intelligence, float spirit, float focus) {
|
||||
float max = baseMax * (((float) Math.pow(intelligence, 0.75f) * 0.0785f) + (0.015f * (int) focus) + ((float) Math.pow(spirit, 0.75f) * 0.0157f));
|
||||
return (float) ((int) (max + 0.5f)); //round to nearest whole number
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user