questname обозначение

STALIN

Генералиссимус
VIP
Сообщения
249
Розыгрыши
0
Репутация
354
Реакции
560
Баллы
1 743
подскажите обозначение параметра для выполнения квеста, (необходимо убить к примеру 10 мобов определенных ID нужно в счетчик добавить квеста) или же подскажите для примера какой квест можно взять из готовых корейцами?*
 
Признаки восстания? Он у тебя на скриншоте, если что.

А вообще честно говоря я может ерунду сморожу, но разве аларм требует какой то параметр? Чёто не припомню такого, вроде он просто любой квест прожрёт, где есть каунт чего либо. Но вот тут могу наврать.
 
Реакции: Rolo
я этот квест показал как пример что вот с права есть счетчик итемов, но мне нужно что бы счетчик работал не на итемы а на мобов (сколько мобов осталось убить и убил уже) п датник не принимает дополнительный параметр я так понял нужно уже ковырять сам клиент) то сообветственно того что я неумею)

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

т.е. если к примеру для предметов это будет выглядеть так:
Код:
goal_id={36551;36556}    goal_type={0;0}    goal_num={70;145}

то для мобов надо указывать в goal_id ид моба, но не просто так, а прибавив к нему 1000000, т.е. к примеру так
Код:
goal_id={1022746;1022747}    goal_type={0;0}    goal_num={15;15}
в данном случае тогда будет показывать имена мобов с ид 22746 и 22747

так же в goal_type вместо 0 можно указывать 1 и тогда в goal_id необходимо указывать ид строки из NpcString, как к примеру так
Код:
goal_id={75021}    goal_type={1}    goal_num={1}
в данном случае в качестве пункта покажет строку с ид 75021 из NpcString

разные типы в goal_type можно комбинировать, например
Код:
goal_id={539354;36054}    goal_type={1;0}    goal_num={5;30}

ну а на стороне сервера пакет ExQuestNpcLogList требует доработки только если там не сделана поддержка goal_type равного 1, но это вряд ли.
 
Последнее редактирование:
Если что вот корректный пакет
Java:
package l2p.gameserver.network.s2c;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import l2p.gameserver.model.quest.QuestNpcLogInfo;
import l2p.gameserver.model.quest.QuestState;
import l2p.gameserver.network.components.Opcode;

public class ExQuestNpcLogList extends L2GameServerPacket
{
    private int _questId;
    private List<int[]> _list = Collections.emptyList();

    public ExQuestNpcLogList(QuestState state)
    {
        _questId = state.getQuest().getId();
        List<QuestNpcLogInfo> list = state.getQuest().getNpcLogList(state.getCond());

        if (list == null)
            return;

        _list = new ArrayList<int[]>(list.size());
        list.stream().forEach(info -> _list.add(info.getActionId() == 0 ? info.getNpcInfo(state) : info.getActionInfo(state)));
    }

    @Override
    protected void writeImpl()
    {
        writeEx(Opcode.ExQuestNpcLogList);
        writeD(_questId);
        writeC(_list.size());

        for (int[] info : _list)
        {
            writeD(info[0]); // ид npc с прибавкой к нему 1000000 или ид строки из NpcString
            writeC(info[1]); // тип данных: 0 - имя нпс, 1 - строка из NpcString
            writeD(info[2]); // значение счетчика
        }
    }
}
и используемый класс QuestNpcLogInfo в нем
Java:
package l2p.gameserver.model.quest;

public class QuestNpcLogInfo
{
    private final int[] _npcIds;
    private final int _actionId;
    private final int _add;
    private final int _max;
    private final String _varName;

    public QuestNpcLogInfo(int[] npcIds, int actionId, String varName, int add, int max)
    {
        _npcIds = npcIds;
        _actionId = actionId;
        _varName = varName;
        _add = add;
        _max = max;
    }

    public int[] getNpcIds()
    {
        return _npcIds;
    }

    public int getActionId()
    {
        return _actionId;
    }

    public String getVarName()
    {
        return _varName;
    }

    public int getAdd()
    {
        return _add;
    }

    public int getMax()
    {
        return _max;
    }
    
