Welcome to RUSaCis - эмулятор Interlude

Присоединяйтесь к нам прямо сейчас, чтобы получить доступ ко всем нашим возможностям. После регистрации и входа в систему вы сможете создавать темы, публиковать ответы в существующих темах, давать репутацию пользователям - так же приобрести исходный код. Это также быстро, так чего же вы ждете?

[NEW] Что хотите видеть в сборке?

trucchi

Бродяга
Регистрация
23 Сен 2025
Сообщения
4
Реакции
2
Баллы
3
RaCoin
0
а с клиентом что делать в таком случае? нужны и новые иконки, и описания и предметы. у нас нет унифицированного клиента rusacis, чтоб делать такие штучки, которые требуют помимо серверной, еще и клиентской доработки
Ну если бы на уровне сервера это было сделано, иконки и прочую лабуду можно было бы уже самому добавить ;)
 

but4luk

Бродяга
INTERLUDE
Регистрация
1 Июн 2026
Сообщения
5
Реакции
1
Баллы
1
RaCoin
0
Здравствуйте! Возможно мой вопрос покажется глупым, но можно ли повлиять на поведение мобов? отродясь в МОСе пробежав с пухой мобы атакуют, а как я видел половина стоит, пот\овина накастовывает на себя бафф и стоит, ктото атакует, но только ты от него отбежал он перестал бить... можно это поведение подправить? Хочется видеть "из коробки" адекватное поведение мобов
 

Mi-star

Death Lord Ipos
INTERLUDE
INTERFACE
Регистрация
24 Апр 2022
Сообщения
94
Реакции
41
Баллы
18
RaCoin
500
Здравствуйте! Возможно мой вопрос покажется глупым, но можно ли повлиять на поведение мобов? отродясь в МОСе пробежав с пухой мобы атакуют, а как я видел половина стоит, пот\овина накастовывает на себя бафф и стоит, ктото атакует, но только ты от него отбежал он перестал бить... можно это поведение подправить? Хочется видеть "из коробки" адекватное поведение мобов
не все мобы в МОСе игнорируют игроков без надетой пушки. Там определенный перечень мобов с этим свойством. можете поставить птс ГФ и побегать посмотреть как они там ведут себя. у нас тут аналогичное поведение мобов
 

Cringe

Вассал
INTERLUDE
INTERLUDE
INTERFACE
Регистрация
5 Мар 2025
Сообщения
51
Реакции
7
Баллы
8
RaCoin
65
не все мобы в МОСе игнорируют игроков без надетой пушки. Там определенный перечень мобов с этим свойством. можете поставить птс ГФ и побегать посмотреть как они там ведут себя. у нас тут аналогичное поведение мобов
Он говорил не о том что не все мобы игнорируют если ты без пухи, а о том что что некоторые мобы которые должны агрится на пуху они стоят хотя пуха одета, есть такое, но это только в коде поправить
 

Mi-star

Death Lord Ipos
INTERLUDE
INTERFACE
Регистрация
24 Апр 2022
Сообщения
94
Реакции
41
Баллы
18
RaCoin
500
Он говорил не о том что не все мобы игнорируют если ты без пухи, а о том что что некоторые мобы которые должны агрится на пуху они стоят хотя пуха одета, есть такое, но это только в коде поправить
Странно, вроде это было исправлено больше года назад. В любом случае можно просто багрепорт кинуть в https://rusacis.com/support-tickets/ чтоб более детально получить фидбек
 

Atrein

Вассал
INTERLUDE
INTERFACE
Регистрация
16 Янв 2022
Сообщения
56
Реакции
28
Баллы
18
RaCoin
5
Можно ещё добавить такую логику: если персонаж надел оружие и из-за этого монахи в MoS начали его атаковать, то при снятии оружия они должны сразу прекращать атаку и возвращаться в пассивное состояние.

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

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

Atrein

Вассал
INTERLUDE
INTERFACE
Регистрация
16 Янв 2022
Сообщения
56
Реакции
28
Баллы
18
RaCoin
5
PcInventory.java
+import net.sf.l2j.gameserver.model.itemcontainer.listeners.MonasteryWeaponAggroListener;


addPaperdollListener(ItemPassiveSkillsListener.getInstance());
+ addPaperdollListener(MonasteryWeaponAggroListener.getInstance());


MonasteryWeaponAggroListener.java:
package net.sf.l2j.gameserver.model.itemcontainer.listeners;

import net.sf.l2j.commons.pool.ThreadPool;

import net.sf.l2j.gameserver.enums.Paperdoll;
import net.sf.l2j.gameserver.model.actor.Creature;
import net.sf.l2j.gameserver.model.actor.Npc;
import net.sf.l2j.gameserver.model.actor.Playable;
import net.sf.l2j.gameserver.model.actor.Player;
import net.sf.l2j.gameserver.model.item.instance.ItemInstance;

