Sync with L2jServer HighFive Nov 14th 2015.

This commit is contained in:
MobiusDev
2015-11-14 16:31:37 +00:00
parent 887fbcc6b5
commit e38353e409
125 changed files with 1998 additions and 1419 deletions

View File

@ -43,7 +43,6 @@ import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.L2Playable;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jserver.gameserver.model.actor.instance.L2FriendlyMobInstance;
import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
import com.l2jserver.gameserver.model.actor.instance.L2GuardInstance;
@ -180,24 +179,24 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
if (target.isInvul())
{
// However EffectInvincible requires to check GMs specially
if ((target instanceof L2PcInstance) && target.isGM())
if (target.isPlayer() && target.isGM())
{
return false;
}
if ((target instanceof L2Summon) && ((L2Summon) target).getOwner().isGM())
if (target.isSummon() && ((L2Summon) target).getOwner().isGM())
{
return false;
}
}
// Check if the target isn't a Folk or a Door
if (target instanceof L2DoorInstance)
if (target.isDoor())
{
return false;
}
// Check if the target isn't dead, is in the Aggro range and is at the same height
if (target.isAlikeDead() || ((target instanceof L2Playable) && !me.isInsideRadius(target, me.getAggroRange(), true, false)))
if (target.isAlikeDead() || ((target.isPlayable()) && !me.isInsideRadius(target, me.getAggroRange(), true, false)))
{
return false;
}

View File

@ -403,7 +403,7 @@ public final class L2ControllableMobAI extends L2AttackableAI
}
// TODO(Zoey76)[#112]: This check must change if summon fall in L2Npc hierarchy.
if (target instanceof L2Npc)
if (target.isNpc())
{
return false;
}

View File