    public int[] getNpcInfo(QuestState st)
    {
        return new int[] { _npcIds[0] + 1000000, 0, st.getInt(_varName) };
    }
    
    public int[] getActionInfo(QuestState st)
    {
        return new int[] { _actionId, 1, st.getInt(_varName) };
    }
}
 
Реакции: Rolo
Код:
tag_?    quest_id    quest_prog    main_name    prog_name    description    cnt1    items[0-13]    cnt2    num_items[0]    quest_x    quest_y    quest_z    lvl_min    lvl_max    quest_type    entity_name    get_item_in_quest    UNK_1    UNK_2    contact_npc_id    contact_npc_x    contact_npc_y    contact_npc_z    restricions    short_description    cnt3    req_class[0-68]   req_cl    cnt4    req_item[0-4]      clan_pet_quest    req_quest_complete    UNK_3    area_id    UNK_4    cnt5    tab5[0]    cnt6    tab6[0]
вот все мои колонки по квест нейм

Java:
public class ExQuestNpcLogList extends L2GameServerPacket {
    private int _questId;
    private List<int[]> _logList = Collections.emptyList();

    public ExQuestNpcLogList(QuestState state) {
        _questId = state.getQuest().getId();
        int cond = state.getCond();
        List<QuestNpcLogInfo> vars = state.getQuest().getNpcLogList(cond);
        if (vars == null)
            return;

        _logList = new ArrayList<int[]>(vars.size());
        for (QuestNpcLogInfo entry : vars) {
            int[] i = new int[2];
            i[0] = entry.getNpcIds()[0] + 1000000;
            i[1] = state.getInt(entry.getVarName());
            _logList.add(i);
        }
    }

    @Override
    protected void writeImpl() {
        writeEx(0xC5);
        writeD(_questId);
        writeC(_logList.size());
        for (int i = 0; i < _logList.size(); i++) {
            int[] values = _logList.get(i);
            writeD(values[0]);
            writeC(0);      // npc index?
            writeD(values[1]);
        }
    }
}
 
Последнее редактирование:
ну у тебя это вот эти
Код:
cnt1    items[0-13]    cnt2    num_items[0]
непонятно только куда потерялся тип показываемого, видимо по недопониманию его запихали в "items[0-13]", т.е. половина данных идут ид предметов/нпс/строк, а другая половина - тип данных
 
был бы кодером понимал бы про что речь идет
Java:
 vars.add(new QuestNpcLogInfo(killIds, varName, max));
уперлись ошибки сюда, просто про серверную часть как то понятно но про клиент это ппц) примера просто нету квеста))
 