/**
 * By Atrein:
 */
public class MonasteryWeaponAggroListener implements OnEquipListener
{
    private static final int CHECK_RANGE = 1200;
    private static final long UNEQUIP_CHECK_DELAY = 150L;
    
    @Override
    public void onEquip(Paperdoll slot, ItemInstance item, Playable actor)
    {
        
    }
    
    @Override
    public void onUnequip(Paperdoll slot, ItemInstance item, Playable actor)
    {
        if (slot != Paperdoll.RHAND)
            return;
        
        if (item == null || !item.isWeapon())
            return;
        
        if (!(actor instanceof Player player))
            return;
        
        ThreadPool.schedule(() -> clearMonasteryWeaponAggro(player), UNEQUIP_CHECK_DELAY);
    }
    
    private static void clearMonasteryWeaponAggro(Player player)
    {
        if (player == null || player.isDead())
            return;
        
        if (player.getActiveWeaponInstance() != null)
            return;
        
        for (Npc npc : player.getKnownTypeInRadius(Npc.class, CHECK_RANGE))
            clearMonasteryWeaponAggro(npc, player);
    }
    
    private static void clearMonasteryWeaponAggro(Npc npc, Player player)
    {
        if (npc == null || npc.isDead())
            return;
        
        if (!isMonasteryWeaponAggroNpc(npc.getNpcId()))
            return;
        
        if (wasDamagedByPlayer(npc, player))
            return;
        
        boolean cleaned = false;
        
        if (npc.getTarget() != null && npc.getTarget().getActingPlayer() == player)
        {
            npc.abortAll(true);
            cleaned = true;
        }
        
        if (npc.getAI().getDesires().removeIf(desire -> isRelatedToPlayer(desire.getFinalTarget(), player)))
            cleaned = true;
        
        for (Creature target : npc.getAI().getAggroList().keySet())
        {
            if (isRelatedToPlayer(target, player))
            {
                npc.getAI().getAggroList().stopHate(target);
                cleaned = true;
            }
        }
        
        for (Creature target : npc.getAI().getHateList().keySet())
        {
            if (isRelatedToPlayer(target, player))
            {
                npc.getAI().getHateList().stopHate(target);
                cleaned = true;
            }
        }
        
        if (clearAiTargetReferences(npc, player))
            cleaned = true;
        
        if (cleaned && !hasAttackDesire(npc))
            npc.getAI().setBackToPeace();
    }
    
    private static boolean wasDamagedByPlayer(Npc npc, Player player)
    {
        final Creature lastAttacker = npc.getLastAttacker();
        return lastAttacker != null && lastAttacker.getActingPlayer() == player;
    }
    
    private static boolean isRelatedToPlayer(Creature target, Player player)
    {
        return target != null && target.getActingPlayer() == player;
    }
    

    private static boolean clearAiTargetReferences(Npc npc, Player player)
    {
        boolean cleaned = false;
        
        if (isRelatedToPlayer(npc._c_ai0, player))
        {
            npc._c_ai0 = null;
            cleaned = true;
        }
        
        if (isRelatedToPlayer(npc._c_ai1, player))
        {
            npc._c_ai1 = null;
            cleaned = true;
        }
        
        if (isRelatedToPlayer(npc._c_ai2, player))
        {
            npc._c_ai2 = null;
            cleaned = true;
        }
        
        if (isRelatedToPlayer(npc._c_ai3, player))
        {
            npc._c_ai3 = null;
            cleaned = true;
        }
        
        if (isRelatedToPlayer(npc._c_ai4, player))
        {
            npc._c_ai4 = null;
            cleaned = true;
        }
        
        return cleaned;
    }
    
    private static boolean hasAttackDesire(Npc npc)
    {
        return npc.getAI().getDesires().stream().anyMatch(desire -> desire.getType() == net.sf.l2j.gameserver.enums.IntentionType.ATTACK);
    }
    
    private static boolean isMonasteryWeaponAggroNpc(int npcId)
    {
        return switch (npcId)
        {
            case 22124, // Solina Brother
                22126, // Silent Seeker
                22129  // Warrior Monk
                    -> true;
            
            default -> false;
        };
    }
    
    public static MonasteryWeaponAggroListener getInstance()
    {
        return SingletonHolder.INSTANCE;
    }
    
    private static class SingletonHolder
    {
        protected static final MonasteryWeaponAggroListener INSTANCE = new MonasteryWeaponAggroListener();
    }
}
 

Atrein

Вассал
INTERLUDE
INTERFACE
Регистрация
16 Янв 2022
Сообщения
56
Реакции
28
Баллы
18
RaCoin
5
Сверху Снизу