forked from MagicBane/Server
				
			
				 7 changed files with 391 additions and 8 deletions
			
			
		@ -0,0 +1,332 @@
				@@ -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