ну мой фрагмент кода из Quest.java, отвечающий за все это
Java:
    private Map<Integer, List<QuestNpcLogInfo>> _npcLogList = Collections.emptyMap();

    public List<QuestNpcLogInfo> getNpcLogList(int cond)
    {
        return _npcLogList.get(cond);
    }

    public void addKillNpcWithLog(int cond, int add, int max, String varName, int... killIds)
    {
        if (killIds.length == 0)
            throw new IllegalArgumentException("Npc list cant be empty!");

        addKillId(killIds);

        if (_npcLogList.isEmpty())
            _npcLogList = new HashMap<Integer, List<QuestNpcLogInfo>>(5);

        List<QuestNpcLogInfo> vars = _npcLogList.get(cond);

        if (vars == null)
            _npcLogList.put(cond, (vars = new ArrayList<QuestNpcLogInfo>(5)));

        vars.add(new QuestNpcLogInfo(killIds, 0, varName, add, max));
    }

    public void addKillNpcWithLog(int cond, int max, String varName, int... killIds)
    {
        addKillNpcWithLog(cond, 1, max, varName, killIds);
    }

    public void addKillNpcWithLog(int cond, int max, int... killIds)
    {
        addKillNpcWithLog(cond, 1, max, VAR_COUNTER, killIds);
    }

    public void addActionWithLog(int cond, int add, int max, String varName, int actionId)
    {
        if (_npcLogList.isEmpty())
            _npcLogList = new HashMap<Integer, List<QuestNpcLogInfo>>(5);

        List<QuestNpcLogInfo> vars = _npcLogList.get(cond);

        if (vars == null)
            _npcLogList.put(cond, (vars = new ArrayList<QuestNpcLogInfo>(5)));

        vars.add(new QuestNpcLogInfo(new int[0], actionId, varName, add, max));
    }

    public void addActionWithLog(int cond, int max, String varName, int actionId)
    {
        addActionWithLog(cond, 1, max, varName, actionId);
    }

    public void addActionWithLog(int cond, int max, int actionId)
    {
        addActionWithLog(cond, max, VAR_COUNTER, actionId);
    }

    public boolean updateKill(NpcInstance npc, QuestState st)
    {
        return updateKill(npc.getId(), st);
    }

    public boolean updateKill(int npcId, QuestState st)
    {
        Player player = st.getPlayer();

        if (player == null)
            return false;

        List<QuestNpcLogInfo> vars = getNpcLogList(st.getCond());

        if (vars == null)
            return false;

        boolean done = true;
        boolean find = false;

        for (QuestNpcLogInfo info : vars)
        {
            int count = st.getInt(info.getVarName());

            if (!find && ArrayUtils.contains(info.getNpcIds(), npcId))
            {
                find = true;

                if (count < info.getMax())
                {
                    count = Math.min(count + info.getAdd(), info.getMax());
                    st.set(info.getVarName(), count);
                    player.sendPacket(new ExQuestNpcLogList(st));
                }
            }

            if (count < info.getMax())
                done = false;
        }

        return done;
    }

    public boolean updateAction(int actionId, QuestState st)
    {
        Player player = st.getPlayer();

        if (player == null)
            return false;

        List<QuestNpcLogInfo> vars = getNpcLogList(st.getCond());

        if (vars == null)
            return false;

        boolean done = true;
        boolean find = false;

        for (QuestNpcLogInfo info : vars)
        {
            int count = st.getInt(info.getVarName());

            if (!find && info.getActionId() == actionId)
            {
                find = true;

                if (count < info.getMax())
                {
                    count = Math.min(count + info.getAdd(), info.getMax());
                    st.set(info.getVarName(), count);
                    player.sendPacket(new ExQuestNpcLogList(st));
                }
            }

            if (count < info.getMax())
                done = false;
        }

        return done;
    }
и пример квеста в котором задействовано и убийство мобов с показом количества и выполнение определенных действий
Java:
package quests;

import org.apache.commons.lang3.ArrayUtils;

import l2p.gameserver.data.holder.QuestRewardHolder;
import l2p.gameserver.enums.Race;
import l2p.gameserver.model.instances.NpcInstance;
import l2p.gameserver.model.quest.Quest;
import l2p.gameserver.model.quest.QuestState;

/**
 * @author Gaikotsu
 * @version 4.4
 */
public class _10417_DaimonTheWhiteEyed extends Quest
{
    private static final int EyeOfArgos = 31683;
    private static final int Janitt = 33851;

    private static final int[] Mobs = { 21294, 21295, 21296, 21297, 21299, 21304, 23311, 23312 };
    private static final int DaimonTheWhiteEyed = 27499;

    private static final int ActionId = 541711;

    public _10417_DaimonTheWhiteEyed()
    {
        super(PARTY_NONE);

        addLevelCheck(70);
        addRaceCheck(Race.HUMAN, Race.ELF, Race.DARK_ELF, Race.ORC, Race.DWARF, Race.KAMAEL);
        addQuestCompletedCheck(_10416_InSearchOfTheEyeOfArgos.class);
        addStartNpc(EyeOfArgos);
        addTalkId(Janitt);
        addKillId(Mobs);
        addActionWithLog(1, 100, VAR_COUNTER_1, ActionId);
        addKillNpcWithLog(2, 1, VAR_COUNTER_2, DaimonTheWhiteEyed);
    }

    @Override
    public String onEvent(String event, QuestState st, NpcInstance npc)
    {
        String htmltext = event;

        if (event.equalsIgnoreCase("31683-04.htm"))
        {
            st.setState(STARTED);
            st.setCond(1);
            st.playSound(SOUND_ACCEPT);
        }
        else if (event.equalsIgnoreCase("31683-08.htm"))
        {
            st.setCond(4);
            st.playSound(SOUND_MIDDLE);
        }
        else if (event.equalsIgnoreCase("33851-02.htm"))
        {
            QuestRewardHolder.getInstance().giveRewards(st);
            st.exitCurrentQuest(false);
        }

        return htmltext;
    }

