Перейти к содержанию
Авторизация  
Relvl

[Bug-Fix] [L2Jserver] Исправление Неправильной Работы Автолута Хербов.

Рекомендуемые сообщения

В последнем билде L2JServer HF не правильно работает автолут хербов при магической атаке.

Вместо того, чтоб кастовать скил с аттриботом Simultaneous, ядро добавляло планировку использования после завершения основого каста персонажа.

 

Это приводит к тому, что если быстро убивать много мобов без паузы - планировка хербов накапливается, и они применяются не сразу, а только после остановки каста минимум на 200мс.

Вместо того, чтоб найти причину проблемы, разработчики просто прикрыли ошибку такой вот затычкой.

 

Решение проблемы:

 

В классе L2PcInstance метод addItem() должен выглядеть так:

 

public L2ItemInstance addItem(String process, int itemId, long count, L2Object reference, boolean sendMessage){
if (count > 0){
L2ItemInstance item = null;
if(ItemTable.getInstance().getTemplate(itemId) != null){
item = ItemTable.getInstance().createDummyItem(itemId);
}
else{
_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 && !item.isHerb()){
if (count > 1){
 if (process.equalsIgnoreCase("sweep") || process.equalsIgnoreCase("Quest")){
 SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
 sm.addItemName(itemId);
 sm.addItemNumber(count);
 sendPacket(sm);
 }
 else{
 SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_PICKED_UP_S1_S2);
 sm.addItemName(itemId);
 sm.addItemNumber(count);
 sendPacket(sm);
 }
}
else{
 if (process.equalsIgnoreCase("sweep") || process.equalsIgnoreCase("Quest")){
 SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
 sm.addItemName(itemId);
 sendPacket(sm);
 }
 else{
 SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_PICKED_UP_S1);
 sm.addItemName(itemId);
 sendPacket(sm);
 }
}
}
//Auto use herbs - autoloot
if (item.getItemType() == L2EtcItemType.HERB){
L2ItemInstance herb = new L2ItemInstance(_charId, itemId);
IItemHandler handler = ItemHandler.getInstance().getHandler(herb.getEtcItem());
if (handler == null)
 _log.warning("No item handler registered for Herb - item ID " + herb.getItemId() + ".");
else
 handler.useItem(this, herb, false);
}
else{
// Add the item to inventory
L2ItemInstance createdItem = _inventory.addItem(process, itemId, count, this, reference);

// If over capacity, drop the item
if (!isGM() && !_inventory.validateCapacity(0, item.isQuestItem()) && createdItem.isDropable() && (!createdItem.isStackable() || createdItem.getLastChange() != L2ItemInstance.MODIFIED))
 dropItem("InvDrop", createdItem, null, true);

// Cursed Weapon
else if(CursedWeaponsManager.getInstance().isCursed(createdItem.getItemId()))
 CursedWeaponsManager.getInstance().activate(this, createdItem);

// Combat Flag
else if(FortSiegeManager.getInstance().isCombat(createdItem.getItemId())){
 if( FortSiegeManager.getInstance().activateCombatFlag(this, item)){
 Fort fort = FortManager.getInstance().getFort(this);
 fort.getSiege().announceToPlayer(SystemMessage.getSystemMessage(SystemMessageId.C1_ACQUIRED_THE_FLAG), this.getName());
 }
}
// Territory Ward
else if (createdItem.getItemId() >= 13560 && createdItem.getItemId() <= 13568)
{
 TerritoryWard ward = TerritoryWarManager.getInstance().getTerritoryWard(createdItem.getItemId() - 13479);
 if (ward != null)
 ward.activate(this, createdItem);
}
return createdItem;
}
}
return null;
}

 

 

 

В классе ItemSkillsTemplate метод useItem() должен выглядеть так:

 

