Sync with L2JServer Jan 24th 2015.

This commit is contained in:
mobius
2015-01-24 20:02:32 +00:00
parent d349bd3924
commit 1c6301c46d
1012 changed files with 23069 additions and 6307 deletions

View File

@@ -21,6 +21,7 @@ package com.l2jserver.gameserver.model.actor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
@@ -89,8 +90,7 @@ public class L2Attackable extends L2Npc
private int _seederObjId = 0;
private ItemHolder _harvestItem;
// Spoil
private boolean _isSpoil = false;
private int _isSpoiledBy = 0;
private int _spoilerObjectId;
private ItemHolder[] _sweepItems;
// Over-hit
private boolean _overhit;
@@ -473,7 +473,14 @@ public class L2Attackable extends L2Npc
// Penalty applied to the attacker's XP
// If this attacker have servitor, get Exp Penalty applied for the servitor.
final float penalty = attacker.hasServitor() ? ((L2ServitorInstance) attacker.getSummon()).getExpMultiplier() : 1;
float penalty = 1;
Optional<L2Summon> summon = attacker.getServitors().values().stream().filter(s -> ((L2ServitorInstance) s).getExpMultiplier() > 1).findFirst();
if (summon.isPresent())
{
penalty = ((L2ServitorInstance) summon.get()).getExpMultiplier();
}
// If there's NO party in progress
if (attackerParty == null)
@@ -992,7 +999,7 @@ public class L2Attackable extends L2Npc
CursedWeaponsManager.getInstance().checkDrop(this, player);
if (isSpoil())
if (isSpoiled())
{
List<ItemHolder> sweepItems = npcTemplate.calculateDrops(DropListScope.CORPSE, this, player);
if ((sweepItems != null) && !sweepItems.isEmpty())
@@ -1162,7 +1169,7 @@ public class L2Attackable extends L2Npc
{
for (ItemHolder item : _sweepItems)
{
lootItems.add(ItemTable.getInstance().createDummyItem(item.getId()).getItem());
lootItems.add(ItemTable.getInstance().getTemplate(item.getId()));
}
}
return lootItems;
@@ -1215,7 +1222,7 @@ public class L2Attackable extends L2Npc
*/
public boolean checkSpoilOwner(L2PcInstance sweeper, boolean sendMessage)
{
if ((sweeper.getObjectId() != getIsSpoiledBy()) && !sweeper.isInLooterParty(getIsSpoiledBy()))
if ((sweeper.getObjectId() != getSpoilerObjectId()) && !sweeper.isInLooterParty(getSpoilerObjectId()))
{
if (sendMessage)
{
@@ -1425,7 +1432,7 @@ public class L2Attackable extends L2Npc
{
super.onSpawn();
// Clear mob spoil, seed
setSpoil(false);
setSpoilerObjectId(0);
// Clear all aggro char from list
clearAggroList();
// Clear Harvester reward
@@ -1453,30 +1460,30 @@ public class L2Attackable extends L2Npc
}
/**
* @return True if this L2NpcInstance has drops that can be sweeped.
* Checks if its spoiled.
* @return {@code true} if its spoiled, {@code false} otherwise
*/
public boolean isSpoil()
public boolean isSpoiled()
{
return _isSpoil;
return _spoilerObjectId != 0;
}
/**
* Set the spoil state of this L2NpcInstance.
* @param isSpoil
* Gets the spoiler object ID.
* @return the spoiler object ID if its spoiled, 0 otherwise
*/
public void setSpoil(boolean isSpoil)
public final int getSpoilerObjectId()
{
_isSpoil = isSpoil;
return _spoilerObjectId;
}
public final int getIsSpoiledBy()
/**
* Sets the spoiler object ID.
* @param spoilerObjectId spoilerObjectId the spoiler object ID
*/
public final void setSpoilerObjectId(int spoilerObjectId)
{
return _isSpoiledBy;
}
public final void setIsSpoiledBy(int value)
{
_isSpoiledBy = value;
_spoilerObjectId = spoilerObjectId;
}
/**

View File

@@ -52,8 +52,8 @@ import com.l2jserver.gameserver.ai.CtrlEvent;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.ai.L2AttackableAI;
import com.l2jserver.gameserver.ai.L2CharacterAI;
import com.l2jserver.gameserver.datatables.CategoryData;
import com.l2jserver.gameserver.datatables.DoorTable;
import com.l2jserver.gameserver.data.xml.impl.CategoryData;
import com.l2jserver.gameserver.data.xml.impl.DoorData;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.enums.CategoryType;
import com.l2jserver.gameserver.enums.InstanceType;
@@ -1141,7 +1141,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
if (player != null)
{
AttackStanceTaskManager.getInstance().addAttackStanceTask(player);
if (player.getSummon() != target)
if ((player.getPet() != target) && !player.hasServitor(target.getObjectId()))
{
player.updatePvPStatus(target);
}
@@ -1677,7 +1677,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
switch (skill.getTargetType())
{
case AREA_SUMMON: // We need it to correct facing
target = getSummon();
target = getServitors().values().stream().findFirst().orElse(getPet());
break;
case AURA:
case AURA_CORPSE_MOB:
@@ -2867,7 +2867,20 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
/**
* @return the summon
*/
public L2Summon getSummon()
public L2Summon getPet()
{
return null;
}
/**
* @return the summon
*/
public Map<Integer, L2Summon> getServitors()
{
return Collections.emptyMap();
}
public L2Summon getServitor(int objectId)
{
return null;
}
@@ -2877,7 +2890,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
*/
public final boolean hasSummon()
{
return getSummon() != null;
return (getPet() != null) || !getServitors().isEmpty();
}
/**
@@ -2885,15 +2898,25 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
*/
public final boolean hasPet()
{
return hasSummon() && getSummon().isPet();
return getPet() != null;
}
public final boolean hasServitor(int objectId)
{
return getServitors().containsKey(objectId);
}
/**
* @return {@code true} if the character has a servitor, {@code false} otherwise
*/
public final boolean hasServitor()
public final boolean hasServitors()
{
return hasSummon() && getSummon().isServitor();
return !getServitors().isEmpty();
}
public void removeServitor(int objectId)
{
getServitors().remove(objectId);
}
public final boolean isRooted()
@@ -3939,9 +3962,9 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
broadcastPacket(su);
}
}
if ((getSummon() != null) && isAffected(EffectFlag.SERVITOR_SHARE))
if (hasServitors() && isAffected(EffectFlag.SERVITOR_SHARE))
{
getSummon().broadcastStatusUpdate();
getServitors().values().forEach(L2Summon::broadcastStatusUpdate);
}
}
else if (isNpc())
@@ -4223,7 +4246,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
final boolean isFloating = isFlying() || isInsideZone(ZoneId.WATER);
// Z coordinate will follow geodata or client values
if ((Config.GEODATA > 0) && (Config.COORD_SYNCHRONIZE == 2) && !isFloating && !m.disregardingGeodata && ((GameTimeController.getInstance().getGameTicks() % 10) == 0 // once a second to reduce possible cpu load
if ((Config.COORD_SYNCHRONIZE == 2) && !isFloating && !m.disregardingGeodata && ((GameTimeController.getInstance().getGameTicks() % 10) == 0 // once a second to reduce possible cpu load
) && GeoData.getInstance().hasGeo(xPrev, yPrev))
{
int geoHeight = GeoData.getInstance().getSpawnHeight(xPrev, yPrev, zPrev);
@@ -4499,7 +4522,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
// make water move short and use no geodata checks for swimming chars
// distance in a click can easily be over 3000
if ((Config.GEODATA > 0) && isInsideZone(ZoneId.WATER) && (distance > 700))
if (isInsideZone(ZoneId.WATER) && (distance > 700))
{
double divider = 700 / distance;
x = curX + (int) (divider * dx);
@@ -4567,7 +4590,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
m.onGeodataPathIndex = -1; // Initialize not on geodata path
m.disregardingGeodata = false;
if ((Config.GEODATA > 0) && !isFlying() // flying chars not checked - even canSeeTarget doesn't work yet
if (!isFlying() // flying chars not checked - even canSeeTarget doesn't work yet
&& (!isInsideZone(ZoneId.WATER) || isInsideZone(ZoneId.SIEGE))) // swimming also not checked unless in siege zone - but distance is limited
{
final boolean isInVehicle = isPlayer() && (getActingPlayer().getVehicle() != null);
@@ -4584,9 +4607,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
int gty = (originalY - L2World.MAP_MIN_Y) >> 4;
// Movement checks:
// when geodata == 2, for all characters except mobs returning home (could be changed later to teleport if pathfinding fails)
// when geodata == 1, for L2Playable and L2RiftInvaderInstance only
if (((Config.GEODATA == 2) && !(isAttackable() && ((L2Attackable) this).isReturningToSpawnPoint())) || (isPlayer() && !(isInVehicle && (distance > 1500))) || (isSummon() && !(getAI().getIntention() == AI_INTENTION_FOLLOW)) // assuming intention_follow only when following owner
// when PATHFINDING > 0, for all characters except mobs returning home (could be changed later to teleport if pathfinding fails)
if (((Config.PATHFINDING > 0) && (!(isAttackable() && ((L2Attackable) this).isReturningToSpawnPoint()))) || (isPlayer() && !(isInVehicle && (distance > 1500))) || (isSummon() && !(getAI().getIntention() == AI_INTENTION_FOLLOW)) // assuming intention_follow only when following owner
|| isAfraid())
{
if (isOnGeodataPath())
@@ -4637,7 +4659,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
// Pathfinding checks. Only when geodata setting is 2, the LoS check gives shorter result
// than the original movement was and the LoS gives a shorter distance than 2000
// This way of detecting need for pathfinding could be changed.
if ((Config.GEODATA == 2) && ((originalDistance - distance) > 30) && (distance < 2000) && !isAfraid())
if ((Config.PATHFINDING > 0) && ((originalDistance - distance) > 30) && (distance < 2000) && !isAfraid())
{
// Path calculation
// Overrides previous movement check
@@ -4679,7 +4701,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
z = m.geoPath.get(m.onGeodataPathIndex).getZ();
// check for doors in the route
if (DoorTable.getInstance().checkIfDoorsBetween(curX, curY, curZ, x, y, z, getInstanceId()))
if (DoorData.getInstance().checkIfDoorsBetween(curX, curY, curZ, x, y, z, getInstanceId()))
{
m.geoPath = null;
getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
@@ -4687,7 +4709,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
}
for (int i = 0; i < (m.geoPath.size() - 1); i++)
{
if (DoorTable.getInstance().checkIfDoorsBetween(m.geoPath.get(i), m.geoPath.get(i + 1), getInstanceId()))
if (DoorData.getInstance().checkIfDoorsBetween(m.geoPath.get(i), m.geoPath.get(i + 1), getInstanceId()))
{
m.geoPath = null;
getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
@@ -4705,7 +4727,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
}
}
// If no distance to go through, the movement is canceled
if ((distance < 1) && ((Config.GEODATA == 2) || isPlayable()))
if ((distance < 1) && ((Config.PATHFINDING > 0) || isPlayable()))
{
if (isSummon())
{
@@ -5588,7 +5610,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
_skiprange++;
continue;
}
if ((escapeRange > 0) && (Config.GEODATA > 0) && !GeoData.getInstance().canSeeTarget(this, target))
if ((escapeRange > 0) && !GeoData.getInstance().canSeeTarget(this, target))
{
_skipgeo++;
continue;
@@ -5996,7 +6018,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
// attack of the own pet does not flag player
// triggering trap not flag trap owner
if ((player.getSummon() != target) && !isTrap() && !((skill.getEffectPoint() == 0) && (skill.getAffectRange() > 0)))
if ((player.getPet() != target) && !player.hasServitor(target.getObjectId()) && !isTrap() && !((skill.getEffectPoint() == 0) && (skill.getAffectRange() > 0)))
{
player.updatePvPStatus((L2Character) target);
}
@@ -6058,9 +6080,19 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
if (player.hasSummon())
{
if ((targets.length == 1) && Util.contains(targets, player.getSummon()))
if (targets.length == 1)
{
skillEffectPoint = 0;
if (Util.contains(targets, player.getPet()))
{
skillEffectPoint = 0;
}
for (L2Summon servitor : player.getServitors().values())
{
if (Util.contains(targets, servitor))
{
skillEffectPoint = 0;
}
}
}
}
@@ -6073,7 +6105,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
{
if ((npcTarget == skillTarget) || (npcMob == skillTarget))
{
L2Character originalCaster = isSummon() ? getSummon() : player;
L2Character originalCaster = isSummon() ? this : player;
attackable.addDamageHate(originalCaster, 0, (skillEffectPoint * 150) / (attackable.getLevel() + 7));
}
}

View File

@@ -91,6 +91,7 @@ import com.l2jserver.gameserver.network.serverpackets.ExChangeNpcState;
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jserver.gameserver.network.serverpackets.NpcInfo;
import com.l2jserver.gameserver.network.serverpackets.NpcInfoAbnormalVisualEffect;
import com.l2jserver.gameserver.network.serverpackets.ServerObjectInfo;
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
import com.l2jserver.gameserver.taskmanager.DecayTaskManager;
@@ -566,7 +567,7 @@ public class L2Npc extends L2Character
}
else
{
player.sendPacket(new NpcInfo(this));
player.sendPacket(new NpcInfoAbnormalVisualEffect(this));
}
}
}
@@ -1723,6 +1724,17 @@ public class L2Npc extends L2Character
}
}
/**
* Sends an event to a given object.
* @param eventName the event name
* @param receiver the receiver
* @param reference the reference
*/
public void sendScriptEvent(String eventName, L2Object receiver, L2Object reference)
{
EventDispatcher.getInstance().notifyEventAsync(new OnNpcEventReceived(eventName, this, (L2Npc) receiver, reference), receiver);
}
/**
* Gets point in range between radiusMin and radiusMax from this NPC
* @param radiusMin miminal range from NPC (not closer than)

View File

@@ -22,7 +22,7 @@ import com.l2jserver.Config;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.ai.L2CharacterAI;
import com.l2jserver.gameserver.ai.L2SummonAI;
import com.l2jserver.gameserver.datatables.ExperienceTable;
import com.l2jserver.gameserver.data.xml.impl.ExperienceData;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.enums.Race;
@@ -53,17 +53,18 @@ import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.model.skills.targets.L2TargetType;
import com.l2jserver.gameserver.model.zone.ZoneId;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.AbstractNpcInfo.SummonInfo;
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
import com.l2jserver.gameserver.network.serverpackets.ExPartyPetWindowAdd;
import com.l2jserver.gameserver.network.serverpackets.ExPartyPetWindowDelete;
import com.l2jserver.gameserver.network.serverpackets.ExPartyPetWindowUpdate;
import com.l2jserver.gameserver.network.serverpackets.ExPetInfo;
import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
import com.l2jserver.gameserver.network.serverpackets.PetDelete;
import com.l2jserver.gameserver.network.serverpackets.PetInfo;
import com.l2jserver.gameserver.network.serverpackets.PetItemList;
import com.l2jserver.gameserver.network.serverpackets.PetStatusUpdate;
import com.l2jserver.gameserver.network.serverpackets.RelationChanged;
import com.l2jserver.gameserver.network.serverpackets.SummonInfo;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
import com.l2jserver.gameserver.network.serverpackets.TeleportToLocation;
import com.l2jserver.gameserver.taskmanager.DecayTaskManager;
@@ -78,6 +79,7 @@ public abstract class L2Summon extends L2Playable
private boolean _previousFollowStatus = true;
protected boolean _restoreSummon = true;
private int _shotsMask = 0;
private int _summonPoints = 0;
// @formatter:off
private static final int[] PASSIVE_SUMMONS =
@@ -218,7 +220,14 @@ public abstract class L2Summon extends L2Playable
{
for (L2PcInstance player : getKnownList().getKnownPlayers().values())
{
player.sendPacket(new SummonInfo(this, player, 1));
if (isPet())
{
player.sendPacket(new ExPetInfo(this, player, 1));
}
else
{
player.sendPacket(new SummonInfo(this, player, 1));
}
}
}
@@ -232,20 +241,20 @@ public abstract class L2Summon extends L2Playable
public long getExpForThisLevel()
{
if (getLevel() >= ExperienceTable.getInstance().getMaxPetLevel())
if (getLevel() >= ExperienceData.getInstance().getMaxPetLevel())
{
return 0;
}
return ExperienceTable.getInstance().getExpForLevel(getLevel());
return ExperienceData.getInstance().getExpForLevel(getLevel());
}
public long getExpForNextLevel()
{
if (getLevel() >= (ExperienceTable.getInstance().getMaxPetLevel() - 1))
if (getLevel() >= (ExperienceData.getInstance().getMaxPetLevel() - 1))
{
return 0;
}
return ExperienceTable.getInstance().getExpForLevel(getLevel() + 1);
return ExperienceData.getInstance().getExpForLevel(getLevel() + 1);
}
@Override
@@ -435,7 +444,14 @@ public abstract class L2Summon extends L2Playable
storeEffect(true);
if (owner != null)
{
owner.setPet(null);
if (isPet())
{
owner.setPet(null);
}
else
{
owner.removeServitor(getObjectId());
}
}
// Stop AI tasks
@@ -898,7 +914,15 @@ public abstract class L2Summon extends L2Playable
{
continue;
}
player.sendPacket(new SummonInfo(this, player, val));
if (isPet())
{
player.sendPacket(new ExPetInfo(this, player, val));
}
else
{
player.sendPacket(new SummonInfo(this, player, val));
}
}
}
@@ -923,7 +947,7 @@ public abstract class L2Summon extends L2Playable
// Check if the L2PcInstance is the owner of the Pet
if (activeChar == getOwner())
{
activeChar.sendPacket(new PetInfo(this, 0));
activeChar.sendPacket(new PetInfo(this, 1));
// The PetInfo packet wipes the PartySpelled (list of active spells' icons). Re-add them
updateEffectIcons(true);
if (isPet())
@@ -933,7 +957,14 @@ public abstract class L2Summon extends L2Playable
}
else
{
activeChar.sendPacket(new SummonInfo(this, activeChar, 0));
if (isPet())
{
activeChar.sendPacket(new ExPetInfo(this, activeChar, 0));
}
else
{
activeChar.sendPacket(new SummonInfo(this, activeChar, 0));
}
}
}
@@ -1111,12 +1142,6 @@ public abstract class L2Summon extends L2Playable
return true;
}
@Override
public L2Summon getSummon()
{
return this;
}
@Override
public boolean isChargedShot(ShotType type)
{
@@ -1232,4 +1257,14 @@ public abstract class L2Summon extends L2Playable
}
return formId;
}
public void setSummonPoints(int summonPoints)
{
_summonPoints = summonPoints;
}
public int getSummonPoints()
{
return _summonPoints;
}
}

View File

@@ -24,7 +24,7 @@ import java.util.concurrent.Future;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.datatables.PetDataTable;
import com.l2jserver.gameserver.data.xml.impl.PetDataTable;
import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.enums.CategoryType;
import com.l2jserver.gameserver.enums.InstanceType;

View File

@@ -18,7 +18,7 @@
*/
package com.l2jserver.gameserver.model.actor.instance;
import com.l2jserver.gameserver.datatables.NpcData;
import com.l2jserver.gameserver.data.xml.impl.NpcData;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;

View File

@@ -21,7 +21,7 @@ package com.l2jserver.gameserver.model.actor.instance;
import java.util.Arrays;
import java.util.StringTokenizer;
import com.l2jserver.gameserver.datatables.ClanTable;
import com.l2jserver.gameserver.data.sql.impl.ClanTable;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.instancemanager.ClanHallManager;
import com.l2jserver.gameserver.model.L2Clan;

View File

@@ -23,8 +23,8 @@ import java.util.StringTokenizer;
import com.l2jserver.Config;
import com.l2jserver.gameserver.cache.HtmCache;
import com.l2jserver.gameserver.data.sql.impl.TeleportLocationTable;
import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.datatables.TeleportLocationTable;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
import com.l2jserver.gameserver.instancemanager.ClanHallManager;

View File

@@ -20,7 +20,7 @@ package com.l2jserver.gameserver.model.actor.instance;
import com.l2jserver.Config;
import com.l2jserver.gameserver.cache.HtmCache;
import com.l2jserver.gameserver.datatables.ClassListData;
import com.l2jserver.gameserver.data.xml.impl.ClassListData;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;

View File

@@ -34,6 +34,7 @@ import com.l2jserver.gameserver.model.L2Party;
import com.l2jserver.gameserver.model.actor.L2Attackable;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Playable;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.tasks.cubics.CubicAction;
import com.l2jserver.gameserver.model.actor.tasks.cubics.CubicDisappear;
import com.l2jserver.gameserver.model.actor.tasks.cubics.CubicHeal;
@@ -367,7 +368,8 @@ public final class L2CubicInstance implements IIdentifiable
return;
}
// test owners target if it is valid then use it
if ((ownerTarget instanceof L2Character) && (ownerTarget != _owner.getSummon()) && (ownerTarget != _owner))
final L2Summon pet = _owner.getPet();
if (ownerTarget.isCharacter() && (ownerTarget != pet) && !_owner.hasServitor(ownerTarget.getObjectId()) && (ownerTarget != _owner))
{
// target mob which has aggro on you or your summon
if (ownerTarget instanceof L2Attackable)
@@ -379,11 +381,19 @@ public final class L2CubicInstance implements IIdentifiable
}
if (_owner.hasSummon())
{
if ((((L2Attackable) ownerTarget).getAggroList().get(_owner.getSummon()) != null) && !((L2Attackable) ownerTarget).isDead())
if ((((L2Attackable) ownerTarget).getAggroList().get(pet) != null) && !((L2Attackable) ownerTarget).isDead())
{
_target = (L2Character) ownerTarget;
return;
}
for (L2Summon servitor : _owner.getServitors().values())
{
if ((((L2Attackable) ownerTarget).getAggroList().get(servitor) != null) && !((L2Attackable) ownerTarget).isDead())
{
_target = (L2Character) ownerTarget;
return;
}
}
}
}
@@ -730,27 +740,40 @@ public final class L2CubicInstance implements IIdentifiable
}
}
}
if (partyMember.getSummon() != null)
final L2Summon pet = partyMember.getPet();
if (pet != null)
{
if (partyMember.getSummon().isDead())
{
continue;
}
// If party member's pet not dead, check if it is in cast range of heal cubic.
if (!isInCubicRange(_owner, partyMember.getSummon()))
if (pet.isDead() || !isInCubicRange(_owner, pet))
{
continue;
}
// member's pet is in cubic casting range, check if he need heal and if he have
// the lowest HP
if (partyMember.getSummon().getCurrentHp() < partyMember.getSummon().getMaxHp())
if (pet.getCurrentHp() < pet.getMaxHp())
{
if (percentleft > (partyMember.getSummon().getCurrentHp() / partyMember.getSummon().getMaxHp()))
if (percentleft > (pet.getCurrentHp() / pet.getMaxHp()))
{
percentleft = (partyMember.getSummon().getCurrentHp() / partyMember.getSummon().getMaxHp());
target = partyMember.getSummon();
percentleft = (pet.getCurrentHp() / pet.getMaxHp());
target = pet;
}
}
}
for (L2Summon s : partyMember.getServitors().values())
{
if (s.isDead() || !isInCubicRange(_owner, s))
{
continue;
}
// member's pet is in cubic casting range, check if he need heal and if he have
// the lowest HP
if (s.getCurrentHp() < s.getMaxHp())
{
if (percentleft > (s.getCurrentHp() / s.getMaxHp()))
{
percentleft = (s.getCurrentHp() / s.getMaxHp());
target = s;
}
}
}
@@ -763,11 +786,19 @@ public final class L2CubicInstance implements IIdentifiable
percentleft = (_owner.getCurrentHp() / _owner.getMaxHp());
target = _owner;
}
if (_owner.hasSummon())
for (L2Summon summon : _owner.getServitors().values())
{
if (!_owner.getSummon().isDead() && (_owner.getSummon().getCurrentHp() < _owner.getSummon().getMaxHp()) && (percentleft > (_owner.getSummon().getCurrentHp() / _owner.getSummon().getMaxHp())) && isInCubicRange(_owner, _owner.getSummon()))
if (!summon.isDead() && (summon.getCurrentHp() < summon.getMaxHp()) && (percentleft > (summon.getCurrentHp() / summon.getMaxHp())) && isInCubicRange(_owner, summon))
{
target = _owner.getSummon();
target = summon;
}
}
final L2Summon pet = _owner.getPet();
if (pet != null)
{
if (!pet.isDead() && (pet.getCurrentHp() < pet.getMaxHp()) && (percentleft > (pet.getCurrentHp() / pet.getMaxHp())) && isInCubicRange(_owner, pet))
{
target = _owner.getPet();
}
}
}

