/* * This program 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. * * This program 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 . */ package com.l2jserver.gameserver.model.olympiad; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; import com.l2jserver.Config; import com.l2jserver.L2DatabaseFactory; import com.l2jserver.gameserver.datatables.HeroSkillTable; import com.l2jserver.gameserver.datatables.NpcTable; import com.l2jserver.gameserver.datatables.SpawnTable; import com.l2jserver.gameserver.instancemanager.CastleManager; import com.l2jserver.gameserver.instancemanager.FortManager; import com.l2jserver.gameserver.model.L2ItemInstance; import com.l2jserver.gameserver.model.L2Party; import com.l2jserver.gameserver.model.L2Skill; import com.l2jserver.gameserver.model.L2Spawn; import com.l2jserver.gameserver.model.L2World; import com.l2jserver.gameserver.model.actor.L2Summon; import com.l2jserver.gameserver.model.actor.instance.L2PcInstance; import com.l2jserver.gameserver.model.actor.instance.L2PetInstance; import com.l2jserver.gameserver.model.olympiad.Olympiad.COMP_TYPE; import com.l2jserver.gameserver.network.SystemMessageId; import com.l2jserver.gameserver.network.clientpackets.Say2; import com.l2jserver.gameserver.network.serverpackets.CreatureSay; import com.l2jserver.gameserver.network.serverpackets.ExOlympiadMatchEnd; import com.l2jserver.gameserver.network.serverpackets.ExOlympiadMode; import com.l2jserver.gameserver.network.serverpackets.ExOlympiadUserInfo; import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate; import com.l2jserver.gameserver.network.serverpackets.SkillCoolTime; import com.l2jserver.gameserver.network.serverpackets.SystemMessage; import com.l2jserver.gameserver.templates.StatsSet; import com.l2jserver.gameserver.templates.chars.L2NpcTemplate; import com.l2jserver.util.L2FastList; /** * * @author GodKratos */ class OlympiadGame { protected static final Logger _log = Logger.getLogger(OlympiadGame.class.getName()); protected static final Logger _logResults = Logger.getLogger("olympiad"); protected final COMP_TYPE _type; protected boolean _aborted; protected boolean _gamestarted; protected boolean _playerOneDisconnected; protected boolean _playerTwoDisconnected; protected boolean _playerOneDefaulted; protected boolean _playerTwoDefaulted; protected String _playerOneName; protected String _playerTwoName; protected int _playerOneID = 0; protected int _playerTwoID = 0; protected int _playerOneClass = 0; protected int _playerTwoClass = 0; protected static final int OLY_BUFFER = 36402; protected static final int OLY_MANAGER = 31688; private static final String POINTS = "olympiad_points"; private static final String COMP_DONE = "competitions_done"; private static final String COMP_WON = "competitions_won"; private static final String COMP_LOST = "competitions_lost"; private static final String COMP_DRAWN = "competitions_drawn"; protected static boolean _battleStarted; protected static boolean _gameIsStarted; protected long _startTime = 0; public int _damageP1 = 0; public int _damageP2 = 0; public L2PcInstance _playerOne; public L2PcInstance _playerTwo; public L2Spawn _spawnOne; public L2Spawn _spawnTwo; protected L2FastList _players; private final int[] _stadiumPort; private int x1, y1, z1, x2, y2, z2; public final int _stadiumID; protected SystemMessage _sm; private SystemMessage _sm2; private SystemMessage _sm3; protected OlympiadGame(int id, COMP_TYPE type, L2FastList list) { _aborted = false; _gamestarted = false; _stadiumID = id; _playerOneDisconnected = false; _playerTwoDisconnected = false; _type = type; _stadiumPort = OlympiadManager.STADIUMS[id].getCoordinates(); if (list != null) { _players = list; _playerOne = list.get(0); _playerTwo = list.get(1); try { _playerOneName = _playerOne.getName(); _playerTwoName = _playerTwo.getName(); _playerOne.setOlympiadGameId(id); _playerTwo.setOlympiadGameId(id); _playerOneID = _playerOne.getObjectId(); _playerTwoID = _playerTwo.getObjectId(); _playerOneClass = _playerOne.getBaseClass(); _playerTwoClass = _playerTwo.getBaseClass(); } catch (Exception e) { _aborted = true; clearPlayers(); } if (Config.DEBUG) _log.info("Olympiad System: Game - " + id + ": " + _playerOne.getName() + " Vs " + _playerTwo.getName()); } else { _aborted = true; clearPlayers(); return; } } public boolean isAborted() { return _aborted; } protected void clearPlayers() { _playerOne = null; _playerTwo = null; _players = null; _playerOneName = ""; _playerTwoName = ""; _playerOneID = 0; _playerTwoID = 0; } protected void handleDisconnect(L2PcInstance player) { if (_gamestarted) { if (player == _playerOne) _playerOneDisconnected = true; else if (player == _playerTwo) _playerTwoDisconnected = true; } } public L2Spawn SpawnBuffer(int xPos, int yPos, int zPos, int npcId) { final L2NpcTemplate template = NpcTable.getInstance().getTemplate(npcId); try { final L2Spawn spawn = new L2Spawn(template); spawn.setLocx(xPos); spawn.setLocy(yPos); spawn.setLocz(zPos); spawn.setAmount(1); spawn.setHeading(0); spawn.setRespawnDelay(1); SpawnTable.getInstance().addNewSpawn(spawn, false); spawn.init(); return spawn; } catch (Exception e) { _log.log(Level.WARNING, "", e); return null; } } protected void removals() { if (_aborted) return; if (_playerOne == null || _playerTwo == null) return; if (_playerOneDisconnected || _playerTwoDisconnected) return; for (L2PcInstance player : _players) { try { // Remove Buffs player.stopAllEffectsExceptThoseThatLastThroughDeath(); // Remove Clan Skills if (player.getClan() != null) { for (L2Skill skill : player.getClan().getAllSkills()) player.removeSkill(skill, false, true); if (player.getClan().getHasCastle() > 0) CastleManager.getInstance().getCastleByOwner(player.getClan()).removeResidentialSkills(player); if (player.getClan().getHasFort() > 0) FortManager.getInstance().getFortByOwner(player.getClan()).removeResidentialSkills(player); } // Abort casting if player casting if (player.isCastingNow()) { player.abortCast(); } // Force the character to be visible player.getAppearance().setVisible(); // Remove Hero Skills if (player.isHero()) { for (L2Skill skill : HeroSkillTable.getHeroSkills()) player.removeSkill(skill, false); } // Heal Player fully player.setCurrentCp(player.getMaxCp()); player.setCurrentHp(player.getMaxHp()); player.setCurrentMp(player.getMaxMp()); // Remove Summon's Buffs if (player.getPet() != null) { L2Summon summon = player.getPet(); summon.stopAllEffects(); if (summon instanceof L2PetInstance) summon.unSummon(player); } // stop any cubic that has been given by other player. player.stopCubicsByOthers(); // Remove player from his party if (player.getParty() != null) { L2Party party = player.getParty(); party.removePartyMember(player); } // Remove Agathion if (player.getAgathionId() > 0) { player.setAgathionId(0); player.broadcastUserInfo(); } player.checkItemRestriction(); // Remove shot automation player.disableAutoShotsAll(); // Discharge any active shots if (player.getActiveWeaponInstance() != null) { player.getActiveWeaponInstance().setChargedSoulshot(L2ItemInstance.CHARGED_NONE); player.getActiveWeaponInstance().setChargedSpiritshot(L2ItemInstance.CHARGED_NONE); } // enable skills with cool time <= 15 minutes for (L2Skill skill : player.getAllSkills()) if (skill.getReuseDelay() <= 900000) player.enableSkill(skill); player.sendSkillList(); player.sendPacket(new SkillCoolTime(player)); } catch (Exception e) { _log.log(Level.WARNING, "", e); } } } protected boolean portPlayersToArena() { final boolean _playerOneCrash = (_playerOne == null || _playerOneDisconnected); final boolean _playerTwoCrash = (_playerTwo == null || _playerTwoDisconnected); if (_playerOneCrash || _playerTwoCrash || _aborted) { _playerOne = null; _playerTwo = null; _aborted = true; return false; } try { x1 = _playerOne.getX(); y1 = _playerOne.getY(); z1 = _playerOne.getZ(); x2 = _playerTwo.getX(); y2 = _playerTwo.getY(); z2 = _playerTwo.getZ(); if (_playerOne.isSitting()) _playerOne.standUp(); if (_playerTwo.isSitting()) _playerTwo.standUp(); _playerOne.setTarget(null); _playerTwo.setTarget(null); _gamestarted = true; _playerOne.setIsInOlympiadMode(true); _playerOne.setIsOlympiadStart(false); _playerOne.setOlympiadSide(1); _playerOne.olyBuff = 5; _playerTwo.setIsInOlympiadMode(true); _playerTwo.setIsOlympiadStart(false); _playerTwo.setOlympiadSide(2); _playerTwo.olyBuff = 5; _playerOne.setInstanceId(0); _playerOne.teleToLocation(_stadiumPort[0] + 1200, _stadiumPort[1], _stadiumPort[2], false); _playerTwo.setInstanceId(0); _playerTwo.teleToLocation(_stadiumPort[0] - 1200, _stadiumPort[1], _stadiumPort[2], false); _playerOne.sendPacket(new ExOlympiadMode(2)); _playerTwo.sendPacket(new ExOlympiadMode(2)); _spawnOne = SpawnBuffer(_stadiumPort[0] + 1100, _stadiumPort[1], _stadiumPort[2], OLY_BUFFER); _spawnTwo = SpawnBuffer(_stadiumPort[0] - 1100, _stadiumPort[1], _stadiumPort[2], OLY_BUFFER); _gameIsStarted = false; } catch (NullPointerException e) { _log.log(Level.WARNING, "", e); return false; } return true; } protected void cleanEffects() { if (_playerOne == null || _playerTwo == null) return; if (_playerOneDisconnected || _playerTwoDisconnected) return; for (L2PcInstance player : _players) { try { player.stopAllEffectsExceptThoseThatLastThroughDeath(); player.clearSouls(); player.clearCharges(); if(player.getAgathionId() > 0) player.setAgathionId(0); if (player.getPet() != null) { L2Summon summon = player.getPet(); summon.stopAllEffects(); } } catch (Exception e) { _log.log(Level.WARNING, "cleanEffects()", e); } } } protected void portPlayersBack() { if (_playerOne != null) { _playerOne.sendPacket(new ExOlympiadMatchEnd()); _playerOne.teleToLocation(x1, y1, z1, true); } if (_playerTwo != null) { _playerTwo.sendPacket(new ExOlympiadMatchEnd()); _playerTwo.teleToLocation(x2, y2, z2, true); } } protected void PlayersStatusBack() { for (L2PcInstance player : _players) { if (player == null) continue; try { if (Olympiad.getInstance().playerInStadia(player)) { if (player.isDead()) player.setIsDead(false); player.getStatus().startHpMpRegeneration(); player.setCurrentCp(player.getMaxCp()); player.setCurrentHp(player.getMaxHp()); player.setCurrentMp(player.getMaxMp()); } if(player.isTransformed()) player.untransform(); player.setIsInOlympiadMode(false); player.setIsOlympiadStart(false); player.setOlympiadSide(-1); player.setOlympiadGameId(-1); player.sendPacket(new ExOlympiadMode(0)); // Add Clan Skills if (player.getClan() != null) { for (L2Skill skill : player.getClan().getAllSkills()) { if (skill.getMinPledgeClass() <= player.getPledgeClass()) player.addSkill(skill, false); } if (player.getClan().getHasCastle() > 0) CastleManager.getInstance().getCastleByOwner(player.getClan()).giveResidentialSkills(player); if (player.getClan().getHasFort() > 0) FortManager.getInstance().getFortByOwner(player.getClan()).giveResidentialSkills(player); } // Add Hero Skills if (player.isHero()) { for (L2Skill skill : HeroSkillTable.getHeroSkills()) player.addSkill(skill, false); } player.sendSkillList(); } catch (Exception e) { _log.log(Level.WARNING, "portPlayersToArena()", e); } } } protected boolean haveWinner() { if (_aborted || _playerOne == null || _playerTwo == null || _playerOneDisconnected || _playerTwoDisconnected) { return true; } double playerOneHp = 0; try { if (_playerOne != null && _playerOne.getOlympiadGameId() != -1) { playerOneHp = _playerOne.getCurrentHp(); } } catch (Exception e) { playerOneHp = 0; } double playerTwoHp = 0; try { if (_playerTwo != null && _playerTwo.getOlympiadGameId() != -1) { playerTwoHp = _playerTwo.getCurrentHp(); } } catch (Exception e) { playerTwoHp = 0; } if (playerTwoHp <= 0 || playerOneHp <= 0) { return true; } return false; } protected void validateWinner() { if (_aborted) return; final boolean _pOneCrash = (_playerOne == null || _playerOneDisconnected); final boolean _pTwoCrash = (_playerTwo == null || _playerTwoDisconnected); final int _div; final int _gpreward; final String classed; switch (_type) { case NON_CLASSED: _div = 5; _gpreward = Config.ALT_OLY_NONCLASSED_RITEM_C; classed = "no"; break; default: _div = 3; _gpreward = Config.ALT_OLY_CLASSED_RITEM_C; classed = "yes"; break; } final StatsSet playerOneStat = Olympiad.getNobleStats(_playerOneID); final StatsSet playerTwoStat = Olympiad.getNobleStats(_playerTwoID); final int playerOnePlayed = playerOneStat.getInteger(COMP_DONE); final int playerTwoPlayed = playerTwoStat.getInteger(COMP_DONE); final int playerOneWon = playerOneStat.getInteger(COMP_WON); final int playerTwoWon = playerTwoStat.getInteger(COMP_WON); final int playerOneLost = playerOneStat.getInteger(COMP_LOST); final int playerTwoLost = playerTwoStat.getInteger(COMP_LOST); final int playerOneDrawn = playerOneStat.getInteger(COMP_DRAWN); final int playerTwoDrawn = playerTwoStat.getInteger(COMP_DRAWN); final int playerOnePoints = playerOneStat.getInteger(POINTS); final int playerTwoPoints = playerTwoStat.getInteger(POINTS); final int pointDiff = Math.min(Math.min(playerOnePoints, playerTwoPoints) / _div, Config.ALT_OLY_MAX_POINTS); // Check for if a player defaulted before battle started if (_playerOneDefaulted || _playerTwoDefaulted) { if (_playerOneDefaulted) { final int lostPoints = Math.min(playerOnePoints / 3, Config.ALT_OLY_MAX_POINTS); playerOneStat.set(POINTS, playerOnePoints - lostPoints); Olympiad.updateNobleStats(_playerOneID, playerOneStat); SystemMessage sm = new SystemMessage(SystemMessageId.C1_HAS_LOST_S2_OLYMPIAD_POINTS); sm.addString(_playerOneName); sm.addNumber(lostPoints); broadcastMessage(sm, false); if (Config.DEBUG) _log.info("Olympia Result: " + _playerOneName + " lost " + lostPoints + " points for defaulting"); if (Config.ALT_OLY_LOG_FIGHTS) { LogRecord record = new LogRecord(Level.INFO, _playerOneName+" default"); record.setParameters(new Object[]{_playerOneName, _playerTwoName, 0, 0, 0, 0, lostPoints, classed}); _logResults.log(record); } } if (_playerTwoDefaulted) { final int lostPoints = Math.min(playerTwoPoints / 3, Config.ALT_OLY_MAX_POINTS); playerTwoStat.set(POINTS, playerTwoPoints - lostPoints); Olympiad.updateNobleStats(_playerTwoID, playerTwoStat); SystemMessage sm = new SystemMessage(SystemMessageId.C1_HAS_LOST_S2_OLYMPIAD_POINTS); sm.addString(_playerTwoName); sm.addNumber(lostPoints); broadcastMessage(sm, false); if (Config.DEBUG) _log.info("Olympia Result: " + _playerTwoName + " lost " + lostPoints + " points for defaulting"); if (Config.ALT_OLY_LOG_FIGHTS) { LogRecord record = new LogRecord(Level.INFO, _playerTwoName+" default"); record.setParameters(new Object[]{_playerOneName, _playerTwoName, 0, 0, 0, 0, lostPoints, classed}); _logResults.log(record); } } return; } // Create results for players if a player crashed if (_pOneCrash || _pTwoCrash) { if (_pOneCrash && !_pTwoCrash) { try { playerOneStat.set(POINTS, playerOnePoints - pointDiff); playerOneStat.set(COMP_LOST, playerOneLost + 1); if (Config.DEBUG) _log.info("Olympia Result: " + _playerOneName + " vs " + _playerTwoName + " ... " + _playerOneName + " lost " + pointDiff + " points for crash"); if (Config.ALT_OLY_LOG_FIGHTS) { LogRecord record = new LogRecord(Level.INFO, _playerOneName+" crash"); record.setParameters(new Object[]{_playerOneName, _playerTwoName, 0, 0, 0, 0, pointDiff, classed}); _logResults.log(record); } playerTwoStat.set(POINTS, playerTwoPoints + pointDiff); playerTwoStat.set(COMP_WON, playerTwoWon + 1); if (Config.DEBUG) _log.info("Olympia Result: " + _playerOneName + " vs " + _playerTwoName + " ... " + _playerTwoName + " Win " + pointDiff + " points"); _sm = new SystemMessage(SystemMessageId.C1_HAS_WON_THE_GAME); _sm2 = new SystemMessage(SystemMessageId.C1_HAS_GAINED_S2_OLYMPIAD_POINTS); _sm.addString(_playerTwoName); broadcastMessage(_sm, true); _sm2.addString(_playerTwoName); _sm2.addNumber(pointDiff); broadcastMessage(_sm2, false); } catch (Exception e) { _log.log(Level.WARNING, "Exception on validateWinnder(): " + e.getMessage(), e); } } else if (_pTwoCrash && !_pOneCrash) { try { playerTwoStat.set(POINTS, playerTwoPoints - pointDiff); playerTwoStat.set(COMP_LOST, playerTwoLost + 1); if (Config.DEBUG) _log.info("Olympia Result: " + _playerTwoName + " vs " + _playerOneName + " ... " + _playerTwoName + " lost " + pointDiff + " points for crash"); if (Config.ALT_OLY_LOG_FIGHTS) { LogRecord record = new LogRecord(Level.INFO, _playerTwoName+" crash"); record.setParameters(new Object[]{_playerOneName, _playerTwoName, 0, 0, 0, 0, pointDiff, classed}); _logResults.log(record); } playerOneStat.set(POINTS, playerOnePoints + pointDiff); playerOneStat.set(COMP_WON, playerOneWon + 1); if (Config.DEBUG) _log.info("Olympia Result: " + _playerTwoName + " vs " + _playerOneName + " ... " + _playerOneName + " Win " + pointDiff + " points"); _sm = new SystemMessage(SystemMessageId.C1_HAS_WON_THE_GAME); _sm2 = new SystemMessage(SystemMessageId.C1_HAS_GAINED_S2_OLYMPIAD_POINTS); _sm.addString(_playerOneName); broadcastMessage(_sm, true); _sm2.addString(_playerOneName); _sm2.addNumber(pointDiff); broadcastMessage(_sm2, false); } catch (Exception e) { _log.log(Level.WARNING, "Exception on validateWinnder(): " + e.getMessage(), e); } } else if (_pOneCrash && _pTwoCrash) { try { playerOneStat.set(POINTS, playerOnePoints - pointDiff); playerOneStat.set(COMP_LOST, playerOneLost + 1); playerTwoStat.set(POINTS, playerTwoPoints - pointDiff); playerTwoStat.set(COMP_LOST, playerTwoLost + 1); if (Config.DEBUG) _log.info("Olympia Result: " + _playerOneName + " vs " + _playerTwoName + " ... " + " both lost " + pointDiff + " points for crash"); if (Config.ALT_OLY_LOG_FIGHTS) { LogRecord record = new LogRecord(Level.INFO, "both crash"); record.setParameters(new Object[]{_playerOneName, _playerTwoName, 0, 0, 0, 0, pointDiff, classed}); _logResults.log(record); } } catch (Exception e) { _log.log(Level.WARNING, "Exception on validateWinnder(): " + e.getMessage(), e); } } playerOneStat.set(COMP_DONE, playerOnePlayed + 1); playerTwoStat.set(COMP_DONE, playerTwoPlayed + 1); Olympiad.updateNobleStats(_playerOneID, playerOneStat); Olympiad.updateNobleStats(_playerTwoID, playerTwoStat); return; } double playerOneHp = 0; if (!_playerOne.isDead()) { playerOneHp = _playerOne.getCurrentHp() + _playerOne.getCurrentCp(); } double playerTwoHp = 0; if (!_playerTwo.isDead()) { playerTwoHp = _playerTwo.getCurrentHp() + _playerTwo.getCurrentCp(); } _sm = new SystemMessage(SystemMessageId.C1_HAS_WON_THE_GAME); _sm2 = new SystemMessage(SystemMessageId.C1_HAS_GAINED_S2_OLYMPIAD_POINTS); _sm3 = new SystemMessage(SystemMessageId.C1_HAS_LOST_S2_OLYMPIAD_POINTS); String result = ""; // if players crashed, search if they've relogged _playerOne = L2World.getInstance().getPlayer(_playerOneID); _players.set(0, _playerOne); _playerTwo = L2World.getInstance().getPlayer(_playerTwoID); _players.set(1, _playerTwo); String winner = "draw"; // Calculate Fight time long _fightTime = (System.currentTimeMillis() - _startTime); if (_playerOne == null && _playerTwo == null) { playerOneStat.set(COMP_DRAWN, playerOneDrawn + 1); playerTwoStat.set(COMP_DRAWN, playerTwoDrawn + 1); result = " tie"; _sm = new SystemMessage(SystemMessageId.THE_GAME_ENDED_IN_A_TIE); broadcastMessage(_sm, true); } else if (_playerTwo == null || _playerTwo.isOnline() == 0 || (playerTwoHp == 0 && playerOneHp != 0) || (_damageP1 > _damageP2 && playerTwoHp != 0 && playerOneHp != 0)) { playerOneStat.set(POINTS, playerOnePoints + pointDiff); playerTwoStat.set(POINTS, playerTwoPoints - pointDiff); playerOneStat.set(COMP_WON, playerOneWon + 1); playerTwoStat.set(COMP_LOST, playerTwoLost + 1); _sm.addString(_playerOneName); broadcastMessage(_sm, true); _sm2.addString(_playerOneName); _sm2.addNumber(pointDiff); broadcastMessage(_sm2, false); _sm3.addString(_playerTwoName); _sm3.addNumber(pointDiff); broadcastMessage(_sm3, false); winner = _playerOneName + " won"; try { // Save Fight Result saveResults(_playerOneID,_playerTwoID,_playerOneClass,_playerTwoClass,1,_startTime,_fightTime, (_type == COMP_TYPE.CLASSED ? 1 : 0)); result = " (" + playerOneHp + "hp vs " + playerTwoHp + "hp - " + _damageP1 + "dmg vs " + _damageP2 + "dmg) " + _playerOneName + " win " + pointDiff + " points"; L2ItemInstance item = _playerOne.getInventory().addItem("Olympiad", Config.ALT_OLY_BATTLE_REWARD_ITEM, _gpreward, _playerOne, null); InventoryUpdate iu = new InventoryUpdate(); iu.addModifiedItem(item); _playerOne.sendPacket(iu); SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S); sm.addItemName(item); sm.addNumber(_gpreward); _playerOne.sendPacket(sm); } catch (Exception e) { } } else if (_playerOne == null || _playerOne.isOnline() == 0 || (playerOneHp == 0 && playerTwoHp != 0) || (_damageP2 > _damageP1 && playerOneHp != 0 && playerTwoHp != 0)) { playerTwoStat.set(POINTS, playerTwoPoints + pointDiff); playerOneStat.set(POINTS, playerOnePoints - pointDiff); playerTwoStat.set(COMP_WON, playerTwoWon + 1); playerOneStat.set(COMP_LOST, playerOneLost + 1); _sm.addString(_playerTwoName); broadcastMessage(_sm, true); _sm2.addString(_playerTwoName); _sm2.addNumber(pointDiff); broadcastMessage(_sm2, false); _sm3.addString(_playerOneName); _sm3.addNumber(pointDiff); broadcastMessage(_sm3, false); winner = _playerTwoName + " won"; try { // Save Fight Result saveResults(_playerOneID,_playerTwoID,_playerOneClass,_playerTwoClass,2,_startTime,_fightTime,(_type == COMP_TYPE.CLASSED ? 1 : 0)); result = " (" + playerOneHp + "hp vs " + playerTwoHp + "hp - " + _damageP1 + "dmg vs " + _damageP2 + "dmg) " + _playerTwoName + " win " + pointDiff + " points"; L2ItemInstance item = _playerTwo.getInventory().addItem("Olympiad", Config.ALT_OLY_BATTLE_REWARD_ITEM, _gpreward, _playerTwo, null); InventoryUpdate iu = new InventoryUpdate(); iu.addModifiedItem(item); _playerTwo.sendPacket(iu); SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S); sm.addItemName(item); sm.addNumber(_gpreward); _playerTwo.sendPacket(sm); } catch (Exception e) { } } else { // Save Fight Result saveResults(_playerOneID,_playerTwoID,_playerOneClass,_playerTwoClass,0,_startTime,_fightTime,(_type == COMP_TYPE.CLASSED ? 1 : 0)); result = " tie"; _sm = new SystemMessage(SystemMessageId.THE_GAME_ENDED_IN_A_TIE); broadcastMessage(_sm, true); final int pointOneDiff = Math.min(playerOnePoints / 5, Config.ALT_OLY_MAX_POINTS); final int pointTwoDiff = Math.min(playerTwoPoints / 5, Config.ALT_OLY_MAX_POINTS); playerOneStat.set(POINTS, playerOnePoints - pointOneDiff); playerTwoStat.set(POINTS, playerTwoPoints - pointTwoDiff); playerOneStat.set(COMP_DRAWN, playerOneDrawn + 1); playerTwoStat.set(COMP_DRAWN, playerTwoDrawn + 1); _sm2 = new SystemMessage(SystemMessageId.C1_HAS_LOST_S2_OLYMPIAD_POINTS); _sm2.addString(_playerOneName); _sm2.addNumber(pointOneDiff); broadcastMessage(_sm2, false); _sm3 = new SystemMessage(SystemMessageId.C1_HAS_LOST_S2_OLYMPIAD_POINTS); _sm3.addString(_playerTwoName); _sm3.addNumber(pointTwoDiff); broadcastMessage(_sm3, false); } if (Config.DEBUG) _log.info("Olympia Result: " + _playerOneName + " vs " + _playerTwoName + " ... " + result); playerOneStat.set(COMP_DONE, playerOnePlayed + 1); playerTwoStat.set(COMP_DONE, playerTwoPlayed + 1); Olympiad.updateNobleStats(_playerOneID, playerOneStat); Olympiad.updateNobleStats(_playerTwoID, playerTwoStat); if (Config.ALT_OLY_LOG_FIGHTS) { LogRecord record = new LogRecord(Level.INFO, winner); record.setParameters(new Object[]{_playerOneName, _playerTwoName, playerOneHp, playerTwoHp, _damageP1, _damageP2, pointDiff, classed}); _logResults.log(record); } byte step = 10; for (byte i = 40; i > 0; i -= step) { _sm = new SystemMessage(SystemMessageId.YOU_WILL_BE_MOVED_TO_TOWN_IN_S1_SECONDS); _sm.addNumber(i); broadcastMessage(_sm, false); switch (i) { case 10: step = 5; break; case 5: step = 1; break; } try { Thread.sleep(step*1000); } catch (InterruptedException e) { } } } protected boolean makeCompetitionStart() { _startTime = System.currentTimeMillis(); if (_aborted) return false; _sm = new SystemMessage(SystemMessageId.STARTS_THE_GAME); broadcastMessage(_sm, true); _gameIsStarted = true; try { for (L2PcInstance player : _players) { player.setIsOlympiadStart(true); player.updateEffectIcons(); } } catch (Exception e) { _log.log(Level.WARNING, "", e); _aborted = true; return false; } return true; } protected void addDamage(L2PcInstance player, int damage) { if (_playerOne == null || _playerTwo == null) return; if (player == _playerOne) _damageP1 += damage; else if (player == _playerTwo) _damageP2 += damage; } protected String getTitle() { final String msg = _playerOneName + " / " + _playerTwoName; return msg; } protected L2PcInstance[] getPlayers() { if (_players == null || _players.isEmpty()) return null; final L2PcInstance[] players = new L2PcInstance[_players.size()]; _players.toArray(players); return players; } protected void broadcastMessage(SystemMessage sm, boolean toAll) { for (L2PcInstance player : _players) { if (player != null) { player.sendPacket(sm); } } if (toAll && OlympiadManager.STADIUMS[_stadiumID].getSpectators() != null) { for (L2PcInstance spec : OlympiadManager.STADIUMS[_stadiumID].getSpectators()) { if (spec != null) spec.sendPacket(sm); } } } protected void announceGame() { int objId; String npcName; String gameType = null; switch (_type) { case NON_CLASSED: gameType = "class-free individual match"; break; default: gameType = "class-specific individual match"; break; } for (L2Spawn manager : SpawnTable.getInstance().getSpawnTable().values()) { if (manager != null && manager.getNpcid() == OLY_MANAGER) { objId = manager.getLastSpawn().getObjectId(); npcName = manager.getLastSpawn().getName(); manager.getLastSpawn().broadcastPacket(new CreatureSay(objId, Say2.SHOUT, npcName, "Olympiad " + gameType + " is going to begin in Arena " + (_stadiumID + 1) + " in a moment.")); } } } protected void saveResults(int _playerOne, int _playerTwo, int _playerOneClass, int _playerTwoClass, int _winner, long _startTime, long _fightTime, int _classed) { Connection con = null; try { con = L2DatabaseFactory.getInstance().getConnection(); PreparedStatement statement = con.prepareStatement("INSERT INTO olympiad_fights (charOneId, charTwoId, charOneClass, charTwoClass, winner, start, time, classed) values(?,?,?,?,?,?,?,?)"); statement.setInt(1, _playerOne); statement.setInt(2, _playerTwo); statement.setInt(3, _playerOneClass); statement.setInt(4, _playerTwoClass); statement.setInt(5, _winner); statement.setLong(6, _startTime); statement.setLong(7, _fightTime); statement.setInt(8, _classed); statement.execute(); statement.close(); } catch (SQLException e) { if(_log.isLoggable(Level.SEVERE)) _log.log(Level.SEVERE, "SQL exception while saving olympiad fight.", e); } finally { L2DatabaseFactory.close(con); } } } /** * * @author ascharot * */ class OlympiadGameTask implements Runnable { protected static final Logger _log = Logger.getLogger(OlympiadGameTask.class.getName()); public OlympiadGame _game = null; protected static final long BATTLE_PERIOD = Config.ALT_OLY_BATTLE; // 6 mins private boolean _terminated = false; private boolean _started = false; public boolean isTerminated() { return _terminated || _game._aborted; } public boolean isStarted() { return _started; } public OlympiadGameTask(OlympiadGame game) { _game = game; } protected boolean checkBattleStatus() { boolean _pOneCrash = (_game._playerOne == null || _game._playerOneDisconnected); boolean _pTwoCrash = (_game._playerTwo == null || _game._playerTwoDisconnected); if (_pOneCrash || _pTwoCrash || _game._aborted) { return false; } return true; } protected boolean checkDefaulted() { _game._playerOne = L2World.getInstance().getPlayer(_game._playerOneID); _game._players.set(0, _game._playerOne); _game._playerTwo = L2World.getInstance().getPlayer(_game._playerTwoID); _game._players.set(1, _game._playerTwo); for (int i = 0; i < 2; i++) { boolean defaulted = false; L2PcInstance player = _game._players.get(i); if (player != null) player.setOlympiadGameId(_game._stadiumID); L2PcInstance otherPlayer = _game._players.get(i^1); SystemMessage sm = null; if (player == null) { defaulted = true; } else if (player.isDead()) { sm = new SystemMessage(SystemMessageId.C1_CANNOT_PARTICIPATE_OLYMPIAD_WHILE_DEAD); sm.addPcName(player); defaulted = true; } else if (player.isSubClassActive()) { sm = new SystemMessage(SystemMessageId.C1_CANNOT_PARTICIPATE_IN_OLYMPIAD_WHILE_CHANGED_TO_SUB_CLASS); sm.addPcName(player); defaulted = true; } else if (player.isCursedWeaponEquipped()) { sm = new SystemMessage(SystemMessageId.C1_CANNOT_JOIN_OLYMPIAD_POSSESSING_S2); sm.addPcName(player); sm.addItemName(player.getCursedWeaponEquippedId()); defaulted = true; } else if (player.getInventoryLimit()*0.8 <= player.getInventory().getSize()) { sm = new SystemMessage(SystemMessageId.C1_CANNOT_PARTICIPATE_IN_OLYMPIAD_INVENTORY_SLOT_EXCEEDS_80_PERCENT); sm.addPcName(player); defaulted = true; } if (defaulted) { if (player != null) player.sendPacket(sm); if (otherPlayer != null) otherPlayer.sendPacket(new SystemMessage(SystemMessageId.THE_GAME_HAS_BEEN_CANCELLED_BECAUSE_THE_OTHER_PARTY_DOES_NOT_MEET_THE_REQUIREMENTS_FOR_JOINING_THE_GAME)); if (i == 0) _game._playerOneDefaulted = true; else _game._playerTwoDefaulted = true; } } return _game._playerOneDefaulted || _game._playerTwoDefaulted; } public void run() { _started = true; if (_game != null) { if (_game._playerOne == null || _game._playerTwo == null) { return; } if (teleportCountdown()) runGame(); _terminated = true; _game.validateWinner(); _game.PlayersStatusBack(); _game.cleanEffects(); if (_game._gamestarted) { _game._gamestarted = false; OlympiadManager.STADIUMS[_game._stadiumID].closeDoors(); try { _game.portPlayersBack(); } catch (Exception e) { _log.log(Level.WARNING, "Exception on portPlayersBack(): " + e.getMessage(), e); } } if (OlympiadManager.STADIUMS[_game._stadiumID].getSpectators() != null) { for (L2PcInstance spec : OlympiadManager.STADIUMS[_game._stadiumID].getSpectators()) { if (spec != null) spec.sendPacket(new ExOlympiadMatchEnd()); } } if (_game._spawnOne != null) { _game._spawnOne.getLastSpawn().deleteMe(); _game._spawnOne = null; } if (_game._spawnTwo != null) { _game._spawnTwo.getLastSpawn().deleteMe(); _game._spawnTwo = null; } _game.clearPlayers(); OlympiadManager.getInstance().removeGame(_game); _game = null; } } private boolean runGame() { SystemMessage sm; // Checking for opponents and teleporting to arena if (checkDefaulted()) { return false; } OlympiadManager.STADIUMS[_game._stadiumID].closeDoors(); _game.portPlayersToArena(); _game.removals(); if (Config.ALT_OLY_ANNOUNCE_GAMES) _game.announceGame(); try { Thread.sleep(5000); } catch (InterruptedException e) { } synchronized (this) { if (!OlympiadGame._battleStarted) OlympiadGame._battleStarted = true; } byte step = 10; for (byte i = 60; i > 0; i -= step) { sm = new SystemMessage(SystemMessageId.THE_GAME_WILL_START_IN_S1_SECOND_S); sm.addNumber(i); _game.broadcastMessage(sm, true); switch (i) { case 10: _game._damageP1 = 0; _game._damageP2 = 0; OlympiadManager.STADIUMS[_game._stadiumID].openDoors(); step = 5; break; case 5: step = 1; break; } try { Thread.sleep(step*1000); } catch (InterruptedException e) { } } if (!checkBattleStatus()) { return false; } _game._spawnOne.getLastSpawn().deleteMe(); _game._spawnTwo.getLastSpawn().deleteMe(); _game._spawnOne = null; _game._spawnTwo = null; if (!_game.makeCompetitionStart()) { return false; } _game._playerOne.sendPacket(new ExOlympiadUserInfo(_game._playerOne)); _game._playerOne.sendPacket(new ExOlympiadUserInfo(_game._playerTwo)); _game._playerTwo.sendPacket(new ExOlympiadUserInfo(_game._playerTwo)); _game._playerTwo.sendPacket(new ExOlympiadUserInfo(_game._playerOne)); if (OlympiadManager.STADIUMS[_game._stadiumID].getSpectators() != null) { for (L2PcInstance spec : OlympiadManager.STADIUMS[_game._stadiumID].getSpectators()) { if (spec != null) { spec.sendPacket(new ExOlympiadUserInfo(_game._playerOne)); spec.sendPacket(new ExOlympiadUserInfo(_game._playerTwo)); } } } // Wait 3 mins (Battle) for (int i = 0; i < BATTLE_PERIOD; i += 10000) { try { Thread.sleep(10000); // If game haveWinner then stop waiting battle_period // and validate winner if (_game.haveWinner()) break; } catch (InterruptedException e) { } } return checkBattleStatus(); } private boolean teleportCountdown() { SystemMessage sm; // Waiting for teleport to arena byte step = 60; for (byte i = Config.ALT_OLY_WAIT_TIME; i > 0; i -= step) { sm = new SystemMessage(SystemMessageId.YOU_WILL_ENTER_THE_OLYMPIAD_STADIUM_IN_S1_SECOND_S); sm.addNumber(i); _game.broadcastMessage(sm, false); switch (i) { case 60: step = 30; break; case 30: step = 15; break; case 15: step = 5; break; case 5: step = 1; break; } try { Thread.sleep(step*1000); } catch (InterruptedException e) { return false; } } return true; } }