/** * Starts the participation of the TvTEvent<br> * 1. Get L2NpcTemplate by Config.TVT_EVENT_PARTICIPATION_NPC_ID<br> * 2. Try to spawn a new npc of it<br> * <br> * * @return boolean: true if success, otherwise false<br> */ public static boolean startParticipation() { try { _npcSpawn = new L2Spawn(Config.TVT_EVENT_PARTICIPATION_NPC_ID); _npcSpawn.setX(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[0]); _npcSpawn.setY(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[1]); _npcSpawn.setZ(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[2]); _npcSpawn.setAmount(1); _npcSpawn.setHeading(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[3]); _npcSpawn.setRespawnDelay(1); // later no need to delete spawn from db, we don't store it (false) SpawnTable.getInstance().addNewSpawn(_npcSpawn, false); _npcSpawn.init(); _lastNpcSpawn = _npcSpawn.getLastSpawn(); _lastNpcSpawn.setCurrentHp(_lastNpcSpawn.getMaxHp()); _lastNpcSpawn.setTitle("TvT Event Participation"); _lastNpcSpawn.isAggressive(); _lastNpcSpawn.decayMe(); _lastNpcSpawn.spawnMe( _npcSpawn.getLastSpawn().getX(), _npcSpawn.getLastSpawn().getY(), _npcSpawn.getLastSpawn().getZ()); _lastNpcSpawn.broadcastPacket(new MagicSkillUse(_lastNpcSpawn, _lastNpcSpawn, 1034, 1, 1, 1)); } catch (Exception e) { _log.log( Level.WARNING, "TvTEventEngine[TvTEvent.startParticipation()]: exception: " + e.getMessage(), e); return false; } setState(EventState.PARTICIPATING); EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventRegistrationStart()); return true; }
/** * Is called when a player is killed<br> * <br> * * @param killerCharacter as L2Character<br> * @param killedPlayerInstance as L2PcInstance<br> */ public static void onKill(L2Character killerCharacter, L2PcInstance killedPlayerInstance) { if ((killedPlayerInstance == null) || !isStarted()) { return; } final byte killedTeamId = getParticipantTeamId(killedPlayerInstance.getObjectId()); if (killedTeamId == -1) { return; } new TvTEventTeleporter( killedPlayerInstance, _teams[killedTeamId].getCoordinates(), false, false); if (killerCharacter == null) { return; } L2PcInstance killerPlayerInstance = null; if ((killerCharacter instanceof L2PetInstance) || (killerCharacter instanceof L2ServitorInstance)) { killerPlayerInstance = ((L2Summon) killerCharacter).getOwner(); if (killerPlayerInstance == null) { return; } } else if (killerCharacter instanceof L2PcInstance) { killerPlayerInstance = (L2PcInstance) killerCharacter; } else { return; } final byte killerTeamId = getParticipantTeamId(killerPlayerInstance.getObjectId()); if ((killerTeamId != -1) && (killedTeamId != -1) && (killerTeamId != killedTeamId)) { final TvTEventTeam killerTeam = _teams[killerTeamId]; killerTeam.increasePoints(); final CreatureSay cs = new CreatureSay( killerPlayerInstance.getObjectId(), ChatType.WHISPER, killerPlayerInstance.getName(), "I have killed " + killedPlayerInstance.getName() + "!"); for (L2PcInstance playerInstance : _teams[killerTeamId].getParticipatedPlayers().values()) { if (playerInstance != null) { playerInstance.sendPacket(cs); } } // Notify to scripts. EventDispatcher.getInstance() .notifyEventAsync( new OnTvTEventKill(killerPlayerInstance, killedPlayerInstance, killerTeam)); } }
/** * Calculates the TvTEvent reward<br> * 1. If both teams are at a tie(points equals), send it as system message to all participants, if * one of the teams have 0 participants left online abort rewarding<br> * 2. Wait till teams are not at a tie anymore<br> * 3. Set state EvcentState.REWARDING<br> * 4. Reward team with more points<br> * 5. Show win html to wining team participants<br> * <br> * * @return String: winning team name<br> */ public static String calculateRewards() { if (_teams[0].getPoints() == _teams[1].getPoints()) { // Check if one of the teams have no more players left if ((_teams[0].getParticipatedPlayerCount() == 0) || (_teams[1].getParticipatedPlayerCount() == 0)) { // set state to rewarding setState(EventState.REWARDING); // return here, the fight can't be completed return "TvT Event: Event has ended. No team won due to inactivity!"; } // Both teams have equals points sysMsgToAllParticipants("TvT Event: Event has ended, both teams have tied."); if (Config.TVT_REWARD_TEAM_TIE) { rewardTeam(_teams[0]); rewardTeam(_teams[1]); return "TvT Event: Event has ended with both teams tying."; } return "TvT Event: Event has ended with both teams tying."; } // Set state REWARDING so nobody can point anymore setState(EventState.REWARDING); // Get team which has more points final TvTEventTeam team = _teams[_teams[0].getPoints() > _teams[1].getPoints() ? 0 : 1]; rewardTeam(team); // Notify to scripts. EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventFinish()); return "TvT Event: Event finish. Team " + team.getName() + " won with " + team.getPoints() + " kills."; }
/** * Starts the TvTEvent fight<br> * 1. Set state EventState.STARTING<br> * 2. Close doors specified in configs<br> * 3. Abort if not enough participants(return false)<br> * 4. Set state EventState.STARTED<br> * 5. Teleport all participants to team spot<br> * <br> * * @return boolean: true if success, otherwise false<br> */ public static boolean startFight() { // Set state to STARTING setState(EventState.STARTING); // Randomize and balance team distribution final Map<Integer, L2PcInstance> allParticipants = new HashMap<>(); allParticipants.putAll(_teams[0].getParticipatedPlayers()); allParticipants.putAll(_teams[1].getParticipatedPlayers()); _teams[0].cleanMe(); _teams[1].cleanMe(); L2PcInstance player; Iterator<L2PcInstance> iter; if (needParticipationFee()) { iter = allParticipants.values().iterator(); while (iter.hasNext()) { player = iter.next(); if (!hasParticipationFee(player)) { iter.remove(); } } } final int balance[] = {0, 0}; int priority = 0, highestLevelPlayerId; L2PcInstance highestLevelPlayer; // TODO: allParticipants should be sorted by level instead of using highestLevelPcInstanceOf for // every fetch while (!allParticipants.isEmpty()) { // Priority team gets one player highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants); highestLevelPlayer = allParticipants.get(highestLevelPlayerId); allParticipants.remove(highestLevelPlayerId); _teams[priority].addPlayer(highestLevelPlayer); balance[priority] += highestLevelPlayer.getLevel(); // Exiting if no more players if (allParticipants.isEmpty()) { break; } // The other team gets one player // TODO: Code not dry priority = 1 - priority; highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants); highestLevelPlayer = allParticipants.get(highestLevelPlayerId); allParticipants.remove(highestLevelPlayerId); _teams[priority].addPlayer(highestLevelPlayer); balance[priority] += highestLevelPlayer.getLevel(); // Recalculating priority priority = balance[0] > balance[1] ? 1 : 0; } // Check for enought participants if ((_teams[0].getParticipatedPlayerCount() < Config.TVT_EVENT_MIN_PLAYERS_IN_TEAMS) || (_teams[1].getParticipatedPlayerCount() < Config.TVT_EVENT_MIN_PLAYERS_IN_TEAMS)) { // Set state INACTIVE setState(EventState.INACTIVE); // Cleanup of teams _teams[0].cleanMe(); _teams[1].cleanMe(); // Unspawn the event NPC unSpawnNpc(); AntiFeedManager.getInstance().clear(AntiFeedManager.TVT_ID); return false; } if (needParticipationFee()) { iter = _teams[0].getParticipatedPlayers().values().iterator(); while (iter.hasNext()) { player = iter.next(); if (!payParticipationFee(player)) { iter.remove(); } } iter = _teams[1].getParticipatedPlayers().values().iterator(); while (iter.hasNext()) { player = iter.next(); if (!payParticipationFee(player)) { iter.remove(); } } } if (Config.TVT_EVENT_IN_INSTANCE) { try { _TvTEventInstance = InstanceManager.getInstance().createDynamicInstance(Config.TVT_EVENT_INSTANCE_FILE); InstanceManager.getInstance().getInstance(_TvTEventInstance).setAllowSummon(false); InstanceManager.getInstance().getInstance(_TvTEventInstance).setPvPInstance(true); InstanceManager.getInstance() .getInstance(_TvTEventInstance) .setEmptyDestroyTime((Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY * 1000) + 60000L); } catch (Exception e) { _TvTEventInstance = 0; _log.log( Level.WARNING, "TvTEventEngine[TvTEvent.createDynamicInstance]: exception: " + e.getMessage(), e); } } // Opens all doors specified in configs for tvt openDoors(Config.TVT_DOORS_IDS_TO_OPEN); // Closes all doors specified in configs for tvt closeDoors(Config.TVT_DOORS_IDS_TO_CLOSE); // Set state STARTED setState(EventState.STARTED); // Iterate over all teams for (TvTEventTeam team : _teams) { // Iterate over all participated player instances in this team for (L2PcInstance playerInstance : team.getParticipatedPlayers().values()) { if (playerInstance != null) { // Disable player revival. playerInstance.setCanRevive(false); // Teleporter implements Runnable and starts itself new TvTEventTeleporter(playerInstance, team.getCoordinates(), false, false); } } } // Notify to scripts. EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventStart()); return true; }