View File

@@ -28,7 +28,7 @@ import javolution.util.FastList;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.ai.L2CharacterAI;
import com.l2jserver.gameserver.ai.L2DoorAI;
import com.l2jserver.gameserver.datatables.DoorTable;
import com.l2jserver.gameserver.data.xml.impl.DoorData;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.enums.Race;
import com.l2jserver.gameserver.instancemanager.CastleManager;
@@ -95,7 +95,7 @@ public class L2DoorInstance extends L2Character
if (getGroupName() != null)
{
DoorTable.addDoorGroup(getGroupName(), getId());
DoorData.addDoorGroup(getGroupName(), getId());
}
if (isOpenableByTime())
@@ -535,7 +535,7 @@ public class L2DoorInstance extends L2Character
private void manageGroupOpen(boolean open, String groupName)
{
Set<Integer> set = DoorTable.getDoorsByGroup(groupName);
Set<Integer> set = DoorData.getDoorsByGroup(groupName);
L2DoorInstance first = null;
for (Integer id : set)
{
@@ -741,7 +741,7 @@ public class L2DoorInstance extends L2Character
{
if (getInstanceId() == 0)
{
return DoorTable.getInstance().getDoor(doorId);
return DoorData.getInstance().getDoor(doorId);
}
Instance inst = InstanceManager.getInstance().getInstance(getInstanceId());

View File

@@ -20,8 +20,8 @@ package com.l2jserver.gameserver.model.actor.instance;
import java.util.StringTokenizer;
import com.l2jserver.gameserver.datatables.DoorTable;
import com.l2jserver.gameserver.datatables.TeleportLocationTable;
import com.l2jserver.gameserver.data.sql.impl.TeleportLocationTable;
import com.l2jserver.gameserver.data.xml.impl.DoorData;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.model.L2TeleportLocation;
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
@@ -120,7 +120,7 @@ public class L2DoormenInstance extends L2NpcInstance
while (st.hasMoreTokens())
{
DoorTable.getInstance().getDoor(Integer.parseInt(st.nextToken())).openMe();
DoorData.getInstance().getDoor(Integer.parseInt(st.nextToken())).openMe();
}
}
@@ -131,7 +131,7 @@ public class L2DoormenInstance extends L2NpcInstance
while (st.hasMoreTokens())
{
DoorTable.getInstance().getDoor(Integer.parseInt(st.nextToken())).closeMe();
DoorData.getInstance().getDoor(Integer.parseInt(st.nextToken())).closeMe();
}
}

View File

@@ -20,17 +20,13 @@ package com.l2jserver.gameserver.model.actor.instance;
import java.util.List;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.SkillTreesData;
import com.l2jserver.gameserver.data.xml.impl.SkillTreesData;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.instancemanager.FishingChampionshipManager;
import com.l2jserver.gameserver.model.L2SkillLearn;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jserver.gameserver.model.base.AcquireSkillType;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ExAcquirableSkillListByClass;
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
public final class L2FishermanInstance extends L2MerchantInstance
@@ -65,35 +61,6 @@ public final class L2FishermanInstance extends L2MerchantInstance
{
showFishSkillList(player);
}
else if (command.startsWith("FishingChampionship"))
{
if (Config.ALT_FISH_CHAMPIONSHIP_ENABLED)
{
FishingChampionshipManager.getInstance().showChampScreen(player, this);
}
else
{
sendHtml(player, this, "no_fish_event001.htm");
}
}
else if (command.startsWith("FishingReward"))
{
if (Config.ALT_FISH_CHAMPIONSHIP_ENABLED)
{
if (FishingChampionshipManager.getInstance().isWinner(player.getName()))
{
FishingChampionshipManager.getInstance().getReward(player);
}
else
{
sendHtml(player, this, "no_fish_event_reward001.htm");
}
}
else
{
sendHtml(player, this, "no_fish_event001.htm");
}
}
else
{
super.onBypassFeedback(player, command);
@@ -123,11 +90,4 @@ public final class L2FishermanInstance extends L2MerchantInstance
player.sendPacket(new ExAcquirableSkillListByClass(skills, AcquireSkillType.FISHING));
}
}
private static void sendHtml(L2PcInstance player, L2Npc npc, String htmlName)
{
final NpcHtmlMessage html = new NpcHtmlMessage(npc.getObjectId());
html.setFile(player.getHtmlPrefix(), "data/html/fisherman/championship/" + htmlName);
player.sendPacket(html);
}
}