@ -147,11 +147,11 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
if ((target != null) && target.isInvul())
{
// However EffectInvincible requires to check GMs specially
if ((target instanceof L2PcInstance) && target.isGM())
if (target.isPlayer() && target.isGM())
{
return false;
}
if ((target instanceof L2Summon) && ((L2Summon) target).getOwner().isGM())
if (target.isSummon() && ((L2Summon) target).getOwner().isGM())
{
return false;
}

View File

@ -26,6 +26,7 @@ import static com.l2jserver.gameserver.ai.CtrlIntention.AI_INTENTION_MOVE_TO;
import static com.l2jserver.gameserver.ai.CtrlIntention.AI_INTENTION_PICK_UP;
import static com.l2jserver.gameserver.ai.CtrlIntention.AI_INTENTION_REST;
import com.l2jserver.gameserver.enums.DuelState;
import com.l2jserver.gameserver.model.L2Object;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.actor.L2Character;
@ -33,6 +34,8 @@ import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.instance.L2StaticObjectInstance;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.model.skills.targets.L2TargetType;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
public class L2PlayerAI extends L2PlayableAI
{
@ -190,7 +193,12 @@ public class L2PlayerAI extends L2PlayableAI
clientActionFailed();
return;
}
if (_actor.getActingPlayer().getDuelState() == DuelState.DEAD)
{
clientActionFailed();
_actor.getActingPlayer().sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CANNOT_MOVE_WHILE_FROZEN_PLEASE_WAIT));
return;
}
if (_actor.isAllSkillsDisabled() || _actor.isCastingNow() || _actor.isAttackingNow())
{
clientActionFailed();

View File

@ -136,11 +136,11 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
if (target.isInvul())
{
// However EffectInvincible requires to check GMs specially
if ((target instanceof L2PcInstance) && target.isGM())
if (target.isPlayer() && target.isGM())
{
return false;
}
if ((target instanceof L2Summon) && ((L2Summon) target).getOwner().isGM())
if (target.isSummon() && ((L2Summon) target).getOwner().isGM())
{
return false;
}

View File

@ -1583,7 +1583,7 @@ public final class SkillTreesData implements IXmlReader
*/
public boolean isClanSkill(int skillId, int skillLevel)
{
final int hashCode = SkillData.getSkillHashCode(skillId, skillId);
final int hashCode = SkillData.getSkillHashCode(skillId, skillLevel);
return _pledgeSkillTree.containsKey(hashCode) || _subPledgeSkillTree.containsKey(hashCode);
}

View File

@ -18,13 +18,16 @@
*/
package com.l2jserver.gameserver.enums;
/**
* @author Zealar
*/
public enum DuelResult
{
Continue,
Team1Win,
Team2Win,
Team1Surrender,
Team2Surrender,
Canceled,
Timeout
CONTINUE,
TEAM_1_WIN,
TEAM_2_WIN,
TEAM_1_SURRENDER,
TEAM_2_SURRENDER,
CANCELED,
TIMEOUT
}

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* L2J Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.gameserver.enums;
/**
* @author Zealar
*/
public enum DuelState
{
NO_DUEL,
DUELLING,
DEAD,
WINNER,
INTERRUPTED
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* L2J Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.gameserver.enums;
/**
* @author Zealar
*/
public enum StartPosType
{
FIXED,
RANDOM
}

View File

@ -18,21 +18,21 @@
*/
package com.l2jserver.gameserver.instancemanager;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import com.l2jserver.gameserver.enums.PrivateStoreType;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.Duel;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.model.zone.ZoneId;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
import com.l2jserver.util.Rnd;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
public final class DuelManager
{
private static final List<String> ARENAS = Arrays.asList("OlympiadGrassyArena.xml", "OlympiadHerossVestigesArena.xml", "OlympiadOrbisArena.xml", "OlympiadThreeBridgesArena.xml");
private final Map<Integer, Duel> _duels = new ConcurrentHashMap<>();
private final AtomicInteger _currentDuelId = new AtomicInteger();
@ -46,7 +46,7 @@ public final class DuelManager
return _duels.get(duelId);
}
public void addDuel(L2PcInstance playerA, L2PcInstance playerB, int partyDuel)
public void addDuel(L2PcInstance playerA, L2PcInstance playerB, boolean partyDuel)
{
if ((playerA == null) || (playerB == null))
{
@ -55,7 +55,7 @@ public final class DuelManager
// return if a player has PvPFlag
String engagedInPvP = "The duel was canceled because a duelist engaged in PvP combat.";
if (partyDuel == 1)
if (partyDuel)
{
boolean playerInPvP = false;
for (L2PcInstance temp : playerA.getParty().getMembers())
@ -154,23 +154,6 @@ public final class DuelManager
}
}
/**
* Removes player from duel.
* @param player - the removed player
*/
public void onRemoveFromParty(L2PcInstance player)
{
if ((player == null) || !player.isInDuel())
{
return;
}
final Duel duel = getDuel(player.getDuelId());
if (duel != null)
{
duel.onRemoveFromParty(player);
}
}
/**
* Broadcasts a packet to the team opposing the given player.
* @param player
@ -183,43 +166,81 @@ public final class DuelManager
return;
}
final Duel duel = getDuel(player.getDuelId());
if (duel == null)
{
return;
}
if ((duel.getPlayerA() == null) || (duel.getPlayerB() == null))
{
return;
}
if (duel.getPlayerA() == player)
if (duel.getTeamA().contains(player))
{
duel.broadcastToTeam2(packet);
}
else if (duel.getPlayerB() == player)
else
{
duel.broadcastToTeam1(packet);
}
else if (duel.isPartyDuel())
{
if ((duel.getPlayerA().getParty() != null) && duel.getPlayerA().getParty().getMembers().contains(player))
{
duel.broadcastToTeam2(packet);
}
else if ((duel.getPlayerB().getParty() != null) && duel.getPlayerB().getParty().getMembers().contains(player))
{
duel.broadcastToTeam1(packet);
}
}
}
/**
* Gets new a random Olympiad Stadium instance name.
* @return an instance name
* Checks if this player might join / start a duel.<br>
* @param player
* @param target
* @param partyDuel
* @return true if the player might join/start a duel.
*/
public String getDuelArena()
public static boolean canDuel(L2PcInstance player, L2PcInstance target, boolean partyDuel)
{
return ARENAS.get(Rnd.get(ARENAS.size()));
SystemMessageId reason = null;
if (target.isInCombat() || target.isJailed())
{
reason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_CURRENTLY_ENGAGED_IN_BATTLE;
}
else if (target.isTransformed())
{
reason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_CURRENTLY_POLYMORPHED;
}
else if (target.isDead() || target.isAlikeDead() || ((target.getCurrentHp() < (target.getMaxHp() / 2)) || (target.getCurrentMp() < (target.getMaxMp() / 2))))
{
reason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_S_HP_OR_MP_IS_BELOW_50;
}
else if (target.isInDuel())
{
reason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_ALREADY_ENGAGED_IN_A_DUEL;
}
else if (target.isInOlympiadMode())
{
reason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_PARTICIPATING_IN_THE_OLYMPIAD_OR_THE_CEREMONY_OF_CHAOS;
}
else if (target.isCursedWeaponEquipped())
{
reason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_IN_A_CHAOTIC_OR_PURPLE_STATE;
}
else if (target.getPrivateStoreType() != PrivateStoreType.NONE)
{
reason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_CURRENTLY_ENGAGED_IN_A_PRIVATE_STORE_OR_MANUFACTURE;
}
else if (target.isMounted() || target.isInBoat())
{
reason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_CURRENTLY_RIDING_A_BOAT_FENRIR_OR_STRIDER;
}
else if (target.isFishing())
{
reason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_CURRENTLY_FISHING;
}
else if ((!partyDuel && target.isInsideZone(ZoneId.PEACE)) || target.isInsideZone(ZoneId.PVP) || target.isInsideZone(ZoneId.SIEGE))
{
reason = SystemMessageId.C1_CANNOT_MAKE_A_CHALLENGE_TO_A_DUEL_BECAUSE_C1_IS_CURRENTLY_IN_A_DUEL_PROHIBITED_AREA_PEACEFUL_ZONE_BATTLE_ZONE_NEAR_WATER_RESTART_PROHIBITED_AREA;
}
if (reason != null)
{
SystemMessage msg = SystemMessage.getSystemMessage(reason);
msg.addString(target.getName());
player.sendPacket(msg);
return false;
}
return true;
}
public static final DuelManager getInstance()

View File

@ -412,7 +412,7 @@ public final class MapRegionManager implements IXmlReader
Instance inst = InstanceManager.getInstance().getInstance(player.getInstanceId());
if (inst != null)
{
loc = inst.getSpawnLoc();
loc = inst.getExitLoc();
if (loc != null)
{
return loc;

View File

@ -36,7 +36,6 @@ import com.l2jserver.gameserver.GameTimeController;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.enums.PartyDistributionType;
import com.l2jserver.gameserver.instancemanager.DuelManager;
import com.l2jserver.gameserver.instancemanager.PcCafePointsManager;
import com.l2jserver.gameserver.model.actor.L2Attackable;
import com.l2jserver.gameserver.model.actor.L2Character;
@ -485,11 +484,6 @@ public class L2Party extends AbstractPlayerGroup
getMembers().remove(player);
recalculatePartyLevel();
if (player.isInDuel())
{
DuelManager.getInstance().onRemoveFromParty(player);
}
try
{
// Channeling a player!
@ -564,10 +558,6 @@ public class L2Party extends AbstractPlayerGroup
if (getLeader() != null)
{
getLeader().setParty(null);
if (getLeader().isInDuel())
{
DuelManager.getInstance().onRemoveFromParty(getLeader());
}
}
if (_changeDistributionTypeRequestTask != null)
{

View File

@ -2973,7 +2973,27 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
@Override
public boolean isInvul()
{
return _isInvul || _isTeleporting || isAffected(EffectFlag.INVUL);
return _isInvul || _isTeleporting;
}
public boolean isHpBlocked()
{
return isAffected(EffectFlag.BLOCK_HP);
}
public boolean isMpBlocked()
{
return isAffected(EffectFlag.BLOCK_MP);
}
public boolean isBuffBlocked()
{
return isAffected(EffectFlag.BLOCK_BUFF);
}
public boolean isDebuffBlocked()
{
return isAffected(EffectFlag.BLOCK_DEBUFF);
}
public void setIsMortal(boolean b)

View File

@ -338,8 +338,8 @@ public final class L2CubicInstance implements IIdentifiable
// Duel targeting
if (_owner.isInDuel())
{
L2PcInstance PlayerA = DuelManager.getInstance().getDuel(_owner.getDuelId()).getPlayerA();
L2PcInstance PlayerB = DuelManager.getInstance().getDuel(_owner.getDuelId()).getPlayerB();
L2PcInstance PlayerA = DuelManager.getInstance().getDuel(_owner.getDuelId()).getTeamLeaderA();
L2PcInstance PlayerB = DuelManager.getInstance().getDuel(_owner.getDuelId()).getTeamLeaderB();
if (DuelManager.getInstance().getDuel(_owner.getDuelId()).isPartyDuel())
{

View File

@ -83,6 +83,7 @@ import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.enums.CastleSide;
import com.l2jserver.gameserver.enums.CategoryType;
import com.l2jserver.gameserver.enums.ChatType;
import com.l2jserver.gameserver.enums.DuelState;
import com.l2jserver.gameserver.enums.HtmlActionScope;
import com.l2jserver.gameserver.enums.IllegalActionPunishmentType;
import com.l2jserver.gameserver.enums.InstanceType;
@ -500,10 +501,8 @@ public final class L2PcInstance extends L2Playable
private int _olyBuffsCount = 0;
/** Duel */
private boolean _isInDuel = false;
private int _duelState = Duel.DUELSTATE_NODUEL;
private DuelState _duelState = DuelState.NO_DUEL;
private int _duelId = 0;
private SystemMessageId _noDuelReason = SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL;
/** Boat and AirShip */
private L2Vehicle _vehicle = null;
@ -4756,6 +4755,14 @@ public final class L2PcInstance extends L2Playable
@Override
public void doCast(Skill skill)
{
if (getCurrentSkill() != null)
{
if (!checkUseMagicConditions(skill, getCurrentSkill().isCtrlPressed(), getCurrentSkill().isShiftPressed()))
{
setIsCastingNow(false);
return;
}
}
super.doCast(skill);
setRecentFakeDeath(false);
}
@ -6721,7 +6728,7 @@ public final class L2PcInstance extends L2Playable
@Override
public boolean isInvul()
{
return super.isInvul() || (_teleportProtectEndTime > GameTimeController.getInstance().getGameTicks());
return super.isInvul() || _isTeleporting;
}
/**
@ -8638,8 +8645,17 @@ public final class L2PcInstance extends L2Playable
}
// is AutoAttackable if both players are in the same duel and the duel is still going on
if (attacker.isPlayable() && (getDuelState() == Duel.DUELSTATE_DUELLING) && (getDuelId() == attacker.getActingPlayer().getDuelId()))
if (attacker.isPlayable() && (getDuelState() == DuelState.DUELLING) && (getDuelId() == attacker.getActingPlayer().getDuelId()))
{
Duel duel = DuelManager.getInstance().getDuel(getDuelId());
if (duel.getTeamA().contains(this) && duel.getTeamA().contains(attacker))
{
return false;
}
else if (duel.getTeamB().contains(this) && duel.getTeamB().contains(attacker))
{
return false;
}
return true;
}
@ -8814,12 +8830,6 @@ public final class L2PcInstance extends L2Playable
setQueuedSkill(null, false, false);
}
if (!checkUseMagicConditions(skill, forceUse, dontMove))
{
setIsCastingNow(false);
return false;
}
// Check if the target is correct and Notify the AI with AI_INTENTION_CAST and target
L2Object target = null;
switch (skill.getTargetType())
@ -10181,7 +10191,7 @@ public final class L2PcInstance extends L2Playable
@Override
public boolean isInDuel()
{
return _isInDuel;
return _duelState != DuelState.NO_DUEL;
}
@Override
@ -10190,12 +10200,12 @@ public final class L2PcInstance extends L2Playable
return _duelId;
}
public void setDuelState(int mode)
public void setDuelState(DuelState mode)
{
_duelState = mode;
}
public int getDuelState()
public DuelState getDuelState()
{
return _duelState;
}
@ -10208,90 +10218,21 @@ public final class L2PcInstance extends L2Playable
{
if (duelId > 0)
{
_isInDuel = true;
_duelState = Duel.DUELSTATE_DUELLING;
_duelState = DuelState.DUELLING;
_duelId = duelId;
}
else
{
if (_duelState == Duel.DUELSTATE_DEAD)
if (_duelState == DuelState.DEAD)
{
enableAllSkills();
getStatus().startHpMpRegeneration();
}
_isInDuel = false;
_duelState = Duel.DUELSTATE_NODUEL;
_duelState = DuelState.NO_DUEL;
_duelId = 0;
}
}
/**
* This returns a SystemMessage stating why the player is not available for duelling.
* @return S1_CANNOT_DUEL... message
*/
public SystemMessage getNoDuelReason()
{
SystemMessage sm = SystemMessage.getSystemMessage(_noDuelReason);
sm.addPcName(this);
_noDuelReason = SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL;
return sm;
}
/**
* Checks if this player might join / start a duel.<br>
* To get the reason use getNoDuelReason() after calling this function.
* @return true if the player might join/start a duel.
*/
public boolean canDuel()
{
if (isInCombat() || isJailed())
{
_noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_CURRENTLY_ENGAGED_IN_BATTLE;
return false;
}
if (isDead() || isAlikeDead() || ((getCurrentHp() < (getMaxHp() / 2)) || (getCurrentMp() < (getMaxMp() / 2))))
{
_noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_S_HP_OR_MP_IS_BELOW_50;
return false;
}
if (isInDuel())
{
_noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_ALREADY_ENGAGED_IN_A_DUEL;
return false;
}
if (isInOlympiadMode())
{
_noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_PARTICIPATING_IN_THE_OLYMPIAD_OR_THE_CEREMONY_OF_CHAOS;
return false;
}
if (isCursedWeaponEquipped())
{
_noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_IN_A_CHAOTIC_OR_PURPLE_STATE;
return false;
}
if (getPrivateStoreType() != PrivateStoreType.NONE)
{
_noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_CURRENTLY_ENGAGED_IN_A_PRIVATE_STORE_OR_MANUFACTURE;
return false;
}
if (isMounted() || isInBoat())
{
_noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_CURRENTLY_RIDING_A_BOAT_FENRIR_OR_STRIDER;
return false;
}
if (isFishing())
{
_noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_CURRENTLY_FISHING;
return false;
}
if (isInsideZone(ZoneId.PVP) || isInsideZone(ZoneId.PEACE) || isInsideZone(ZoneId.SIEGE))
{
_noDuelReason = SystemMessageId.C1_CANNOT_MAKE_A_CHALLENGE_TO_A_DUEL_BECAUSE_C1_IS_CURRENTLY_IN_A_DUEL_PROHIBITED_AREA_PEACEFUL_ZONE_BATTLE_ZONE_NEAR_WATER_RESTART_PROHIBITED_AREA;
return false;
}
return true;
}
public boolean isNoble()
{
return _noble;
@ -11959,7 +11900,7 @@ public final class L2PcInstance extends L2Playable
if (inst != null)
{
inst.removePlayer(getObjectId());
final Location loc = inst.getSpawnLoc();
final Location loc = inst.getExitLoc();
if (loc != null)
{
final int x = loc.getX() + Rnd.get(-30, 30);
@ -12997,7 +12938,7 @@ public final class L2PcInstance extends L2Playable
final SystemMessage sm;
if (target.isInvul() && !target.isVulnerableFor(this) && !target.isNpc())
if ((target.isInvul() || target.isHpBlocked()) && !target.isVulnerableFor(this) && !target.isNpc())
{
sm = SystemMessage.getSystemMessage(SystemMessageId.THE_ATTACK_HAS_BEEN_BLOCKED);
}

View File

@ -184,40 +184,6 @@ public class L2ServitorInstance extends L2Summon implements Runnable
{
}
/**
* Servitors' skills automatically change their level based on the servitor's level.<br>
* Until level 70, the servitor gets 1 lv of skill per 10 levels.<br>
* After that, it is 1 skill level per 5 servitor levels.<br>
* If the resulting skill level doesn't exist use the max that does exist!
*/
@Override
public void doCast(Skill skill)
{
final int petLevel = getLevel();
int skillLevel = petLevel / 10;
if (petLevel >= 70)
{
skillLevel += (petLevel - 65) / 10;
}
// Adjust the level for servitors less than level 1.
if (skillLevel < 1)
{
skillLevel = 1;
}
final Skill skillToCast = SkillData.getInstance().getSkill(skill.getId(), skillLevel);
if (skillToCast != null)
{
super.doCast(skillToCast);
}
else
{
super.doCast(skill);
}
}
@Override
public void setRestoreSummon(boolean val)
{

View File

@ -86,13 +86,13 @@ public class L2SiegeFlagInstance extends L2Npc
@Override
public boolean canBeAttacked()
{
return !isInvul();
return !(isInvul() || isHpBlocked());
}
@Override
public boolean isAutoAttackable(L2Character attacker)
{
return !isInvul();
return !(isInvul() || isHpBlocked());
}
@Override

View File

@ -338,7 +338,7 @@ public final class L2TrapInstance extends L2Npc
OlympiadGameManager.getInstance().notifyCompetitorDamage(getOwner(), damage);
}
if (target.isInvul() && !(target instanceof L2NpcInstance))
if ((target.isInvul() || target.isHpBlocked()) && !target.isNpc())
{
_owner.sendPacket(SystemMessageId.THE_ATTACK_HAS_BEEN_BLOCKED);
}

View File

@ -141,7 +141,7 @@ public class CharStatus
}
// invul handling
if (getActiveChar().isInvul() && !(isDOT || isHPConsumption))
if ((getActiveChar().isInvul() || getActiveChar().isHpBlocked()) && !(isDOT || isHPConsumption))
{
return;
}

View File

@ -18,10 +18,10 @@
*/
package com.l2jserver.gameserver.model.actor.status;
import com.l2jserver.gameserver.enums.DuelState;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.Duel;
public class NpcStatus extends CharStatus
{
@ -49,7 +49,7 @@ public class NpcStatus extends CharStatus
final L2PcInstance attackerPlayer = attacker.getActingPlayer();
if ((attackerPlayer != null) && attackerPlayer.isInDuel())
{
attackerPlayer.setDuelState(Duel.DUELSTATE_INTERRUPTED);
attackerPlayer.setDuelState(DuelState.INTERRUPTED);
}
// Add attackers to npc's attacker list

View File

@ -20,6 +20,7 @@ package com.l2jserver.gameserver.model.actor.status;
import com.l2jserver.Config;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.enums.DuelState;
import com.l2jserver.gameserver.enums.PrivateStoreType;
import com.l2jserver.gameserver.instancemanager.DuelManager;
import com.l2jserver.gameserver.model.actor.L2Character;
@ -27,7 +28,6 @@ import com.l2jserver.gameserver.model.actor.L2Playable;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.stat.PcStat;
import com.l2jserver.gameserver.model.entity.Duel;
import com.l2jserver.gameserver.model.stats.Formulas;
import com.l2jserver.gameserver.model.stats.Stats;
import com.l2jserver.gameserver.network.SystemMessageId;
@ -83,7 +83,7 @@ public class PcStatus extends PlayableStatus
return;
}
if (getActiveChar().isInvul() && !getActiveChar().isVulnerableFor(attacker) && !(isDOT || isHPConsumption))
if ((getActiveChar().isInvul() || getActiveChar().isHpBlocked()) && !getActiveChar().isVulnerableFor(attacker) && !(isDOT || isHPConsumption))
{
return;
}
@ -129,11 +129,11 @@ public class PcStatus extends PlayableStatus
if (getActiveChar().isInDuel())
{
if (getActiveChar().getDuelState() == Duel.DUELSTATE_DEAD)
if (getActiveChar().getDuelState() == DuelState.DEAD)
{
return;
}
else if (getActiveChar().getDuelState() == Duel.DUELSTATE_WINNER)
else if (getActiveChar().getDuelState() == DuelState.WINNER)
{
return;
}
@ -141,7 +141,7 @@ public class PcStatus extends PlayableStatus
// cancel duel if player got hit by another player, that is not part of the duel
if (attackerPlayer.getDuelId() != getActiveChar().getDuelId())
{
getActiveChar().setDuelState(Duel.DUELSTATE_INTERRUPTED);
getActiveChar().setDuelState(DuelState.INTERRUPTED);
}
}
}
@ -280,7 +280,10 @@ public class PcStatus extends PlayableStatus
{
attacker.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
attacker.sendPacket(ActionFailed.STATIC_PACKET);
attacker.setTarget(null);
attacker.abortAttack();
}
// let the DuelManager know of his defeat
DuelManager.getInstance().onPlayerDefeat(getActiveChar());
value = 1;

View File

@ -18,11 +18,11 @@
*/
package com.l2jserver.gameserver.model.actor.status;
import com.l2jserver.gameserver.enums.DuelState;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Playable;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.Duel;
import com.l2jserver.gameserver.model.stats.Stats;
import com.l2jserver.gameserver.util.Util;
@ -50,7 +50,7 @@ public class SummonStatus extends PlayableStatus
final L2PcInstance attackerPlayer = attacker.getActingPlayer();
if ((attackerPlayer != null) && ((getActiveChar().getOwner() == null) || (getActiveChar().getOwner().getDuelId() != attackerPlayer.getDuelId())))
{
attackerPlayer.setDuelState(Duel.DUELSTATE_INTERRUPTED);
attackerPlayer.setDuelState(DuelState.INTERRUPTED);
}
final L2PcInstance caster = getActiveChar().getTransferingDamageTo();

View File

@ -24,6 +24,10 @@ package com.l2jserver.gameserver.model.effects;
public enum EffectFlag
{
NONE,
BLOCK_BUFF,
BLOCK_DEBUFF,
BLOCK_HP,
BLOCK_MP,
RESURRECTION_SPECIAL,
NOBLESS_BLESSING,
SILENT_MOVE,
@ -39,7 +43,6 @@ public enum EffectFlag
SLEEP,
STUNNED,
BETRAYED,
INVUL,
PARALYZED,
BLOCK_RESURRECTION,
SERVITOR_SHARE;

View File

@ -25,6 +25,9 @@ package com.l2jserver.gameserver.model.effects;
public enum L2EffectType
{
AGGRESSION,
BLOCK_BUFF,
BLOCK_DAMAGE,
BLOCK_DEBUFF,
BUFF,
CHARM_OF_LUCK,
CHAT_BLOCK,
@ -66,5 +69,5 @@ public enum L2EffectType
SUMMON_PET,
SUMMON_NPC,
TELEPORT,
TELEPORT_TO_TARGET,
TELEPORT_TO_TARGET
}

File diff suppressed because it is too large Load Diff

View File

@ -82,7 +82,9 @@ public final class Instance
private final List<L2Npc> _npcs = new CopyOnWriteArrayList<>();
private final Map<Integer, L2DoorInstance> _doors = new ConcurrentHashMap<>();
private final Map<String, List<L2Spawn>> _manualSpawn = new HashMap<>();
private Location _spawnLoc = null;
// private StartPosType _enterLocationOrder; TODO implement me
private List<Location> _enterLocations = null;
private Location _exitLocation = null;
private boolean _allowSummon = true;
private long _emptyDestroyTime = -1;
private long _lastLeft = -1;
@ -323,21 +325,38 @@ public final class Instance
return _timerText;
}
/**
* @return the spawn location for this instance to be used when enter in instance
*/
public List<Location> getEnterLocs()
{
return _enterLocations;
}
/**
* Sets the spawn location for this instance to be used when enter in instance
* @param loc
*/
public void addEnterLoc(Location loc)
{
_enterLocations.add(loc);
}
/**
* @return the spawn location for this instance to be used when leaving the instance
*/
public Location getSpawnLoc()
public Location getExitLoc()
{
return _spawnLoc;
return _exitLocation;
}
/**
* Sets the spawn location for this instance to be used when leaving the instance
* @param loc
*/
public void setSpawnLoc(Location loc)
public void setExitLoc(Location loc)
{
_spawnLoc = loc;
_exitLocation = loc;
}
public void removePlayers()
@ -348,9 +367,9 @@ public final class Instance
if ((player != null) && (player.getInstanceId() == getId()))
{
player.setInstanceId(0);
if (getSpawnLoc() != null)
if (getExitLoc() != null)
{
player.teleToLocation(getSpawnLoc(), true);
player.teleToLocation(getExitLoc(), true);
}
else
{
@ -477,257 +496,272 @@ public final class Instance
Node first = n.getFirstChild();
for (n = first; n != null; n = n.getNextSibling())
{
if ("activityTime".equalsIgnoreCase(n.getNodeName()))
switch (n.getNodeName().toLowerCase())
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
case "activitytime":
{
_checkTimeUpTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckTimeUp(Integer.parseInt(a.getNodeValue()) * 60000), 15000);
_instanceEndTime = System.currentTimeMillis() + (Long.parseLong(a.getNodeValue()) * 60000) + 15000;
}
}
// @formatter:off
/*
else if ("timeDelay".equalsIgnoreCase(n.getNodeName()))
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
instance.setTimeDelay(Integer.parseInt(a.getNodeValue()));
}
}
*/
// @formatter:on
else if ("allowSummon".equalsIgnoreCase(n.getNodeName()))
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
setAllowSummon(Boolean.parseBoolean(a.getNodeValue()));
}
}
else if ("emptyDestroyTime".equalsIgnoreCase(n.getNodeName()))
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
_emptyDestroyTime = Long.parseLong(a.getNodeValue()) * 1000;
}
}
else if ("showTimer".equalsIgnoreCase(n.getNodeName()))
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
_showTimer = Boolean.parseBoolean(a.getNodeValue());
}
a = n.getAttributes().getNamedItem("increase");
if (a != null)
{
_isTimerIncrease = Boolean.parseBoolean(a.getNodeValue());
}
a = n.getAttributes().getNamedItem("text");
if (a != null)
{
_timerText = a.getNodeValue();
}
}
else if ("PvPInstance".equalsIgnoreCase(n.getNodeName()))
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
setPvPInstance(Boolean.parseBoolean(a.getNodeValue()));
}
}
else if ("doorlist".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
int doorId = 0;
if ("door".equalsIgnoreCase(d.getNodeName()))
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
doorId = Integer.parseInt(d.getAttributes().getNamedItem("doorId").getNodeValue());
StatsSet set = new StatsSet();
set.add(DoorData.getInstance().getDoorTemplate(doorId));
for (Node bean = d.getFirstChild(); bean != null; bean = bean.getNextSibling())
{
if ("set".equalsIgnoreCase(bean.getNodeName()))
{
NamedNodeMap attrs = bean.getAttributes();
String setname = attrs.getNamedItem("name").getNodeValue();
String value = attrs.getNamedItem("val").getNodeValue();
set.set(setname, value);
}
}
addDoor(doorId, set);
_checkTimeUpTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckTimeUp(Integer.parseInt(a.getNodeValue()) * 60000), 15000);
_instanceEndTime = System.currentTimeMillis() + (Long.parseLong(a.getNodeValue()) * 60000) + 15000;
}
break;
}
}
else if ("spawnlist".equalsIgnoreCase(n.getNodeName()))
{
for (Node group = n.getFirstChild(); group != null; group = group.getNextSibling())
case "allowsummon":
{
if ("group".equalsIgnoreCase(group.getNodeName()))
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
String spawnGroup = group.getAttributes().getNamedItem("name").getNodeValue();
List<L2Spawn> manualSpawn = new ArrayList<>();
for (Node d = group.getFirstChild(); d != null; d = d.getNextSibling())
setAllowSummon(Boolean.parseBoolean(a.getNodeValue()));
}
break;
}
case "emptydestroytime":
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
_emptyDestroyTime = Long.parseLong(a.getNodeValue()) * 1000;
}
break;
}
case "showtimer":
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
_showTimer = Boolean.parseBoolean(a.getNodeValue());
}
a = n.getAttributes().getNamedItem("increase");
if (a != null)
{
_isTimerIncrease = Boolean.parseBoolean(a.getNodeValue());
}
a = n.getAttributes().getNamedItem("text");
if (a != null)
{
_timerText = a.getNodeValue();
}
break;
}
case "pvpinstance":
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
setPvPInstance(Boolean.parseBoolean(a.getNodeValue()));
}
break;
}
case "doorlist":
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
int doorId = 0;
if ("door".equalsIgnoreCase(d.getNodeName()))
{
int npcId = 0, x = 0, y = 0, z = 0, heading = 0, respawn = 0, respawnRandom = 0, delay = -1;
Boolean allowRandomWalk = null;
if ("spawn".equalsIgnoreCase(d.getNodeName()))
doorId = Integer.parseInt(d.getAttributes().getNamedItem("doorId").getNodeValue());
StatsSet set = new StatsSet();
set.add(DoorData.getInstance().getDoorTemplate(doorId));
for (Node bean = d.getFirstChild(); bean != null; bean = bean.getNextSibling())
{
npcId = Integer.parseInt(d.getAttributes().getNamedItem("npcId").getNodeValue());
x = Integer.parseInt(d.getAttributes().getNamedItem("x").getNodeValue());
y = Integer.parseInt(d.getAttributes().getNamedItem("y").getNodeValue());
z = Integer.parseInt(d.getAttributes().getNamedItem("z").getNodeValue());
heading = Integer.parseInt(d.getAttributes().getNamedItem("heading").getNodeValue());
respawn = Integer.parseInt(d.getAttributes().getNamedItem("respawn").getNodeValue());
if (d.getAttributes().getNamedItem("onKillDelay") != null)
if ("set".equalsIgnoreCase(bean.getNodeName()))
{
delay = Integer.parseInt(d.getAttributes().getNamedItem("onKillDelay").getNodeValue());
NamedNodeMap attrs = bean.getAttributes();
String setname = attrs.getNamedItem("name").getNodeValue();
String value = attrs.getNamedItem("val").getNodeValue();
set.set(setname, value);
}
if (d.getAttributes().getNamedItem("respawnRandom") != null)
}
addDoor(doorId, set);
}
}
break;
}
case "spawnlist":
{
for (Node group = n.getFirstChild(); group != null; group = group.getNextSibling())
{
if ("group".equalsIgnoreCase(group.getNodeName()))
{
String spawnGroup = group.getAttributes().getNamedItem("name").getNodeValue();
List<L2Spawn> manualSpawn = new ArrayList<>();
for (Node d = group.getFirstChild(); d != null; d = d.getNextSibling())
{
int npcId = 0, x = 0, y = 0, z = 0, heading = 0, respawn = 0, respawnRandom = 0, delay = -1;
Boolean allowRandomWalk = null;
if ("spawn".equalsIgnoreCase(d.getNodeName()))
{
respawnRandom = Integer.parseInt(d.getAttributes().getNamedItem("respawnRandom").getNodeValue());
}
if (d.getAttributes().getNamedItem("allowRandomWalk") != null)
{
allowRandomWalk = Boolean.valueOf(d.getAttributes().getNamedItem("allowRandomWalk").getNodeValue());
}
final L2Spawn spawnDat = new L2Spawn(npcId);
spawnDat.setX(x);
spawnDat.setY(y);
spawnDat.setZ(z);
spawnDat.setAmount(1);
spawnDat.setHeading(heading);
spawnDat.setRespawnDelay(respawn, respawnRandom);
if (respawn == 0)
{
spawnDat.stopRespawn();
}
else
{
spawnDat.startRespawn();
}
spawnDat.setInstanceId(getId());
if (allowRandomWalk == null)
{
spawnDat.setIsNoRndWalk(!_allowRandomWalk);
}
else
{
spawnDat.setIsNoRndWalk(!allowRandomWalk);
}
if (spawnGroup.equals("general"))
{
L2Npc spawned = spawnDat.doSpawn();
if ((delay >= 0) && (spawned instanceof L2Attackable))
npcId = Integer.parseInt(d.getAttributes().getNamedItem("npcId").getNodeValue());
x = Integer.parseInt(d.getAttributes().getNamedItem("x").getNodeValue());
y = Integer.parseInt(d.getAttributes().getNamedItem("y").getNodeValue());
z = Integer.parseInt(d.getAttributes().getNamedItem("z").getNodeValue());
heading = Integer.parseInt(d.getAttributes().getNamedItem("heading").getNodeValue());
respawn = Integer.parseInt(d.getAttributes().getNamedItem("respawn").getNodeValue());
if (d.getAttributes().getNamedItem("onKillDelay") != null)
{
((L2Attackable) spawned).setOnKillDelay(delay);
delay = Integer.parseInt(d.getAttributes().getNamedItem("onKillDelay").getNodeValue());
}
if (d.getAttributes().getNamedItem("respawnRandom") != null)
{
respawnRandom = Integer.parseInt(d.getAttributes().getNamedItem("respawnRandom").getNodeValue());
}
if (d.getAttributes().getNamedItem("allowRandomWalk") != null)
{
allowRandomWalk = Boolean.valueOf(d.getAttributes().getNamedItem("allowRandomWalk").getNodeValue());
}
final L2Spawn spawnDat = new L2Spawn(npcId);
spawnDat.setX(x);
spawnDat.setY(y);
spawnDat.setZ(z);
spawnDat.setAmount(1);
spawnDat.setHeading(heading);
spawnDat.setRespawnDelay(respawn, respawnRandom);
if (respawn == 0)
{
spawnDat.stopRespawn();
}
else
{
spawnDat.startRespawn();
}
spawnDat.setInstanceId(getId());
if (allowRandomWalk == null)
{
spawnDat.setIsNoRndWalk(!_allowRandomWalk);
}
else
{
spawnDat.setIsNoRndWalk(!allowRandomWalk);
}
if (spawnGroup.equals("general"))
{
L2Npc spawned = spawnDat.doSpawn();
if ((delay >= 0) && (spawned instanceof L2Attackable))
{
((L2Attackable) spawned).setOnKillDelay(delay);
}
}
else
{
manualSpawn.add(spawnDat);
}
}
else
}
if (!manualSpawn.isEmpty())
{
_manualSpawn.put(spawnGroup, manualSpawn);
}
}
}
break;
}
case "exitpoint":
{
int x = Integer.parseInt(n.getAttributes().getNamedItem("x").getNodeValue());
int y = Integer.parseInt(n.getAttributes().getNamedItem("y").getNodeValue());
int z = Integer.parseInt(n.getAttributes().getNamedItem("z").getNodeValue());
_exitLocation = new Location(x, y, z);
break;
}
case "spawnpoints":
{
_enterLocations = new ArrayList<>();
for (Node loc = n.getFirstChild(); loc != null; loc = loc.getNextSibling())
{
if (loc.getNodeName().equals("Location"))
{
try
{
int x = Integer.parseInt(loc.getAttributes().getNamedItem("x").getNodeValue());
int y = Integer.parseInt(loc.getAttributes().getNamedItem("y").getNodeValue());
int z = Integer.parseInt(loc.getAttributes().getNamedItem("z").getNodeValue());
_enterLocations.add(new Location(x, y, z));
}
catch (Exception e)
{
_log.log(Level.WARNING, "Error parsing instance xml: " + e.getMessage(), e);
}
}
}
break;
}
case "reenter":
{
a = n.getAttributes().getNamedItem("additionStyle");
if (a != null)
{
_type = InstanceReenterType.valueOf(a.getNodeValue());
}
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
long time = -1;
DayOfWeek day = null;
int hour = -1;
int minute = -1;
if ("reset".equalsIgnoreCase(d.getNodeName()))
{
a = d.getAttributes().getNamedItem("time");
if (a != null)
{
time = Long.parseLong(a.getNodeValue());
if (time > 0)
{
manualSpawn.add(spawnDat);
_resetData.add(new InstanceReenterTimeHolder(time));
break;
}
}
}
if (!manualSpawn.isEmpty())
{
_manualSpawn.put(spawnGroup, manualSpawn);
else if (time == -1)
{
a = d.getAttributes().getNamedItem("day");
if (a != null)
{
day = DayOfWeek.valueOf(a.getNodeValue().toUpperCase());
}
a = d.getAttributes().getNamedItem("hour");
if (a != null)
{
hour = Integer.parseInt(a.getNodeValue());
}
a = d.getAttributes().getNamedItem("minute");
if (a != null)
{
minute = Integer.parseInt(a.getNodeValue());
}
_resetData.add(new InstanceReenterTimeHolder(day, hour, minute));
}
}
}
break;
}
}
else if ("spawnpoint".equalsIgnoreCase(n.getNodeName()))
{
try
case "removebuffs":
{
int x = Integer.parseInt(n.getAttributes().getNamedItem("spawnX").getNodeValue());
int y = Integer.parseInt(n.getAttributes().getNamedItem("spawnY").getNodeValue());
int z = Integer.parseInt(n.getAttributes().getNamedItem("spawnZ").getNodeValue());
_spawnLoc = new Location(x, y, z);
}
catch (Exception e)
{
_log.log(Level.WARNING, "Error parsing instance xml: " + e.getMessage(), e);
_spawnLoc = null;
}
}
else if ("reenter".equalsIgnoreCase(n.getNodeName()))
{
a = n.getAttributes().getNamedItem("additionStyle");
if (a != null)
{
_type = InstanceReenterType.valueOf(a.getNodeValue());
}
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
long time = -1;
DayOfWeek day = null;
int hour = -1;
int minute = -1;
a = n.getAttributes().getNamedItem("type");
if (a != null)
{
_removeBuffType = InstanceRemoveBuffType.valueOf(a.getNodeValue().toUpperCase());
}
if ("reset".equalsIgnoreCase(d.getNodeName()))
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
a = d.getAttributes().getNamedItem("time");
if (a != null)
if ("skill".equalsIgnoreCase(d.getNodeName()))
{
time = Long.parseLong(a.getNodeValue());
if (time > 0)
{
_resetData.add(new InstanceReenterTimeHolder(time));
break;
}
}
else if (time == -1)
{
a = d.getAttributes().getNamedItem("day");
a = d.getAttributes().getNamedItem("id");
if (a != null)
{
day = DayOfWeek.valueOf(a.getNodeValue().toUpperCase());
_exceptionList.add(Integer.parseInt(a.getNodeValue()));
}
a = d.getAttributes().getNamedItem("hour");
if (a != null)
{
hour = Integer.parseInt(a.getNodeValue());
}
a = d.getAttributes().getNamedItem("minute");
if (a != null)
{
minute = Integer.parseInt(a.getNodeValue());
}
_resetData.add(new InstanceReenterTimeHolder(day, hour, minute));
}
}
}
}
else if ("removeBuffs".equalsIgnoreCase(n.getNodeName()))
{
a = n.getAttributes().getNamedItem("type");
if (a != null)
{
_removeBuffType = InstanceRemoveBuffType.valueOf(a.getNodeValue().toUpperCase());
}
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("skill".equalsIgnoreCase(d.getNodeName()))
{
a = d.getAttributes().getNamedItem("id");
if (a != null)
{
_exceptionList.add(Integer.parseInt(a.getNodeValue()));
}
}
break;
}
}
}
@ -854,9 +888,9 @@ public final class Instance
if (player.isDead() && (player.getInstanceId() == getId()))
{
player.setInstanceId(0);
if (getSpawnLoc() != null)
if (getExitLoc() != null)
{
player.teleToLocation(getSpawnLoc(), true);
player.teleToLocation(getExitLoc(), true);
}
else
{
@ -934,4 +968,4 @@ public final class Instance
{
return _exceptionList;
}
}
}

