Перейти к содержанию

hodor

Пользователи
  • Публикаций

    64
  • Зарегистрирован

  • Посещение

  • Отзывы

    0%

Весь контент hodor

  1. hodor

    Tutorial

    помогло бы, просто вы не так скопировали наверное.
  2. Я сам додумался, но очень удивился помощи, спасибо
  3. Зафиксил, можно закрывать тему. Огромное спасибо тебе
  4. Решил начать исправлять с шадоуитемов. Вообщем теперь шапка падает в инвентарь после окончания маны, её нельзя одеть, при релоге пропадает из инвентаря: /* * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.l2j.gameserver.model.itemcontainer.listeners; import net.sf.l2j.gameserver.model.actor.L2Playable; import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; import net.sf.l2j.gameserver.model.item.instance.ItemInstance; import net.sf.l2j.gameserver.network.SystemMessageId; import net.sf.l2j.gameserver.network.serverpackets.InventoryUpdate; import net.sf.l2j.gameserver.network.serverpackets.SystemMessage; public class ShadowWeaponListener implements OnEquipListener { private static ShadowWeaponListener instance = new ShadowWeaponListener(); public static ShadowWeaponListener getInstance() { return instance; } @Override public void onEquip(int slot, ItemInstance item, L2Playable playable) { if (item.isShadowItem()) { item.startTimer(new ShadowLifeTimeTask(item, playable)); } } @Override public void onUnequip(int slot, ItemInstance item, L2Playable playable) { if (item.isShadowItem()) { item.stopTimer(); } } protected class ShadowLifeTimeTask implements Runnable { private final ItemInstance _item; private final L2PcInstance _player; ShadowLifeTimeTask(ItemInstance item, L2Playable actor) { _item = item; _player = (L2PcInstance) actor; } @Override public void run() { if (!_item.isEquipped()) { return; } int mana; synchronized (_item) { _item.setMana(_item.getMana() - 1); mana = _item.getMana(); if (mana <= 0) { // Remove item first. /*_player.getInventory().unEquipItemInSlotAndRecord(_item.getLocationSlot()); InventoryUpdate iu = new InventoryUpdate(); iu.addModifiedItem(_item); _player.sendPacket(iu); _player.broadcastUserInfo();*/ _player.getInventory().destroyItem("ShadowItem", _item, _player, null); _player.getInventory().unEquipItemInSlotAndRecord(_item.getLocationSlot()); InventoryUpdate iu = new InventoryUpdate(); iu.addModifiedItem(_item); _player.sendPacket(iu); _player.broadcastUserInfo(); } } SystemMessage sm = null; if (mana == 10) { sm = SystemMessage.getSystemMessage(SystemMessageId.S1S_REMAINING_MANA_IS_NOW_10); } else if (mana == 5) { sm = SystemMessage.getSystemMessage(SystemMessageId.S1S_REMAINING_MANA_IS_NOW_5); } else if (mana == 1) { sm = SystemMessage.getSystemMessage(SystemMessageId.S1S_REMAINING_MANA_IS_NOW_1); } else if (mana <= 0) { sm = SystemMessage.getSystemMessage(SystemMessageId.S1S_REMAINING_MANA_IS_NOW_0); } /*else { _player.getInventory().unEquipItemInSlotAndRecord(_item.getLocationSlot()); InventoryUpdate iu = new InventoryUpdate(); iu.addModifiedItem(_item); _player.sendPacket(iu); _player.broadcastUserInfo(); }*/ if (sm != null) { sm.addItemName(_item.getItemId()); _player.sendPacket(sm); } } } }
  5. Я сделал большую часть своими руками и логикой не зная явы вообще так, что перестань умничать! Я лишь попросил помощи, чтобы исправить появившийся баг, а не написать мне код в 1000 строк.... Что сложного сказать куда дописать пару строк фикса, я же весь код LifeTimeManagera выложил?! Вы все только умничать умеете, жаль я не знаю как -1 репутации давать - давно бы навыдовал таким "умникам".
  6. Еще бы знать как это сделать Если знаешь - скажи как (код напиши) и куда его сунуть.
  7. Добавил LifeTime (удаляет итем по истечению времени даже если шмотка не одета) и появился баг если это шмотка, оружие - удаляется из инвентаря, но остается на персонаже... Вот как это выглядит (только одел шмотку): А вот тут время шмотки истекает и она удаляется из инвентаря, но почему-то остается как вид на персонаже, но после релога или телепорта в другой город вид шмотки пропадает: Сам код ( /* LifeTime start */ сделал для удобство поиска того, что я добавлял ) :
  8. Исправил, тему можно закрыть.
  9. Подскажите как зафиксить ошибку: clean: [delete] Deleting directory C:\Source\L2jFatum Rev. 30\build-ant\core checkRequirements: [echo] Verification of your JDK version. init: [mkdir] Created dir: C:\Source\L2jFatum Rev. 30\build-ant\core [mkdir] Created dir: C:\Source\L2jFatum Rev. 30\build-ant\core\classes compile: [javac] Compiling 1739 source files to C:\Source\L2jFatum Rev. 30\build-ant\core\classes [javac] C:\Source\L2jFatum Rev. 30\java\net\sf\l2j\gameserver\model\entity\events\EventManager.java:22: warning: Service is internal proprietary API and may be removed in a future release [javac] import sun.misc.Service; [javac] ^ [javac] C:\Source\L2jFatum Rev. 30\java\net\sf\l2j\gameserver\threadmanager\ExclusiveTask.java:47: error: cannot find symbol [javac] _future = ThreadPoolManager.getInstance().schedule(_runnable, delay); [javac] ^ [javac] symbol: method schedule(Runnable,long) [javac] location: class ThreadPoolManager [javac] C:\Source\L2jFatum Rev. 30\java\net\sf\l2j\gameserver\threadmanager\ExclusiveTask.java:54: error: cannot find symbol [javac] _future = ThreadPoolManager.getInstance().scheduleAtFixedRate(_runnable, delay, period); [javac] ^ [javac] symbol: method scheduleAtFixedRate(Runnable,long,long) [javac] location: class ThreadPoolManager [javac] C:\Source\L2jFatum Rev. 30\java\net\sf\l2j\gameserver\model\entity\events\EventManager.java:56: warning: Service is internal proprietary API and may be removed in a future release [javac] Iterator<?> iterator = Service.providers(AbstractEvent.class); [javac] ^ [javac] 2 errors [javac] 2 warnings BUILD FAILED C:\Source\L2jFatum Rev. 30\build-core.xml:30: Compile failed; see the compiler error output for details. Total time: 9 seconds ThreadPoolManager: /* * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.l2j.gameserver; import java.lang.Thread.UncaughtExceptionHandler; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RunnableScheduledFuture; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import net.sf.l2j.commons.config.Config; import net.sf.l2j.commons.util.StringUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <p> * This class is made to handle all the ThreadPools used in L2j. * </p> * <p> * Scheduled Tasks can either be sent to a {@link #_generalScheduledThreadPool "general"} or {@link #_effectsScheduledThreadPool "effects"} {@link ScheduledThreadPoolExecutor ScheduledThreadPool}: The "effects" one is used for every effects (skills, hp/mp regen ...) while the "general" one is used * for everything else that needs to be scheduled.<br> * There also is an {@link #_aiScheduledThreadPool "ai"} {@link ScheduledThreadPoolExecutor ScheduledThreadPool} used for AI Tasks. * </p> * <p> * Tasks can be sent to {@link ScheduledThreadPoolExecutor ScheduledThreadPool} either with: * <ul> * <li>{@link #scheduleEffect(Runnable, long)} : for effects Tasks that needs to be executed only once.</li> * <li>{@link #scheduleGeneral(Runnable, long)} : for scheduled Tasks that needs to be executed once.</li> * <li>{@link #scheduleAi(Runnable, long)} : for AI Tasks that needs to be executed once</li> * </ul> * or * <ul> * <li>{@link #scheduleEffectAtFixedRate(Runnable, long, long)} : for effects Tasks that needs to be executed periodicaly.</li> * <li>{@link #scheduleGeneralAtFixedRate(Runnable, long, long)} : for scheduled Tasks that needs to be executed periodicaly.</li> * <li>{@link #scheduleAiAtFixedRate(Runnable, long, long)} : for AI Tasks that needs to be executed periodicaly</li> * </ul> * </p> * <p> * For all Tasks that should be executed with no delay asynchronously in a ThreadPool there also are usual {@link ThreadPoolExecutor ThreadPools} that can grow/shrink according to their load.: * <ul> * <li>{@link #_generalPacketsThreadPool GeneralPackets} where most packets handler are executed.</li> * <li> * {@link #_ioPacketsThreadPool I/O Packets} where all the i/o packets are executed.</li> * <li>There will be an AI ThreadPool where AI events should be executed</li> * <li>A general ThreadPool where everything else that needs to run asynchronously with no delay should be executed ( {@link net.sf.l2j.gameserver.model.actor.knownlist KnownList} updates, SQL updates/inserts...)?</li> * </ul> * </p> * @author -Wooden- */ public class ThreadPoolManager { protected static final Logger _log = LoggerFactory.getLogger(ThreadPoolManager.class.getName()); private static final class RunnableWrapper implements Runnable { private final Runnable _r; public RunnableWrapper(final Runnable r) { _r = r; } @Override public final void run() { try { _r.run(); } catch (final Throwable e) { final Thread t = Thread.currentThread(); final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler(); if (h != null) { h.uncaughtException(t, e); } } } } protected ScheduledThreadPoolExecutor _effectsScheduledThreadPool; protected ScheduledThreadPoolExecutor _generalScheduledThreadPool; protected ScheduledThreadPoolExecutor _aiScheduledThreadPool; private final ThreadPoolExecutor _generalPacketsThreadPool; private final ThreadPoolExecutor _ioPacketsThreadPool; private final ThreadPoolExecutor _generalThreadPool; /** temp workaround for VM issue */ private static final long MAX_DELAY = Long.MAX_VALUE / 1000000 / 2; private boolean _shutdown; public static ThreadPoolManager getInstance() { return SingletonHolder._instance; } protected ThreadPoolManager() { _effectsScheduledThreadPool = new ScheduledThreadPoolExecutor(Config.THREAD_P_EFFECTS, new PriorityThreadFactory("EffectsSTPool", Thread.NORM_PRIORITY)); _generalScheduledThreadPool = new ScheduledThreadPoolExecutor(Config.THREAD_P_GENERAL, new PriorityThreadFactory("GeneralSTPool", Thread.NORM_PRIORITY)); _ioPacketsThreadPool = new ThreadPoolExecutor(Config.IO_PACKET_THREAD_CORE_SIZE, Integer.MAX_VALUE, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new PriorityThreadFactory("I/O Packet Pool", Thread.NORM_PRIORITY + 1)); _generalPacketsThreadPool = new ThreadPoolExecutor(Config.GENERAL_PACKET_THREAD_CORE_SIZE, Config.GENERAL_PACKET_THREAD_CORE_SIZE + 2, 15L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new PriorityThreadFactory("Normal Packet Pool", Thread.NORM_PRIORITY + 1)); _generalThreadPool = new ThreadPoolExecutor(Config.GENERAL_THREAD_CORE_SIZE, Config.GENERAL_THREAD_CORE_SIZE + 2, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new PriorityThreadFactory("General Pool", Thread.NORM_PRIORITY)); _aiScheduledThreadPool = new ScheduledThreadPoolExecutor(Config.AI_MAX_THREAD, new PriorityThreadFactory("AISTPool", Thread.NORM_PRIORITY)); scheduleGeneralAtFixedRate(new PurgeTask(), 10 * 60 * 1000l, 5 * 60 * 1000l); } public static long validateDelay(long delay) { if (delay < 0) { delay = 0; } else if (delay > MAX_DELAY) { delay = MAX_DELAY; } return delay; } public ScheduledFuture<?> scheduleEffect(Runnable r, long delay) { try { delay = ThreadPoolManager.validateDelay(delay); return _effectsScheduledThreadPool.schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS); } catch (RejectedExecutionException e) { return null; } } public ScheduledFuture<?> scheduleEffectAtFixedRate(Runnable r, long initial, long delay) { try { delay = ThreadPoolManager.validateDelay(delay); initial = ThreadPoolManager.validateDelay(initial); return _effectsScheduledThreadPool.scheduleAtFixedRate(new RunnableWrapper(r), initial, delay, TimeUnit.MILLISECONDS); } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ } } @Deprecated public boolean removeEffect(RunnableScheduledFuture<?> r) { return _effectsScheduledThreadPool.remove(r); } public ScheduledFuture<?> scheduleGeneral(Runnable r, long delay) { try { delay = ThreadPoolManager.validateDelay(delay); return _generalScheduledThreadPool.schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS); } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ } } public ScheduledFuture<?> scheduleGeneralAtFixedRate(Runnable r, long initial, long delay) { try { delay = ThreadPoolManager.validateDelay(delay); initial = ThreadPoolManager.validateDelay(initial); return _generalScheduledThreadPool.scheduleAtFixedRate(new RunnableWrapper(r), initial, delay, TimeUnit.MILLISECONDS); } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ } } @Deprecated public boolean removeGeneral(RunnableScheduledFuture<?> r) { return _generalScheduledThreadPool.remove(r); } public ScheduledFuture<?> scheduleAi(Runnable r, long delay) { try { delay = ThreadPoolManager.validateDelay(delay); return _aiScheduledThreadPool.schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS); } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ } } public ScheduledFuture<?> scheduleAiAtFixedRate(Runnable r, long initial, long delay) { try { delay = ThreadPoolManager.validateDelay(delay); initial = ThreadPoolManager.validateDelay(initial); return _aiScheduledThreadPool.scheduleAtFixedRate(new RunnableWrapper(r), initial, delay, TimeUnit.MILLISECONDS); } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ } } public void executePacket(Runnable pkt) { _generalPacketsThreadPool.execute(pkt); } public void executeCommunityPacket(Runnable r) { _generalPacketsThreadPool.execute(r); } public void executeIOPacket(Runnable pkt) { _ioPacketsThreadPool.execute(pkt); } public void executeTask(Runnable r) { _generalThreadPool.execute(r); } public void executeAi(Runnable r) { _aiScheduledThreadPool.execute(new RunnableWrapper(r)); } private static class PriorityThreadFactory implements ThreadFactory { private final int _prio; private final String _name; private final AtomicInteger _threadNumber = new AtomicInteger(1); private final ThreadGroup _group; public PriorityThreadFactory(String name, int prio) { _prio = prio; _name = name; _group = new ThreadGroup(_name); } @Override public Thread newThread(Runnable r) { Thread t = new Thread(_group, r); t.setName(_name + "-" + _threadNumber.getAndIncrement()); t.setPriority(_prio); return t; } public ThreadGroup getGroup() { return _group; } } public void shutdown() { _shutdown = true; _effectsScheduledThreadPool.shutdown(); _generalScheduledThreadPool.shutdown(); _generalPacketsThreadPool.shutdown(); _ioPacketsThreadPool.shutdown(); _generalThreadPool.shutdown(); _log.info("All ThreadPools are now stopped."); } public boolean isShutdown() { return _shutdown; } public void purge() { _effectsScheduledThreadPool.purge(); _generalScheduledThreadPool.purge(); _aiScheduledThreadPool.purge(); _ioPacketsThreadPool.purge(); _generalPacketsThreadPool.purge(); _generalThreadPool.purge(); } public String getPacketStats() { final StringBuilder sb = new StringBuilder(1000); ThreadFactory tf = _generalPacketsThreadPool.getThreadFactory(); if (tf instanceof PriorityThreadFactory) { PriorityThreadFactory ptf = (PriorityThreadFactory) tf; int count = ptf.getGroup().activeCount(); Thread[] threads = new Thread[count + 2]; ptf.getGroup().enumerate(threads); StringUtil.append(sb, "General Packet Thread Pool:\r\n" + "Tasks in the queue: ", String.valueOf(_generalPacketsThreadPool.getQueue().size()), "\r\n" + "Showing threads stack trace:\r\n" + "There should be ", String.valueOf(count), " Threads\r\n"); for (Thread t : threads) { if (t == null) { continue; } StringUtil.append(sb, t.getName(), "\r\n"); for (StackTraceElement ste : t.getStackTrace()) { StringUtil.append(sb, ste.toString(), "\r\n"); } } } sb.append("Packet Tp stack traces printed.\r\n"); return sb.toString(); } public String getIOPacketStats() { final StringBuilder sb = new StringBuilder(1000); ThreadFactory tf = _ioPacketsThreadPool.getThreadFactory(); if (tf instanceof PriorityThreadFactory) { PriorityThreadFactory ptf = (PriorityThreadFactory) tf; int count = ptf.getGroup().activeCount(); Thread[] threads = new Thread[count + 2]; ptf.getGroup().enumerate(threads); StringUtil.append(sb, "I/O Packet Thread Pool:\r\n" + "Tasks in the queue: ", String.valueOf(_ioPacketsThreadPool.getQueue().size()), "\r\n" + "Showing threads stack trace:\r\n" + "There should be ", String.valueOf(count), " Threads\r\n"); for (Thread t : threads) { if (t == null) { continue; } StringUtil.append(sb, t.getName(), "\r\n"); for (StackTraceElement ste : t.getStackTrace()) { StringUtil.append(sb, ste.toString(), "\r\n"); } } } sb.append("Packet Tp stack traces printed.\r\n"); return sb.toString(); } public String getGeneralStats() { final StringBuilder sb = new StringBuilder(1000); ThreadFactory tf = _generalThreadPool.getThreadFactory(); if (tf instanceof PriorityThreadFactory) { PriorityThreadFactory ptf = (PriorityThreadFactory) tf; int count = ptf.getGroup().activeCount(); Thread[] threads = new Thread[count + 2]; ptf.getGroup().enumerate(threads); StringUtil.append(sb, "General Thread Pool:\r\n" + "Tasks in the queue: ", String.valueOf(_generalThreadPool.getQueue().size()), "\r\n" + "Showing threads stack trace:\r\n" + "There should be ", String.valueOf(count), " Threads\r\n"); for (Thread t : threads) { if (t == null) { continue; } StringUtil.append(sb, t.getName(), "\r\n"); for (StackTraceElement ste : t.getStackTrace()) { StringUtil.append(sb, ste.toString(), "\r\n"); } } } sb.append("Packet Tp stack traces printed.\r\n"); return sb.toString(); } protected class PurgeTask implements Runnable { @Override public void run() { _effectsScheduledThreadPool.purge(); _generalScheduledThreadPool.purge(); _aiScheduledThreadPool.purge(); } } private static class SingletonHolder { protected static final ThreadPoolManager _instance = new ThreadPoolManager(); } } ExclusiveTask: package net.sf.l2j.gameserver.threadmanager; import java.util.concurrent.Future; import net.sf.l2j.gameserver.ThreadPoolManager; /** * @author NB4L1 */ public abstract class ExclusiveTask { private final boolean _returnIfAlreadyRunning; private Future<?> _future; private boolean _isRunning; private Thread _currentThread; protected ExclusiveTask(boolean returnIfAlreadyRunning) { _returnIfAlreadyRunning = returnIfAlreadyRunning; } protected ExclusiveTask() { this(false); } public synchronized boolean isScheduled() { return _future != null; } public synchronized final void cancel() { if (_future != null) { _future.cancel(false); _future = null; } } public synchronized final void schedule(long delay) { cancel(); _future = ThreadPoolManager.getInstance().schedule(_runnable, delay); } public synchronized final void scheduleAtFixedRate(long delay, long period) { cancel(); _future = ThreadPoolManager.getInstance().scheduleAtFixedRate(_runnable, delay, period); } private final Runnable _runnable = new Runnable() { @Override public void run() { if (tryLock()) { try { onElapsed(); } finally { unlock(); } } } }; protected abstract void onElapsed(); private synchronized boolean tryLock() { if (_returnIfAlreadyRunning) return !_isRunning; _currentThread = Thread.currentThread(); for (; { try { notifyAll(); if (_currentThread != Thread.currentThread()) return false; if (!_isRunning) return true; wait(); } catch (InterruptedException e) { } } } private synchronized void unlock() { _isRunning = false; } }
  10. Во-первых, ты на 6 дней меня старше, так что "выкать" я не буду. Во-вторых, я сам пофиксил проблему с расстоянием позаимствовав немного кода с aCis 360 и это не стоит 500 рублей.....
  11. Я тебе выше писал, что за фикс заплачу 200р, но ответа от тебя не получил.. Смысл мне переводить тебе какую-то сумму, о которой мы даже не договаривались и не пойми за что вообще тебе деньги кидать..
  12. Так ты помогаешь зафиксить или форсишь меня идти учить яву? Ты определись уже
  13. Так может ты скажешь откуда я это должен узнать, если не из кода, который я тебе скинул.....
  14. public enum WeaponType implements ItemType { NONE(40), SWORD(40), BLUNT(40), DAGGER(40), BOW(500), POLE(66), ETC(40), FIST(40), DUAL(40), DUALFIST(40), BIGSWORD(40), FISHINGROD(40), BIGBLUNT(40), PET(40);
  15. 1) Да 2) Да, но они прописаны в ядре и в xml файле т.к aCis 3) Без оружие атакует на таком же расстояние, что и с мечем, дагером (смотри скрин в теме) 4) Подбегает на расстояние красной стрелки (смотри скрин)
  16. Умел бы правильно вытаскивать и знал бы что вытаскивать - давно бы починил, потому что сборка на aCis сделана и вытащил бы с оригинального 360 aCis.
  17. Я думаю надо разобраться почему такое происходит. Исходники L2jFatum 30 Rev. L2jFatum разрабатывался на aCis исходниках и имеет проблему с атакой, что странно, потому что я ставил aCis 360 и там с атакой все нормально...
  18. Ну как тебе защита конкурента?
  19. Ищу толкового кодера, который сможет зафиксить баг: http://forummaxi.ru/topic/77710-%D1%80%D0%B0%D1%81%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5-%D0%BC%D0%B5%D0%B6%D0%B4%D1%83-%D0%BF%D0%B5%D1%80%D1%81%D0%BE%D0%BD%D0%B0%D0%B6%D0%B5%D0%BC-%D0%B8-%D0%BC%D0%BE%D0%B1%D0%BE%D0%BC-%D0%BF%D1%80%D0%B8-%D0%B0%D1%82%D0%B0%D0%BA%D0%B5-%D0%BA/ Исходники есть. Пишите мне в личные сообщения на форуме.
  20. Мобов удалось зафиксить, теперь они подходят впритык к персонажу, когда он начинает бить их мечем на большом расстояние: L2AttackableAI.java protected void thinkAttack() добавил след: if (dist > range || !GeoData.getInstance().canSeeTarget(npc, attackTarget)) { if (attackTarget.isMoving()) range -= 30; if (range < 5) range = 5; moveToPawn(attackTarget, range); return; } _accessor.doAttack((L2Character) getTarget()); А вот персонажа самого зафиксить не получается... Помогите За фикс мобов спасибо @Jumper
×
×
  • Создать...