Please login or register to view links AionServer-4.7.5.X (Aion Core rev.7420; By GiGatR00n I use this I can't send an update list
You need source code. Fix code at class PvpService and Player Controller. If you do not know how to fix it look in the assembly where it works these classes
Спойлер PvpService és a Player Controller Sorry, I can't find the error: PvpService.java package com.aionemu.gameserver.services; import java.util.ArrayList; import java.util.List; import javolution.util.FastMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.aionemu.commons.utils.Rnd; import com.aionemu.gameserver.configs.main.CustomConfig; import com.aionemu.gameserver.configs.main.EventSystem; import com.aionemu.gameserver.configs.main.GroupConfig; import com.aionemu.gameserver.configs.main.LoggingConfig; import com.aionemu.gameserver.configs.main.PunishmentConfig; import com.aionemu.gameserver.controllers.attack.AggroInfo; import com.aionemu.gameserver.controllers.attack.KillList; import com.aionemu.gameserver.eventEngine.crazy_daeva.CrazyDaevaService; import com.aionemu.gameserver.model.gameobjects.player.Player; import com.aionemu.gameserver.model.gameobjects.player.RewardType; import com.aionemu.gameserver.model.ingameshop.InGameShopEn; import com.aionemu.gameserver.model.team2.alliance.PlayerAlliance; import com.aionemu.gameserver.model.team2.group.PlayerGroup; import com.aionemu.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE; import com.aionemu.gameserver.questEngine.QuestEngine; import com.aionemu.gameserver.questEngine.model.QuestEnv; import com.aionemu.gameserver.services.abyss.AbyssPointsService; import com.aionemu.gameserver.services.item.ItemService; import com.aionemu.gameserver.utils.MathUtil; import com.aionemu.gameserver.utils.PacketSendUtility; import com.aionemu.gameserver.utils.audit.AuditLogger; import com.aionemu.gameserver.utils.stats.AbyssRankEnum; import com.aionemu.gameserver.utils.stats.StatFunctions; /** * @author Sarynth */ public class PvpService { private static Logger log = LoggerFactory.getLogger("KILL_LOG"); public static final PvpService getInstance() { return SingletonHolder.instance; } private FastMap<Integer, KillList> pvpKillLists; private PvpService() { pvpKillLists = new FastMap<Integer, KillList>(); } /** * @param winnerId * @param victimId * @return */ private int getKillsFor(int winnerId, int victimId) { KillList winnerKillList = pvpKillLists.get(winnerId); if (winnerKillList == null) { return 0; } return winnerKillList.getKillsFor(victimId); } /** * @param winnerId * @param victimId */ private void addKillFor(int winnerId, int victimId) { KillList winnerKillList = pvpKillLists.get(winnerId); if (winnerKillList == null) { winnerKillList = new KillList(); pvpKillLists.put(winnerId, winnerKillList); } winnerKillList.addKillFor(victimId); } /** * @param victim */ public void doReward(Player victim) { // winner is the player that receives the kill count final Player winner = victim.getAggroList().getMostPlayerDamage(); int totalDamage = victim.getAggroList().getTotalDamage(); if (totalDamage == 0 || winner == null || winner.getRace() == victim.getRace()) { return; } if (victim.getBattleGround() != null) { return; } // Add Player Kill to record. if (this.getKillsFor(winner.getObjectId(), victim.getObjectId()) < CustomConfig.MAX_DAILY_PVP_KILLS) { winner.getAbyssRank().setAllKill(); int kills = winner.getAbyssRank().getAllKill(); // Pvp Kill Reward. if (CustomConfig.ENABLE_KILL_REWARD) { if (kills % CustomConfig.KILLS_NEEDED1 == 1) { ItemService.addItem(winner, CustomConfig.REWARD1, 1); PacketSendUtility.sendMessage(winner, "Congratulations, you have won " + "[item: " + CustomConfig.REWARD1 + "] for having killed " + CustomConfig.KILLS_NEEDED1 + " players !"); log.info("[REWARD] Player [" + winner.getName() + "] win 2 [" + CustomConfig.REWARD1 + "]"); } if (kills % CustomConfig.KILLS_NEEDED2 == 3) { ItemService.addItem(winner, CustomConfig.REWARD2, 1); PacketSendUtility.sendMessage(winner, "Congratulations, you have won " + "[item: " + CustomConfig.REWARD2 + "] for having killed " + CustomConfig.KILLS_NEEDED2 + " players !"); log.info("[REWARD] Player [" + winner.getName() + "] win 4 [" + CustomConfig.REWARD2 + "]"); } if (kills % CustomConfig.KILLS_NEEDED3 == 5) { ItemService.addItem(winner, CustomConfig.REWARD3, 1); PacketSendUtility.sendMessage(winner, "Congratulations, you have won " + "[item: " + CustomConfig.REWARD3 + "] for having killed " + CustomConfig.KILLS_NEEDED3 + " players !"); log.info("[REWARD] Player [" + winner.getName() + "] win 6 [" + CustomConfig.REWARD3 + "]"); } } // PvP Toll Reward if (CustomConfig.ENABLE_TOLL_REWARD) { if (Rnd.get(0, 100) > CustomConfig.TOLL_CHANCE){ InGameShopEn.getInstance().addToll(winner, CustomConfig.TOLL_QUANTITY); PacketSendUtility.sendMessage(winner, "You've recived " + CustomConfig.TOLL_QUANTITY + " tolls from PvP!"); } } } //Crazy kill if (EventSystem.ENABLE_CRAZY) { if (winner.getRndCrazy() >= EventSystem.CRAZY_LOWEST_RND) { AbyssPointsService.addAp(winner, 500); AbyssPointsService.addGp(winner, 20); } } // Announce that player has died. PacketSendUtility.broadcastPacketAndReceive(victim, SM_SYSTEM_MESSAGE.STR_MSG_COMBAT_FRIENDLY_DEATH_TO_B(victim.getName(), winner.getName())); // Pvp Kill Reward. int reduceap = PunishmentConfig.PUNISHMENT_REDUCEAP; if (reduceap < 0) { reduceap *= -1; } if (reduceap > 100) { reduceap = 100; } //Kill-log if (LoggingConfig.LOG_KILL) { log.info("[KILL] Player [" + winner.getName() + "] killed [" + victim.getName() + "]"); } if ((LoggingConfig.LOG_PL) || (reduceap > 0)) { String ip1 = winner.getClientConnection().getIP(); String mac1 = winner.getClientConnection().getMacAddress(); String ip2 = victim.getClientConnection().getIP(); String mac2 = victim.getClientConnection().getMacAddress(); if ((mac1 != null) && (mac2 != null)) { if ((ip1.equalsIgnoreCase(ip2)) && (mac1.equalsIgnoreCase(mac2))) { AuditLogger.info(winner, "Power Leveling : " + winner.getName() + " with " + victim.getName() + ", They have the sames ip=" + ip1 + " and mac=" + mac1 + "."); if (reduceap > 0) { int win_ap = winner.getAbyssRank().getAp() * reduceap / 100; int vic_ap = victim.getAbyssRank().getAp() * reduceap / 100; AbyssPointsService.addAp(winner, -win_ap); AbyssPointsService.addAp(victim, -vic_ap); PacketSendUtility.sendMessage(winner, "[PL-AP] You lost " + reduceap + "% of your total ap"); PacketSendUtility.sendMessage(victim, "[PL-AP] You lost " + reduceap + "% of your total ap"); } return; } if (ip1.equalsIgnoreCase(ip2)) { AuditLogger.info(winner, "Possible Power Leveling : " + winner.getName() + " with " + victim.getName() + ", They have the sames ip=" + ip1 + "."); AuditLogger.info(winner, "Check if " + winner.getName() + " and " + victim.getName() + " are Brothers-Sisters-Lovers-dogs-cats..."); } } } // Keep track of how much damage was dealt by players // so we can remove AP based on player damage... int playerDamage = 0; boolean success; // Distribute AP to groups and players that had damage. for (AggroInfo aggro : victim.getAggroList().getFinalDamageList(true)) { success = false; if (aggro.getAttacker() instanceof Player) { success = rewardPlayer(victim, totalDamage, aggro); } else if (aggro.getAttacker() instanceof PlayerGroup) { success = rewardPlayerGroup(victim, totalDamage, aggro); } else if (aggro.getAttacker() instanceof PlayerAlliance) { success = rewardPlayerAlliance(victim, totalDamage, aggro); } // Add damage last, so we don't include damage from same race. (Duels, Arena) if (success) { playerDamage += aggro.getDamage(); } } SerialKillerService.getInstance().updateRank(winner, victim); //notify Quest engine for winner + his group notifyKillQuests(winner, victim); // Apply lost AP to defeated player final int apLost = StatFunctions.calculatePvPApLost(victim, winner); final int apActuallyLost = (int) (apLost * playerDamage / totalDamage); if (apActuallyLost > 0) { AbyssPointsService.addAp(victim, -apActuallyLost); } } /** * @param victim * @param totalDamage * @param aggro * @return true if group is not same race */ private boolean rewardPlayerGroup(Player victim, int totalDamage, AggroInfo aggro) { // Reward Group PlayerGroup group = ((PlayerGroup) aggro.getAttacker()); // Don't Reward Player of Same Faction. if (group.getRace() == victim.getRace()) { return false; } // Find group members in range List<Player> players = new ArrayList<Player>(); // Find highest rank and level in local group int maxRank = AbyssRankEnum.GRADE9_SOLDIER.getId(); int maxLevel = 0; for (Player member : group.getMembers()) { if (MathUtil.isIn3dRange(member, victim, GroupConfig.GROUP_MAX_DISTANCE)) { // Don't distribute AP to a dead player! if (!member.getLifeStats().isAlreadyDead()) { players.add(member); if (member.getLevel() > maxLevel) { maxLevel = member.getLevel(); } if (member.getAbyssRank().getRank().getId() > maxRank) { maxRank = member.getAbyssRank().getRank().getId(); } } } } // They are all dead or out of range. if (players.isEmpty()) { return false; } int baseApReward = StatFunctions.calculatePvpApGained(victim, maxRank, maxLevel); int baseXpReward = StatFunctions.calculatePvpXpGained(victim, maxRank, maxLevel); int baseDpReward = StatFunctions.calculatePvpDpGained(victim, maxRank, maxLevel); float groupPercentage = (float) aggro.getDamage() / totalDamage; int apRewardPerMember = Math.round(baseApReward * groupPercentage / players.size()); int xpRewardPerMember = Math.round(baseXpReward * groupPercentage / players.size()); int dpRewardPerMember = Math.round(baseDpReward * groupPercentage / players.size()); for (Player member : players) { int memberApGain = 1; int memberXpGain = 1; int memberDpGain = 1; if (this.getKillsFor(member.getObjectId(), victim.getObjectId()) < CustomConfig.MAX_DAILY_PVP_KILLS) { if (apRewardPerMember > 0) { memberApGain = Math.round(RewardType.AP_PLAYER.calcReward(member, apRewardPerMember)); } if (xpRewardPerMember > 0) { memberXpGain = Math.round(xpRewardPerMember * member.getRates().getXpPlayerGainRate()); } if (dpRewardPerMember > 0) { memberDpGain = Math.round(StatFunctions.adjustPvpDpGained(dpRewardPerMember, victim.getLevel(), member.getLevel()) * member.getRates().getDpPlayerRate()); } } Player partner = member.findPartner(); if (member.isMarried() && member.getPlayerGroup2().getMembers() == partner && member.getPlayerGroup2().getMembers().size() == 2) { AbyssPointsService.addAp(member, victim, memberApGain + (memberApGain * 20 / 100)); //20% more AP for weddings } else { AbyssPointsService.addAp(member, victim, memberApGain); } member.getCommonData().addExp(memberXpGain, RewardType.PVP_KILL, victim.getName()); member.getCommonData().addEventExp(memberXpGain); member.getCommonData().addDp(memberDpGain); this.addKillFor(member.getObjectId(), victim.getObjectId()); } return true; } /** * @param victim * @param totalDamage * @param aggro * @return true if group is not same race */ private boolean rewardPlayerAlliance(Player victim, int totalDamage, AggroInfo aggro) { // Reward Alliance PlayerAlliance alliance = ((PlayerAlliance) aggro.getAttacker()); // Don't Reward Player of Same Faction. if (alliance.getLeaderObject().getRace() == victim.getRace()) { return false; } // Find group members in range List<Player> players = new ArrayList<Player>(); // Find highest rank and level in local group int maxRank = AbyssRankEnum.GRADE9_SOLDIER.getId(); int maxLevel = 0; for (Player member : alliance.getMembers()) { if (!member.isOnline()) { continue; } if (MathUtil.isIn3dRange(member, victim, GroupConfig.GROUP_MAX_DISTANCE)) { // Don't distribute AP to a dead player! if (!member.getLifeStats().isAlreadyDead()) { players.add(member); if (member.getLevel() > maxLevel) { maxLevel = member.getLevel(); } if (member.getAbyssRank().getRank().getId() > maxRank) { maxRank = member.getAbyssRank().getRank().getId(); } } } } // They are all dead or out of range. if (players.isEmpty()) { return false; } int baseApReward = StatFunctions.calculatePvpApGained(victim, maxRank, maxLevel); int baseXpReward = StatFunctions.calculatePvpXpGained(victim, maxRank, maxLevel); int baseDpReward = StatFunctions.calculatePvpDpGained(victim, maxRank, maxLevel); float groupPercentage = (float) aggro.getDamage() / totalDamage; int apRewardPerMember = Math.round(baseApReward * groupPercentage / players.size()); int xpRewardPerMember = Math.round(baseXpReward * groupPercentage / players.size()); int dpRewardPerMember = Math.round(baseDpReward * groupPercentage / players.size()); for (Player member : players) { int memberApGain = 1; int memberXpGain = 1; int memberDpGain = 1; if (this.getKillsFor(member.getObjectId(), victim.getObjectId()) < CustomConfig.MAX_DAILY_PVP_KILLS) { if (apRewardPerMember > 0) { memberApGain = Math.round(RewardType.AP_PLAYER.calcReward(member, apRewardPerMember)); } if (xpRewardPerMember > 0) { memberXpGain = Math.round(xpRewardPerMember * member.getRates().getXpPlayerGainRate()); } if (dpRewardPerMember > 0) { memberDpGain = Math.round(StatFunctions.adjustPvpDpGained(dpRewardPerMember, victim.getLevel(), member.getLevel()) * member.getRates().getDpPlayerRate()); } } AbyssPointsService.addAp(member, victim, memberApGain); member.getCommonData().addExp(memberXpGain, RewardType.PVP_KILL, victim.getName()); member.getCommonData().addEventExp(memberXpGain); member.getCommonData().addDp(memberDpGain); this.addKillFor(member.getObjectId(), victim.getObjectId()); } return true; } /** * @param victim * @param totalDamage * @param aggro * @return true if player is not same race */ private boolean rewardPlayer(Player victim, int totalDamage, AggroInfo aggro) { // Reward Player Player winner = ((Player) aggro.getAttacker()); // Don't Reward Player out of range/dead/same faction if (winner.getRace() == victim.getRace() || !MathUtil.isIn3dRange(winner, victim, GroupConfig.GROUP_MAX_DISTANCE) || winner.getLifeStats().isAlreadyDead()) { return false; } int baseApReward = 1; int baseXpReward = 1; int baseDpReward = 1; if (this.getKillsFor(winner.getObjectId(), victim.getObjectId()) < CustomConfig.MAX_DAILY_PVP_KILLS) { baseApReward = StatFunctions.calculatePvpApGained(victim, winner.getAbyssRank().getRank().getId(), winner.getLevel()); baseXpReward = StatFunctions.calculatePvpXpGained(victim, winner.getAbyssRank().getRank().getId(), winner.getLevel()); baseDpReward = StatFunctions.calculatePvpDpGained(victim, winner.getAbyssRank().getRank().getId(), winner.getLevel()); if (EventSystem.ENABLE_CRAZY) { if (winner.getRace() != victim.getRace()) { CrazyDaevaService.getInstance().increaseRawKillCount(winner); } } } int apPlayerReward = Math.round(baseApReward * aggro.getDamage() / totalDamage); apPlayerReward = (int) RewardType.AP_PLAYER.calcReward(winner, apPlayerReward); int xpPlayerReward = Math.round(baseXpReward * winner.getRates().getXpPlayerGainRate() * aggro.getDamage() / totalDamage); int dpPlayerReward = Math.round(baseDpReward * winner.getRates().getDpPlayerRate() * aggro.getDamage() / totalDamage); AbyssPointsService.addAp(winner, victim, apPlayerReward); winner.getCommonData().addExp(xpPlayerReward, RewardType.PVP_KILL, victim.getName()); winner.getCommonData().addEventExp(xpPlayerReward); winner.getCommonData().addDp(dpPlayerReward); this.addKillFor(winner.getObjectId(), victim.getObjectId()); return true; } private void notifyKillQuests(Player winner, Player victim) { if (winner.getRace() == victim.getRace()) { return; } List<Player> rewarded = new ArrayList<Player>(); int worldId = victim.getWorldId(); if (winner.isInGroup2()) { rewarded.addAll(winner.getPlayerGroup2().getOnlineMembers()); } else if (winner.isInAlliance2()) { rewarded.addAll(winner.getPlayerAllianceGroup2().getOnlineMembers()); } else { rewarded.add(winner); } for (Player p : rewarded) { if (!MathUtil.isIn3dRange(p, victim, GroupConfig.GROUP_MAX_DISTANCE) || p.getLifeStats().isAlreadyDead()) { continue; } QuestEngine.getInstance().onKillInWorld(new QuestEnv(victim, p, 0, 0), worldId); QuestEngine.getInstance().onKillRanked(new QuestEnv(victim, p, 0, 0), victim.getAbyssRank().getRank()); } rewarded.clear(); } @SuppressWarnings("synthetic-access") private static class SingletonHolder { protected static final PvpService instance = new PvpService(); } } ------------------------------------------------------- PlayerController.java package com.aionemu.gameserver.controllers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Nonnull; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.concurrent.Future; import com.aionemu.gameserver.ai2.manager.LookManager; import com.aionemu.gameserver.configs.main.EventSystem; import com.aionemu.gameserver.configs.main.HTMLConfig; import com.aionemu.gameserver.configs.main.MembershipConfig; import com.aionemu.gameserver.configs.main.SecurityConfig; import com.aionemu.gameserver.controllers.attack.AttackUtil; import com.aionemu.gameserver.dataholders.DataManager; import com.aionemu.gameserver.dataholders.PlayerInitialData; import com.aionemu.gameserver.eventEngine.battleground.model.templates.BattleGroundTemplate; import com.aionemu.gameserver.eventEngine.battleground.services.battleground.AssaultBattleGround; import com.aionemu.gameserver.eventEngine.battleground.services.battleground.BattleGroundManager; import com.aionemu.gameserver.eventEngine.battleground.services.battleground.CTFBattleGround; import com.aionemu.gameserver.eventEngine.crazy_daeva.CrazyDaevaService; import com.aionemu.gameserver.model.DescriptionId; import com.aionemu.gameserver.model.EmotionType; import com.aionemu.gameserver.model.Race; import com.aionemu.gameserver.model.TaskId; import com.aionemu.gameserver.model.actions.PlayerMode; import com.aionemu.gameserver.model.gameobjects.Kisk; import com.aionemu.gameserver.model.gameobjects.Npc; import com.aionemu.gameserver.model.gameobjects.Summon; import com.aionemu.gameserver.model.gameobjects.VisibleObject; import com.aionemu.gameserver.model.gameobjects.Item; import com.aionemu.gameserver.model.gameobjects.Creature; import com.aionemu.gameserver.model.gameobjects.Pet; import com.aionemu.gameserver.model.gameobjects.Gatherable; import com.aionemu.gameserver.model.gameobjects.StaticObject; import com.aionemu.gameserver.model.gameobjects.player.AbyssRank; import com.aionemu.gameserver.model.gameobjects.player.BindPointPosition; import com.aionemu.gameserver.model.gameobjects.player.Player; import com.aionemu.gameserver.model.gameobjects.state.CreatureState; import com.aionemu.gameserver.model.gameobjects.state.CreatureVisualState; import com.aionemu.gameserver.model.house.House; import com.aionemu.gameserver.model.skill.PlayerSkillEntry; import com.aionemu.gameserver.model.stats.container.PlayerGameStats; import com.aionemu.gameserver.model.summons.SummonMode; import com.aionemu.gameserver.model.summons.UnsummonType; import com.aionemu.gameserver.model.team2.group.PlayerFilters.ExcludePlayerFilter; import com.aionemu.gameserver.model.templates.flypath.FlyPathEntry; import com.aionemu.gameserver.model.templates.panels.SkillPanel; import com.aionemu.gameserver.model.templates.quest.QuestItems; import com.aionemu.gameserver.model.templates.stats.PlayerStatsTemplate; import com.aionemu.gameserver.network.aion.serverpackets.SM_PLAYER_INFO; import com.aionemu.gameserver.network.aion.serverpackets.SM_EMOTION; import com.aionemu.gameserver.network.aion.serverpackets.SM_PET; import com.aionemu.gameserver.network.aion.serverpackets.SM_MOTION; import com.aionemu.gameserver.network.aion.serverpackets.SM_NPC_INFO; import com.aionemu.gameserver.network.aion.serverpackets.SM_KISK_UPDATE; import com.aionemu.gameserver.network.aion.serverpackets.SM_EMOTION_SWITCH; import com.aionemu.gameserver.network.aion.serverpackets.SM_HEADING_UPDATE; import com.aionemu.gameserver.network.aion.serverpackets.SM_GATHERABLE_INFO; import com.aionemu.gameserver.network.aion.serverpackets.SM_DELETE; import com.aionemu.gameserver.network.aion.serverpackets.SM_NEARBY_QUESTS; import com.aionemu.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE; import com.aionemu.gameserver.network.aion.serverpackets.SM_DIE; import com.aionemu.gameserver.network.aion.serverpackets.SM_ATTACK_STATUS; import com.aionemu.gameserver.network.aion.serverpackets.SM_SKILL_CANCEL; import com.aionemu.gameserver.network.aion.serverpackets.SM_ITEM_USAGE_ANIMATION; import com.aionemu.gameserver.network.aion.serverpackets.SM_PRIVATE_STORE; import com.aionemu.gameserver.network.aion.serverpackets.SM_LEVEL_UPDATE; import com.aionemu.gameserver.network.aion.serverpackets.SM_PACKAGE_INFO_NOTIFY; import com.aionemu.gameserver.network.aion.serverpackets.SM_STATS_INFO; import com.aionemu.gameserver.network.aion.serverpackets.SM_PLAYER_STATE; import com.aionemu.gameserver.network.aion.serverpackets.SM_PLAYER_STANCE; import com.aionemu.gameserver.network.aion.serverpackets.SM_ATTACK_STATUS.LOG; import com.aionemu.gameserver.network.aion.serverpackets.SM_ATTACK_STATUS.TYPE; import com.aionemu.gameserver.questEngine.QuestEngine; import com.aionemu.gameserver.questEngine.model.QuestEnv; import com.aionemu.gameserver.restrictions.RestrictionsManager; import com.aionemu.gameserver.services.QuestService; import com.aionemu.gameserver.services.SerialKillerService; import com.aionemu.gameserver.services.SiegeService; import com.aionemu.gameserver.services.DuelService; import com.aionemu.gameserver.services.PvpService; import com.aionemu.gameserver.services.HTMLService; import com.aionemu.gameserver.services.ClassChangeService; import com.aionemu.gameserver.services.SkillLearnService; import com.aionemu.gameserver.services.LegionService; import com.aionemu.gameserver.services.abyss.AbyssService; import com.aionemu.gameserver.services.craft.CraftSkillUpdateService; import com.aionemu.gameserver.services.ecfunctions.oneVsone.ArenaMasterService; import com.aionemu.gameserver.services.ecfunctions.oneVsone.OneVsOneStruct; import com.aionemu.gameserver.services.instance.InstanceService; import com.aionemu.gameserver.services.item.ItemService; import com.aionemu.gameserver.services.summons.SummonsService; import com.aionemu.gameserver.skillengine.SkillEngine; import com.aionemu.gameserver.skillengine.model.Effect; import com.aionemu.gameserver.skillengine.model.DispelCategoryType; import com.aionemu.gameserver.skillengine.model.SkillTargetSlot; import com.aionemu.gameserver.skillengine.model.Skill; import com.aionemu.gameserver.skillengine.model.SkillTemplate; import com.aionemu.gameserver.skillengine.model.HealType; import com.aionemu.gameserver.skillengine.model.Skill.SkillMethod; import com.aionemu.gameserver.taskmanager.tasks.PlayerMoveTaskManager; import com.aionemu.gameserver.taskmanager.tasks.TeamEffectUpdater; import com.aionemu.gameserver.utils.MathUtil; import com.aionemu.gameserver.utils.PacketSendUtility; import com.aionemu.gameserver.utils.ThreadPoolManager; import com.aionemu.gameserver.utils.audit.AuditLogger; import com.aionemu.gameserver.world.MapRegion; import com.aionemu.gameserver.world.World; import com.aionemu.gameserver.world.WorldType; import com.aionemu.gameserver.world.geo.GeoService; import com.aionemu.gameserver.world.zone.ZoneInstance; import com.aionemu.gameserver.world.zone.ZoneName; /** * This class is for controlling players. * * @author -Nemesiss-, ATracer, xavier, Sarynth, RotO, xTz, KID, Sippolo */ public class PlayerController extends CreatureController<Player> { private Logger log = LoggerFactory.getLogger(PlayerController.class); private boolean isInShutdownProgress; private long lastAttackMilis = 0; private long lastAttackedMilis = 0; private int stance = 0; @SuppressWarnings("unused") private Listener mListener; protected BattleGroundTemplate template; @Override public void see(VisibleObject object) { super.see(object); if (object instanceof Player) { Player player = (Player) object; PacketSendUtility.sendPacket(getOwner(), new SM_PLAYER_INFO(player, getOwner().isAggroIconTo(player))); PacketSendUtility.sendPacket(getOwner(), new SM_MOTION(player.getObjectId(), player.getMotions().getActiveMotions())); if (player.isInPlayerMode(PlayerMode.RIDE)) { PacketSendUtility.sendPacket(getOwner(), new SM_EMOTION(player, EmotionType.RIDE, 0, player.ride.getNpcId())); } if (player.getPet() != null) { LoggerFactory.getLogger(PlayerController.class).debug("Player " + getOwner().getName() + " sees " + object.getName() + " that has toypet"); PacketSendUtility.sendPacket(getOwner(), new SM_PET(3, player.getPet())); } player.getEffectController().sendEffectIconsTo(getOwner()); } else if (object instanceof Kisk) { Kisk kisk = ((Kisk) object); PacketSendUtility.sendPacket(getOwner(), new SM_NPC_INFO(kisk, getOwner())); if (getOwner().getRace() == kisk.getOwnerRace()) { PacketSendUtility.sendPacket(getOwner(), new SM_KISK_UPDATE(kisk)); } } else if (object instanceof Npc) { Npc npc = ((Npc) object); LookManager.corrigateHeading(npc, this.getOwner()); PacketSendUtility.sendPacket(getOwner(), new SM_NPC_INFO(npc, getOwner())); PacketSendUtility.sendPacket(getOwner(), new SM_EMOTION_SWITCH(npc, npc.getState(), EmotionType.SELECT_TARGET)); PacketSendUtility.sendPacket(getOwner(), new SM_HEADING_UPDATE(object.getObjectId(), (byte) object.getHeading())); if (!npc.getEffectController().isEmpty()) { npc.getEffectController().sendEffectIconsTo(getOwner()); } QuestEngine.getInstance().onAtDistance(new QuestEnv(object, getOwner(), 0, 0)); } else if (object instanceof Summon) { Summon npc = ((Summon) object); PacketSendUtility.sendPacket(getOwner(), new SM_NPC_INFO(npc, getOwner())); if (!npc.getEffectController().isEmpty()) { npc.getEffectController().sendEffectIconsTo(getOwner()); } } else if (object instanceof Gatherable || object instanceof StaticObject) { PacketSendUtility.sendPacket(getOwner(), new SM_GATHERABLE_INFO(object)); } else if (object instanceof Pet) { PacketSendUtility.sendPacket(getOwner(), new SM_PET(3, (Pet) object)); } } @Override public void notSee(VisibleObject object, boolean isOutOfRange) { super.notSee(object, isOutOfRange); if (object instanceof Pet) { PacketSendUtility.sendPacket(getOwner(), new SM_PET(4, (Pet) object)); } else { PacketSendUtility.sendPacket(getOwner(), new SM_DELETE(object, isOutOfRange ? 0 : 15)); } } public void updateNearbyQuests() { HashMap<Integer, Integer> nearbyQuestList = new HashMap<>(); for (int questId : getOwner().getPosition().getMapRegion().getParent().getQuestIds()) { int diff = 0; if (questId <= 0xFFFF) { diff = QuestService.getLevelRequirementDiff(questId, getOwner().getCommonData().getLevel()); } if (diff <= 2 && QuestService.checkStartConditions(new QuestEnv(null, getOwner(), questId, 0), false)) { nearbyQuestList.put(questId, diff); } } PacketSendUtility.sendPacket(getOwner(), new SM_NEARBY_QUESTS(nearbyQuestList)); } @Override public void onEnterZone(ZoneInstance zone) { Player player = getOwner(); if (!zone.canRide() && player.isInPlayerMode(PlayerMode.RIDE)) { player.unsetPlayerMode(PlayerMode.RIDE); } InstanceService.onEnterZone(player, zone); if (zone.getAreaTemplate().getZoneName() == null) { log.error("No name found for a Zone in the map " + zone.getAreaTemplate().getWorldId()); } else { QuestEngine.getInstance().onEnterZone(new QuestEnv(null, player, 0, 0), zone.getAreaTemplate().getZoneName()); } } @Override public void onLeaveZone(ZoneInstance zone) { Player player = getOwner(); InstanceService.onLeaveZone(player, zone); ZoneName zoneName = zone.getAreaTemplate().getZoneName(); if (zoneName == null) { log.warn("No name for zone template in " + zone.getAreaTemplate().getWorldId()); return; } QuestEngine.getInstance().onLeaveZone(new QuestEnv(null, player, 0, 0), zoneName); } /** * {@inheritDoc} Should only be triggered from one place (life stats) */ // TODO [AT] move public void onEnterWorld() { InstanceService.onEnterInstance(getOwner()); if (getOwner().getPosition().getWorldMapInstance().getParent().isExceptBuff()) { getOwner().getEffectController().removeAllEffects(); } if (getOwner().getBattleGround() != null && getOwner().getWorldId() != getOwner().getBattleGround().getWorldId()) { BattleGroundManager.unregisterPlayer(getOwner()); getOwner().battlegroundWaiting = false; getOwner().setBattleGround(null); } for (Effect ef : getOwner().getEffectController().getAbnormalEffects()) { if (ef.isDeityAvatar()) { // remove abyss transformation if worldtype != abyss && worldtype != balaurea if (getOwner().getWorldType() != WorldType.ABYSS && getOwner().getWorldType() != WorldType.BALAUREA || getOwner().isInInstance() || getOwner().getWorldId() == 600040000) { ef.endEffect(); getOwner().getEffectController().clearEffect(ef); } } else if (ef.getSkillTemplate().getDispelCategory() == DispelCategoryType.NPC_BUFF) { ef.endEffect(); getOwner().getEffectController().clearEffect(ef); } } } // TODO [AT] move public void onLeaveWorld() { SerialKillerService.getInstance().onLeaveMap(getOwner()); ArenaMasterService.getInstance().onLeaveInstance(getOwner()); InstanceService.onLeaveInstance(getOwner()); } public void validateLoginZone() { int mapId; float x, y, z; byte h; boolean moveToBind = false; BindPointPosition bind = getOwner().getBindPoint(); if (bind != null) { mapId = bind.getMapId(); x = bind.getX(); y = bind.getY(); z = bind.getZ(); h = bind.getHeading(); } else { PlayerInitialData.LocationData start = DataManager.PLAYER_INITIAL_DATA.getSpawnLocation(getOwner().getRace()); mapId = start.getMapId(); x = start.getX(); y = start.getY(); z = start.getZ(); h = start.getHeading(); } if (!SiegeService.getInstance().validateLoginZone(getOwner())) { moveToBind = true; } else { long lastOnline = getOwner().getCommonData().getLastOnline().getTime(); long secondsOffline = (System.currentTimeMillis() / 1000) - lastOnline / 1000; if (secondsOffline > 10 * 60) { //Logout in no-recall zone sends you to bindpoint after 10 (??) minutes for (ZoneInstance zone : getOwner().getPosition().getMapRegion().getZones(getOwner())) { if (!zone.canRecall()) { moveToBind = true; break; } } } } if (moveToBind) { World.getInstance().setPosition(getOwner(), mapId, x, y, z, h); } } public void onDie(@Nonnull Creature lastAttacker, boolean showPacket) { Player player = this.getOwner(); player.getController().cancelCurrentSkill(); player.setRebirthRevive(getOwner().haveSelfRezEffect()); showPacket = player.hasResurrectBase() ? false : showPacket; Creature master = lastAttacker.getMaster(); // crazy Daeva if (EventSystem.ENABLE_CRAZY) { if (((master instanceof Player)) && (master.getRace() != player.getRace())) { CrazyDaevaService.getInstance().crazyOnDie(player, (Player) master, true); } } // Battelground if (master instanceof Player) { if (((Player) master).getBattleGround() != null && ((Player) master).getBattleGround() instanceof AssaultBattleGround) { ((AssaultBattleGround) (((Player) master).getBattleGround())).onKillPlayer(player, (Player) master); } } // 1 vs 1 Event if (EventSystem.ENABLE_ONEVONE){ if (((master instanceof Player)) && ((Player) master).isInPkMode()){ for(int worldId : OneVsOneStruct.worldid){ if(master.getWorldId() == worldId){ ArenaMasterService.getInstance().onDie((Player) master, player); } } } } // High ranked kill announce AbyssRank ar = player.getAbyssRank(); if (AbyssService.isOnPvpMap(player) && ar != null) { if (ar.getRank().getId() >= 10) { AbyssService.rankedKillAnnounce(player); } } if (DuelService.getInstance().isDueling(player.getObjectId())) { if (master != null && DuelService.getInstance().isDueling(player.getObjectId(), master.getObjectId())) { DuelService.getInstance().loseDuel(player); player.getEffectController().removeAbnormalEffectsByTargetSlot(SkillTargetSlot.DEBUFF); player.getLifeStats().setCurrentHpPercent(33); player.getLifeStats().setCurrentMpPercent(33); return; } DuelService.getInstance().loseDuel(player); } /** * Release summon */ Summon summon = player.getSummon(); if (summon != null) { SummonsService.doMode(SummonMode.RELEASE, summon, UnsummonType.UNSPECIFIED); } // setIsFlyingBeforeDead for PlayerReviveService if (player.isInState(CreatureState.FLYING)) { player.setIsFlyingBeforeDeath(true); } // ride player.setPlayerMode(PlayerMode.RIDE, null); player.unsetState(CreatureState.RESTING); player.unsetState(CreatureState.FLOATING_CORPSE); // unsetflying player.unsetState(CreatureState.FLYING); player.unsetState(CreatureState.GLIDING); player.setFlyState(0); if (player.isInInstance()) { if (player.getPosition().getWorldMapInstance().getInstanceHandler().onDie(player, lastAttacker)) { super.onDie(lastAttacker); return; } } MapRegion mapRegion = player.getPosition().getMapRegion(); if (mapRegion != null && mapRegion.onDie(lastAttacker, getOwner())) { return; } this.doReward(); if (master instanceof Npc || master == player) { if (player.getLevel() > 4 && !isNoDeathPenaltyInEffect()) player.getCommonData().calculateExpLoss(); } // Effects removed with super.onDie() super.onDie(lastAttacker); //test it if bug (maybe not needed) if (player.getBattleGround() != null && player.getBattleGround() instanceof CTFBattleGround && master instanceof Player) { int tplId = player.getBattleGround().getTplId(); template = DataManager.BATTLEGROUND_DATA.getBattleGroundTemplate(tplId); player.getBattleGround().increasePoints((Player) master, template.getRules().getKillPlayer()); } if (player.battlegroundFlag != null) { player.getBattleGround().broadcastToBattleGround(player.getCommonData().getName() + (player.getLegion() != null ? " de " + player.getLegion().getLegionName() : "") + " got the " + (player.battlegroundFlag.getRace() == Race.ELYOS ? "Elyséen" : "Asmodien") + " !", null); if (master instanceof Player) { player.getBattleGround().increasePoints((Player) master, template.getRules().getFlagBase()); } player.battlegroundFlag.getController().dropped = true; player.battlegroundFlag.setFlagHolder(null); player.battlegroundFlag = null; if (player.getController().getTask(TaskId.BATTLEGROUND_CARRY_FLAG) != null) { player.getController().getTask(TaskId.BATTLEGROUND_CARRY_FLAG).cancel(true); player.getController().addTask(TaskId.BATTLEGROUND_CARRY_FLAG, null); } } player.getActionList().clearAll(); // send sm_emotion with DIE // have to be send after state is updated! sendDieFromCreature(lastAttacker, showPacket); QuestEngine.getInstance().onDie(new QuestEnv(null, player, 0, 0)); if (player.isInGroup2()) { player.getPlayerGroup2().sendPacket(SM_SYSTEM_MESSAGE.STR_MSG_COMBAT_FRIENDLY_DEATH(player.getName()), new ExcludePlayerFilter(player)); } } @Override public void onDie(@Nonnull Creature lastAttacker) { this.onDie(lastAttacker, true); } public void sendDie() { sendDieFromCreature(getOwner(), true); } private void sendDieFromCreature(@Nonnull Creature lastAttacker, boolean showPacket) { Player player = this.getOwner(); PacketSendUtility.broadcastPacket(player, new SM_EMOTION(player, EmotionType.DIE, 0, player.equals(lastAttacker) ? 0 : lastAttacker.getObjectId()), true); if (showPacket) { int kiskTimeRemaining = (player.getKisk() != null ? player.getKisk().getRemainingLifetime() : 0); PacketSendUtility.sendPacket(player, new SM_DIE(player.canUseRebirthRevive(), player.haveSelfRezItem(), kiskTimeRemaining, 0, isInvader(player))); } PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_MSG_COMBAT_MY_DEATH); } private boolean isInvader(Player player) { if (player.getRace().equals(Race.ASMODIANS)) { return player.getWorldId() == 210060000; } else { return player.getWorldId() == 220050000; } } @Override public void doReward() { PvpService.getInstance().doReward(getOwner()); } @Override public void onBeforeSpawn() { this.onBeforeSpawn(true); /* super.onBeforeSpawn(); startProtectionActiveTask(); if (getOwner().getIsFlyingBeforeDeath()) { getOwner().unsetState(CreatureState.FLOATING_CORPSE); } else { getOwner().unsetState(CreatureState.DEAD); } getOwner().setState(CreatureState.ACTIVE); */ } public void onBeforeSpawn(boolean blink) { super.onBeforeSpawn(); if (blink) { startProtectionActiveTask(); } if (getOwner().getIsFlyingBeforeDeath()) { getOwner().unsetState(CreatureState.FLOATING_CORPSE); } else { getOwner().unsetState(CreatureState.DEAD); } getOwner().setState(CreatureState.ACTIVE); } @Override public void attackTarget(Creature target, int time) { PlayerGameStats gameStats = getOwner().getGameStats(); if (!RestrictionsManager.canAttack(getOwner(), target)) { return; } // Normal attack is already limited client side (ex. Press C and attacker approaches target) // but need a check server side too also for Z axis issue if (!MathUtil.isInAttackRange(getOwner(), target, (float) (getOwner().getGameStats().getAttackRange().getCurrent() / 1000f) + 1)) { return; } if (!GeoService.getInstance().canSee(getOwner(), target)) { PacketSendUtility.sendPacket(getOwner(), SM_SYSTEM_MESSAGE.STR_ATTACK_OBSTACLE_EXIST); return; } if (target instanceof Npc) { QuestEngine.getInstance().onAttack(new QuestEnv(target, getOwner(), 0, 0)); } int attackSpeed = gameStats.getAttackSpeed().getCurrent(); long milis = System.currentTimeMillis(); // network ping.. if (milis - lastAttackMilis + 300 < attackSpeed) { // hack return; } lastAttackMilis = milis; /** * notify attack observers */ super.attackTarget(target, time); } @Override public void onAttack(Creature creature, int skillId, TYPE type, int damage, boolean notifyAttack, LOG log) { if (getOwner().getLifeStats().isAlreadyDead()) { return; } if (getOwner().isInvul() || getOwner().isProtectionActive()) { damage = 0; } if (getOwner().getBattleGround() != null && !getOwner().getBattleGround().running) { damage = 0; } if (getOwner().getActionList() != null) { getOwner().getActionList().addDamage(creature, damage); } cancelUseItem(); cancelGathering(); super.onAttack(creature, skillId, type, damage, notifyAttack, log); PacketSendUtility.broadcastPacket(getOwner(), new SM_ATTACK_STATUS(getOwner(), type, skillId, damage, log), true); if (creature instanceof Npc) { QuestEngine.getInstance().onAttack(new QuestEnv(creature, getOwner(), 0, 0)); } lastAttackedMilis = System.currentTimeMillis(); } /** * @param skillId * @param targetType * @param x * @param y * @param z */ public void useSkill(int skillId, int targetType, float x, float y, float z, int time) { Player player = getOwner(); Skill skill = SkillEngine.getInstance().getSkillFor(player, skillId, player.getTarget()); if (skill != null) { if (!RestrictionsManager.canUseSkill(player, skill)) { return; } skill.setTargetType(targetType, x, y, z); skill.setHitTime(time); skill.useSkill(); } } /** * @param template * @param targetType * @param x * @param y * @param z * @param clientHitTime */ public void useSkill(SkillTemplate template, int targetType, float x, float y, float z, int clientHitTime, int skillLevel) { Player player = getOwner(); Skill skill = null; skill = SkillEngine.getInstance().getSkillFor(player, template, player.getTarget()); if (skill == null && player.isTransformed()) { SkillPanel panel = DataManager.PANEL_SKILL_DATA.getSkillPanel(player.getTransformModel().getPanelId()); if (panel != null && panel.canUseSkill(template.getSkillId(), skillLevel)) { skill = SkillEngine.getInstance().getSkillFor(player, template, player.getTarget(), skillLevel); } } if (skill != null) { if (!RestrictionsManager.canUseSkill(player, skill)) { return; } skill.setTargetType(targetType, x, y, z); skill.setHitTime(clientHitTime); skill.useSkill(); } } @Override public void onMove() { getOwner().getObserveController().notifyMoveObservers(); super.onMove(); } @Override public void onStopMove() { PlayerMoveTaskManager.getInstance().removePlayer(getOwner()); getOwner().getObserveController().notifyMoveObservers(); getOwner().getMoveController().setInMove(false); cancelCurrentSkill(); updateZone(); super.onStopMove(); } @Override public void onStartMove() { getOwner().getMoveController().setInMove(true); PlayerMoveTaskManager.getInstance().addPlayer(getOwner()); cancelUseItem(); cancelCurrentSkill(); super.onStartMove(); } @Override public void cancelCurrentSkill() { if (getOwner().getCastingSkill() == null) { return; } Player player = getOwner(); Skill castingSkill = player.getCastingSkill(); castingSkill.cancelCast(); player.removeSkillCoolDown(castingSkill.getSkillTemplate().getCooldownId()); player.setCasting(null); player.setNextSkillUse(0); if (castingSkill.getSkillMethod() == SkillMethod.CAST || castingSkill.getSkillMethod() == SkillMethod.CHARGE) { PacketSendUtility.broadcastPacket(player, new SM_SKILL_CANCEL(player, castingSkill.getSkillTemplate().getSkillId()), true); PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_SKILL_CANCELED); } else if (castingSkill.getSkillMethod() == SkillMethod.ITEM) { PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_ITEM_CANCELED(new DescriptionId(castingSkill.getItemTemplate().getNameId()))); player.removeItemCoolDown(castingSkill.getItemTemplate().getUseLimits().getDelayId()); PacketSendUtility.broadcastPacket(player, new SM_ITEM_USAGE_ANIMATION(player.getObjectId(), castingSkill.getFirstTarget().getObjectId(), castingSkill.getItemObjectId(), castingSkill.getItemTemplate().getTemplateId(), 0, 3, 0), true); } } @Override public void cancelUseItem() { Player player = getOwner(); Item usingItem = player.getUsingItem(); player.setUsingItem(null); if (hasTask(TaskId.ITEM_USE)) { cancelTask(TaskId.ITEM_USE); PacketSendUtility.broadcastPacket(player, new SM_ITEM_USAGE_ANIMATION(player.getObjectId(), usingItem == null ? 0 : usingItem.getObjectId(), usingItem == null ? 0 : usingItem.getItemTemplate().getTemplateId(), 0, 3, 0), true); } } public void cancelGathering() { Player player = getOwner(); if (player.getTarget() instanceof Gatherable) { Gatherable g = (Gatherable) player.getTarget(); g.getController().finishGathering(player); } } public void updatePassiveStats() { Player player = getOwner(); for (PlayerSkillEntry skillEntry : player.getSkillList().getAllSkills()) { Skill skill = SkillEngine.getInstance().getSkillFor(player, skillEntry.getSkillId(), player.getTarget()); if (skill != null && skill.isPassive()) { skill.useSkill(); } } } @Override public Player getOwner() { return (Player) super.getOwner(); } @Override public void onRestore(HealType healType, int value) { super.onRestore(healType, value); switch (healType) { case DP: getOwner().getCommonData().addDp(value); break; default: break; } } /** * @param player * @return */ // TODO [AT] move to Player public boolean isDueling(Player player) { return DuelService.getInstance().isDueling(player.getObjectId(), getOwner().getObjectId()); } // TODO [AT] rename or remove public boolean isInShutdownProgress() { return isInShutdownProgress; } // TODO [AT] rename or remove public void setInShutdownProgress(boolean isInShutdownProgress) { this.isInShutdownProgress = isInShutdownProgress; } @Override public void onDialogSelect(int dialogId, Player player, int questId, int extendedRewardIndex) { switch (dialogId) { case 2: PacketSendUtility.sendPacket(player, new SM_PRIVATE_STORE(getOwner().getStore(), player)); break; } } public void upgradePlayer() { Player player = getOwner(); byte level = player.getLevel(); PlayerStatsTemplate statsTemplate = DataManager.PLAYER_STATS_DATA.getTemplate(player); player.setPlayerStatsTemplate(statsTemplate); player.getLifeStats().synchronizeWithMaxStats(); player.getLifeStats().updateCurrentStats(); PacketSendUtility.broadcastPacket(player, new SM_LEVEL_UPDATE(player.getObjectId(), 0, level), true); // Guides Html on level up if (HTMLConfig.ENABLE_GUIDES) { HTMLService.sendGuideHtml(player); } // Temporal ClassChangeService.showClassChangeDialog(player); QuestEngine.getInstance().onLvlUp(new QuestEnv(null, player, 0, 0)); updateNearbyQuests(); // add new skills SkillLearnService.addNewSkills(player); PacketSendUtility.broadcastPacket(player, new SM_PACKAGE_INFO_NOTIFY(0), true); player.getController().updatePassiveStats(); // add recipe for morph if (level == 10) { CraftSkillUpdateService.getInstance().setMorphRecipe(player); } if (player.isInTeam()) { TeamEffectUpdater.getInstance().startTask(player); } if (player.isLegionMember()) { LegionService.getInstance().updateMemberInfo(player); } player.getNpcFactions().onLevelUp(); PacketSendUtility.sendPacket(player, new SM_STATS_INFO(player)); } /** * After entering game player char is "blinking" which means that it's in * under some protection, after making an action char stops blinking. - * Starts protection active - Schedules task to end protection */ public void startProtectionActiveTask() { if (!getOwner().isProtectionActive()) { getOwner().setVisualState(CreatureVisualState.BLINKING); AttackUtil.cancelCastOn((Creature) getOwner()); AttackUtil.removeTargetFrom((Creature) getOwner()); PacketSendUtility.broadcastPacket(getOwner(), new SM_PLAYER_STATE(getOwner()), true); Future<?> task = ThreadPoolManager.getInstance().schedule(new Runnable() { @Override public void run() { stopProtectionActiveTask(); } }, 60000); addTask(TaskId.PROTECTION_ACTIVE, task); } } /** * Stops protection active task after first move or use skill */ public void stopProtectionActiveTask() { cancelTask(TaskId.PROTECTION_ACTIVE); Player player = getOwner(); if (player != null && player.isSpawned()) { player.unsetVisualState(CreatureVisualState.BLINKING); PacketSendUtility.broadcastPacket(player, new SM_PLAYER_STATE(player), true); notifyAIOnMove(); } } /** * When player arrives at destination point of flying teleport */ public void onFlyTeleportEnd() { Player player = getOwner(); if (player.isInPlayerMode(PlayerMode.WINDSTREAM)) { player.unsetPlayerMode(PlayerMode.WINDSTREAM); player.getLifeStats().triggerFpReduce(); player.unsetState(CreatureState.FLYING); player.setState(CreatureState.ACTIVE); player.setState(CreatureState.GLIDING); player.getGameStats().updateStatsAndSpeedVisually(); } else { player.unsetState(CreatureState.FLIGHT_TELEPORT); player.setFlightTeleportId(0); if (SecurityConfig.ENABLE_FLYPATH_VALIDATOR) { long diff = (System.currentTimeMillis() - player.getFlyStartTime()); FlyPathEntry path = player.getCurrentFlyPath(); if (player.getWorldId() != path.getEndWorldId()) { AuditLogger.info(player, "Player tried to use flyPath #" + path.getId() + " from not native start world " + player.getWorldId() + ". expected " + path.getEndWorldId()); } if (diff < path.getTimeInMs()) { AuditLogger.info(player, "Player " + player.getName() + " used flypath bug " + diff + " instead of " + path.getTimeInMs()); /* * todo if works teleport player to start_* xyz, or even ban */ } player.setCurrentFlypath(null); } player.setFlightDistance(0); player.setState(CreatureState.ACTIVE); updateZone(); } } public boolean addItems(int itemId, int count) { return ItemService.addQuestItems(getOwner(), Collections.singletonList(new QuestItems(itemId, count))); } public void startStance(final int skillId) { stance = skillId; } public void stopStance() { getOwner().getEffectController().removeEffect(stance); PacketSendUtility.sendPacket(getOwner(), new SM_PLAYER_STANCE(getOwner(), 0)); stance = 0; } public int getStanceSkillId() { return stance; } public boolean isUnderStance() { return stance != 0; } public void updateSoulSickness(int skillId) { Player player = getOwner(); House house = player.getActiveHouse(); if (house != null) { switch (house.getHouseType()) { case MANSION: case ESTATE: case PALACE: return; default: break; } } if (!player.havePermission(MembershipConfig.DISABLE_SOULSICKNESS)) { int deathCount = player.getCommonData().getDeathCount(); if (deathCount < 10) { deathCount++; player.getCommonData().setDeathCount(deathCount); } if (skillId == 0) { skillId = 8291; } SkillEngine.getInstance().getSkill(player, skillId, deathCount, player).useSkill(); } } /** * Player is considered in combat if he's been attacked or has attacked less * or equal 10s before * * @return true if the player is actively in combat */ public boolean isInCombat() { return (((System.currentTimeMillis() - lastAttackedMilis) <= 10000) || ((System.currentTimeMillis() - lastAttackMilis) <= 10000)); } /** * Check if NoDeathPenalty is active * * @param player * @return boolean */ public boolean isNoDeathPenaltyInEffect() { // Check if NoDeathPenalty is active Iterator<Effect> iterator = getOwner().getEffectController().iterator(); while (iterator.hasNext()) { Effect effect = iterator.next(); if (effect.isNoDeathPenalty()) { return true; } } return false; } /** * Check if NoResurrectPenalty is active * * @param player * @return boolean */ public boolean isNoResurrectPenaltyInEffect() { // Check if NoResurrectPenalty is active Iterator<Effect> iterator = getOwner().getEffectController().iterator(); while (iterator.hasNext()) { Effect effect = iterator.next(); if (effect.isNoResurrectPenalty()) { return true; } } return false; } /** * Check if HiPass is active * * @param player * @return boolean */ public boolean isHiPassInEffect() { // Check if HiPass is active Iterator<Effect> iterator = getOwner().getEffectController().iterator(); while (iterator.hasNext()) { Effect effect = iterator.next(); if (effect.isHiPass()) { return true; } } return false; } public void registerListener(Listener listener) { this.mListener = listener; } public void unregisterListener() { this.mListener = null; } public static abstract interface Listener { public abstract void onPlayerUsedSkill(int paramInt, Player paramPlayer); } }
Неграмотные люди пользуются гугл-переводчиком потом копипастят мусор. --- Double Post Merged, 15 июл 2019, Original Post Date: 15 июл 2019 --- Адекватный ответ Автору темы был дан где смотреть. Кто имеет базовые знания справится.
Мусор это как раз твои ответы в разделе помощи грамотный ты наш, да наверное и всё остальное что ты ту постишь. или у этого есть ещё какой то смысл ? кроме как, если вы не шарите ищите в шаровых сборках где это работает просвети нас неграмотных на чисто русском языке, на русском форуме. Тем более автору темы, всё равно этот текст переводить на немецкий, как бы международного скандала не возникло бы . Или ты только посты, где указаны ошибки в твоей сборке можешь удалять и закрывать поспешно тему? Я думаю, кто имеет базовые знания и с этим справится, в отличии от тебя. Please login or register to view links
Ясно, понятно мусор неадекватный который пришел по рофлить. Откуда ты вылез вообще. --- Double Post Merged, 16 июл 2019, Original Post Date: 15 июл 2019 --- PlayerController method inDie. Add comment custom event and check die mode --- Double Post Merged, 16 июл 2019 --- Check console on error message
Оо это уже переход на личности и оскорбления, следи за своим гнилым базаром. Тебя никто тут не оскорблял и право тебе никто тут не давал это делать. Или тебя так бомбануло? О того, что ты оформил тему с продажей 4.75, а я дополнил тему багами от твоего клиента? Ты сразу почистил тему от моего поста, потом закрыл, а теперь я темы вообще не наблюдаю. Что только подтверждает правдивость всего написанного. Ты на форуме сидишь с целью продажи своего мусора который все равно никому не нужен, да и ответы в разделах помощи не лучше. Please login or register to view links я представляю что там в версиях выше, если тут такое
Крч товарищ подлизалкин иди в игнор. Со мной много проектов работает и все довольны работой. --- Double Post Merged, 16 июл 2019, Original Post Date: 16 июл 2019 --- Then comment custom event's at method onDie (PlayerController) and check death.
В общем всё ясно понятно, он даже не отрицает по сборке которую поспешил убрать с форума удалив посты. Только оскорблять пытается в ответ как школьник. А вот тут уже интересно, можешь назвать хоть один? Хоть одного довольного клиента? Помнится на последнем проекте катаклизм 5.3 х5 где стояла сборка этого уникума, даже игроки называли этого разраба аутистом, видя его работу. Или такого не было? Можешь в принципе не отвечать, уверен ты не одного не назовешь проекта и способен только на детсадовский агр.
что за кипишь драки нет )) P.S. почему бы ТС не написать на форум коров если он использует их сборку или тем же немцам , пускай помогут и гугл переводчик использовать не прийдется , ах да забыл всем пох ))) в ру комьюнити хоть кто то еще шевелится а остальные давно забили
Hi! If a married couple is present during any fortress siege, the fortress does not turn into asmodian/elyos. The following error-message appears: java.lang.NullPointerException: null at com.aionemu.gameserver.model.team2.common.service.PlayerTeamDistributionService.doReward(PlayerTeamDistributionService.java:117) ~[AC-Game.jar:na] at com.aionemu.gameserver.controllers.NpcController.doReward(NpcController.java:246) ~[AC-Game.jar:na] at com.aionemu.gameserver.controllers.NpcController.onDie(NpcController.java:158) ~[AC-Game.jar:na] at com.aionemu.gameserver.model.stats.container.CreatureLifeStats.reduceHp(CreatureLifeStats.java:143) ~[AC-Game.jar:na] at com.aionemu.gameserver.controllers.CreatureController.onAttack(CreatureController.java:267) ~[AC-Game.jar:na] at com.aionemu.gameserver.controllers.NpcController.onAttack(NpcController.java:330) ~[AC-Game.jar:na] at com.aionemu.gameserver.controllers.CreatureController.onAttack(CreatureController.java:299) ~[AC-Game.jar:na] at com.aionemu.gameserver.skillengine.effect.DamageEffect.applyEffect(DamageEffect.java:57) ~[AC-Game.jar:na] at com.aionemu.gameserver.skillengine.model.Effect.applyEffect(Effect.java:745) ~[AC-Game.jar:na] at com.aionemu.gameserver.skillengine.model.Skill.applyEffect(Skill.java:760) ~[AC-Game.jar:na] at com.aionemu.gameserver.skillengine.model.Skill$1.run(Skill.java:740) ~[AC-Game.jar:na] at com.aionemu.commons.utils.concurrent.ExecuteWrapper.execute(ExecuteWrapper.java:56) ~[ac-commons-1.3.jar:na] at com.aionemu.commons.utils.concurrent.RunnableWrapper.run(RunnableWrapper.java:51) [ac-commons-1.3.jar:na] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_95] at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_95] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178) [na:1.7.0_95] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292) [na:1.7.0_95] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_95] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_95] at java.lang.Thread.run(Thread.java:745) [na:1.7.0_95] If there is no married couple during fortress siege, this bug does not pop up. Has anyone already encountered this problem? Do you have an advice to give us? Thank you! Help Please!
Check the custom fragment code in "com.aionemu.gameserver.model.team2.common.service.PlayerTeamDistributionService.doReward" wedding related
No errors found. My PlayerTeamDistributionService.java package com.aionemu.gameserver.model.team2.common.service; import java.util.ArrayList; import java.util.List; import com.aionemu.gameserver.configs.main.CustomConfig; import com.aionemu.gameserver.configs.main.GroupConfig; import com.aionemu.gameserver.model.gameobjects.AionObject; import com.aionemu.gameserver.model.gameobjects.Npc; import com.aionemu.gameserver.model.gameobjects.player.Player; import com.aionemu.gameserver.model.gameobjects.player.RewardType; import com.aionemu.gameserver.model.gameobjects.player.XPCape; import com.aionemu.gameserver.model.team2.TemporaryPlayerTeam; import com.aionemu.gameserver.questEngine.QuestEngine; import com.aionemu.gameserver.questEngine.model.QuestEnv; import com.aionemu.gameserver.services.abyss.AbyssPointsService; import com.aionemu.gameserver.services.drop.DropRegistrationService; import com.aionemu.gameserver.utils.MathUtil; import com.aionemu.gameserver.utils.stats.StatFunctions; import com.google.common.base.Predicate; /** * @author ATracer, nrg */ public class PlayerTeamDistributionService { /** * This method will send a reward if a player is in a team */ public static void doReward(TemporaryPlayerTeam<?> team, float damagePercent, Npc owner, AionObject winner) { if (team == null || owner == null) { return; } // Find team's members and determine highest level PlayerTeamRewardStats filteredStats = new PlayerTeamRewardStats(owner); team.applyOnMembers(filteredStats); // All are dead or not nearby if (filteredStats.players.isEmpty() || !filteredStats.hasLivingPlayer) { return; } // Reward mode long expReward; if (filteredStats.players.size() + filteredStats.mentorCount == 1) { expReward = (long) (StatFunctions.calculateSoloExperienceReward(filteredStats.players.get(0), owner)); } else { expReward = (long) (StatFunctions.calculateGroupExperienceReward(filteredStats.highestLevel, owner)); } // Party Bonus 2 members 10%, 3 members 20% ... 6 members 50% int size = filteredStats.players.size(); int bonus = 100; if (size > 1) { bonus = 150 + (size - 2) * 10; } for (Player member : filteredStats.players) { Player partner = member.findPartner(); //mentor and dead players shouldn't receive AP/EP/DP if (member.isMentor() || member.getLifeStats().isAlreadyDead()) { continue; } // Reward init long rewardXp = (long) (expReward * bonus * member.getLevel()) / (filteredStats.partyLvlSum * 100); int rewardDp = StatFunctions.calculateGroupDPReward(member, owner); int rewardGP = StatFunctions.calculateGPReward(member, owner); float rewardAp = 1; // Players 10 levels below highest member get 0 reward. if (filteredStats.highestLevel - member.getLevel() >= 10) { rewardXp = 0; rewardDp = 0; } else if (filteredStats.mentorCount > 0) { int cape = XPCape.values()[(int) member.getLevel()].value(); if (cape < rewardXp) { rewardXp = cape; } } // Dmg percent correction rewardXp *= damagePercent; rewardDp *= damagePercent; rewardAp *= damagePercent; if (member.isMarried() && member.getPlayerGroup2().getMembers() == partner && member.getPlayerGroup2().getMembers().size() == 2) { member.getCommonData().addExp(rewardXp + (rewardXp * 20 / 100), RewardType.GROUP_HUNTING, owner.getObjectTemplate().getNameId()); member.getCommonData().addEventExp(rewardXp + (rewardXp * 20 / 100)); } else { member.getCommonData().addExp(rewardXp, RewardType.GROUP_HUNTING, owner.getObjectTemplate().getNameId()); member.getCommonData().addEventExp(rewardXp); } // DP reward member.getCommonData().addDp(rewardDp); // AP reward if (owner.isRewardAP() && !(filteredStats.mentorCount > 0 && CustomConfig.MENTOR_GROUP_AP)) { rewardAp *= StatFunctions.calculatePvEApGained(member, owner); int ap = (int) rewardAp / filteredStats.players.size(); if (ap >= 1) { AbyssPointsService.addAp(member, owner, ap); } } // GP reward if (owner.isRewardGP()) { if (rewardGP >= 1) { AbyssPointsService.addGp(member, owner, rewardGP); } } } // Give Drop Player mostDamagePlayer = owner.getAggroList().getMostPlayerDamageOfMembers(team.getMembers(), filteredStats.highestLevel); if (mostDamagePlayer == null) { return; } if (winner.equals(team) && (!owner.getAi2().getName().equals("chest") || filteredStats.mentorCount == 0)) { DropRegistrationService.getInstance().registerDrop(owner, mostDamagePlayer, filteredStats.highestLevel, filteredStats.players); } } private static class PlayerTeamRewardStats implements Predicate<Player> { final List<Player> players = new ArrayList<Player>(); int partyLvlSum = 0; int highestLevel = 0; int mentorCount = 0; boolean hasLivingPlayer = false; Npc owner; public PlayerTeamRewardStats(Npc owner) { this.owner = owner; } @Override public boolean apply(Player member) { if (member.isOnline()) { if (MathUtil.isIn3dRange(member, owner, GroupConfig.GROUP_MAX_DISTANCE)) { QuestEngine.getInstance().onKill(new QuestEnv(owner, member, 0, 0)); if (member.isMentor()) { mentorCount++; return true; } if (!hasLivingPlayer && !member.getLifeStats().isAlreadyDead()) { hasLivingPlayer = true; } players.add(member); partyLvlSum += member.getLevel(); if (member.getLevel() > highestLevel) { highestLevel = member.getLevel(); } } } return true; } } }
Код: if (member.isMarried() && member.getPlayerGroup2().getMembers() == partner && member.getPlayerGroup2().getMembers().size() == 2) { member.getCommonData().addExp(rewardXp + (rewardXp * 20 / 100), RewardType.GROUP_HUNTING, owner.getObjectTemplate().getNameId()); member.getCommonData().addEventExp(rewardXp + (rewardXp * 20 / 100)); } View by the logs there is an error --- Double Post Merged, 19 июл 2019, Original Post Date: 19 июл 2019 --- Add a check to "null" --- Double Post Merged, 19 июл 2019 --- And in general this is bad code. --- Double Post Merged, 19 июл 2019 --- It is better delete code --- Double Post Merged, 19 июл 2019 --- this
I'm sorry but I do not understand Delete this code? if (member.isMarried() && member.getPlayerGroup2().getMembers() == partner && member.getPlayerGroup2().getMembers().size() == 2) { member.getCommonData().addExp(rewardXp + (rewardXp * 20 / 100), RewardType.GROUP_HUNTING, owner.getObjectTemplate().getNameId()); member.getCommonData().addEventExp(rewardXp + (rewardXp * 20 / 100)); } So what would the code look like? I'm sorry I don't quite understand what you wrote.
Код: DELETE if (member.isMarried() && member.getPlayerGroup2().getMembers() == partner && member.getPlayerGroup2().getMembers().size() == 2) { member.getCommonData().addExp(rewardXp + (rewardXp * 20 / 100), RewardType.GROUP_HUNTING, owner.getObjectTemplate().getNameId()); member.getCommonData().addEventExp(rewardXp + (rewardXp * 20 / 100)); } else { member.getCommonData().addExp(rewardXp, RewardType.GROUP_HUNTING, owner.getObjectTemplate().getNameId()); member.getCommonData().addEventExp(rewardXp); } PAST member.getCommonData().addExp(rewardXp, RewardType.GROUP_HUNTING, owner.getObjectTemplate().getNameId()); member.getCommonData().addEventExp(rewardXp);