View File

@ -20,6 +20,7 @@ package com.l2jserver.gameserver.model.entity;
import com.l2jserver.Config;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.enums.DuelState;
import com.l2jserver.gameserver.enums.Team;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
@ -77,14 +78,14 @@ public class TvTEventTeleporter implements Runnable
_playerInstance.getServitors().values().forEach(s -> s.unSummon(_playerInstance));
if ((Config.TVT_EVENT_EFFECTS_REMOVAL == 0) || ((Config.TVT_EVENT_EFFECTS_REMOVAL == 1) && ((_playerInstance.getTeam() == Team.NONE) || (_playerInstance.isInDuel() && (_playerInstance.getDuelState() != Duel.DUELSTATE_INTERRUPTED)))))
if ((Config.TVT_EVENT_EFFECTS_REMOVAL == 0) || ((Config.TVT_EVENT_EFFECTS_REMOVAL == 1) && ((_playerInstance.getTeam() == Team.NONE) || (_playerInstance.isInDuel() && (_playerInstance.getDuelState() != DuelState.INTERRUPTED)))))
{
_playerInstance.stopAllEffectsExceptThoseThatLastThroughDeath();
}
if (_playerInstance.isInDuel())
{
_playerInstance.setDuelState(Duel.DUELSTATE_INTERRUPTED);
_playerInstance.setDuelState(DuelState.INTERRUPTED);
}
int TvTInstance = TvTEvent.getTvTEventInstance();

