forked from MagicBane/Server
FatBoy-DOTC
2 months ago
7 changed files with 391 additions and 8 deletions
@ -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); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue