starting of new power manager
This commit is contained in:
@@ -32,6 +32,7 @@ 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 org.pmw.tinylog.Logger;
|
||||
@@ -118,7 +119,7 @@ public enum PowersManager {
|
||||
// Add EffectsBase
|
||||
ArrayList<EffectsBase> effectList = new ArrayList<>();
|
||||
|
||||
for (Effect entry : EffectsParser.effect_data.values()) {
|
||||
for (Effect entry : WpakPowerManager.effect_data.values()) {
|
||||
EffectsBase effectBase = new EffectsBase(entry);
|
||||
effectList.add(effectBase);
|
||||
PowersManager.effectsBaseByToken.put(effectBase.getToken(), effectBase);
|
||||
@@ -133,7 +134,7 @@ public enum PowersManager {
|
||||
|
||||
HashMap<String, EffectsBase> effects = PowersManager.effectsBaseByIDString;
|
||||
|
||||
for (PowerAction powerAction : PowerActionParser.power_actions) {
|
||||
for (PowerAction powerAction : WpakPowerManager.power_actions.values()) {
|
||||
AbstractPowerAction apa;
|
||||
String type = powerAction.action_type;
|
||||
String IDString = powerAction.action_id;
|
||||
|
||||
@@ -14,6 +14,7 @@ import engine.job.AbstractScheduleJob;
|
||||
import engine.net.client.msg.PerformActionMsg;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.powers.PowersBase;
|
||||
import engine.wpak.data.Power;
|
||||
|
||||
public class UsePowerJob extends AbstractScheduleJob {
|
||||
|
||||
@@ -34,6 +35,16 @@ public class UsePowerJob extends AbstractScheduleJob {
|
||||
this.targetLiveCounter = targetLiveCounter;
|
||||
}
|
||||
|
||||
public UsePowerJob(PlayerCharacter pc, PerformActionMsg msg, int token, Power pb, int casterLiveCounter, int targetLiveCounter) {
|
||||
super();
|
||||
this.pc = pc;
|
||||
this.msg = msg;
|
||||
this.token = token;
|
||||
this.pb = pb;
|
||||
this.casterLiveCounter = casterLiveCounter;
|
||||
this.targetLiveCounter = targetLiveCounter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doJob() {
|
||||
PowersManager.finishUsePower(this.msg, this.pc, casterLiveCounter, targetLiveCounter);
|
||||
|
||||
@@ -25,7 +25,6 @@ import java.util.regex.Pattern;
|
||||
public class EffectsParser {
|
||||
|
||||
public static String effectsPath = ConfigManager.DEFAULT_DATA_DIR + "wpak/Effects.cfg";
|
||||
public static HashMap<String, Effect> effect_data = new HashMap<>();
|
||||
private static final Pattern EFFECT_REGEX = Pattern.compile("(?<=EFFECTBEGIN)(.+?)(?=EFFECTEND)", Pattern.DOTALL);
|
||||
private static final Pattern SOURCE_REGEX = Pattern.compile("(?<=SOURCEBEGIN)(.+?)(?=SOURCEEND)", Pattern.DOTALL);
|
||||
private static final Pattern MODS_REGEX = Pattern.compile("(?<=MODSBEGIN)(.+?)(?=MODSEND)", Pattern.DOTALL);
|
||||
@@ -52,7 +51,7 @@ public class EffectsParser {
|
||||
|
||||
while (matcher.find()) {
|
||||
Effect effect = parseEffectEntry(matcher.group());
|
||||
effect_data.put(effect.effect_id, effect);
|
||||
WpakPowerManager.effect_data.put(effect.effect_id, effect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ package engine.wpak;
|
||||
|
||||
import engine.gameManager.ConfigManager;
|
||||
import engine.mbEnums;
|
||||
import engine.util.Hasher;
|
||||
import engine.wpak.data.Effect;
|
||||
import engine.wpak.data.PowerAction;
|
||||
import engine.wpak.data.StatTransfer;
|
||||
@@ -31,8 +32,6 @@ public class PowerActionParser {
|
||||
private static final Pattern POWER_ACTION_REGEX = Pattern.compile("(?<=POWERACTIONBEGIN)(.+?)(?=POWERACTIONEND)", Pattern.DOTALL);
|
||||
private static final String powerActionPath = ConfigManager.DEFAULT_DATA_DIR + "wpak/PowerActions.cfg";
|
||||
|
||||
public static ArrayList<PowerAction> power_actions= new ArrayList<>();
|
||||
|
||||
public static void parseWpakFile() {
|
||||
|
||||
// Read .wpak file from disk
|
||||
@@ -54,7 +53,7 @@ public class PowerActionParser {
|
||||
while (matcher.find()) {
|
||||
|
||||
PowerAction powerAction = parsePowerActionEntry(matcher.group().trim());
|
||||
power_actions.add(powerAction);
|
||||
WpakPowerManager.power_actions.put(Hasher.SBStringHash(powerAction.action_id),powerAction);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ package engine.wpak;
|
||||
|
||||
import engine.gameManager.ConfigManager;
|
||||
import engine.mbEnums;
|
||||
import engine.util.Hasher;
|
||||
import engine.wpak.data.*;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -50,7 +51,7 @@ public class PowersParser {
|
||||
while (matcher.find()) {
|
||||
|
||||
Power power = parsePowerEntry(matcher.group().trim());
|
||||
|
||||
WpakPowerManager.powers.put(Hasher.SBStringHash(power.power_id),power);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,332 @@
|
||||
package engine.wpak;
|
||||
|
||||
import engine.gameManager.*;
|
||||
import engine.job.JobContainer;
|
||||
import engine.job.JobScheduler;
|
||||
import engine.jobs.FinishRecycleTimeJob;
|
||||
import engine.jobs.UsePowerJob;
|
||||
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.wpak.data.Effect;
|
||||
import engine.wpak.data.EquipmentPreReq;
|
||||
import engine.wpak.data.Power;
|
||||
import engine.wpak.data.PowerAction;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public 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 (pb.isSpell() && !pb.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 (pb.isSpell())
|
||||
playerCharacter.cancelOnSpell();
|
||||
|
||||
// get cast time in ms.
|
||||
time = pb.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, casterLiveCounter, targetLiveCounter);
|
||||
else {
|
||||
UsePowerJob upj = new UsePowerJob(playerCharacter, copyMsg, copyMsg.getPowerUsedID(), powerCast, casterLiveCounter, targetLiveCounter);
|
||||
JobContainer jc = js.scheduleJob(upj, time);
|
||||
|
||||
// make lastPower
|
||||
playerCharacter.setLastPower(jc);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void finishUsePower(PerformActionMsg msg, int castCount, int targetCount){
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,4 +66,44 @@ 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));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user