123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781 |
- /*
- * 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.model.entity;
- import java.util.Map.Entry;
- import java.util.concurrent.ScheduledFuture;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- import javolution.util.FastList;
- import javolution.util.FastMap;
- import com.l2jserver.Config;
- import com.l2jserver.gameserver.ThreadPoolManager;
- import com.l2jserver.gameserver.datatables.SkillData;
- import com.l2jserver.gameserver.datatables.SpawnTable;
- import com.l2jserver.gameserver.enums.Team;
- import com.l2jserver.gameserver.instancemanager.HandysBlockCheckerManager;
- import com.l2jserver.gameserver.model.ArenaParticipantsHolder;
- import com.l2jserver.gameserver.model.L2Spawn;
- import com.l2jserver.gameserver.model.L2World;
- import com.l2jserver.gameserver.model.actor.instance.L2BlockInstance;
- import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
- import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
- import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
- 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.ActionFailed;
- import com.l2jserver.gameserver.network.serverpackets.ExBasicActionList;
- import com.l2jserver.gameserver.network.serverpackets.ExCubeGameChangePoints;
- import com.l2jserver.gameserver.network.serverpackets.ExCubeGameCloseUI;
- import com.l2jserver.gameserver.network.serverpackets.ExCubeGameEnd;
- import com.l2jserver.gameserver.network.serverpackets.ExCubeGameExtendedChangePoints;
- import com.l2jserver.gameserver.network.serverpackets.RelationChanged;
- import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
- import com.l2jserver.util.Rnd;
- /**
- * @author BiggBoss
- */
- public final class BlockCheckerEngine
- {
- protected static final Logger _log = Logger.getLogger(BlockCheckerEngine.class.getName());
- // The object which holds all basic members info
- protected ArenaParticipantsHolder _holder;
- // Maps to hold player of each team and his points
- protected FastMap<L2PcInstance, Integer> _redTeamPoints = new FastMap<>();
- protected FastMap<L2PcInstance, Integer> _blueTeamPoints = new FastMap<>();
- // The initial points of the event
- protected int _redPoints = 15;
- protected int _bluePoints = 15;
- // Current used arena
- protected int _arena = -1;
- // All blocks
- protected FastList<L2Spawn> _spawns = new FastList<>();
- // Sets if the red team won the event at the end of this (used for packets)
- protected boolean _isRedWinner;
- // Time when the event starts. Used on packet sending
- protected long _startedTime;
- // The needed arena coordinates
- // Arena X: team1X, team1Y, team2X, team2Y, ArenaCenterX, ArenaCenterY
- protected static final int[][] _arenaCoordinates =
- {
- // Arena 0 - Team 1 XY, Team 2 XY - CENTER XY
- {
- -58368,
- -62745,
- -57751,
- -62131,
- -58053,
- -62417
- },
- // Arena 1 - Team 1 XY, Team 2 XY - CENTER XY
- {
- -58350,
- -63853,
- -57756,
- -63266,
- -58053,
- -63551
- },
- // Arena 2 - Team 1 XY, Team 2 XY - CENTER XY
- {
- -57194,
- -63861,
- -56580,
- -63249,
- -56886,
- -63551
- },
- // Arena 3 - Team 1 XY, Team 2 XY - CENTER XY
- {
- -57200,
- -62727,
- -56584,
- -62115,
- -56850,
- -62391
- }
- };
- // Common z coordinate
- private static final int _zCoord = -2405;
- // List of dropped items in event (for later deletion)
- protected FastList<L2ItemInstance> _drops = new FastList<>();
- // Default arena
- private static final byte DEFAULT_ARENA = -1;
- // Event is started
- protected boolean _isStarted = false;
- // Event end
- protected ScheduledFuture<?> _task;
- // Preserve from exploit reward by logging out
- protected boolean _abnormalEnd = false;
-
- public BlockCheckerEngine(ArenaParticipantsHolder holder, int arena)
- {
- _holder = holder;
- if ((arena > -1) && (arena < 4))
- {
- _arena = arena;
- }
-
- for (L2PcInstance player : holder.getRedPlayers())
- {
- _redTeamPoints.put(player, 0);
- }
- for (L2PcInstance player : holder.getBluePlayers())
- {
- _blueTeamPoints.put(player, 0);
- }
- }
-
- /**
- * Updates the player holder before the event starts to synchronize all info
- * @param holder
- */
- public void updatePlayersOnStart(ArenaParticipantsHolder holder)
- {
- _holder = holder;
- }
-
- /**
- * Returns the current holder object of this object engine
- * @return HandysBlockCheckerManager.ArenaParticipantsHolder
- */
- public ArenaParticipantsHolder getHolder()
- {
- return _holder;
- }
-
- /**
- * Will return the id of the arena used by this event
- * @return false;
- */
- public int getArena()
- {
- return _arena;
- }
-
- /**
- * Returns the time when the event started
- * @return long
- */
- public long getStarterTime()
- {
- return _startedTime;
- }
-
- /**
- * Returns the current red team points
- * @return int
- */
- public int getRedPoints()
- {
- synchronized (this)
- {
- return _redPoints;
- }
- }
-
- /**
- * Returns the current blue team points
- * @return int
- */
- public int getBluePoints()
- {
- synchronized (this)
- {
- return _bluePoints;
- }
- }
-
- /**
- * Returns the player points
- * @param player
- * @param isRed
- * @return int
- */
- public int getPlayerPoints(L2PcInstance player, boolean isRed)
- {
- if (!_redTeamPoints.containsKey(player) && !_blueTeamPoints.containsKey(player))
- {
- return 0;
- }
-
- if (isRed)
- {
- return _redTeamPoints.get(player);
- }
- return _blueTeamPoints.get(player);
- }
-
- /**
- * Increases player points for his teams
- * @param player
- * @param team
- */
- public synchronized void increasePlayerPoints(L2PcInstance player, int team)
- {
- if (player == null)
- {
- return;
- }
-
- if (team == 0)
- {
- int points = _redTeamPoints.get(player) + 1;
- _redTeamPoints.put(player, points);
- _redPoints++;
- _bluePoints--;
- }
- else
- {
- int points = _blueTeamPoints.get(player) + 1;
- _blueTeamPoints.put(player, points);
- _bluePoints++;
- _redPoints--;
- }
- }
-
- /**
- * Will add a new drop into the list of dropped items
- * @param item
- */
- public void addNewDrop(L2ItemInstance item)
- {
- if (item != null)
- {
- _drops.add(item);
- }
- }
-
- /**
- * Will return true if the event is already started
- * @return boolean
- */
- public boolean isStarted()
- {
- return _isStarted;
- }
-
- /**
- * Will send all packets for the event members with the relation info
- * @param plr
- */
- protected void broadcastRelationChanged(L2PcInstance plr)
- {
- for (L2PcInstance p : _holder.getAllPlayers())
- {
- p.sendPacket(new RelationChanged(plr, plr.getRelation(p), plr.isAutoAttackable(p)));
- }
- }
-
- /**
- * Called when a there is an empty team. The event will end.
- */
- public void endEventAbnormally()
- {
- try
- {
- synchronized (this)
- {
- _isStarted = false;
-
- if (_task != null)
- {
- _task.cancel(true);
- }
-
- _abnormalEnd = true;
-
- ThreadPoolManager.getInstance().executeGeneral(new EndEvent());
-
- if (Config.DEBUG)
- {
- _log.config("Handys Block Checker Event at arena " + _arena + " ended due lack of players!");
- }
- }
- }
- catch (Exception e)
- {
- _log.log(Level.SEVERE, "Couldnt end Block Checker event at " + _arena, e);
- }
- }
-
- /**
- * This inner class set ups all player and arena parameters to start the event
- */
- public class StartEvent implements Runnable
- {
- // In event used skills
- private final Skill _freeze, _transformationRed, _transformationBlue;
- // Common and unparametizer packet
- private final ExCubeGameCloseUI _closeUserInterface = new ExCubeGameCloseUI();
-
- public StartEvent()
- {
- // Initialize all used skills
- _freeze = SkillData.getInstance().getSkill(6034, 1);
- _transformationRed = SkillData.getInstance().getSkill(6035, 1);
- _transformationBlue = SkillData.getInstance().getSkill(6036, 1);
- }
-
- /**
- * Will set up all player parameters and port them to their respective location based on their teams
- */
- private void setUpPlayers()
- {
- // Set current arena as being used
- HandysBlockCheckerManager.getInstance().setArenaBeingUsed(_arena);
-
- // Initialize packets avoiding create a new one per player
- _redPoints = _spawns.size() / 2;
- _bluePoints = _spawns.size() / 2;
- final ExCubeGameChangePoints initialPoints = new ExCubeGameChangePoints(300, _bluePoints, _redPoints);
- ExCubeGameExtendedChangePoints clientSetUp;
-
- for (L2PcInstance player : _holder.getAllPlayers())
- {
- if (player == null)
- {
- continue;
- }
-
- // Send the secret client packet set up
- boolean isRed = _holder.getRedPlayers().contains(player);
-
- clientSetUp = new ExCubeGameExtendedChangePoints(300, _bluePoints, _redPoints, isRed, player, 0);
- player.sendPacket(clientSetUp);
-
- player.sendPacket(ActionFailed.STATIC_PACKET);
-
- // Teleport Player - Array access
- // Team 0 * 2 = 0; 0 = 0, 0 + 1 = 1.
- // Team 1 * 2 = 2; 2 = 2, 2 + 1 = 3
- int tc = _holder.getPlayerTeam(player) * 2;
- // Get x and y coordinates
- int x = _arenaCoordinates[_arena][tc];
- int y = _arenaCoordinates[_arena][tc + 1];
- player.teleToLocation(x, y, _zCoord);
- // Set the player team
- if (isRed)
- {
- _redTeamPoints.put(player, 0);
- player.setTeam(Team.RED);
- }
- else
- {
- _blueTeamPoints.put(player, 0);
- player.setTeam(Team.BLUE);
- }
- player.stopAllEffects();
-
- if (player.hasSummon())
- {
- player.getSummon().unSummon(player);
- }
-
- // Give the player start up effects
- // Freeze
- _freeze.applyEffects(player, player);
- // Transformation
- if (_holder.getPlayerTeam(player) == 0)
- {
- _transformationRed.applyEffects(player, player);
- }
- else
- {
- _transformationBlue.applyEffects(player, player);
- }
- // Set the current player arena
- player.setBlockCheckerArena((byte) _arena);
- player.setInsideZone(ZoneId.PVP, true);
- // Send needed packets
- player.sendPacket(initialPoints);
- player.sendPacket(_closeUserInterface);
- // ExBasicActionList
- player.sendPacket(ExBasicActionList.STATIC_PACKET);
- broadcastRelationChanged(player);
- }
- }
-
- @Override
- public void run()
- {
- // Wrong arena passed, stop event
- if (_arena == -1)
- {
- _log.severe("Couldnt set up the arena Id for the Block Checker event, cancelling event...");
- return;
- }
- _isStarted = true;
- // Spawn the blocks
- ThreadPoolManager.getInstance().executeGeneral(new SpawnRound(16, 1));
- // Start up player parameters
- setUpPlayers();
- // Set the started time
- _startedTime = System.currentTimeMillis() + 300000;
- }
- }
-
- /**
- * This class spawns the second round of boxes and schedules the event end
- */
- private class SpawnRound implements Runnable
- {
- int _numOfBoxes;
- int _round;
-
- SpawnRound(int numberOfBoxes, int round)
- {
- _numOfBoxes = numberOfBoxes;
- _round = round;
- }
-
- @Override
- public void run()
- {
- if (!_isStarted)
- {
- return;
- }
-
- switch (_round)
- {
- case 1:
- // Schedule second spawn round
- _task = ThreadPoolManager.getInstance().scheduleGeneral(new SpawnRound(20, 2), 60000);
- break;
- case 2:
- // Schedule third spawn round
- _task = ThreadPoolManager.getInstance().scheduleGeneral(new SpawnRound(14, 3), 60000);
- break;
- case 3:
- // Schedule Event End Count Down
- _task = ThreadPoolManager.getInstance().scheduleGeneral(new EndEvent(), 180000);
- break;
- }
- // random % 2, if == 0 will spawn a red block
- // if != 0, will spawn a blue block
- byte random = 2;
- // Spawn blocks
- try
- {
- // Creates 50 new blocks
- for (int i = 0; i < _numOfBoxes; i++)
- {
- final L2Spawn spawn = new L2Spawn(18672);
- spawn.setX(_arenaCoordinates[_arena][4] + Rnd.get(-400, 400));
- spawn.setY(_arenaCoordinates[_arena][5] + Rnd.get(-400, 400));
- spawn.setZ(_zCoord);
- spawn.setAmount(1);
- spawn.setHeading(1);
- spawn.setRespawnDelay(1);
- SpawnTable.getInstance().addNewSpawn(spawn, false);
- spawn.init();
- L2BlockInstance block = (L2BlockInstance) spawn.getLastSpawn();
- // switch color
- if ((random % 2) == 0)
- {
- block.setRed(true);
- }
- else
- {
- block.setRed(false);
- }
-
- block.disableCoreAI(true);
- _spawns.add(spawn);
- random++;
- }
- }
- catch (Exception e)
- {
- _log.warning(getClass().getSimpleName() + ": " + e.getMessage());
- }
-
- // Spawn the block carrying girl
- if ((_round == 1) || (_round == 2))
- {
- try
- {
- final L2Spawn girlSpawn = new L2Spawn(18676);
- girlSpawn.setX(_arenaCoordinates[_arena][4] + Rnd.get(-400, 400));
- girlSpawn.setY(_arenaCoordinates[_arena][5] + Rnd.get(-400, 400));
- girlSpawn.setZ(_zCoord);
- girlSpawn.setAmount(1);
- girlSpawn.setHeading(1);
- girlSpawn.setRespawnDelay(1);
- SpawnTable.getInstance().addNewSpawn(girlSpawn, false);
- girlSpawn.init();
- // Schedule his deletion after 9 secs of spawn
- ThreadPoolManager.getInstance().scheduleGeneral(new CarryingGirlUnspawn(girlSpawn), 9000);
- }
- catch (Exception e)
- {
- _log.warning("Couldnt Spawn Block Checker NPCs! Wrong instance type at npc table?");
- _log.warning(getClass().getSimpleName() + ": " + e.getMessage());
- }
- }
-
- _redPoints += _numOfBoxes / 2;
- _bluePoints += _numOfBoxes / 2;
-
- int timeLeft = (int) ((getStarterTime() - System.currentTimeMillis()) / 1000);
- ExCubeGameChangePoints changePoints = new ExCubeGameChangePoints(timeLeft, getBluePoints(), getRedPoints());
- getHolder().broadCastPacketToTeam(changePoints);
- }
- }
-
- private class CarryingGirlUnspawn implements Runnable
- {
- private final L2Spawn _spawn;
-
- protected CarryingGirlUnspawn(L2Spawn spawn)
- {
- _spawn = spawn;
- }
-
- @Override
- public void run()
- {
- if (_spawn == null)
- {
- _log.warning("HBCE: Block Carrying Girl is null");
- return;
- }
- SpawnTable.getInstance().deleteSpawn(_spawn, false);
- _spawn.stopRespawn();
- _spawn.getLastSpawn().deleteMe();
- }
- }
-
- /*
- * private class CountDown implements Runnable {
- * @Override public void run() { _holder.broadCastPacketToTeam(SystemMessage.getSystemMessage(SystemMessageId.BLOCK_CHECKER_ENDS_5)); ThreadPoolManager.getInstance().scheduleGeneral(new EndEvent(), 5000); } }
- */
-
- /**
- * This class erase all event parameters on player and port them back near Handy. Also, unspawn blocks, runs a garbage collector and set as free the used arena
- */
- protected class EndEvent implements Runnable
- {
- // Garbage collector and arena free setter
- private void clearMe()
- {
- HandysBlockCheckerManager.getInstance().clearPaticipantQueueByArenaId(_arena);
- _holder.clearPlayers();
- _blueTeamPoints.clear();
- _redTeamPoints.clear();
- HandysBlockCheckerManager.getInstance().setArenaFree(_arena);
-
- for (L2Spawn spawn : _spawns)
- {
- spawn.stopRespawn();
- spawn.getLastSpawn().deleteMe();
- SpawnTable.getInstance().deleteSpawn(spawn, false);
- }
- _spawns.clear();
-
- for (L2ItemInstance item : _drops)
- {
- // npe
- if (item == null)
- {
- continue;
- }
-
- // a player has it, it will be deleted later
- if (!item.isVisible() || (item.getOwnerId() != 0))
- {
- continue;
- }
-
- item.decayMe();
- L2World.getInstance().removeObject(item);
- }
- _drops.clear();
- }
-
- /**
- * Reward players after event. Tie - No Reward
- */
- private void rewardPlayers()
- {
- if (_redPoints == _bluePoints)
- {
- return;
- }
-
- _isRedWinner = _redPoints > _bluePoints ? true : false;
-
- if (_isRedWinner)
- {
- rewardAsWinner(true);
- rewardAsLooser(false);
- SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.TEAM_C1_WON);
- msg.addString("Red Team");
- _holder.broadCastPacketToTeam(msg);
- }
- else if (_bluePoints > _redPoints)
- {
- rewardAsWinner(false);
- rewardAsLooser(true);
- SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.TEAM_C1_WON);
- msg.addString("Blue Team");
- _holder.broadCastPacketToTeam(msg);
- }
- else
- {
- rewardAsLooser(true);
- rewardAsLooser(false);
- }
- }
-
- /**
- * Reward the speicifed team as a winner team 1) Higher score - 8 extra 2) Higher score - 5 extra
- * @param isRed
- */
- private void rewardAsWinner(boolean isRed)
- {
- FastMap<L2PcInstance, Integer> tempPoints = isRed ? _redTeamPoints : _blueTeamPoints;
-
- // Main give
- for (Entry<L2PcInstance, Integer> points : tempPoints.entrySet())
- {
- if (points.getKey() == null)
- {
- continue;
- }
-
- if (points.getValue() >= 10)
- {
- points.getKey().addItem("Block Checker", 13067, 2, points.getKey(), true);
- }
- else
- {
- tempPoints.remove(points.getKey());
- }
- }
-
- int first = 0, second = 0;
- L2PcInstance winner1 = null, winner2 = null;
- for (Entry<L2PcInstance, Integer> entry : tempPoints.entrySet())
- {
- L2PcInstance pc = entry.getKey();
- int pcPoints = entry.getValue();
- if (pcPoints > first)
- {
- // Move old data
- second = first;
- winner2 = winner1;
- // Set new data
- first = pcPoints;
- winner1 = pc;
- }
- else if (pcPoints > second)
- {
- second = pcPoints;
- winner2 = pc;
- }
- }
- if (winner1 != null)
- {
- winner1.addItem("Block Checker", 13067, 8, winner1, true);
- }
- if (winner2 != null)
- {
- winner2.addItem("Block Checker", 13067, 5, winner2, true);
- }
- }
-
- /**
- * Will reward the looser team with the predefined rewards Player got >= 10 points: 2 coins Player got < 10 points: 0 coins
- * @param isRed
- */
- private void rewardAsLooser(boolean isRed)
- {
- FastMap<L2PcInstance, Integer> tempPoints = isRed ? _redTeamPoints : _blueTeamPoints;
-
- for (Entry<L2PcInstance, Integer> entry : tempPoints.entrySet())
- {
- L2PcInstance player = entry.getKey();
- if ((player != null) && (entry.getValue() >= 10))
- {
- player.addItem("Block Checker", 13067, 2, player, true);
- }
- }
- }
-
- /**
- * Telport players back, give status back and send final packet
- */
- private void setPlayersBack()
- {
- final ExCubeGameEnd end = new ExCubeGameEnd(_isRedWinner);
-
- for (L2PcInstance player : _holder.getAllPlayers())
- {
- if (player == null)
- {
- continue;
- }
-
- player.stopAllEffects();
- // Remove team aura
- player.setTeam(Team.NONE);
- // Set default arena
- player.setBlockCheckerArena(DEFAULT_ARENA);
- // Remove the event items
- PcInventory inv = player.getInventory();
- if (inv.getItemByItemId(13787) != null)
- {
- long count = inv.getInventoryItemCount(13787, 0);
- inv.destroyItemByItemId("Handys Block Checker", 13787, count, player, player);
- }
- if (inv.getItemByItemId(13788) != null)
- {
- long count = inv.getInventoryItemCount(13788, 0);
- inv.destroyItemByItemId("Handys Block Checker", 13788, count, player, player);
- }
- broadcastRelationChanged(player);
- // Teleport Back
- player.teleToLocation(-57478, -60367, -2370);
- player.setInsideZone(ZoneId.PVP, false);
- // Send end packet
- player.sendPacket(end);
- player.broadcastUserInfo();
- }
- }
-
- @Override
- public void run()
- {
- if (!_abnormalEnd)
- {
- rewardPlayers();
- }
- setPlayersBack();
- clearMe();
- _isStarted = false;
- _abnormalEnd = false;
- }
- }
- }
|