public boolean useItem(L2Playable playable, L2ItemInstance item, boolean forceUse){
final L2PcInstance player = playable.getActingPlayer();
if (!playable.isPet() && !playable.isPlayer()){
return false;
}

if (!TvTEvent.onScrollUse(playable.getObjectId())){
playable.sendPacket(ActionFailed.STATIC_PACKET);
return false;
}

// Pets can use items only when they are tradable.
if (playable.isPet() && !item.isTradeable()){
player.sendPacket(SystemMessageId.ITEM_NOT_FOR_PETS);
return false;
}

// Verify that item is not under reuse.
if (!checkReuse(player, null, item)){
return false;
}

int skillId;
int skillLvl;

final SkillHolder[] skills = item.getEtcItem().getSkills();
if (skills == null){
_log.info("Item " + item + " does not have registered any skill for handler.");
return false;
}

for (SkillHolder skillInfo : skills){
if (skillInfo == null)
continue;

skillId = skillInfo.getSkillId();
skillLvl = skillInfo.getSkillLvl();
L2Skill itemSkill = skillInfo.getSkill();

if (itemSkill != null){
if (!itemSkill.checkCondition(playable, playable.getTarget(), false)){
 return false;
}

if (playable.isSkillDisabled(itemSkill)){
 return false;
}

// Verify that skill is not under reuse.
if (!checkReuse(player, itemSkill, item)){
 return false;
}

if (!item.isPotion() && !item.isElixir() && !item.isHerb() && playable.isCastingNow()){
 return false;
}

if ((itemSkill.getItemConsumeId() == 0) && (itemSkill.getItemConsume() > 0) && (item.isPotion() || item.isElixir() || item.isHerb() || itemSkill.isSimultaneousCast())){
 if (!playable.destroyItem("Consume", item.getObjectId(), itemSkill.getItemConsume(), playable, false)){
 player.sendPacket(SystemMessageId.NOT_ENOUGH_ITEMS);
 return false;
 }
}

// send message to owner
if (playable.isPet()){
 SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.PET_USES_S1);
 sm.addString(itemSkill.getName());
 player.sendPacket(sm);
}
else{
 switch (skillId){
 // short buff icon for healing potions
 case 2031:
 case 2032:
 case 2037:
 case 26025:
 case 26026:
 final int buffId = player._shortBuffTaskSkillId;
 if ((skillId == 2037) || (skillId == 26025)){
 player.shortBuffStatusUpdate(skillId, skillLvl, itemSkill.getBuffDuration() / 1000);
 }
 else if (((skillId == 2032) || (skillId == 26026)) && (buffId != 2037) && (buffId != 26025)){
 player.shortBuffStatusUpdate(skillId, skillLvl, itemSkill.getBuffDuration() / 1000);
 }
 else{
 if ((buffId != 2037) && (buffId != 26025) && (buffId != 2032) && (buffId != 26026)){
	 player.shortBuffStatusUpdate(skillId, skillLvl, itemSkill.getBuffDuration() / 1000);
 }
 }
 break;
 }
}

if (item.isPotion() || item.isElixir() || item.isHerb() || itemSkill.isSimultaneousCast()){
 playable.doSimultaneousCast(itemSkill);
 // Summons should be affected by herbs too, self time effect is handled at L2Effect constructor
 if (!playable.isPet() && (item.isHerb()) && (player.getPet() != null) && (player.getPet() instanceof L2ServitorInstance)){
 player.getPet().doSimultaneousCast(itemSkill);
 }
}
else{
 playable.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
 if (!playable.useMagic(itemSkill, forceUse, false)){
 return false;
 }

 if ((itemSkill.getItemConsumeId() == 0) && (itemSkill.getItemConsume() > 0)){
 if (!playable.destroyItem("Consume", item.getObjectId(), itemSkill.getItemConsume(), null, false)){
 player.sendPacket(SystemMessageId.NOT_ENOUGH_ITEMS);
 return false;
 }
 }
}

if (itemSkill.getReuseDelay() > 0){
 player.addTimeStamp(itemSkill, itemSkill.getReuseDelay());
}
}
}
return true;
}

 

 

В классах L2Item и L2ItemInstance добавить недостающие методы соответственно:

 

public boolean isHerb(){
return (getItemType() == L2EtcItemType.HERB);
}

 

 


public boolean isHerb(){
return _item.isHerb();
}

 

 

После этого 1 переменная и один класс-раннер помечаются как неиспользуемые, их можно удалить без вреда.

 

Проверил наличие бага на более старых ревизиях, и на некоторых сборках, сделаных на основе лыжы... практически везде присутствует.

Изменено пользователем Relvl
  • Upvote 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация  

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...