View File

@@ -20,7 +20,7 @@ package com.l2jserver.gameserver.model.actor.instance;
import java.util.StringTokenizer;
import com.l2jserver.gameserver.datatables.NpcData;
import com.l2jserver.gameserver.data.xml.impl.NpcData;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.idfactory.IdFactory;
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;

View File

@@ -23,8 +23,8 @@ import java.util.StringTokenizer;
import com.l2jserver.Config;
import com.l2jserver.gameserver.cache.HtmCache;
import com.l2jserver.gameserver.data.sql.impl.TeleportLocationTable;
import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.datatables.TeleportLocationTable;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.model.ClanPrivilege;
import com.l2jserver.gameserver.model.L2TeleportLocation;

View File

@@ -18,7 +18,7 @@
*/
package com.l2jserver.gameserver.model.actor.instance;
import com.l2jserver.gameserver.datatables.BuyListData;
import com.l2jserver.gameserver.data.xml.impl.BuyListData;
import com.l2jserver.gameserver.datatables.MerchantPriceConfigTable;
import com.l2jserver.gameserver.datatables.MerchantPriceConfigTable.MerchantPriceConfig;
import com.l2jserver.gameserver.enums.InstanceType;

View File

@@ -22,7 +22,7 @@ import java.util.List;
import java.util.Map;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.SkillTreesData;
import com.l2jserver.gameserver.data.xml.impl.SkillTreesData;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.model.L2SkillLearn;
import com.l2jserver.gameserver.model.actor.L2Npc;

View File

