/** Teleports all players to a free arena. */ public void teleportPlayers() { if (!_partyDuel) { return; } final String instanceName = DuelManager.getInstance().getDuelArena(); final L2OlympiadStadiumZone zone = ZoneManager.getInstance() .getAllZones(L2OlympiadStadiumZone.class) // .stream() .filter(z -> z.getInstanceTemplate().equals(instanceName)) .findFirst() .orElse(null); if (zone == null) { throw new RuntimeException("Unable to find a party duel arena!"); } final List<Location> spawns = zone.getSpawns(); _duelInstanceId = InstanceManager.getInstance().createDynamicInstance(instanceName); // Remove Olympiad buffers for (L2Npc buffer : InstanceManager.getInstance().getInstance(getDueldInstanceId()).getNpcs()) { if ((buffer instanceof L2OlympiadManagerInstance) && buffer.isVisible()) { buffer.decayMe(); } } final Location spawn1 = spawns.get(Rnd.get(spawns.size() / 2)); for (L2PcInstance temp : _playerA.getParty().getMembers()) { temp.teleToLocation(spawn1.getX(), spawn1.getY(), spawn1.getZ(), 0, _duelInstanceId, 0); } final Location spawn2 = spawns.get(Rnd.get(spawns.size() / 2, spawns.size())); for (L2PcInstance temp : _playerB.getParty().getMembers()) { temp.teleToLocation(spawn2.getX(), spawn2.getY(), spawn2.getZ(), 0, _duelInstanceId, 0); } }
@Override protected void runImpl() { DuelManager.getInstance().doSurrender(getClient().getActiveChar()); }
/** * The duel has reached a state in which it can no longer continue * * @param result the duel result. */ public void endDuel(DuelResult result) { if ((_playerA == null) || (_playerB == null)) { // clean up _playerConditions.clear(); DuelManager.getInstance().removeDuel(this); return; } // inform players of the result SystemMessage sm = null; switch (result) { case Team1Win: case Team2Surrender: restorePlayerConditions(false); // send SystemMessage if (_partyDuel) { sm = SystemMessage.getSystemMessage(SystemMessageId.C1_S_PARTY_HAS_WON_THE_DUEL); } else { sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_WON_THE_DUEL); } sm.addString(_playerA.getName()); broadcastToTeam1(sm); broadcastToTeam2(sm); break; case Team1Surrender: case Team2Win: restorePlayerConditions(false); // send SystemMessage if (_partyDuel) { sm = SystemMessage.getSystemMessage(SystemMessageId.C1_S_PARTY_HAS_WON_THE_DUEL); } else { sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_WON_THE_DUEL); } sm.addString(_playerB.getName()); broadcastToTeam1(sm); broadcastToTeam2(sm); break; case Canceled: stopFighting(); // Don't restore hp, mp, cp restorePlayerConditions(true); // TODO: is there no other message for a canceled duel? // send SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.THE_DUEL_HAS_ENDED_IN_A_TIE); broadcastToTeam1(sm); broadcastToTeam2(sm); break; case Timeout: stopFighting(); // hp,mp,cp seem to be restored in a timeout too... restorePlayerConditions(false); // send SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.THE_DUEL_HAS_ENDED_IN_A_TIE); broadcastToTeam1(sm); broadcastToTeam2(sm); break; } final ExDuelEnd duelEnd = _partyDuel ? ExDuelEnd.PARTY_DUEL : ExDuelEnd.PLAYER_DUEL; broadcastToTeam1(duelEnd); broadcastToTeam2(duelEnd); // clean up _playerConditions.clear(); DuelManager.getInstance().removeDuel(this); }
/** Starts the duel */ public void startDuel() { if ((_playerA == null) || (_playerB == null) || _playerA.isInDuel() || _playerB.isInDuel()) { _playerConditions.clear(); DuelManager.getInstance().removeDuel(this); return; } if (_partyDuel) { // Set duel state and team for (L2PcInstance temp : _playerA.getParty().getMembers()) { temp.cancelActiveTrade(); temp.setIsInDuel(_duelId); temp.setTeam(Team.BLUE); temp.broadcastUserInfo(); broadcastToTeam2(new ExDuelUpdateUserInfo(temp)); } for (L2PcInstance temp : _playerB.getParty().getMembers()) { temp.cancelActiveTrade(); temp.setIsInDuel(_duelId); temp.setTeam(Team.RED); temp.broadcastUserInfo(); broadcastToTeam1(new ExDuelUpdateUserInfo(temp)); } // Send duel packets broadcastToTeam1(ExDuelReady.PARTY_DUEL); broadcastToTeam2(ExDuelReady.PARTY_DUEL); broadcastToTeam1(ExDuelStart.PARTY_DUEL); broadcastToTeam2(ExDuelStart.PARTY_DUEL); // Open arena doors for (L2DoorInstance door : InstanceManager.getInstance().getInstance(getDueldInstanceId()).getDoors()) { if ((door != null) && !door.getOpen()) { door.openMe(); } } } else { // Set duel state and team _playerA.setIsInDuel(_duelId); _playerA.setTeam(Team.BLUE); _playerB.setIsInDuel(_duelId); _playerB.setTeam(Team.RED); // Send duel Start packets // Send duel packets broadcastToTeam1(ExDuelReady.PLAYER_DUEL); broadcastToTeam2(ExDuelReady.PLAYER_DUEL); broadcastToTeam1(ExDuelStart.PLAYER_DUEL); broadcastToTeam2(ExDuelStart.PLAYER_DUEL); broadcastToTeam1(new ExDuelUpdateUserInfo(_playerB)); broadcastToTeam2(new ExDuelUpdateUserInfo(_playerA)); _playerA.broadcastUserInfo(); _playerB.broadcastUserInfo(); } // play sound broadcastToTeam1(B04_S01); broadcastToTeam2(B04_S01); // start dueling task ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleDuelTask(this), 1000); }
public final void reduceHp( double value, L2Character attacker, boolean awake, boolean isDOT, boolean isHPConsumption, boolean ignoreCP) { if (getActiveChar().isDead()) { return; } // If OFFLINE_MODE_NO_DAMAGE is enabled and player is offline and he is in store/craft mode, no // damage is taken. if (Config.OFFLINE_MODE_NO_DAMAGE && (getActiveChar().getClient() != null) && getActiveChar().getClient().isDetached() && ((Config.OFFLINE_TRADE_ENABLE && ((getActiveChar().getPrivateStoreType() == L2PcInstance.STORE_PRIVATE_SELL) || (getActiveChar().getPrivateStoreType() == L2PcInstance.STORE_PRIVATE_BUY))) || (Config.OFFLINE_CRAFT_ENABLE && (getActiveChar().isInCraftMode() || (getActiveChar().getPrivateStoreType() == L2PcInstance.STORE_PRIVATE_MANUFACTURE))))) { return; } if (getActiveChar().isInvul() && !(isDOT || isHPConsumption)) { return; } if (!isHPConsumption) { getActiveChar().stopEffectsOnDamage(awake); // Attacked players in craft/shops stand up. if (getActiveChar().isInCraftMode() || getActiveChar().isInStoreMode()) { getActiveChar().setPrivateStoreType(L2PcInstance.STORE_PRIVATE_NONE); getActiveChar().standUp(); getActiveChar().broadcastUserInfo(); } else if (getActiveChar().isSitting()) { getActiveChar().standUp(); } if (!isDOT) { if (getActiveChar().isStunned() && (Rnd.get(10) == 0)) { getActiveChar().stopStunning(true); } } } int fullValue = (int) value; int tDmg = 0; int mpDam = 0; if ((attacker != null) && (attacker != getActiveChar())) { final L2PcInstance attackerPlayer = attacker.getActingPlayer(); if (attackerPlayer != null) { if (attackerPlayer.isGM() && !attackerPlayer.getAccessLevel().canGiveDamage()) { return; } if (getActiveChar().isInDuel()) { if (getActiveChar().getDuelState() == Duel.DUELSTATE_DEAD) { return; } else if (getActiveChar().getDuelState() == Duel.DUELSTATE_WINNER) { return; } // 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); } } } // Check and calculate transfered damage final L2Summon summon = getActiveChar().getSummon(); if (getActiveChar().hasSummon() && summon.isServitor() && Util.checkIfInRange(1000, getActiveChar(), summon, true)) { tDmg = ((int) value * (int) getActiveChar() .getStat() .calcStat(Stats.TRANSFER_DAMAGE_PERCENT, 0, null, null)) / 100; // Only transfer dmg up to current HP, it should not be killed tDmg = Math.min((int) summon.getCurrentHp() - 1, tDmg); if (tDmg > 0) { summon.reduceCurrentHp(tDmg, attacker, null); value -= tDmg; fullValue = (int) value; // reduce the announced value here as player will get a message about // summon damage } } mpDam = ((int) value * (int) getActiveChar().getStat().calcStat(Stats.MANA_SHIELD_PERCENT, 0, null, null)) / 100; if (mpDam > 0) { mpDam = (int) (value - mpDam); if (mpDam > getActiveChar().getCurrentMp()) { getActiveChar().sendPacket(SystemMessageId.MP_BECAME_0_ARCANE_SHIELD_DISAPPEARING); getActiveChar().getFirstEffect(1556).stopEffectTask(); value = mpDam - getActiveChar().getCurrentMp(); getActiveChar().setCurrentMp(0); } else { getActiveChar().reduceCurrentMp(mpDam); SystemMessage smsg = SystemMessage.getSystemMessage( SystemMessageId.ARCANE_SHIELD_DECREASED_YOUR_MP_BY_S1_INSTEAD_OF_HP); smsg.addNumber(mpDam); getActiveChar().sendPacket(smsg); return; } } final L2PcInstance caster = getActiveChar().getTransferingDamageTo(); if ((caster != null) && (getActiveChar().getParty() != null) && Util.checkIfInRange(1000, getActiveChar(), caster, true) && !caster.isDead() && (getActiveChar() != caster) && getActiveChar().getParty().getMembers().contains(caster)) { int transferDmg = 0; transferDmg = ((int) value * (int) getActiveChar() .getStat() .calcStat(Stats.TRANSFER_DAMAGE_TO_PLAYER, 0, null, null)) / 100; transferDmg = Math.min((int) caster.getCurrentHp() - 1, transferDmg); if ((transferDmg > 0) && (attacker instanceof L2Playable)) { int membersInRange = 0; for (L2PcInstance member : caster.getParty().getMembers()) { if (Util.checkIfInRange(1000, member, caster, false) && (member != caster)) { membersInRange++; } } if (caster.getCurrentCp() > 0) { if (caster.getCurrentCp() > transferDmg) { reduceCp(transferDmg); } else { transferDmg = (int) (transferDmg - caster.getCurrentCp()); reduceCp((int) caster.getCurrentCp()); } } caster.reduceCurrentHp(transferDmg / membersInRange, attacker, null); value -= transferDmg; fullValue = (int) value; } } if (!ignoreCP && (attacker instanceof L2Playable)) { if (getCurrentCp() >= value) { setCurrentCp(getCurrentCp() - value); // Set Cp to diff of Cp vs value value = 0; // No need to subtract anything from Hp } else { value -= getCurrentCp(); // Get diff from value vs Cp; will apply diff to Hp setCurrentCp(0, false); // Set Cp to 0 } } if ((fullValue > 0) && !isDOT) { SystemMessage smsg; // Send a System Message to the L2PcInstance smsg = SystemMessage.getSystemMessage(SystemMessageId.C1_RECEIVED_DAMAGE_OF_S3_FROM_C2); smsg.addString(getActiveChar().getName()); smsg.addCharName(attacker); smsg.addNumber(fullValue); getActiveChar().sendPacket(smsg); if (tDmg > 0) { smsg = SystemMessage.getSystemMessage(SystemMessageId.C1_RECEIVED_DAMAGE_OF_S3_FROM_C2); smsg.addString(getActiveChar().getSummon().getName()); smsg.addCharName(attacker); smsg.addNumber(tDmg); getActiveChar().sendPacket(smsg); if (attackerPlayer != null) { smsg = SystemMessage.getSystemMessage( SystemMessageId.GIVEN_S1_DAMAGE_TO_YOUR_TARGET_AND_S2_DAMAGE_TO_SERVITOR); smsg.addNumber(fullValue); smsg.addNumber(tDmg); attackerPlayer.sendPacket(smsg); } } } } if (value > 0) { value = getCurrentHp() - value; if (value <= 0) { if (getActiveChar().isInDuel()) { getActiveChar().disableAllSkills(); stopHpMpRegeneration(); if (attacker != null) { attacker.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE); attacker.sendPacket(ActionFailed.STATIC_PACKET); } // let the DuelManager know of his defeat DuelManager.getInstance().onPlayerDefeat(getActiveChar()); value = 1; } else { value = 0; } } setCurrentHp(value); } if (getActiveChar().getCurrentHp() < 0.5) { getActiveChar().abortAttack(); getActiveChar().abortCast(); if (getActiveChar().isInOlympiadMode()) { stopHpMpRegeneration(); getActiveChar().setIsDead(true); getActiveChar().setIsPendingRevive(true); if (getActiveChar().hasSummon()) { getActiveChar().getSummon().getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null); } return; } getActiveChar().doDie(attacker); if (!Config.DISABLE_TUTORIAL) { QuestState qs = getActiveChar().getQuestState("255_Tutorial"); if (qs != null) { qs.getQuest().notifyEvent("CE30", null, getActiveChar()); } } } }