View File

@ -1372,6 +1372,21 @@ public final class Skill implements IIdentifiable
return;
}
if (isDebuff())
{
if (effected.isDebuffBlocked())
{
return;
}
}
else
{
if (effected.isBuffBlocked() && !isBad())
{
return;
}
}
if (effected.isInvulAgainst(getId(), getLevel()))
{
effected.sendDebugMessage("Skill " + toString() + " has been ignored (invul against)");

View File

@ -1337,12 +1337,9 @@ public final class Formulas
double attack = 2 * actor.getMAtk(target, skill) * calcGeneralTraitBonus(actor, target, skill.getTraitType(), false);
double d = (attack - defence) / (attack + defence);
if (skill.isDebuff())
if (skill.isDebuff() && target.isDebuffBlocked())
{
if (target.calcStat(Stats.DEBUFF_IMMUNITY, 0, null, skill) > 0)
{
return false;
}
return false;
}
d += 0.5 * Rnd.nextGaussian();
@ -1372,7 +1369,7 @@ public final class Formulas
return false;
}
if (skill.isDebuff() && (target.calcStat(Stats.DEBUFF_IMMUNITY, 0, attacker, skill) > 0))
if (skill.isDebuff() && target.isDebuffBlocked())
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_RESISTED_YOUR_S2);
sm.addCharName(target);
@ -1470,7 +1467,7 @@ public final class Formulas
{
return true;
}
else if (target.calcStat(Stats.DEBUFF_IMMUNITY, 0, null, skill) > 0)
else if (target.isDebuffBlocked())
{
return false;
}
@ -2024,6 +2021,7 @@ public final class Formulas
int cancelMagicLvl = skill.getMagicLevel();
final double vuln = target.calcStat(Stats.CANCEL_VULN, 0, target, null);
final double prof = activeChar.calcStat(Stats.CANCEL_PROF, 0, target, null);
double resMod = 1 + (((vuln + prof) * -1) / 100);
double finalRate = rate / resMod;