@@ -37,6 +37,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;
@@ -63,23 +64,23 @@ import com.l2jserver.gameserver.ai.L2SummonAI;
import com.l2jserver.gameserver.cache.WarehouseCacheManager;
import com.l2jserver.gameserver.communitybbs.BB.Forum;
import com.l2jserver.gameserver.communitybbs.Manager.ForumsBBSManager;
import com.l2jserver.gameserver.datatables.AdminTable;
import com.l2jserver.gameserver.datatables.CharNameTable;
import com.l2jserver.gameserver.datatables.CharSummonTable;
import com.l2jserver.gameserver.datatables.CharTemplateTable;
import com.l2jserver.gameserver.datatables.ClanTable;
import com.l2jserver.gameserver.datatables.ClassListData;
import com.l2jserver.gameserver.datatables.EnchantSkillGroupsData;
import com.l2jserver.gameserver.datatables.ExperienceTable;
import com.l2jserver.gameserver.datatables.FishData;
import com.l2jserver.gameserver.datatables.HennaData;
import com.l2jserver.gameserver.data.sql.impl.CharNameTable;
import com.l2jserver.gameserver.data.sql.impl.CharSummonTable;
import com.l2jserver.gameserver.data.sql.impl.ClanTable;
import com.l2jserver.gameserver.data.xml.impl.AdminData;
import com.l2jserver.gameserver.data.xml.impl.ClassListData;
import com.l2jserver.gameserver.data.xml.impl.EnchantSkillGroupsData;
import com.l2jserver.gameserver.data.xml.impl.ExperienceData;
import com.l2jserver.gameserver.data.xml.impl.FishData;
import com.l2jserver.gameserver.data.xml.impl.HennaData;
import com.l2jserver.gameserver.data.xml.impl.NpcData;
import com.l2jserver.gameserver.data.xml.impl.PetDataTable;
import com.l2jserver.gameserver.data.xml.impl.PlayerTemplateData;
import com.l2jserver.gameserver.data.xml.impl.PlayerXpPercentLostData;
import com.l2jserver.gameserver.data.xml.impl.RecipeData;
import com.l2jserver.gameserver.data.xml.impl.SkillTreesData;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.datatables.NpcData;
import com.l2jserver.gameserver.datatables.PetDataTable;
import com.l2jserver.gameserver.datatables.PlayerXpPercentLostData;
import com.l2jserver.gameserver.datatables.RecipeData;
import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.datatables.SkillTreesData;
import com.l2jserver.gameserver.enums.CastleSide;
import com.l2jserver.gameserver.enums.CategoryType;
import com.l2jserver.gameserver.enums.HtmlActionScope;
@@ -640,8 +641,10 @@ public final class L2PcInstance extends L2Playable
private int _hennaLUC;
private int _hennaCHA;
/** The L2Summon of the L2PcInstance */
private L2Summon _summon = null;
/** The Pet of the L2PcInstance */
private L2Summon _pet = null;
/** Servitors of the L2PcInstance */
private volatile Map<Integer, L2Summon> _servitors = null;
/** The L2Decoy of the L2PcInstance */
private L2Decoy _decoy = null;
/** The L2Trap of the L2PcInstance */
@@ -1192,7 +1195,7 @@ public final class L2PcInstance extends L2Playable
*/
public final L2PcTemplate getBaseTemplate()
{
return CharTemplateTable.getInstance().getTemplate(_baseClass);
return PlayerTemplateData.getInstance().getTemplate(_baseClass);
}
/**
@@ -1209,7 +1212,7 @@ public final class L2PcInstance extends L2Playable
*/
public void setTemplate(ClassId newclass)
{
super.setTemplate(CharTemplateTable.getInstance().getTemplate(newclass));
super.setTemplate(PlayerTemplateData.getInstance().getTemplate(newclass));
}
@Override
@@ -1730,17 +1733,48 @@ public final class L2PcInstance extends L2Playable
// If this player has a pet update the pets pvp flag as well
if (hasSummon())
{
sendPacket(new RelationChanged(getSummon(), getRelation(this), false));
final RelationChanged rc = new RelationChanged();
final L2Summon pet = getPet();
if (pet != null)
{
rc.addRelation(pet, getRelation(this), false);
}
if (hasServitors())
{
getServitors().values().forEach(s -> rc.addRelation(s, getRelation(this), false));
}
sendPacket(rc);
}
Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
final Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
for (L2PcInstance target : plrs)
for (L2PcInstance player : plrs)
{
target.sendPacket(new RelationChanged(this, getRelation(target), isAutoAttackable(target)));
if (hasSummon())
if ((player == null) || !isVisibleFor(player))
{
target.sendPacket(new RelationChanged(getSummon(), getRelation(target), isAutoAttackable(target)));
continue;
}
final int relation = getRelation(player);
Integer oldrelation = getKnownList().getKnownRelations().get(player.getObjectId());
if ((oldrelation == null) || (oldrelation != relation))
{
final RelationChanged rc = new RelationChanged();
rc.addRelation(this, relation, isAutoAttackable(player));
if (hasSummon())
{
final L2Summon pet = getPet();
if (pet != null)
{
rc.addRelation(pet, relation, isAutoAttackable(player));
}
if (hasServitors())
{
getServitors().values().forEach(s -> rc.addRelation(s, relation, isAutoAttackable(player)));
}
}
player.sendPacket(rc);
getKnownList().getKnownRelations().put(player.getObjectId(), relation);
}
}
}
@@ -2675,6 +2709,14 @@ public final class L2PcInstance extends L2Playable
Skill skill;
for (L2SkillLearn s : autoGetSkills)
{
final int maxLvl = SkillData.getInstance().getMaxLevel(s.getSkillId());
final int hashCode = SkillData.getSkillHashCode(s.getSkillId(), maxLvl);
if (SkillTreesData.getInstance().isCurrentClassSkillNoParent(getClassId(), hashCode) || SkillTreesData.getInstance().isRemoveSkill(getClassId(), s.getSkillId()))
{
continue;
}
skill = st.getSkill(s.getSkillId(), s.getSkillLevel());
if (skill != null)
{
@@ -2711,7 +2753,7 @@ public final class L2PcInstance extends L2Playable
{
return getTemplate().getRace();
}
return CharTemplateTable.getInstance().getTemplate(_baseClass).getRace();
return PlayerTemplateData.getInstance().getTemplate(_baseClass).getRace();
}
public L2Radar getRadar()
@@ -3341,18 +3383,14 @@ public final class L2PcInstance extends L2Playable
{
if (count > 0)
{
L2ItemInstance item = null;
if (ItemTable.getInstance().getTemplate(itemId) != null)
{
item = ItemTable.getInstance().createDummyItem(itemId);
}
else
final L2Item item = ItemTable.getInstance().getTemplate(itemId);
if (item == null)
{
_log.log(Level.SEVERE, "Item doesn't exist so cannot be added. Item ID: " + itemId);
return null;
}
// Sends message to client if requested
if (sendMessage && ((!isCastingNow() && item.getItem().hasExImmediateEffect()) || !item.getItem().hasExImmediateEffect()))
if (sendMessage && ((!isCastingNow() && item.hasExImmediateEffect()) || !item.hasExImmediateEffect()))
{
if (count > 1)
{
@@ -3389,9 +3427,9 @@ public final class L2PcInstance extends L2Playable
}
// Auto-use herbs.
if (item.getItem().hasExImmediateEffect())
if (item.hasExImmediateEffect())
{
final IItemHandler handler = ItemHandler.getInstance().getHandler(item.getEtcItem());
final IItemHandler handler = ItemHandler.getInstance().getHandler(item instanceof L2EtcItem ? (L2EtcItem) item : null);
if (handler == null)
{
_log.warning("No item handler registered for Herb ID " + item.getId() + "!");
@@ -3415,14 +3453,6 @@ public final class L2PcInstance extends L2Playable
{
CursedWeaponsManager.getInstance().activate(this, createdItem);
}
else if (FortSiegeManager.getInstance().isCombat(createdItem.getId()))
{
if (FortSiegeManager.getInstance().activateCombatFlag(this, item))
{
Fort fort = FortManager.getInstance().getFort(this);
fort.getSiege().announceToPlayer(SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_ACQUIRED_THE_FLAG), getName());
}
}
return createdItem;
}
}
@@ -3969,7 +3999,8 @@ public final class L2PcInstance extends L2Playable
}
// Pet is summoned and not the item that summoned the pet AND not the buggle from strider you're mounting
if ((hasSummon() && (getSummon().getControlObjectId() == objectId)) || (getMountObjectID() == objectId))
final L2Summon pet = getPet();
if (((pet != null) && (pet.getControlObjectId() == objectId)) || (getMountObjectID() == objectId))
{
if (Config.DEBUG)
{
@@ -4338,18 +4369,26 @@ public final class L2PcInstance extends L2Playable
continue;
}
player.sendPacket(mov);
if (mov instanceof CharInfo)
final int relation = getRelation(player);
Integer oldrelation = getKnownList().getKnownRelations().get(player.getObjectId());
if ((oldrelation == null) || (oldrelation != relation))
{
int relation = getRelation(player);
Integer oldrelation = getKnownList().getKnownRelations().get(player.getObjectId());
if ((oldrelation != null) && (oldrelation != relation))
final RelationChanged rc = new RelationChanged();
rc.addRelation(this, relation, isAutoAttackable(player));
if (hasSummon())
{
player.sendPacket(new RelationChanged(this, relation, isAutoAttackable(player)));
if (hasSummon())
final L2Summon pet = getPet();
if (pet != null)
{
player.sendPacket(new RelationChanged(getSummon(), relation, isAutoAttackable(player)));
rc.addRelation(pet, relation, isAutoAttackable(player));
}
if (hasServitors())
{
getServitors().values().forEach(s -> rc.addRelation(s, relation, isAutoAttackable(player)));
}
}
player.sendPacket(rc);
getKnownList().getKnownRelations().put(player.getObjectId(), relation);
}
}
}
@@ -4364,28 +4403,36 @@ public final class L2PcInstance extends L2Playable
mov.setInvisible(isInvisible());
Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
final Collection<L2PcInstance> plrs = getKnownList().getKnownPlayersInRadius(radiusInKnownlist);
for (L2PcInstance player : plrs)
{
if (player == null)
if ((player == null) || !isVisibleFor(player))
{
continue;
}
if (isInsideRadius(player, radiusInKnownlist, false, false))
player.sendPacket(mov);
if (mov instanceof CharInfo)
{
player.sendPacket(mov);
if (mov instanceof CharInfo)
final int relation = getRelation(player);
Integer oldrelation = getKnownList().getKnownRelations().get(player.getObjectId());
if ((oldrelation == null) || (oldrelation != relation))
{
int relation = getRelation(player);
Integer oldrelation = getKnownList().getKnownRelations().get(player.getObjectId());
if ((oldrelation != null) && (oldrelation != relation))
final RelationChanged rc = new RelationChanged();
rc.addRelation(this, relation, isAutoAttackable(player));
if (hasSummon())
{
player.sendPacket(new RelationChanged(this, relation, isAutoAttackable(player)));
if (hasSummon())
final L2Summon pet = getPet();
if (pet != null)
{
player.sendPacket(new RelationChanged(getSummon(), relation, isAutoAttackable(player)));
rc.addRelation(pet, relation, isAutoAttackable(player));
}
if (hasServitors())
{
getServitors().values().forEach(s -> rc.addRelation(s, relation, isAutoAttackable(player)));
}
}
player.sendPacket(rc);
getKnownList().getKnownRelations().put(player.getObjectId(), relation);
}
}
}
@@ -4851,6 +4898,7 @@ public final class L2PcInstance extends L2Playable
transformation.onTransform(this);
sendSkillList();
sendPacket(new SkillCoolTime(this));
sendPacket(new ExUserInfoAbnormalVisualEffect(this));
broadcastUserInfo();
// Notify to scripts
@@ -5452,6 +5500,8 @@ public final class L2PcInstance extends L2Playable
int itemDropPercent = 0;
final L2Summon pet = getPet();
for (L2ItemInstance itemDrop : getInventory().getItems())
{
// Don't drop
@@ -5459,7 +5509,7 @@ public final class L2PcInstance extends L2Playable
itemDrop.isTimeLimitedItem() || // Dont drop Time Limited Items
!itemDrop.isDropable() || (itemDrop.getId() == Inventory.ADENA_ID) || // Adena
(itemDrop.getItem().getType2() == L2Item.TYPE2_QUEST) || // Quest Items
(hasSummon() && (getSummon().getControlObjectId() == itemDrop.getId())) || // Control Item of active pet
((pet != null) && (pet.getControlObjectId() == itemDrop.getId())) || // Control Item of active pet
(Arrays.binarySearch(Config.KARMA_LIST_NONDROPPABLE_ITEMS, itemDrop.getId()) >= 0) || // Item listed in the non droppable item list
(Arrays.binarySearch(Config.KARMA_LIST_NONDROPPABLE_PET_ITEMS, itemDrop.getId()) >= 0 // Item listed in the non droppable pet item list
))
@@ -5746,13 +5796,13 @@ public final class L2PcInstance extends L2Playable
long lostExp = 0;
if (!L2Event.isParticipant(this))
{
if (lvl < ExperienceTable.getInstance().getMaxLevel())
if (lvl < ExperienceData.getInstance().getMaxLevel())
{
lostExp = Math.round(((getStat().getExpForLevel(lvl + 1) - getStat().getExpForLevel(lvl)) * percentLost) / 100);
}
else
{
lostExp = Math.round(((getStat().getExpForLevel(ExperienceTable.getInstance().getMaxLevel()) - getStat().getExpForLevel(ExperienceTable.getInstance().getMaxLevel() - 1)) * percentLost) / 100);
lostExp = Math.round(((getStat().getExpForLevel(ExperienceData.getInstance().getMaxLevel()) - getStat().getExpForLevel(ExperienceData.getInstance().getMaxLevel() - 1)) * percentLost) / 100);
}
}
@@ -5806,9 +5856,26 @@ public final class L2PcInstance extends L2Playable
}
@Override
public L2Summon getSummon()
public L2Summon getPet()
{
return _summon;
return _pet;
}
@Override
public Map<Integer, L2Summon> getServitors()
{
return _servitors == null ? Collections.emptyMap() : _servitors;
}
public L2Summon getAnyServitor()
{
return getServitors().values().stream().findAny().orElse(null);
}
@Override
public L2Summon getServitor(int objectId)
{
return getServitors().get(objectId);
}
/**
@@ -5829,11 +5896,26 @@ public final class L2PcInstance extends L2Playable
/**
* Set the L2Summon of the L2PcInstance.
* @param summon
* @param pet
*/
public void setPet(L2Summon summon)
public void setPet(L2Summon pet)
{
_summon = summon;
_pet = pet;
}
public void addServitor(L2Summon servitor)
{
if (_servitors == null)
{
synchronized (this)
{
if (_servitors == null)
{
_servitors = new ConcurrentHashMap<>(1);
}
}
}
_servitors.put(servitor.getObjectId(), servitor);
}
/**
@@ -6697,7 +6779,7 @@ public final class L2PcInstance extends L2Playable
*/
public void setAccessLevel(int level, boolean broadcast)
{
_accessLevel = AdminTable.getInstance().getAccessLevel(level);
_accessLevel = AdminData.getInstance().getAccessLevel(level);
getAppearance().setNameColor(_accessLevel.getNameColor());
getAppearance().setTitleColor(_accessLevel.getTitleColor());
@@ -6708,7 +6790,7 @@ public final class L2PcInstance extends L2Playable
CharNameTable.getInstance().addName(this);
if (!AdminTable.getInstance().hasAccessLevel(level))
if (!AdminData.getInstance().hasAccessLevel(level))
{
_log.warning("Tryed to set unregistered access level " + level + " for " + toString() + ". Setting access level without privileges!");
}
@@ -6731,7 +6813,7 @@ public final class L2PcInstance extends L2Playable
{
if (Config.EVERYBODY_HAS_ADMIN_RIGHTS)
{
return AdminTable.getInstance().getMasterAccessLevel();
return AdminData.getInstance().getMasterAccessLevel();
}
else if (_accessLevel == null)
{
@@ -6769,13 +6851,35 @@ public final class L2PcInstance extends L2Playable
StatusUpdate su = new StatusUpdate(this);
su.addAttribute(StatusUpdate.PVP_FLAG, getKarma());
sendPacket(su);
Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
final Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
for (L2PcInstance player : plrs)
{
player.sendPacket(new RelationChanged(this, getRelation(player), isAutoAttackable(player)));
if (hasSummon())
if ((player == null) || !isVisibleFor(player))
{
player.sendPacket(new RelationChanged(getSummon(), getRelation(player), isAutoAttackable(player)));
continue;
}
final int relation = getRelation(player);
Integer oldrelation = getKnownList().getKnownRelations().get(player.getObjectId());
if ((oldrelation == null) || (oldrelation != relation))
{
final RelationChanged rc = new RelationChanged();
rc.addRelation(this, relation, isAutoAttackable(player));
if (hasSummon())
{
final L2Summon pet = getPet();
if (pet != null)
{
rc.addRelation(pet, relation, isAutoAttackable(player));
}
if (hasServitors())
{
getServitors().values().forEach(s -> rc.addRelation(s, relation, isAutoAttackable(player)));
}
}
player.sendPacket(rc);
getKnownList().getKnownRelations().put(player.getObjectId(), relation);
}
}
}
@@ -6789,13 +6893,34 @@ public final class L2PcInstance extends L2Playable
su.addAttribute(StatusUpdate.KARMA, getKarma());
sendPacket(su);
Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
final Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
for (L2PcInstance player : plrs)
{
player.sendPacket(new RelationChanged(this, getRelation(player), isAutoAttackable(player)));
if (hasSummon())
if ((player == null) || !isVisibleFor(player))
{
player.sendPacket(new RelationChanged(getSummon(), getRelation(player), isAutoAttackable(player)));
continue;
}
final int relation = getRelation(player);
Integer oldrelation = getKnownList().getKnownRelations().get(player.getObjectId());
if ((oldrelation == null) || (oldrelation != relation))
{
final RelationChanged rc = new RelationChanged();
rc.addRelation(this, relation, isAutoAttackable(player));
if (hasSummon())
{
final L2Summon pet = getPet();
if (pet != null)
{
rc.addRelation(pet, relation, isAutoAttackable(player));
}
if (hasServitors())
{
getServitors().values().forEach(s -> rc.addRelation(s, relation, isAutoAttackable(player)));
}
}
player.sendPacket(rc);
getKnownList().getKnownRelations().put(player.getObjectId(), relation);
}
}
}
@@ -6917,7 +7042,7 @@ public final class L2PcInstance extends L2Playable
{
final int activeClassId = rset.getInt("classid");
final boolean female = rset.getInt("sex") != Sex.MALE.ordinal();
final L2PcTemplate template = CharTemplateTable.getInstance().getTemplate(activeClassId);
final L2PcTemplate template = PlayerTemplateData.getInstance().getTemplate(activeClassId);
PcAppearance app = new PcAppearance(rset.getByte("face"), rset.getByte("hairColor"), rset.getByte("hairStyle"), female);
player = new L2PcInstance(objectId, template, rset.getString("account_name"), app);
@@ -6928,7 +7053,7 @@ public final class L2PcInstance extends L2Playable
player.getStat().setExp(rset.getLong("exp"));
player.setExpBeforeDeath(rset.getLong("expBeforeDeath"));
player.getStat().setLevel(rset.getByte("level"));
player.getStat().setSp(rset.getInt("sp"));
player.getStat().setSp(rset.getLong("sp"));
player.setWantsPeace(rset.getInt("wantspeace"));
@@ -7136,9 +7261,18 @@ public final class L2PcInstance extends L2Playable
// Restore pet if exists in the world
player.setPet(L2World.getInstance().getPet(player.getObjectId()));
if (player.hasSummon())
final L2Summon pet = player.getPet();
if (pet != null)
{
player.getSummon().setOwner(player);
pet.setOwner(player);
}
if (player.hasServitors())
{
for (L2Summon summon : player.getServitors().values())
{
summon.setOwner(player);
}
}
// Update the overloaded status of the L2PcInstance
@@ -7240,11 +7374,11 @@ public final class L2PcInstance extends L2Playable
{
SubClass subClass = new SubClass();
subClass.setClassId(rset.getInt("class_id"));
subClass.setIsDualClass(rset.getBoolean("dual_class"));
subClass.setLevel(rset.getByte("level"));
subClass.setExp(rset.getLong("exp"));
subClass.setSp(rset.getLong("sp"));
subClass.setClassIndex(rset.getInt("class_index"));
subClass.setIsDualClass(rset.getBoolean("dual_class"));
// Enforce the correct indexing of _subClasses against their class indexes.
player.getSubClasses().put(subClass.getClassIndex(), subClass);
@@ -7559,9 +7693,9 @@ public final class L2PcInstance extends L2Playable
statement.setLong(2, subClass.getSp());
statement.setInt(3, subClass.getLevel());
statement.setInt(4, subClass.getClassId());
statement.setInt(5, getObjectId());
statement.setInt(6, subClass.getClassIndex());
statement.setBoolean(7, subClass.isDualClass());
statement.setBoolean(5, subClass.isDualClass());
statement.setInt(6, getObjectId());
statement.setInt(7, subClass.getClassIndex());
statement.execute();
statement.clearParameters();
}
@@ -8403,7 +8537,7 @@ public final class L2PcInstance extends L2Playable
}
// Check if the attacker isn't the L2PcInstance Pet
if ((attacker == this) || (attacker == getSummon()))
if ((attacker == this) || (attacker == getPet()) || attacker.hasServitor(attacker.getObjectId()))
{
return false;
}
@@ -8720,9 +8854,11 @@ public final class L2PcInstance extends L2Playable
target = this;
break;
case PET:
target = getPet();
break;
case SERVITOR:
case SUMMON:
target = getSummon();
target = getServitors().values().stream().findFirst().orElse(null);
break;
default:
target = getTarget();
@@ -9005,7 +9141,7 @@ public final class L2PcInstance extends L2Playable
}
}
if ((skill.getFlyType() == FlyType.CHARGE) && (Config.GEODATA > 0) && !GeoData.getInstance().canMove(this, target))
if ((skill.getFlyType() == FlyType.CHARGE) && !GeoData.getInstance().canMove(this, target))
{
sendPacket(SystemMessageId.THE_TARGET_IS_LOCATED_WHERE_YOU_CANNOT_CHARGE);
return false;
@@ -9658,9 +9794,15 @@ public final class L2PcInstance extends L2Playable
public void enterOlympiadObserverMode(Location loc, int id)
{
if (hasSummon())
final L2Summon pet = getPet();
if (pet != null)
{
getSummon().unSummon(this);
pet.unSummon(this);
}
if (hasServitors())
{
getServitors().values().forEach(s -> s.unSummon(this));
}
// Remove Hide.
@@ -10096,7 +10238,7 @@ public final class L2PcInstance extends L2Playable
_noble = val;
sendSkillList();
if (val && (getLevel() == ExperienceTable.getInstance().getMaxLevel()))
if (val && (getLevel() == ExperienceData.getInstance().getMaxLevel()))
{
sendPacket(new ExAcquireAPSkillList(this));
}
@@ -10123,9 +10265,14 @@ public final class L2PcInstance extends L2Playable
{
super.setTeam(team);
broadcastUserInfo();
if (hasSummon())
final L2Summon pet = getPet();
if (pet != null)
{
getSummon().broadcastStatusUpdate();
pet.broadcastStatusUpdate();
}
if (hasServitors())
{
getServitors().values().forEach(L2Summon::broadcastStatusUpdate);
}
}
@@ -10200,9 +10347,10 @@ public final class L2PcInstance extends L2Playable
* 2. This method no longer changes the active _classIndex of the player. This is only done by the calling of setActiveClass() method as that should be the only way to do so.
* @param classId
* @param classIndex
* @param isDualClass
* @return boolean subclassAdded
*/
public boolean addSubClass(int classId, int classIndex)
public boolean addSubClass(int classId, int classIndex, boolean isDualClass)
{
if (!_subclassLock.tryLock())
{
@@ -10223,9 +10371,15 @@ public final class L2PcInstance extends L2Playable
// Note: Never change _classIndex in any method other than setActiveClass().
SubClass newClass = new SubClass();
final SubClass newClass = new SubClass();
newClass.setClassId(classId);
newClass.setClassIndex(classIndex);
if (isDualClass)
{
newClass.setIsDualClass(true);
newClass.setExp(ExperienceData.getInstance().getExpForLevel(Config.BASE_DUALCLASS_LEVEL));
newClass.setLevel(Config.BASE_DUALCLASS_LEVEL);
}
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement(ADD_CHAR_SUBCLASS))
@@ -10254,12 +10408,12 @@ public final class L2PcInstance extends L2Playable
final Map<Integer, Skill> prevSkillList = new HashMap<>();
for (L2SkillLearn skillInfo : skillTree.values())
{
if (skillInfo.getGetLevel() <= 40)
if (skillInfo.getGetLevel() <= newClass.getLevel())
{
Skill prevSkill = prevSkillList.get(skillInfo.getSkillId());
Skill newSkill = SkillData.getInstance().getSkill(skillInfo.getSkillId(), skillInfo.getSkillLevel());
final Skill prevSkill = prevSkillList.get(skillInfo.getSkillId());
final Skill newSkill = SkillData.getInstance().getSkill(skillInfo.getSkillId(), skillInfo.getSkillLevel());
if ((prevSkill != null) && (prevSkill.getLevel() > newSkill.getLevel()))
if (((prevSkill != null) && (prevSkill.getLevel() > newSkill.getLevel())) || SkillTreesData.getInstance().isRemoveSkill(subTemplate, skillInfo.getSkillId()))
{
continue;
}
@@ -10282,9 +10436,10 @@ public final class L2PcInstance extends L2Playable
* 3. Upon Exception, revert the player to their BaseClass to avoid further problems.
* @param classIndex the class index to delete
* @param newClassId the new class Id
* @param isDualClass is subclass dualclass
* @return {@code true} if the sub-class was modified, {@code false} otherwise
*/
public boolean modifySubClass(int classIndex, int newClassId)
public boolean modifySubClass(int classIndex, int newClassId, boolean isDualClass)
{
if (!_subclassLock.tryLock())
{
@@ -10340,7 +10495,7 @@ public final class L2PcInstance extends L2Playable
_subclassLock.unlock();
}
return addSubClass(newClassId, classIndex);
return addSubClass(newClassId, classIndex, isDualClass);
}
public boolean isSubClassActive()
@@ -10400,7 +10555,7 @@ public final class L2PcInstance extends L2Playable
{
_activeClass = classId;
final L2PcTemplate pcTemplate = CharTemplateTable.getInstance().getTemplate(classId);
final L2PcTemplate pcTemplate = PlayerTemplateData.getInstance().getTemplate(classId);
if (pcTemplate == null)
{
_log.severe("Missing template for classId: " + classId);
@@ -10464,9 +10619,9 @@ public final class L2PcInstance extends L2Playable
_charges.set(0);
stopChargeTask();
if (hasServitor())
if (hasServitors())
{
getSummon().unSummon(this);
getServitors().values().forEach(s -> s.unSummon(this));
}
if (classIndex == 0)
@@ -10811,32 +10966,34 @@ public final class L2PcInstance extends L2Playable
}
return;
}
if ((Pet && hasPet() && getSummon().isDead()) || (!Pet && isDead()))
final L2Summon pet = getPet();
if ((Pet && (pet != null) && pet.isDead()) || (!Pet && isDead()))
{
_reviveRequested = 1;
int restoreExp = 0;
_revivePower = Formulas.calculateSkillResurrectRestorePercent(power, reviver);
restoreExp = (int) Math.round(((getExpBeforeDeath() - getExp()) * _revivePower) / 100);
_revivePet = Pet;
if (hasCharmOfCourage())
{
ConfirmDlg dlg = new ConfirmDlg(SystemMessageId.YOUR_CHARM_OF_COURAGE_IS_TRYING_TO_RESURRECT_YOU_WOULD_YOU_LIKE_TO_RESURRECT_NOW.getId());
final ConfirmDlg dlg = new ConfirmDlg(SystemMessageId.YOUR_CHARM_OF_COURAGE_IS_TRYING_TO_RESURRECT_YOU_WOULD_YOU_LIKE_TO_RESURRECT_NOW.getId());
dlg.addTime(60000);
sendPacket(dlg);
return;
}
final long restoreExp = Math.round(((getExpBeforeDeath() - getExp()) * _revivePower) / 100);
ConfirmDlg dlg = new ConfirmDlg(SystemMessageId.C1_IS_ATTEMPTING_TO_DO_A_RESURRECTION_THAT_RESTORES_S2_S3_XP_ACCEPT.getId());
dlg.addPcName(reviver);
dlg.addString(Integer.toString(restoreExp));
dlg.addLong(restoreExp);
dlg.addInt(power);
sendPacket(dlg);
}
}
public void reviveAnswer(int answer)
{
if ((_reviveRequested != 1) || (!isDead() && !_revivePet) || (_revivePet && hasPet() && !getSummon().isDead()))
final L2Summon pet = getPet();
if ((_reviveRequested != 1) || (!isDead() && !_revivePet) || (_revivePet && (pet != null) && !pet.isDead()))
{
return;
}
@@ -10854,15 +11011,15 @@ public final class L2PcInstance extends L2Playable
doRevive();
}
}
else if (hasPet())
else if (pet != null)
{
if (_revivePower != 0)
{
getSummon().doRevive(_revivePower);
pet.doRevive(_revivePower);
}
else
{
getSummon().doRevive();
pet.doRevive();
}
}
}
@@ -10970,16 +11127,25 @@ public final class L2PcInstance extends L2Playable
}
// Modify the position of the pet if necessary
final L2Summon summon = getSummon();
if (summon != null)
final L2Summon pet = getPet();
if (pet != null)
{
summon.setFollowStatus(false);
summon.teleToLocation(getLocation(), false);
((L2SummonAI) summon.getAI()).setStartFollowController(true);
summon.setFollowStatus(true);
summon.updateAndBroadcastStatus(0);
pet.setFollowStatus(false);
pet.teleToLocation(getLocation(), false);
((L2SummonAI) pet.getAI()).setStartFollowController(true);
pet.setFollowStatus(true);
pet.updateAndBroadcastStatus(0);
}
getServitors().values().forEach(s ->
{
s.setFollowStatus(false);
s.teleToLocation(getLocation(), false);
((L2SummonAI) s.getAI()).setStartFollowController(true);
s.setFollowStatus(true);
s.updateAndBroadcastStatus(0);
});
TvTEvent.onTeleported(this);
}
@@ -11212,7 +11378,8 @@ public final class L2PcInstance extends L2Playable
}
// Pet is summoned and not the item that summoned the pet AND not the buggle from strider you're mounting
if ((hasSummon() && (getSummon().getControlObjectId() == objectId)) || (getMountObjectID() == objectId))
final L2Summon pet = getPet();
if (((pet != null) && (pet.getControlObjectId() == objectId)) || (getMountObjectID() == objectId))
{
if (Config.DEBUG)
{
@@ -11551,14 +11718,24 @@ public final class L2PcInstance extends L2Playable
{
try
{
getSummon().setRestoreSummon(true);
getSummon().unSummon(this);
// Dead pet wasn't unsummoned, broadcast npcinfo changes (pet will be without owner name - means owner offline)
if (hasSummon())
L2Summon pet = getPet();
if (pet != null)
{
getSummon().broadcastNpcInfo(0);
pet.setRestoreSummon(true);
pet.unSummon(this);
// Dead pet wasn't unsummoned, broadcast npcinfo changes (pet will be without owner name - means owner offline)
pet = getPet();
if (pet != null)
{
pet.broadcastNpcInfo(0);
}
}
getServitors().values().forEach(s ->
{
s.setRestoreSummon(true);
s.unSummon(this);
});
}
catch (Exception e)
{
@@ -11596,7 +11773,7 @@ public final class L2PcInstance extends L2Playable
{
try
{
AdminTable.getInstance().deleteGm(this);
AdminData.getInstance().deleteGm(this);
}
catch (Exception e)
{
@@ -11639,10 +11816,11 @@ public final class L2PcInstance extends L2Playable
final int x = loc.getX() + Rnd.get(-30, 30);
final int y = loc.getY() + Rnd.get(-30, 30);
setXYZInvisible(x, y, loc.getZ());
if (hasSummon()) // dead pet
final L2Summon pet = getPet();
if (pet != null) // dead pet
{
getSummon().teleToLocation(loc, true);
getSummon().setInstanceId(0);
pet.teleToLocation(loc, true);
pet.setInstanceId(0);
}
}
}
@@ -12766,10 +12944,11 @@ public final class L2PcInstance extends L2Playable
{
return;
}
if (hasSummon())
if (hasPet())
{
setCurrentFeed(((L2PetInstance) getSummon()).getCurrentFed());
_controlItemId = getSummon().getControlObjectId();
final L2Summon pet = getPet();
setCurrentFeed(((L2PetInstance) pet).getCurrentFed());
_controlItemId = pet.getControlObjectId();
sendPacket(new SetupGauge(3, (getCurrentFeed() * 10000) / getFeedConsume(), (getMaxFeed() * 10000) / getFeedConsume()));
if (!isDead())
{
@@ -13239,77 +13418,58 @@ public final class L2PcInstance extends L2Playable
setXYZ(getBoat().getLocation());
activeChar.sendPacket(new CharInfo(this));
int relation1 = getRelation(activeChar);
int relation2 = activeChar.getRelation(this);
Integer oldrelation = getKnownList().getKnownRelations().get(activeChar.getObjectId());
if ((oldrelation != null) && (oldrelation != relation1))
{
activeChar.sendPacket(new RelationChanged(this, relation1, isAutoAttackable(activeChar)));
if (hasSummon())
{
activeChar.sendPacket(new RelationChanged(getSummon(), relation1, isAutoAttackable(activeChar)));
}
}
oldrelation = activeChar.getKnownList().getKnownRelations().get(getObjectId());
if ((oldrelation != null) && (oldrelation != relation2))
{
sendPacket(new RelationChanged(activeChar, relation2, activeChar.isAutoAttackable(this)));
if (activeChar.hasSummon())
{
sendPacket(new RelationChanged(activeChar.getSummon(), relation2, activeChar.isAutoAttackable(this)));
}
}
activeChar.sendPacket(new GetOnVehicle(getObjectId(), getBoat().getObjectId(), getInVehiclePosition()));
}
else if (isInAirShip())
{
setXYZ(getAirShip().getLocation());
activeChar.sendPacket(new CharInfo(this));
int relation1 = getRelation(activeChar);
int relation2 = activeChar.getRelation(this);
Integer oldrelation = getKnownList().getKnownRelations().get(activeChar.getObjectId());
if ((oldrelation != null) && (oldrelation != relation1))
{
activeChar.sendPacket(new RelationChanged(this, relation1, isAutoAttackable(activeChar)));
if (hasSummon())
{
activeChar.sendPacket(new RelationChanged(getSummon(), relation1, isAutoAttackable(activeChar)));
}
}
oldrelation = activeChar.getKnownList().getKnownRelations().get(getObjectId());
if ((oldrelation != null) && (oldrelation != relation2))
{
sendPacket(new RelationChanged(activeChar, relation2, activeChar.isAutoAttackable(this)));
if (activeChar.hasSummon())
{
sendPacket(new RelationChanged(activeChar.getSummon(), relation2, activeChar.isAutoAttackable(this)));
}
}
activeChar.sendPacket(new ExGetOnAirShip(this, getAirShip()));
}
else
{
activeChar.sendPacket(new CharInfo(this));
int relation1 = getRelation(activeChar);
int relation2 = activeChar.getRelation(this);
Integer oldrelation = getKnownList().getKnownRelations().get(activeChar.getObjectId());
if ((oldrelation != null) && (oldrelation != relation1))
}
int relation1 = getRelation(activeChar);
int relation2 = activeChar.getRelation(this);
Integer oldrelation = getKnownList().getKnownRelations().get(activeChar.getObjectId());
if ((oldrelation != null) && (oldrelation != relation1))
{
final RelationChanged rc = new RelationChanged();
rc.addRelation(this, relation1, isAutoAttackable(activeChar));
if (hasSummon())
{
activeChar.sendPacket(new RelationChanged(this, relation1, isAutoAttackable(activeChar)));
if (hasSummon())
final L2Summon pet = getPet();
if (pet != null)
{
activeChar.sendPacket(new RelationChanged(getSummon(), relation1, isAutoAttackable(activeChar)));
rc.addRelation(pet, relation1, isAutoAttackable(activeChar));
}
if (hasServitors())
{
getServitors().values().forEach(s -> rc.addRelation(s, relation1, isAutoAttackable(activeChar)));
}
}
oldrelation = activeChar.getKnownList().getKnownRelations().get(getObjectId());
if ((oldrelation != null) && (oldrelation != relation2))
activeChar.sendPacket(rc);
}
oldrelation = activeChar.getKnownList().getKnownRelations().get(getObjectId());
if ((oldrelation != null) && (oldrelation != relation2))
{
final RelationChanged rc = new RelationChanged();
rc.addRelation(activeChar, relation2, activeChar.isAutoAttackable(this));
if (activeChar.hasSummon())
{
sendPacket(new RelationChanged(activeChar, relation2, activeChar.isAutoAttackable(this)));
if (activeChar.hasSummon())
final L2Summon pet = getPet();
if (pet != null)
{
sendPacket(new RelationChanged(activeChar.getSummon(), relation2, activeChar.isAutoAttackable(this)));
rc.addRelation(pet, relation2, activeChar.isAutoAttackable(this));
}
if (hasServitors())
{
getServitors().values().forEach(s -> rc.addRelation(s, relation2, activeChar.isAutoAttackable(this)));
}
}
sendPacket(rc);
}
switch (getPrivateStoreType())
@@ -13663,6 +13823,12 @@ public final class L2PcInstance extends L2Playable
return false;
}
// If there is no geodata loaded for the place we are client Z correction might cause falling damage.
if (!GeoData.getInstance().hasGeo(getX(), getY()))
{
return false;
}
final int damage = (int) Formulas.calcFallDam(this, deltaZ);
if (damage > 0)
{
@@ -14682,4 +14848,14 @@ public final class L2PcInstance extends L2Playable
{
return getPlayerSide() == CastleSide.LIGHT;
}
public int getMaxSummonPoints()
{
return (int) getStat().calcStat(Stats.MAX_SUMMON_POINTS, 0, null, null);
}
public int getSummonPoints()
{
return getServitors().values().stream().mapToInt(L2Summon::getSummonPoints).sum();
}
}

View File

@@ -32,12 +32,12 @@ import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.datatables.CharSummonTable;
import com.l2jserver.gameserver.data.sql.impl.CharSummonTable;
import com.l2jserver.gameserver.data.sql.impl.SummonEffectsTable;
import com.l2jserver.gameserver.data.sql.impl.SummonEffectsTable.SummonEffect;
import com.l2jserver.gameserver.data.xml.impl.PetDataTable;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.datatables.PetDataTable;
import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.datatables.SummonEffectsTable;
import com.l2jserver.gameserver.datatables.SummonEffectsTable.SummonEffect;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.enums.ItemLocation;
import com.l2jserver.gameserver.enums.PartyDistributionType;
@@ -135,7 +135,8 @@ public class L2PetInstance extends L2Summon
{
try
{
if ((getOwner() == null) || !getOwner().hasSummon() || (getOwner().getSummon().getObjectId() != getObjectId()))
final L2Summon pet = getOwner().getPet();
if ((getOwner() == null) || (pet == null) || (pet.getObjectId() != getObjectId()))
{
stopFeed();
return;
@@ -1162,7 +1163,7 @@ public class L2PetInstance extends L2Summon
// stop feeding task if its active
stopFeed();
if (!isDead() && (getOwner().getSummon() == this))
if (!isDead() && (getOwner().getPet() == this))
{
_feedTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new FeedTask(), 10000, 10000);
}

View File

@@ -23,7 +23,7 @@ import java.util.concurrent.Future;
import com.l2jserver.Config;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.datatables.DoorTable;
import com.l2jserver.gameserver.data.xml.impl.DoorData;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.instancemanager.FourSepulchersManager;
import com.l2jserver.gameserver.model.L2World;
@@ -354,7 +354,7 @@ public class L2SepulcherNpcInstance extends L2Npc
public void openNextDoor(int npcId)
{
int doorId = FourSepulchersManager.getInstance().getHallGateKeepers().get(npcId);
DoorTable _doorTable = DoorTable.getInstance();
DoorData _doorTable = DoorData.getInstance();
_doorTable.getDoor(doorId).openMe();
if (_closeTask != null)
@@ -371,7 +371,7 @@ public class L2SepulcherNpcInstance extends L2Npc
private static class CloseNextDoor implements Runnable
{
final DoorTable _DoorTable = DoorTable.getInstance();
final DoorData _DoorTable = DoorData.getInstance();
private final int _DoorId;

View File

@@ -33,10 +33,10 @@ import javolution.util.FastList;
import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.CharSummonTable;
import com.l2jserver.gameserver.data.sql.impl.CharSummonTable;
import com.l2jserver.gameserver.data.sql.impl.SummonEffectsTable;
import com.l2jserver.gameserver.data.sql.impl.SummonEffectsTable.SummonEffect;
import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.datatables.SummonEffectsTable;
import com.l2jserver.gameserver.datatables.SummonEffectsTable.SummonEffect;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.model.L2Object;
import com.l2jserver.gameserver.model.actor.L2Character;
@@ -188,7 +188,7 @@ public class L2ServitorInstance extends L2Summon implements Runnable
_summonLifeTask.cancel(false);
}
CharSummonTable.getInstance().removeServitor(getOwner());
CharSummonTable.getInstance().removeServitor(getOwner(), getObjectId());
return true;
}
@@ -465,7 +465,7 @@ public class L2ServitorInstance extends L2Summon implements Runnable
if (!_restoreSummon)
{
CharSummonTable.getInstance().removeServitor(owner);
CharSummonTable.getInstance().removeServitor(owner, getObjectId());
}
}

View File

@@ -27,12 +27,13 @@ import javolution.util.FastList;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.data.xml.impl.NpcData;
import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.idfactory.IdFactory;
import com.l2jserver.gameserver.model.L2Object;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jserver.gameserver.model.effects.L2EffectType;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
import com.l2jserver.gameserver.model.skills.Skill;
@@ -64,16 +65,16 @@ public final class L2TamedBeastInstance extends L2FeedableBeastInstance
protected boolean _isFreyaBeast;
private List<Skill> _beastSkills = null;
public L2TamedBeastInstance(int objectId, L2NpcTemplate template)
public L2TamedBeastInstance(int objectId, int npcTemplateId)
{
super(objectId, template);
super(IdFactory.getInstance().getNextId(), NpcData.getInstance().getTemplate(npcTemplateId));
setInstanceType(InstanceType.L2TamedBeastInstance);
setHome(this);
}
public L2TamedBeastInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, int foodSkillId, int x, int y, int z)
public L2TamedBeastInstance(int npcTemplateId, L2PcInstance owner, int foodSkillId, int x, int y, int z)
{
super(objectId, template);
super(IdFactory.getInstance().getNextId(), NpcData.getInstance().getTemplate(npcTemplateId));
_isFreyaBeast = false;
setInstanceType(InstanceType.L2TamedBeastInstance);
setCurrentHp(getMaxHp());
@@ -81,12 +82,12 @@ public final class L2TamedBeastInstance extends L2FeedableBeastInstance
setOwner(owner);
setFoodType(foodSkillId);
setHome(x, y, z);
this.spawnMe(x, y, z);
spawnMe(x, y, z);
}
public L2TamedBeastInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, int food, int x, int y, int z, boolean isFreyaBeast)
public L2TamedBeastInstance(int npcTemplateId, L2PcInstance owner, int food, int x, int y, int z, boolean isFreyaBeast)
{
super(objectId, template);
super(IdFactory.getInstance().getNextId(), NpcData.getInstance().getTemplate(npcTemplateId));
_isFreyaBeast = isFreyaBeast;
setInstanceType(InstanceType.L2TamedBeastInstance);
setCurrentHp(getMaxHp());
@@ -99,7 +100,6 @@ public final class L2TamedBeastInstance extends L2FeedableBeastInstance
{
getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _owner);
}
}
public void onReceiveFood()

View File

@@ -28,10 +28,10 @@ import java.util.stream.Stream;
import com.l2jserver.Config;
import com.l2jserver.gameserver.cache.HtmCache;
import com.l2jserver.gameserver.data.sql.impl.TeleportLocationTable;
import com.l2jserver.gameserver.data.xml.impl.MultisellData;
import com.l2jserver.gameserver.data.xml.impl.TeleportersData;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.datatables.MultisellData;
import com.l2jserver.gameserver.datatables.TeleportLocationTable;
import com.l2jserver.gameserver.datatables.TeleportersData;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.instancemanager.CastleManager;
import com.l2jserver.gameserver.instancemanager.SiegeManager;

View File

@@ -18,19 +18,15 @@
*/
package com.l2jserver.gameserver.model.actor.instance;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.ClanTable;
import com.l2jserver.gameserver.datatables.ClassListData;
import com.l2jserver.gameserver.datatables.SkillTreesData;
import com.l2jserver.gameserver.data.sql.impl.ClanTable;
import com.l2jserver.gameserver.data.xml.impl.SkillTreesData;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.enums.Race;
import com.l2jserver.gameserver.instancemanager.CastleManager;
import com.l2jserver.gameserver.instancemanager.FortManager;
import com.l2jserver.gameserver.instancemanager.FortSiegeManager;
@@ -41,12 +37,9 @@ import com.l2jserver.gameserver.model.L2ClanMember;
import com.l2jserver.gameserver.model.L2SkillLearn;
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jserver.gameserver.model.base.AcquireSkillType;
import com.l2jserver.gameserver.model.base.ClassId;
import com.l2jserver.gameserver.model.base.PlayerClass;
import com.l2jserver.gameserver.model.base.SubClass;
import com.l2jserver.gameserver.model.entity.Castle;
import com.l2jserver.gameserver.model.entity.Fort;
import com.l2jserver.gameserver.model.quest.QuestState;
import com.l2jserver.gameserver.model.zone.ZoneId;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
@@ -57,7 +50,6 @@ import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
import com.l2jserver.gameserver.network.serverpackets.UserInfo;
import com.l2jserver.gameserver.util.Util;
import com.l2jserver.util.StringUtil;
/**
* This class ...
@@ -294,562 +286,12 @@ public class L2VillageMasterInstance extends L2NpcInstance
{
showPledgeSkillList(player);
}
else if (command.startsWith("Subclass"))
{
// Subclasses may not be changed while a skill is in use.
if (player.isCastingNow() || player.isAllSkillsDisabled())
{
player.sendPacket(SystemMessageId.SUBCLASSES_MAY_NOT_BE_CREATED_OR_CHANGED_WHILE_A_SKILL_IS_IN_USE);
return;
}
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
// Subclasses may not be changed while a transformated state.
if (player.getTransformation() != null)
{
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_NoTransformed.htm");
player.sendPacket(html);
return;
}
// Subclasses may not be changed while a summon is active.
if (player.hasSummon())
{
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_NoSummon.htm");
player.sendPacket(html);
return;
}
// Subclasses may not be changed while you have exceeded your inventory limit.
if (!player.isInventoryUnder90(true))
{
player.sendPacket(SystemMessageId.A_SUBCLASS_CANNOT_BE_CREATED_OR_CHANGED_BECAUSE_YOU_HAVE_EXCEEDED_YOUR_INVENTORY_LIMIT);
return;
}
// Subclasses may not be changed while a you are over your weight limit.
if (player.getWeightPenalty() >= 2)
{
player.sendPacket(SystemMessageId.A_SUBCLASS_CANNOT_BE_CREATED_OR_CHANGED_WHILE_YOU_ARE_OVER_YOUR_WEIGHT_LIMIT);
return;
}
int cmdChoice = 0;
int paramOne = 0;
int paramTwo = 0;
try
{
cmdChoice = Integer.parseInt(command.substring(9, 10).trim());
int endIndex = command.indexOf(' ', 11);
if (endIndex == -1)
{
endIndex = command.length();
}
if (command.length() > 11)
{
paramOne = Integer.parseInt(command.substring(11, endIndex).trim());
if (command.length() > endIndex)
{
paramTwo = Integer.parseInt(command.substring(endIndex).trim());
}
}
}
catch (Exception NumberFormatException)
{
_log.warning(L2VillageMasterInstance.class.getName() + ": Wrong numeric values for command " + command);
}
Set<PlayerClass> subsAvailable = null;
switch (cmdChoice)
{
case 0: // Subclass change menu
html.setFile(player.getHtmlPrefix(), getSubClassMenu(player.getRace()));
break;
case 1: // Add Subclass - Initial
// Avoid giving player an option to add a new sub class, if they have max sub-classes already.
if (player.getTotalSubClasses() >= Config.MAX_SUBCLASS)
{
html.setFile(player.getHtmlPrefix(), getSubClassFail());
break;
}
subsAvailable = getAvailableSubClasses(player);
if ((subsAvailable != null) && !subsAvailable.isEmpty())
{
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_Add.htm");
final StringBuilder content1 = StringUtil.startAppend(200);
for (PlayerClass subClass : subsAvailable)
{
StringUtil.append(content1, "<a action=\"bypass -h npc_%objectId%_Subclass 4 ", String.valueOf(subClass.ordinal()), "\" msg=\"1268;", ClassListData.getInstance().getClass(subClass.ordinal()).getClassName(), "\">", ClassListData.getInstance().getClass(subClass.ordinal()).getClientCode(), "</a><br>");
}
html.replace("%list%", content1.toString());
}
else
{
if ((player.getRace() == Race.ELF) || (player.getRace() == Race.DARK_ELF))
{
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_Fail_Elves.htm");
player.sendPacket(html);
}
else if (player.getRace() == Race.KAMAEL)
{
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_Fail_Kamael.htm");
player.sendPacket(html);
}
else
{
// TODO: Retail message
player.sendMessage("There are no sub classes available at this time.");
}
return;
}
break;
case 2: // Change Class - Initial
if (player.getSubClasses().isEmpty())
{
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_ChangeNo.htm");
}
else
{
final StringBuilder content2 = StringUtil.startAppend(200);
if (checkVillageMaster(player.getBaseClass()))
{
StringUtil.append(content2, "<a action=\"bypass -h npc_%objectId%_Subclass 5 0\">", ClassListData.getInstance().getClass(player.getBaseClass()).getClientCode(), "</a><br>");
}
for (Iterator<SubClass> subList = iterSubClasses(player); subList.hasNext();)
{
SubClass subClass = subList.next();
if (checkVillageMaster(subClass.getClassDefinition()))
{
StringUtil.append(content2, "<a action=\"bypass -h npc_%objectId%_Subclass 5 ", String.valueOf(subClass.getClassIndex()), "\">", ClassListData.getInstance().getClass(subClass.getClassId()).getClientCode(), "</a><br>");
}
}
if (content2.length() > 0)
{
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_Change.htm");
html.replace("%list%", content2.toString());
}
else
{
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_ChangeNotFound.htm");
}
}
break;
case 3: // Change/Cancel Subclass - Initial
if ((player.getSubClasses() == null) || player.getSubClasses().isEmpty())
{
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_ModifyEmpty.htm");
break;
}
// custom value
if (player.getTotalSubClasses() > 3)
{
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_ModifyCustom.htm");
final StringBuilder content3 = StringUtil.startAppend(200);
int classIndex = 1;
for (Iterator<SubClass> subList = iterSubClasses(player); subList.hasNext();)
{
SubClass subClass = subList.next();
StringUtil.append(content3, "Sub-class ", String.valueOf(classIndex++), "<br>", "<a action=\"bypass -h npc_%objectId%_Subclass 6 ", String.valueOf(subClass.getClassIndex()), "\">", ClassListData.getInstance().getClass(subClass.getClassId()).getClientCode(), "</a><br>");
}
html.replace("%list%", content3.toString());
}
else
{
// retail html contain only 3 subclasses
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_Modify.htm");
if (player.getSubClasses().containsKey(1))
{
html.replace("%sub1%", ClassListData.getInstance().getClass(player.getSubClasses().get(1).getClassId()).getClientCode());
}
else
{
html.replace("<a action=\"bypass -h npc_%objectId%_Subclass 6 1\">%sub1%</a><br>", "");
}
if (player.getSubClasses().containsKey(2))
{
html.replace("%sub2%", ClassListData.getInstance().getClass(player.getSubClasses().get(2).getClassId()).getClientCode());
}
else
{
html.replace("<a action=\"bypass -h npc_%objectId%_Subclass 6 2\">%sub2%</a><br>", "");
}
if (player.getSubClasses().containsKey(3))
{
html.replace("%sub3%", ClassListData.getInstance().getClass(player.getSubClasses().get(3).getClassId()).getClientCode());
}
else
{
html.replace("<a action=\"bypass -h npc_%objectId%_Subclass 6 3\">%sub3%</a><br>", "");
}
}
break;
case 4: // Add Subclass - Action (Subclass 4 x[x])
/**
* If the character is less than level 75 on any of their previously chosen classes then disallow them to change to their most recently added sub-class choice.
*/
if (!player.getFloodProtectors().getSubclass().tryPerformAction("add subclass"))
{
_log.warning(L2VillageMasterInstance.class.getName() + ": Player " + player.getName() + " has performed a subclass change too fast");
return;
}
boolean allowAddition = true;
if (player.getTotalSubClasses() >= Config.MAX_SUBCLASS)
{
allowAddition = false;
}
if (player.getLevel() < 75)
{
allowAddition = false;
}
if (allowAddition)
{
if (!player.getSubClasses().isEmpty())
{
for (Iterator<SubClass> subList = iterSubClasses(player); subList.hasNext();)
{
SubClass subClass = subList.next();
if (subClass.getLevel() < 75)
{
allowAddition = false;
break;
}
}
}
}
/**
* If quest checking is enabled, verify if the character has completed the Mimir's Elixir (Path to Subclass) and Fate's Whisper (A Grade Weapon) quests by checking for instances of their unique reward items. If they both exist, remove both unique items and continue with adding
* the sub-class.
*/
if (allowAddition && !Config.ALT_GAME_SUBCLASS_WITHOUT_QUESTS)
{
allowAddition = checkQuests(player);
}
if (allowAddition && isValidNewSubClass(player, paramOne))
{
if (!player.addSubClass(paramOne, player.getTotalSubClasses() + 1))
{
return;
}
player.setActiveClass(player.getTotalSubClasses());
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_AddOk.htm");
player.sendPacket(SystemMessageId.THE_NEW_SUBCLASS_HAS_BEEN_ADDED); // Subclass added.
}
else
{
html.setFile(player.getHtmlPrefix(), getSubClassFail());
}
break;
case 5: // Change Class - Action
/**
* If the character is less than level 75 on any of their previously chosen classes then disallow them to change to their most recently added sub-class choice. Note: paramOne = classIndex
*/
if (!player.getFloodProtectors().getSubclass().tryPerformAction("change class"))
{
_log.warning(L2VillageMasterInstance.class.getName() + ": Player " + player.getName() + " has performed a subclass change too fast");
return;
}
if (player.getClassIndex() == paramOne)
{
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_Current.htm");
break;
}
if (paramOne == 0)
{
if (!checkVillageMaster(player.getBaseClass()))
{
return;
}
}
else
{
try
{
if (!checkVillageMaster(player.getSubClasses().get(paramOne).getClassDefinition()))
{
return;
}
}
catch (NullPointerException e)
{
return;
}
}
final int fromClassId = player.getClassId().getId();
player.setActiveClass(paramOne);
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_SUCCESSFULLY_SWITCHED_S1_TO_S2);
msg.addClassId(fromClassId);
msg.addClassId(player.getClassId().getId());
player.sendPacket(msg);
return;
case 6: // Change/Cancel Subclass - Choice
// validity check
if ((paramOne < 1) || (paramOne > Config.MAX_SUBCLASS))
{
return;
}
subsAvailable = getAvailableSubClasses(player);
// another validity check
if ((subsAvailable == null) || subsAvailable.isEmpty())
{
// TODO: Retail message
player.sendMessage("There are no sub classes available at this time.");
return;
}
final StringBuilder content6 = StringUtil.startAppend(200);
for (PlayerClass subClass : subsAvailable)
{
StringUtil.append(content6, "<a action=\"bypass -h npc_%objectId%_Subclass 7 ", String.valueOf(paramOne), " ", String.valueOf(subClass.ordinal()), "\" msg=\"1445;", "\">", ClassListData.getInstance().getClass(subClass.ordinal()).getClientCode(), "</a><br>");
}
switch (paramOne)
{
case 1:
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_ModifyChoice1.htm");
break;
case 2:
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_ModifyChoice2.htm");
break;
case 3:
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_ModifyChoice3.htm");
break;
default:
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_ModifyChoice.htm");
}
html.replace("%list%", content6.toString());
break;
case 7: // Change Subclass - Action
/**
* Warning: the information about this subclass will be removed from the subclass list even if false!
*/
if (!player.getFloodProtectors().getSubclass().tryPerformAction("change class"))
{
_log.warning(L2VillageMasterInstance.class.getName() + ": Player " + player.getName() + " has performed a subclass change too fast");
return;
}
if (!isValidNewSubClass(player, paramTwo))
{
return;
}
if (player.modifySubClass(paramOne, paramTwo))
{
player.abortCast();
player.stopAllEffectsExceptThoseThatLastThroughDeath(); // all effects from old subclass stopped!
player.stopAllEffectsNotStayOnSubclassChange();
player.stopCubics();
player.setActiveClass(paramOne);
html.setFile(player.getHtmlPrefix(), "data/html/villagemaster/SubClass_ModifyOk.htm");
html.replace("%name%", ClassListData.getInstance().getClass(paramTwo).getClientCode());
player.sendPacket(SystemMessageId.THE_NEW_SUBCLASS_HAS_BEEN_ADDED); // Subclass added.
}
else
{
/**
* This isn't good! modifySubClass() removed subclass from memory we must update _classIndex! Else IndexOutOfBoundsException can turn up some place down the line along with other seemingly unrelated problems.
*/
player.setActiveClass(0); // Also updates _classIndex plus switching _classid to baseclass.
player.sendMessage("The sub class could not be added, you have been reverted to your base class.");
return;
}
break;
}
html.replace("%objectId%", String.valueOf(getObjectId()));
player.sendPacket(html);
}
else
{
super.onBypassFeedback(player, command);
}
}
protected String getSubClassMenu(Race race)
{
if (Config.ALT_GAME_SUBCLASS_EVERYWHERE || (race != Race.KAMAEL))
{
return "data/html/villagemaster/SubClass.htm";
}
return "data/html/villagemaster/SubClass_NoOther.htm";
}
protected String getSubClassFail()
{
return "data/html/villagemaster/SubClass_Fail.htm";
}
protected boolean checkQuests(L2PcInstance player)
{
// Noble players can add Sub-Classes without quests
if (player.isNoble())
{
return true;
}
QuestState qs = player.getQuestState("234_FatesWhisper");
if ((qs == null) || !qs.isCompleted())
{
return false;
}
qs = player.getQuestState("Q00235_MimirsElixir");
if ((qs == null) || !qs.isCompleted())
{
return false;
}
return true;
}
/**
* Returns list of available subclasses Base class and already used subclasses removed
* @param player
* @return
*/
private final Set<PlayerClass> getAvailableSubClasses(L2PcInstance player)
{
// get player base class
final int currentBaseId = player.getBaseClass();
final ClassId baseCID = ClassId.getClassId(currentBaseId);
// we need 2nd occupation ID
final int baseClassId;
if (baseCID.level() > 2)
{
baseClassId = baseCID.getParent().ordinal();
}
else
{
baseClassId = currentBaseId;
}
/**
* If the race of your main class is Elf or Dark Elf, you may not select each class as a subclass to the other class. If the race of your main class is Kamael, you may not subclass any other race If the race of your main class is NOT Kamael, you may not subclass any Kamael class You may not
* select Overlord and Warsmith class as a subclass. You may not select a similar class as the subclass. The occupations classified as similar classes are as follows: Treasure Hunter, Plainswalker and Abyss Walker Hawkeye, Silver Ranger and Phantom Ranger Paladin, Dark Avenger, Temple Knight
* and Shillien Knight Warlocks, Elemental Summoner and Phantom Summoner Elder and Shillien Elder Swordsinger and Bladedancer Sorcerer, Spellsinger and Spellhowler Also, Kamael have a special, hidden 4 subclass, the inspector, which can only be taken if you have already completed the other
* two Kamael subclasses
*/
Set<PlayerClass> availSubs = PlayerClass.values()[baseClassId].getAvailableSubclasses(player);
if ((availSubs != null) && !availSubs.isEmpty())
{
for (Iterator<PlayerClass> availSub = availSubs.iterator(); availSub.hasNext();)
{
PlayerClass pclass = availSub.next();
// check for the village master
if (!checkVillageMaster(pclass))
{
availSub.remove();
continue;
}
// scan for already used subclasses
int availClassId = pclass.ordinal();
ClassId cid = ClassId.getClassId(availClassId);
SubClass prevSubClass;
ClassId subClassId;
for (Iterator<SubClass> subList = iterSubClasses(player); subList.hasNext();)
{
prevSubClass = subList.next();
subClassId = ClassId.getClassId(prevSubClass.getClassId());
if (subClassId.equalsOrChildOf(cid))
{
availSub.remove();
break;
}
}
}
}
return availSubs;
}
/**
* Check new subclass classId for validity (villagemaster race/type, is not contains in previous subclasses, is contains in allowed subclasses) Base class not added into allowed subclasses.
* @param player
* @param classId
* @return
*/
private final boolean isValidNewSubClass(L2PcInstance player, int classId)
{
if (!checkVillageMaster(classId))
{
return false;
}
final ClassId cid = ClassId.values()[classId];
SubClass sub;
ClassId subClassId;
for (Iterator<SubClass> subList = iterSubClasses(player); subList.hasNext();)
{
sub = subList.next();
subClassId = ClassId.values()[sub.getClassId()];
if (subClassId.equalsOrChildOf(cid))
{
return false;
}
}
// get player base class
final int currentBaseId = player.getBaseClass();
final ClassId baseCID = ClassId.getClassId(currentBaseId);
// we need 2nd occupation ID
final int baseClassId;
if (baseCID.level() > 2)
{
baseClassId = baseCID.getParent().ordinal();
}
else
{
baseClassId = currentBaseId;
}
Set<PlayerClass> availSubs = PlayerClass.values()[baseClassId].getAvailableSubclasses(player);
if ((availSubs == null) || availSubs.isEmpty())
{
return false;
}
boolean found = false;
for (PlayerClass pclass : availSubs)
{
if (pclass.ordinal() == classId)
{
found = true;
break;
}
}
return found;
}
protected boolean checkVillageMasterRace(PlayerClass pclass)
{
return true;
@@ -877,19 +319,9 @@ public class L2VillageMasterInstance extends L2NpcInstance
*/
public final boolean checkVillageMaster(PlayerClass pclass)
{
if (Config.ALT_GAME_SUBCLASS_EVERYWHERE)
{
return true;
}
return checkVillageMasterRace(pclass) && checkVillageMasterTeachType(pclass);
}
private static final Iterator<SubClass> iterSubClasses(L2PcInstance player)
{
return player.getSubClasses().values().iterator();
}
private static final void dissolveClan(L2PcInstance player, int clanId)
{
if (!player.isClanLeader())

View File

@@ -18,11 +18,9 @@
*/
package com.l2jserver.gameserver.model.actor.instance;
import com.l2jserver.Config;
import com.l2jserver.gameserver.enums.Race;
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jserver.gameserver.model.base.PlayerClass;
import com.l2jserver.gameserver.model.quest.QuestState;
public final class L2VillageMasterKamaelInstance extends L2VillageMasterInstance
{
@@ -31,47 +29,6 @@ public final class L2VillageMasterKamaelInstance extends L2VillageMasterInstance
super(objectId, template);
}
@Override
protected final String getSubClassMenu(Race race)
{
if (Config.ALT_GAME_SUBCLASS_EVERYWHERE || (race == Race.KAMAEL))
{
return "data/html/villagemaster/SubClass.htm";
}
return "data/html/villagemaster/SubClass_NoKamael.htm";
}
@Override
protected final String getSubClassFail()
{
return "data/html/villagemaster/SubClass_Fail_Kamael.htm";
}
@Override
protected final boolean checkQuests(L2PcInstance player)
{
// Noble players can add subbclasses without quests
if (player.isNoble())
{
return true;
}
QuestState qs = player.getQuestState("234_FatesWhisper");
if ((qs == null) || !qs.isCompleted())
{
return false;
}
qs = player.getQuestState("236_SeedsOfChaos");
if ((qs == null) || !qs.isCompleted())
{
return false;
}
return true;
}
@Override
protected final boolean checkVillageMasterRace(PlayerClass pclass)
{

View File

@@ -21,12 +21,13 @@ package com.l2jserver.gameserver.model.actor.stat;
import java.util.concurrent.atomic.AtomicInteger;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.ExperienceTable;
import com.l2jserver.gameserver.datatables.PetDataTable;
import com.l2jserver.gameserver.data.xml.impl.ExperienceData;
import com.l2jserver.gameserver.data.xml.impl.PetDataTable;
import com.l2jserver.gameserver.enums.PartySmallWindowUpdateType;
import com.l2jserver.gameserver.enums.UserInfoType;
import com.l2jserver.gameserver.model.L2PetLevelData;
import com.l2jserver.gameserver.model.PcCondOverride;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.instance.L2ClassMasterInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
@@ -140,9 +141,10 @@ public class PcStat extends PlayableStat
float ratioTakenByPlayer = 0;
// if this player has a pet and it is in his range he takes from the owner's Exp, give the pet Exp now
if (activeChar.hasPet() && Util.checkIfInShortRadius(Config.ALT_PARTY_RANGE, activeChar, activeChar.getSummon(), false))
final L2Summon sPet = activeChar.getPet();
if ((sPet != null) && Util.checkIfInShortRadius(Config.ALT_PARTY_RANGE, activeChar, sPet, false))
{
L2PetInstance pet = (L2PetInstance) activeChar.getSummon();
L2PetInstance pet = (L2PetInstance) sPet;
ratioTakenByPlayer = pet.getPetLevelData().getOwnerExpTaken() / 100f;
// only give exp/sp to the pet by taking from the owner if the pet has a non-zero, positive ratio
@@ -243,7 +245,7 @@ public class PcStat extends PlayableStat
@Override
public final boolean addLevel(byte value)
{
if ((getLevel() + value) > (ExperienceTable.getInstance().getMaxLevel() - 1))
if ((getLevel() + value) > (ExperienceData.getInstance().getMaxLevel() - 1))
{
return false;
}
@@ -281,9 +283,10 @@ public class PcStat extends PlayableStat
}
// Synchronize level with pet if possible.
if (getActiveChar().hasPet())
final L2Summon sPet = getActiveChar().getPet();
if (sPet != null)
{
final L2PetInstance pet = (L2PetInstance) getActiveChar().getSummon();
final L2PetInstance pet = (L2PetInstance) sPet;
if (pet.getPetData().isSynchLevel() && (pet.getLevel() != getLevel()))
{
pet.getStat().setLevel(getLevel());
@@ -317,7 +320,7 @@ public class PcStat extends PlayableStat
partyWindow.addUpdateType(PartySmallWindowUpdateType.LEVEL);
getActiveChar().getParty().broadcastToPartyMembers(getActiveChar(), partyWindow);
}
if ((getLevel() == ExperienceTable.getInstance().getMaxLevel()) && getActiveChar().isNoble())
if ((getLevel() == ExperienceData.getInstance().getMaxLevel()) && getActiveChar().isNoble())
{
getActiveChar().sendPacket(new ExAcquireAPSkillList(getActiveChar()));
}
@@ -342,7 +345,7 @@ public class PcStat extends PlayableStat
@Override
public final long getExpForLevel(int level)
{
return ExperienceTable.getInstance().getExpForLevel(level);
return ExperienceData.getInstance().getExpForLevel(level);
}
@Override
@@ -454,9 +457,9 @@ public class PcStat extends PlayableStat
@Override
public final void setLevel(byte value)
{
if (value > (ExperienceTable.getInstance().getMaxLevel() - 1))
if (value > (ExperienceData.getInstance().getMaxLevel() - 1))
{
value = (byte) (ExperienceTable.getInstance().getMaxLevel() - 1);
value = (byte) (ExperienceData.getInstance().getMaxLevel() - 1);
}
if (getActiveChar().isSubClassActive())

View File

@@ -18,8 +18,8 @@
*/
package com.l2jserver.gameserver.model.actor.stat;
import com.l2jserver.gameserver.datatables.ExperienceTable;
import com.l2jserver.gameserver.datatables.PetDataTable;
import com.l2jserver.gameserver.data.xml.impl.ExperienceData;
import com.l2jserver.gameserver.data.xml.impl.PetDataTable;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
import com.l2jserver.gameserver.model.skills.Skill;
@@ -215,6 +215,6 @@ public class PetStat extends SummonStat
@Override
public int getMaxLevel()
{
return ExperienceTable.getInstance().getMaxPetLevel();
return ExperienceData.getInstance().getMaxPetLevel();
}
}

View File

@@ -21,9 +21,9 @@ package com.l2jserver.gameserver.model.actor.stat;
import java.util.logging.Logger;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.ExperienceTable;
import com.l2jserver.gameserver.datatables.PetDataTable;
import com.l2jserver.gameserver.datatables.SkillTreesData;
import com.l2jserver.gameserver.data.xml.impl.ExperienceData;
import com.l2jserver.gameserver.data.xml.impl.PetDataTable;
import com.l2jserver.gameserver.data.xml.impl.SkillTreesData;
import com.l2jserver.gameserver.instancemanager.ZoneManager;
import com.l2jserver.gameserver.model.actor.L2Playable;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
@@ -264,6 +264,6 @@ public class PlayableStat extends CharStat
public int getMaxLevel()
{
return ExperienceTable.getInstance().getMaxLevel();
return ExperienceData.getInstance().getMaxLevel();
}
}

View File

@@ -147,8 +147,8 @@ public class PcStatus extends PlayableStatus
}
// Check and calculate transfered damage
final L2Summon summon = getActiveChar().getSummon();
if (getActiveChar().hasServitor() && Util.checkIfInRange(1000, getActiveChar(), summon, true))
final L2Summon summon = getActiveChar().getAnyServitor();
if ((summon != null) && Util.checkIfInRange(1000, getActiveChar(), summon, true))
{
tDmg = ((int) value * (int) getActiveChar().getStat().calcStat(Stats.TRANSFER_DAMAGE_PERCENT, 0, null, null)) / 100;
@@ -248,10 +248,10 @@ public class PcStatus extends PlayableStatus
smsg.addInt(fullValue);
getActiveChar().sendPacket(smsg);
if (tDmg > 0)
if ((tDmg > 0) && (summon != null))
{
smsg = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
smsg.addString(getActiveChar().getSummon().getName());
smsg.addString(summon.getName());
smsg.addCharName(attacker);
smsg.addInt(tDmg);
getActiveChar().sendPacket(smsg);
@@ -303,10 +303,12 @@ public class PcStatus extends PlayableStatus
stopHpMpRegeneration();
getActiveChar().setIsDead(true);
getActiveChar().setIsPendingRevive(true);
if (getActiveChar().hasSummon())
final L2Summon pet = getActiveChar().getPet();
if (pet != null)
{
getActiveChar().getSummon().getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null);
pet.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null);
}
getActiveChar().getServitors().values().forEach(s -> s.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null));
return;
}

View File

@@ -24,6 +24,7 @@ import java.util.logging.Logger;
import com.l2jserver.Config;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.instance.L2CubicInstance;
import com.l2jserver.gameserver.model.effects.L2EffectType;
import com.l2jserver.gameserver.model.skills.BuffInfo;
@@ -72,10 +73,13 @@ public final class CubicAction implements Runnable
{
if (_cubic.getOwner().hasSummon())
{
if (!AttackStanceTaskManager.getInstance().hasAttackStanceTask(_cubic.getOwner().getSummon()))
for (L2Summon servitor : _cubic.getOwner().getServitors().values())
{
_cubic.stopAction();
return;
if (!AttackStanceTaskManager.getInstance().hasAttackStanceTask(servitor))
{
_cubic.stopAction();
return;
}
}
}
else

View File

@@ -20,7 +20,7 @@ package com.l2jserver.gameserver.model.actor.tasks.player;
import java.util.logging.Logger;
import com.l2jserver.gameserver.datatables.AdminTable;
import com.l2jserver.gameserver.data.xml.impl.AdminData;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.L2GameClient;
import com.l2jserver.gameserver.network.serverpackets.LeaveWorld;
@@ -48,7 +48,7 @@ public class GameGuardCheckTask implements Runnable
L2GameClient client = _player.getClient();
if ((client != null) && !client.isAuthedGG() && _player.isOnline())
{
AdminTable.getInstance().broadcastMessageToGMs("Client " + client + " failed to reply GameGuard query and is being kicked!");
AdminData.getInstance().broadcastMessageToGMs("Client " + client + " failed to reply GameGuard query and is being kicked!");
_log.info("Client " + client + " failed to reply GameGuard query and is being kicked!");
client.close(LeaveWorld.STATIC_PACKET);

View File

@@ -23,7 +23,7 @@ import java.util.logging.LogRecord;
import java.util.logging.Logger;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.AdminTable;
import com.l2jserver.gameserver.data.xml.impl.AdminData;
import com.l2jserver.gameserver.enums.IllegalActionPunishmentType;
import com.l2jserver.gameserver.instancemanager.PunishmentManager;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
@@ -84,7 +84,7 @@ public final class IllegalPlayerActionTask implements Runnable
//@formatter:on
_log.log(record);
AdminTable.getInstance().broadcastMessageToGMs(_message);
AdminData.getInstance().broadcastMessageToGMs(_message);
if (!_actor.isGM())
{
switch (_punishment)

View File

@@ -25,7 +25,7 @@ import java.util.Map;
import java.util.Set;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.NpcData;
import com.l2jserver.gameserver.data.xml.impl.NpcData;
import com.l2jserver.gameserver.enums.AISkillScope;
import com.l2jserver.gameserver.enums.AIType;
import com.l2jserver.gameserver.enums.Race;

View File

@@ -22,7 +22,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.l2jserver.gameserver.datatables.ExperienceTable;
import com.l2jserver.gameserver.data.xml.impl.ExperienceData;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.StatsSet;
import com.l2jserver.gameserver.model.base.ClassId;
@@ -57,12 +57,12 @@ public class L2PcTemplate extends L2CharTemplate
super(set);
_classId = ClassId.getClassId(set.getInt("classId"));
setRace(_classId.getRace());
_baseHp = new float[ExperienceTable.getInstance().getMaxLevel()];
_baseMp = new float[ExperienceTable.getInstance().getMaxLevel()];
_baseCp = new float[ExperienceTable.getInstance().getMaxLevel()];
_baseHpReg = new double[ExperienceTable.getInstance().getMaxLevel()];
_baseMpReg = new double[ExperienceTable.getInstance().getMaxLevel()];
_baseCpReg = new double[ExperienceTable.getInstance().getMaxLevel()];
_baseHp = new float[ExperienceData.getInstance().getMaxLevel()];
_baseMp = new float[ExperienceData.getInstance().getMaxLevel()];
_baseCp = new float[ExperienceData.getInstance().getMaxLevel()];
_baseHpReg = new double[ExperienceData.getInstance().getMaxLevel()];
_baseMpReg = new double[ExperienceData.getInstance().getMaxLevel()];
_baseCpReg = new double[ExperienceData.getInstance().getMaxLevel()];
_baseSlotDef = new HashMap<>(12);
_baseSlotDef.put(Inventory.PAPERDOLL_CHEST, set.getInt("basePDefchest", 0));

View File

@@ -21,7 +21,7 @@ package com.l2jserver.gameserver.model.actor.transform;
import java.util.ArrayList;
import java.util.List;
import com.l2jserver.gameserver.datatables.SkillTreesData;
import com.l2jserver.gameserver.data.xml.impl.SkillTreesData;
import com.l2jserver.gameserver.model.L2SkillLearn;
import com.l2jserver.gameserver.model.StatsSet;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;