    @Override
    public String onTalk(NpcInstance npc, QuestState st)
    {
        String htmltext = NO_QUEST;
        int cond = st.getCond();
        int npcId = npc.getId();

        if (npcId == EyeOfArgos)
        {
            if (cond == 0)
            {
                if (!isAvailableFor(st.getPlayer()))
                    return "31683-00.htm";
                else
                    return "31683-01.htm";
            }
            else if (cond == 1)
                return "31683-05.htm";
            else if (cond == 2)
                return "31683-06.htm";
            else if (cond == 3)
                return "31683-07.htm";
        }
        else if (npcId == Janitt)
        {
            if (cond == 4)
                return "33851-01.htm";
        }

        return htmltext;
    }

    @Override
    public String onKill(NpcInstance npc, QuestState st)
    {
        int cond = st.getCond();

        if (cond == 1)
        {
            if (ArrayUtils.contains(Mobs, npc.getId()) && updateAction(ActionId, st))
            {
                st.setCond(2);
                st.playSound(SOUND_MIDDLE);
            }
        }
        else if (cond == 2)
        {
            if (updateKill(npc, st))
            {
                st.setCond(3);
                st.playSound(SOUND_MIDDLE);
            }
        }

        return null;
    }
}
 
Реакции: Rolo
Немного не по теме, но неблагодарное это дело писать квесты... Сидишь выдумываешь идею квеста, придумываешь мифологию, пилишь скрипт, html и датки, пилишь своих мобов иногда даже с уник ai, пилишь npc, потом еще все тестишь, тратишь на все это уйму времени, а по итогу игроки тупо пишут: "ой, можно было бы просто в alt+b итемчик запилить с обменом и все... кто это ценит в 22 году?)
 
вот и кореяки видимо так же подумали и выпилили из игры почти все квесты...
 
Потому что в л2 квесты это кал полный, надо которым никто не думал в реальности. Всё делится на 2 примитивных варианта:
1) Сходи в город к нпц
2) Иди убей %число% мобов и принеси %шкура\клык\коготь%"

Единственные квесты, которые постарались сделать интересно - цепь 7 печатей.
 
ты говоришь о корейских квестах. А я тебе о кастомных, насколько крутой ты бы квест не написал - никто его даже читать не будет.
А будут по дефолту все скипать (ну бывает пару исключений игроков конечно но это редкость в 99% скипают). Смысл пытался донести такой - что никто не будет ценить потерянное время на этот квест, ведь ты один знаешь сколько времени ты на это убил - а остальным по сути пофигу - что итем добывается через обменник или через круто навороченный квест - для игроков это будет едино.
У меня есть как и обычные квесты так и навороченные квесты, и обменники - так вот в большинстве случаев для игрока 0 разницы.
По итогу человек получает только убитое время на процесс создание этого квеста.
 
Реакции: Rolo
Ну так одно из другого - квесты в л2 изначально были скучным калом и никто не будет их воспринимать как нечто большее, чем просто получение чего-то там после их выполнения.

Плюс движок клиента\сервера в принципе не приспособлен к адекватному создания красивых и интересных квестов. А самое главное - это мморпг и никому тут нафиг не нужны красивые и интересные квесты, что корейцы наконец поняли в последних хрониках типа эссенса и убрали всю кашицу, добавив просто контент.

"Интересные квесты" это в принципе немного в другой раздел рпг - синглплеерных. А в этой игре квесты как максимум можно строить на херовом движке, используя ЛОР или окружение, из серии: "на мужика напало 4 гоблина иди помоги ему получишь 200 сосок".
 
Реакции: kick
С квестами таверны еще вроде попытались что-то неплохое сделать в принципе.
Хотя один фиг игроки их тупо побыстрее пробегают ради результата и все.
 
ну не просто так же подарить им это)
Скрытое содержимое могут видеть только пользователи групп(ы): Модератор