View File

@ -136,8 +136,6 @@ public enum Stats
HOLY_RES("holyRes"),
DARK_RES("darkRes"),
MAGIC_SUCCESS_RES("magicSuccRes"),
// BUFF_IMMUNITY("buffImmunity"), //TODO: Implement me
DEBUFF_IMMUNITY("debuffImmunity"),
// ELEMENT POWER
FIRE_POWER("firePower"),

View File

@ -743,7 +743,6 @@ public final class L2GamePacketHandler implements IPacketHandler<L2GameClient>,
case 0xcf: // RequestProcureCrop
// msg = new RequestBuyProcure();
break;
case 0xd0:
int id2 = -1;
if (buf.remaining() >= 2)

View File

@ -19,6 +19,7 @@
package com.l2jserver.gameserver.network.clientpackets;
import com.l2jserver.Config;
import com.l2jserver.gameserver.enums.DuelState;
import com.l2jserver.gameserver.model.L2Object;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.PcCondOverride;
@ -28,6 +29,7 @@ import com.l2jserver.gameserver.model.skills.AbnormalType;
import com.l2jserver.gameserver.model.skills.BuffInfo;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
public final class Action extends L2GameClientPacket
{
@ -107,6 +109,12 @@ public final class Action extends L2GameClientPacket
return;
}
if (obj.isPlayable() && (obj.getActingPlayer().getDuelState() == DuelState.DEAD))
{
sendPacket(ActionFailed.STATIC_PACKET);
activeChar.getActingPlayer().sendPacket(SystemMessage.getSystemMessage(SystemMessageId.THE_OTHER_PARTY_IS_FROZEN_PLEASE_WAIT_A_MOMENT));
return;
}
if (!obj.isTargetable() && !activeChar.canOverrideCond(PcCondOverride.TARGET_ALL))
{
sendPacket(ActionFailed.STATIC_PACKET);

View File

@ -45,6 +45,7 @@ import com.l2jserver.gameserver.model.effects.AbstractEffect;
import com.l2jserver.gameserver.model.effects.L2EffectType;
import com.l2jserver.gameserver.model.skills.AbnormalType;
import com.l2jserver.gameserver.model.skills.BuffInfo;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
@ -249,10 +250,10 @@ public final class RequestActionUse extends L2GameClientPacket
activeChar.tryOpenPrivateBuyStore();
break;
case 32: // Wild Hog Cannon - Wild Cannon
useSkill(4230, false);
useSkill("DDMagic", false);
break;
case 36: // Soulless - Toxic Smoke
useSkill(4259, false);
useSkill("RangeDebuff", false);
break;
case 37: // Dwarven Manufacture
if (activeChar.isAlikeDead())
@ -276,7 +277,7 @@ public final class RequestActionUse extends L2GameClientPacket
activeChar.mountPlayer(pet);
break;
case 39: // Soulless - Parasite Burst
useSkill(4138, false);
useSkill("RangeDD", false);
break;
case 41: // Wild Hog Cannon - Attack
if (validateSummon(servitor, false))
@ -292,25 +293,25 @@ public final class RequestActionUse extends L2GameClientPacket
}
break;
case 42: // Kai the Cat - Self Damage Shield
useSkill(4378, activeChar, false);
useSkill("HealMagic", false);
break;
case 43: // Unicorn Merrow - Hydro Screw
useSkill(4137, false);
case 43: // Merrow the Unicorn - Hydro Screw
useSkill("DDMagic", false);
break;
case 44: // Big Boom - Boom Attack
useSkill(4139, false);
useSkill("DDMagic", false);
break;
case 45: // Unicorn Boxer - Master Recharge
useSkill(4025, activeChar, false);
case 45: // Boxer the Unicorn - Master Recharge
useSkill("HealMagic", activeChar, false);
break;
case 46: // Mew the Cat - Mega Storm Strike
useSkill(4261, false);
useSkill("DDMagic", false);
break;
case 47: // Silhouette - Steal Blood
useSkill(4260, false);
useSkill("DDMagic", false);
break;
case 48: // Mechanic Golem - Mech. Cannon
useSkill(4068, false);
useSkill("DDMagic", false);
break;
case 51: // General Manufacture
// Player shouldn't be able to set stores if he/she is alike dead (dead or fake death)
@ -459,97 +460,91 @@ public final class RequestActionUse extends L2GameClientPacket
}
break;
case 1003: // Wind Hatchling/Strider - Wild Stun
useSkill(4710, true);
useSkill("PhysicalSpecial", true);
break;
case 1004: // Wind Hatchling/Strider - Wild Defense
useSkill(4711, activeChar, true);
useSkill("Buff", activeChar, true);
break;
case 1005: // Star Hatchling/Strider - Bright Burst
useSkill(4712, true);
useSkill("DDMagic", true);
break;
case 1006: // Star Hatchling/Strider - Bright Heal
useSkill(4713, activeChar, true);
useSkill("Heal", activeChar, true);
break;
case 1007: // Cat Queen - Blessing of Queen
useSkill(4699, activeChar, false);
case 1007: // Feline Queen - Blessing of Queen
useSkill("Buff1", activeChar, false);
break;
case 1008: // Cat Queen - Gift of Queen
useSkill(4700, activeChar, false);
case 1008: // Feline Queen - Gift of Queen
useSkill("Buff2", activeChar, false);
break;
case 1009: // Cat Queen - Cure of Queen
useSkill(4701, false);
case 1009: // Feline Queen - Cure of Queen
useSkill("DDMagic", false);
break;
case 1010: // Unicorn Seraphim - Blessing of Seraphim
useSkill(4702, activeChar, false);
useSkill("Buff1", activeChar, false);
break;
case 1011: // Unicorn Seraphim - Gift of Seraphim
useSkill(4703, activeChar, false);
useSkill("Buff2", activeChar, false);
break;
case 1012: // Unicorn Seraphim - Cure of Seraphim
useSkill(4704, false);
useSkill("DDMagic", false);
break;
case 1013: // Nightshade - Curse of Shade
useSkill(4705, false);
useSkill("DeBuff1", false);
break;
case 1014: // Nightshade - Mass Curse of Shade
useSkill(4706, false);
useSkill("DeBuff2", false);
break;
case 1015: // Nightshade - Shade Sacrifice
useSkill(4707, false);
useSkill("Heal", false);
break;
case 1016: // Cursed Man - Cursed Blow
useSkill(4709, false);
useSkill("PhysicalSpecial1", false);
break;
case 1017: // Cursed Man - Cursed Strike/Stun
useSkill(4708, false);
case 1017: // Cursed Man - Cursed Strike
useSkill("PhysicalSpecial2", false);
break;
case 1031: // Feline King - Slash
useSkill(5135, false);
useSkill("PhysicalSpecial1", false);
break;
case 1032: // Feline King - Spinning Slash
useSkill(5136, false);
useSkill("PhysicalSpecial2", false);
break;
case 1033: // Feline King - Grip of the Cat
useSkill(5137, false);
case 1033: // Feline King - Hold of King
useSkill("PhysicalSpecial3", false);
break;
case 1034: // Magnus the Unicorn - Whiplash
useSkill(5138, false);
useSkill("PhysicalSpecial1", false);
break;
case 1035: // Magnus the Unicorn - Tridal Wave
useSkill(5139, false);
useSkill("PhysicalSpecial2", false);
break;
case 1036: // Spectral Lord - Corpse Kaboom
useSkill(5142, false);
useSkill("PhysicalSpecial1", false);
break;
case 1037: // Spectral Lord - Dicing Death
useSkill(5141, false);
useSkill("PhysicalSpecial2", false);
break;
case 1038: // Spectral Lord - Force Curse
useSkill(5140, false);
case 1038: // Spectral Lord - Dark Curse
useSkill("PhysicalSpecial3", false);
break;
case 1039: // Swoop Cannon - Cannon Fodder
if ((target != null) && target.isDoor())
{
useSkill(5110, false);
}
useSkill(5110, false);
break;
case 1040: // Swoop Cannon - Big Bang
if ((target != null) && target.isDoor())
{
useSkill(5111, false);
}
useSkill(5111, false);
break;
case 1041: // Great Wolf - Bite Attack
useSkill(5442, true);
useSkill("Skill01", true);
break;
case 1042: // Great Wolf - Maul
useSkill(5444, true);
useSkill("Skill03", true);
break;
case 1043: // Great Wolf - Cry of the Wolf
useSkill(5443, true);
useSkill("Skill02", true);
break;
case 1044: // Great Wolf - Awakening
useSkill(5445, true);
useSkill("Skill04", true);
break;
case 1045: // Great Wolf - Howl
useSkill(5584, true);
@ -570,34 +565,34 @@ public final class RequestActionUse extends L2GameClientPacket
useSkill(5583, false);
break;
case 1051: // Feline Queen - Bless The Body
useSkill(5638, false);
useSkill("buff3", false);
break;
case 1052: // Feline Queen - Bless The Soul
useSkill(5639, false);
useSkill("buff4", false);
break;
case 1053: // Feline Queen - Haste
useSkill(5640, false);
useSkill("buff5", false);
break;
case 1054: // Unicorn Seraphim - Acumen
useSkill(5643, false);
useSkill("buff3", false);
break;
case 1055: // Unicorn Seraphim - Clarity
useSkill(5647, false);
useSkill("buff4", false);
break;
case 1056: // Unicorn Seraphim - Empower
useSkill(5648, false);
useSkill("buff5", false);
break;
case 1057: // Unicorn Seraphim - Wild Magic
useSkill(5646, false);
useSkill("buff6", false);
break;
case 1058: // Nightshade - Death Whisper
useSkill(5652, false);
useSkill("buff3", false);
break;
case 1059: // Nightshade - Focus
useSkill(5653, false);
useSkill("buff4", false);
break;
case 1060: // Nightshade - Guidance
useSkill(5654, false);
useSkill("buff5", false);
break;
case 1061: // Wild Beast Fighter, White Weasel - Death blow
useSkill(5745, true);
@ -630,7 +625,7 @@ public final class RequestActionUse extends L2GameClientPacket
useSkill(5771, true);
break;
case 1071: // Tigress - Power Strike
useSkill(5761, true);
useSkill("DDMagic", true);
break;
case 1072: // Toy Knight - Piercing attack
useSkill(6046, true);
@ -1046,18 +1041,8 @@ public final class RequestActionUse extends L2GameClientPacket
return;
}
if (summon instanceof L2BabyPetInstance)
if (!canControl(summon))
{
if (!((L2BabyPetInstance) summon).isInSupportMode())
{
sendPacket(SystemMessageId.A_PET_ON_AUXILIARY_MODE_CANNOT_USE_SKILLS);
return;
}
}
if ((summon.getLevel() - activeChar.getLevel()) > 20)
{
sendPacket(SystemMessageId.YOUR_PET_IS_TOO_HIGH_LEVEL_TO_CONTROL);
return;
}
@ -1092,6 +1077,69 @@ public final class RequestActionUse extends L2GameClientPacket
}
}
private void useSkill(String skillName, L2Object target, boolean pet)
{
final L2PcInstance activeChar = getActiveChar();
if (activeChar == null)
{
return;
}
final L2Summon summon = activeChar.getPet();
if (!validateSummon(summon, pet))
{
return;
}
if (!canControl(summon))
{
return;
}
if (summon instanceof L2BabyPetInstance)
{
if (!((L2BabyPetInstance) summon).isInSupportMode())
{
sendPacket(SystemMessageId.A_PET_ON_AUXILIARY_MODE_CANNOT_USE_SKILLS);
return;
}
}
final Skill skill = summon.getTemplate().getParameters().getSkillHolder(skillName).getSkill();
if (skill != null)
{
summon.setTarget(target);
summon.useMagic(skill, _ctrlPressed, _shiftPressed);
if (skill.getId() == SWITCH_STANCE_ID)
{
summon.switchMode();
}
}
}
private boolean canControl(L2Summon summon)
{
if (summon instanceof L2BabyPetInstance)
{
if (!((L2BabyPetInstance) summon).isInSupportMode())
{
sendPacket(SystemMessageId.A_PET_ON_AUXILIARY_MODE_CANNOT_USE_SKILLS);
return false;
}
}
if (summon.isPet())
{
if ((summon.getLevel() - getActiveChar().getLevel()) > 20)
{
sendPacket(SystemMessageId.YOUR_PET_IS_TOO_HIGH_LEVEL_TO_CONTROL);
return false;
}
}
return true;
}
/**
* Cast a skill for active summon.<br>
* Target is retrieved from owner's target, then validated by overloaded method useSkill(int, L2Character).
@ -1109,6 +1157,23 @@ public final class RequestActionUse extends L2GameClientPacket
useSkill(skillId, activeChar.getTarget(), pet);
}
/**
* Cast a skill for active summon.<br>
* Target is retrieved from owner's target, then validated by overloaded method useSkill(int, L2Character).
* @param skillName the skill name to use
* @param pet if {@code true} it'll validate a pet, if {@code false} it will validate a servitor
*/
private void useSkill(String skillName, boolean pet)
{
final L2PcInstance activeChar = getActiveChar();
if (activeChar == null)
{
return;
}
useSkill(skillName, activeChar.getTarget(), pet);
}
/**
* Cast a skill for all active summon.<br>
* Target is retrieved from owner's target

View File

@ -94,7 +94,7 @@ public final class RequestDuelAnswerStart extends L2GameClientPacket
player.sendPacket(msg1);
requestor.sendPacket(msg2);
DuelManager.getInstance().addDuel(requestor, player, _partyDuel);
DuelManager.getInstance().addDuel(requestor, player, _partyDuel == 1 ? true : false);
}
else if (_response == -1)
{

View File

@ -19,6 +19,7 @@
package com.l2jserver.gameserver.network.clientpackets;
import com.l2jserver.Config;
import com.l2jserver.gameserver.instancemanager.DuelManager;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
@ -48,87 +49,65 @@ public final class RequestDuelStart extends L2GameClientPacket
{
L2PcInstance activeChar = getClient().getActiveChar();
L2PcInstance targetChar = L2World.getInstance().getPlayer(_player);
if (activeChar == null)
boolean isPartyDuel = _partyDuel == 1 ? true : false;
if ((activeChar == null) || (targetChar == null))
{
return;
}
if (targetChar == null)
{
activeChar.sendPacket(SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL);
return;
}
if (activeChar == targetChar)
{
activeChar.sendPacket(SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL);
if (isPartyDuel)
{
activeChar.sendPacket(SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL);
}
return;
}
// Check if duel is possible
if (!activeChar.canDuel())
{
activeChar.sendPacket(SystemMessageId.YOU_ARE_UNABLE_TO_REQUEST_A_DUEL_AT_THIS_TIME);
return;
}
else if (!targetChar.canDuel())
{
activeChar.sendPacket(targetChar.getNoDuelReason());
return;
}
// Players may not be too far apart
else if (!activeChar.isInsideRadius(targetChar, 250, false, false))
if (!activeChar.isInsideRadius(targetChar, 250, false, false))
{
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_TOO_FAR_AWAY_TO_RECEIVE_A_DUEL_CHALLENGE);
msg.addString(targetChar.getName());
activeChar.sendPacket(msg);
return;
}
else if (Config.FACTION_SYSTEM_ENABLED && ((activeChar.isEvil() && targetChar.isGood()) || (activeChar.isGood() && targetChar.isEvil())))
if (Config.FACTION_SYSTEM_ENABLED && ((activeChar.isEvil() && targetChar.isGood()) || (activeChar.isGood() && targetChar.isEvil())))
{
activeChar.sendPacket(SystemMessageId.YOU_ARE_UNABLE_TO_REQUEST_A_DUEL_AT_THIS_TIME);
return;
}
// Check if duel is possible
if (!DuelManager.canDuel(activeChar, activeChar, isPartyDuel))
{
return;
}
if (!DuelManager.canDuel(activeChar, targetChar, isPartyDuel))
{
return;
}
// Duel is a party duel
if (_partyDuel == 1)
if (isPartyDuel)
{
// Player must be in a party & the party leader
if (!activeChar.isInParty() || !activeChar.getParty().isLeader(activeChar))
if (!activeChar.isInParty() || !activeChar.getParty().isLeader(activeChar) || !targetChar.isInParty() || activeChar.getParty().containsPlayer(targetChar))
{
activeChar.sendMessage("You have to be the leader of a party in order to request a party duel.");
return;
}
// Target must be in a party
else if (!targetChar.isInParty())
{
activeChar.sendPacket(SystemMessageId.SINCE_THE_PERSON_YOU_CHALLENGED_IS_NOT_CURRENTLY_IN_A_PARTY_THEY_CANNOT_DUEL_AGAINST_YOUR_PARTY);
return;
}
// Target may not be of the same party
else if (activeChar.getParty().containsPlayer(targetChar))
{
activeChar.sendMessage("This player is a member of your own party.");
activeChar.sendPacket(SystemMessageId.YOU_ARE_UNABLE_TO_REQUEST_A_DUEL_AT_THIS_TIME);
return;
}
// Check if every player is ready for a duel
for (L2PcInstance temp : activeChar.getParty().getMembers())
{
if (!temp.canDuel())
if (!DuelManager.canDuel(activeChar, temp, isPartyDuel))
{
activeChar.sendMessage("Not all the members of your party are ready for a duel.");
return;
}
}
L2PcInstance partyLeader = null; // snatch party leader of targetChar's party
L2PcInstance partyLeader = targetChar.getParty().getLeader(); // snatch party leader of targetChar's party
for (L2PcInstance temp : targetChar.getParty().getMembers())
{
if (partyLeader == null)
if (!DuelManager.canDuel(activeChar, temp, isPartyDuel))
{
partyLeader = temp;
}
if (!temp.canDuel())
{
activeChar.sendPacket(SystemMessageId.THE_OPPOSING_PARTY_IS_CURRENTLY_UNABLE_TO_ACCEPT_A_CHALLENGE_TO_A_DUEL);
return;
}
}