• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Quest Window

Gubailovo

Well-Known Member
Joined
Dec 19, 2013
Messages
407
Solutions
2
Reaction score
62
help can't understand what the problem is
Скриншот 21-12-2020 214448.jpg

\data\npc\scripts\Farko

Lua:
--::::::::::::::::::::::::::::::::::::::::
--System name: Darkonia RPG
--Short Desc: old-style MMoRPG
--Version: 5.0
--Authors: Torian Kel
--Date: 10 февраля, 2017
--Update: 08 мая, 2018
--Modul Desc: скрипт NPC Farko
--Паладин храма Иваланны
--Обучающий персонаж
--::::::::::::::::::::::::::::::::::::::::

--перенес в библиотеку
--ARC1_START_STORAGE = 5004
--ARC1_QUESTS_COUNT = 6

focus = 0
talk_start = 0

-- тексты
noquest_txt = "Странно, я не помню чтобы давал тебе задание. Или ты просто не принял его."
quest_no_comp_txt = "Потерянный, ты еще не сделал то, о чем я тебя попросил. Приходи когда закончишь задание."

quest_start_texts = {
    [1]="Еще один Потерянный... Ты хоть имя свое помнишь? Да ладно, это сейчас не важно. Первое что нужно сделать - это напомнить тебе как ходить, есть, пить и использовать окружающие вещи. Потому что без этого ты точно не выживешь. \n\nВ столице в изобилии растет черника - вкусная и очень полезная ягода. Собери и принеси мне горсть этой ягоды и я покажу как ее можно использовать. \n\nЦель задания - собрать 20 ягод черники.",
    [2]="Теперь, когда твоей жизни ничего не угрожает, давай найдем что-нибудь, что будет угрожать. Иначе какой из тебя приключенец. Прямо за мной решетка канализации, спускайся и убей пару крыс. 'Какое уникальное задание' - скажешь ты +смеется+, но не на гидру же тебя отправлять на первом задании. \n\nИ не забывай потрошить этих бестий, внутри всегда найдется что-нибудь интересное. К примеру они очень любят воровать и проглатывать золотые, хрен пойми зачем, а деньги тебе сейчас не помешали бы. А мне принеси сыра, его тоже можно найти в луте. Он не такой вкусный как ягоды, но намного питательнее. \n\nЦель задания - собрать 10 кусков сыра.",
    [3]="Если ты и дальше планируешь дышать, то тебе нужно позаботиться о броне получше, чем твои лохмотья. Вот возьми эти деньги и купи себе медную броню у моего друга Herion'а, у него лавка в центре города, налево от депота. Если монет не хватит - ты знаешь где взять еще. \n\nЦель задания - купить у торговца медную броню. ",
    [4]="Прошу, только не говори что таскаешь все свое имущество на себе. +с усмешкой смотрит на битком набитый рюкзак+ Рано или поздно ты, бессмертный, погибнешь и вернешься в этот храм. Но твое тело останется на поле боя, вместе со всем тем что было надето на тебе. А то все твои пожитки. Прими добрый совет - держи все имущество, которое тебе не требуется в данный момент, в своем депоте, а деньги - у банкиров. \n\nИ раз уж ты все равно идешь в ту сторону - купи мне, пожалуйста, у Jadi книгу заклинаний, свою я к сожалению потерял. \n\nЦель задания - купить у торговца книгу заклинаний.",
    [5]="Носился по всему городу и наверное очень проголодался? И не надейся, у меня тут не таверна, еды нет. Но еду можно добыть или купить. С 'купить' ты и сам разберешься, а вот добывать еду я научу. \n\nТеперь иди к любому водоему, да вон хоть к пруду в центре Иваланны, закидывай удочку и жди когда клюнет рыба. В наших озерах много разной водится. И не только рыбы, всегда есть шанс подцепить что-нибудь поинтереснее. Ты удивишься, когда узнаешь что люди в озера выкидывают. \n\nЦель задания - поймать и принести Farko 2 рыбы.",
    [6]="Пора бы тебе уже браться за дело посерьезнее, чем крысы в канализации. Как ты наверное уже знаешь у нашего города есть 'парк'. Охраны там нет, и в него постоянно забредают разные животные и монстры. И каждый день я отправляю туда пару приключенцев, которым нужна практика. Тут и польза, и заработок и в парке некоторое время безопасно. В общем все в выигрыше. \n\nТолько, пожалуйста, не геройствуй, парк опасное место, там встречаются и волки, и троли, и прочие очень приятные создания. Не отходи далеко от ворот, убей нескольких волков и принеси мне пару волчьих зубов. \n\nЦель задания - принести Farko 10 волчьих зубов. ",
    [7]="Знаешь почему тебя называют 'Потерянный'? И вообще почему ты помнишь только то как появился тут в храме, и не помнишь ничего до этого?  \n\nЯ расскажу тебе. Это началось в прошлом году. Неведомые существа атаковали земли некромантов к востоку от земель королевства. Кто-то говорит что это кара богов за надругательство над мертвыми, а кто-то уверен что некросы сами что-то напутали в своих экспериментах. Сейчас правду уже не найти, но главное - некроманты хотят отбить свой замок, и для этого им нужны войска. А где же некромантам их взять как не в Долине Памяти, куда свозят хоронить всех дарконийцев? \n\nНо конечно же долину им просто так никто не отдаст, бои идут уже год, с переменным успехом. Сила королевства в нас, Королевских паладинах. С благословения Ирдиса, мы не даем душам покинуть Предел, и возвращаем их в храмы. Работа тяжелая и паладинов мало, поэтому вернуть получается далеко не всех. А некоторые возвращаются, но слабые и без памяти, совсем потерянные. Таких мы называем Потерянные и стараемся удержать их в этом мире. \n\nТы же, Потерянный, уже почти готов выбрать свой дальнейший путь, осталось дать тебе последнее задание, чтобы убедиться что ты вспомнил хотя бы малую часть того, что знал когда-то. \n\nНедавно до Мастеров дошел слух, что в канализации Иваланны воры из Гильдии Крыс организовали воровской притон. Твоя задача - найти притон и договориться с их Мастером о встрече между ним и Мастером Войнов Хеллкаром. Но будь осторожен, старик очень обидчив и хитер как крыса.  \n\nЦель задания - получить согласие Мастера воров на встречу с Хеллкаром."
}

quest_end_texts = {
    [1]="Долго же тебя не было, уж подумал потерял тебя. Давай сюда ягоды. +бормочет+ Где-то у меня бутылочка завалялась. +выжимает ягоды в бутылку и добавляет какой-то порошок+ Держи, когда-нибудь и ты так сможешь.",
    [2]="Крысы не очень серьезные противники, как раз на один удар дубины. Но золото которое ты из них достаешь - всегда полезная добыча. Кстати о дубине, с твоей палкой только на крыс и ходить. Вот держи, это оружие посерьезнее.",
    [3]="С твоими новыми доспехами отлично будут смотреться медные поножи, выкованные лично мной.",
    [4]="О, вот и долгожданный гонец, с долгожданной книжкой. Где тебя носило, Потерянный?",
    [5]="А вот и ужин. Спасибо, Потерянный. Надо бы тебя чем-нибудь отблагодарить. Подожди, есть у меня тут пара вещей, очень полезных для путешественника, как раз припас для таких случаев.",
    [6]="О, надо же, живой, и волки тебя не сожрали. Видимо скоро ты сможешь браться за серьезные задания и мне не придется каждый раз поднимать тебя в этом храме."
}

reward_texts = {
    [1]="100 опыта\n100 золотых монет\nЗелье жизни",
    [2]="120 опыта\n120 золотых монет\nМеч",
    [3]="200 опыта\n200 золотых монет\nМедные поножи",
    [4]="250 опыта\n250 золотых монет\nAмулет потери",
    [5]="300 опыта\n300 золотых монет\nРюкзак Потерянного\nЛопата для поиска сокровищ\nФакел\nВеревка",
    [6]="400 опыта\n400 золотых монет\nКольцо меча\nКольцо Лечения",
    [7]="1000 опыта\n1200 золотых монет\nЩит Потерянного\nЖелезный шлем\nЖелезные ботинки"
}

function questComplite(cid, curr_quest)
    if curr_quest==1 then
        return doPlayerRemoveItem(cid, 2677, 20) --квест 1, 20 черники
    elseif curr_quest==2 then
        return doPlayerRemoveItem(cid, 2696, 10) --квест 2, 10 кусков сыра
    elseif curr_quest==3 then
        return getPlayerItem(cid, 2465) --проверяем есть ли у игрока медная броня
    elseif curr_quest==4 then
        return doPlayerRemoveItem(cid, 2175, 1) --книга заклинаний
    elseif curr_quest==5 then
        return doPlayerRemoveItem(cid, 2667, 2) --2 рыбы
    elseif curr_quest==6 then
        return doPlayerRemoveItem(cid, 5897, 10) -- 10 волчьих зубов
    else
        return 0
    end
end

--doPlayerAddItem(cid, pay, 1)
function sendReward(cid, curr_quest)
    if curr_quest==1 then
        addMoney(cid, 100)
        addPlayerExp(cid, 100)
        addItem(cid, 8373, 1) -- Зелье жизни
    elseif curr_quest==2 then
        addMoney(cid, 120)
        addPlayerExp(cid, 120)
        addItem(cid, 2376, 1) -- меч
    elseif curr_quest==3 then
        addMoney(cid, 200)
        addPlayerExp(cid, 200)
        addItem(cid, 2478, 1) -- медные поножи
    elseif curr_quest==4 then
        addMoney(cid, 250)
        addPlayerExp(cid, 250)
        addItem(cid, 2173, 1) -- амулет потери
    elseif curr_quest==5 then
        addMoney(cid, 300)
        addPlayerExp(cid, 300)
        addItem(cid, 2120, 1) -- веревка
        addItem(cid, 2050, 1) -- факел
        addItem(cid, 7222, 1) -- лопата для поиска сокровищ
        addItem(cid, 8383, 1) -- рюкзак Потерянного
    elseif curr_quest==6 then
        addMoney(cid, 400)
        addPlayerExp(cid, 400)
        addItem(cid, 2207, 1) -- кольцо меча
        addItem(cid, 2214, 1) -- колько лечения
    else
        return 0
    end
    
    return 1
end

function onThingMove(creature, thing, oldpos, oldstackpos)
end

function onCreatureAppear(creature)
    --selfSay('Я приветствую тебя, ' .. creatureGetName(creature) .. ' в мире Darkonia! Поговори со мной и я помогу тебе освоиться в этом мире.')
end

function onCreatureDisappear(cid, pos)
    if focus == cid then
        selfSay('До свидания, ' .. creatureGetName(focus) .. '!')
        focus = 0
        talk_start = 0
    end
end

function onCreatureTurn(creature)

end

function onCreatureSay(cid, type, msg)
    msg = string.lower(msg)
    cname = creatureGetName(cid)
    
    dist = getDistanceToCreature(cid)
    
    if dist >= 3 then
        return
    end

    ---------------------------------- POWITANIE RU --------------------------------------------
    if string.find(msg, '(%a*)привет(%a*)') and string.len(msg) == 6 then
        if focus == cid then
            selfSay('Я уже говорю с тобой!')
        else
            if focus > 0 then
                selfSay('' .. cname .. ', подожди своей очереди!')
            end
        end
        
        if(focus == 0) then
            selfSay('Привет, ' .. cname .. '! [квест] [сдать] [лечение]')
            focus = cid
        end
        
        talk_start = os.clock()
    end

    ---------------------------------- POWITANIE ENG--------------------------------------------
    if string.find(msg, '(%a*)hi(%a*)') and string.len(msg) == 2 then
        if focus == cid then
            selfSay('Im already talking to you!')
        else
            if focus > 0 then
                selfSay('' .. cname .. ', wait for your turn!')
            end
        end
        
        if(focus == 0) then
            selfSay('Hi, ' .. cname .. '!')
            focus = cid
        end
        
        talk_start = os.clock()
    end

    --------------------------------- POZEGNANIA ---------------------------------------
    if string.find(msg, '(%a*)пока(%a*)') and cid == focus then
        selfSay('До свидания, ' .. cname .. '! ')
        focus = 0
        talk_start = 0
        talkcount = 0
    end

    if string.find(msg, '(%a*)bye(%a*)') and cid == focus then
        selfSay('Farewell, ' .. cname .. '!')
        focus = 0
        talk_start = 0
        talkcount = 0
    end

    --------------------------  ВЫБОР ДЕЙСТВИЯ -----------------------------------
    if string.find(msg, '(%a*)леч(%a*)') and cid == focus then
        selfSay('Используй целебные фонтаны этой часовни, чтобы исцелиться.')
        talk_start = os.clock()
    end
    
    if (string.find(msg, '(%a*)квес(%a*)') or string.find(msg, '(%a*)задан(%a*)')) and cid == focus then
        -- Идея: преобразовывать нажатия кнопок в сообщения в чат от имени игрока
        -- Тогда можно и дописать "окно диалога" в котором команды подобные [квест] [лечение] преобразовывать в кнопки
        
        -- Квест контроль будет проверять выполнение квеста и при его выполнении - отправлять игрока к NPC
    
        -- Здесь выдача квестов только первой арки, что упрощает дело
        -- сначала надо узнать номер текущего квеста
        -- не реагироветь если арка завершена (или реагировать в стиле "я же отправил тебя к ....")
        -- проверять завершен ли квест и выдавать следующий
        curr_quest = getCurrentQuest(cid, QUEST_ARC1_CURRENT)
        
        q_status = getQuestStatus(cid, ARC1_START_STORAGE, curr_quest)
        
        if q_status == QUEST_ENDED and curr_quest < ARC1_QUESTS_COUNT then
            -- запускаем следующий квест
            new_quest = curr_quest+1
            
            setCurrentQuest(cid, QUEST_ARC1_CURRENT, new_quest)
            showQuestWindow(cid, quest_start_texts[new_quest], reward_texts[new_quest], "npc_farko", QUEST_WINDOW_BTN_AC)
            selfSay(quest_start_texts[new_quest])
        elseif q_status == QUEST_STARTED then
            -- повторяем описание квеста
            showQuestWindow(cid, quest_start_texts[curr_quest], reward_texts[curr_quest], "npc_farko", QUEST_WINDOW_BTN_C)
            selfSay(quest_start_texts[curr_quest])
        elseif curr_quest > 0 then
            -- ситуация когда номер квеста есть, но его статус не определен
            -- возникает, например, при выдаче первого квеста, когда квест контроль дал подсказку по следующей квестовой арке
            -- или если игрок просмотрел задание квеста, но не взял его
            showQuestWindow(cid, quest_start_texts[curr_quest], reward_texts[curr_quest], "npc_farko", QUEST_WINDOW_BTN_AC)
            selfSay(quest_start_texts[curr_quest])
        end
        
        
        --selfSay('Выдача квеста.')
        
        talk_start = os.clock()
    end

    --Игрок принимает текущий квест
    if string.find(msg, '(%a*)accept(%a*)') and cid == focus then
        -- при согласии
        -- При этом квестовое окно закрывается
        -- Не плохо бы на этом моменте закидывать принятый квест в панельку контроля квестов
        curr_quest = getCurrentQuest(cid, QUEST_ARC1_CURRENT)
        setQuestStatus(cid, ARC1_START_STORAGE, curr_quest, QUEST_STARTED)
        
        -- здесь выдаем "предметы для выполнения квеста"
        if curr_quest == 3 then
            addMoney(cid, 400)
        end
        
        if curr_quest == 5 then
            addItem(cid, 2580, 1) -- удочка
            addItem(cid, 3976, 100) -- черви
        end
        
        talk_start = os.clock()
    end
    
    --игрок не принял квест, квест окно закрывается
    if string.find(msg, '(%a*)close(%a*)') and cid == focus then
        talk_start = os.clock()
    end

    if string.find(msg, '(%a*)сдать(%a*)') and cid == focus then
        --так как награды за квест и цели квестов разные, то проще и разумнее всего проверять и выдавать по id квеста
        curr_quest = getCurrentQuest(cid, QUEST_ARC1_CURRENT)
        q_status = getQuestStatus(cid, ARC1_START_STORAGE, curr_quest)
        
        if q_status == QUEST_STARTED then
            -- определяем выполнены ли условия квеста
            if questComplite(focus, curr_quest) == 1 then
                showQuestWindow(cid, quest_end_texts[curr_quest] .. " ", reward_texts[curr_quest] .. " ", "npc_farko", QUEST_WINDOW_BTN_C)
                selfSay(quest_end_texts[curr_quest])
            
                sendReward(focus, curr_quest)
                setQuestStatus(cid, ARC1_START_STORAGE, curr_quest, QUEST_ENDED)
            else
                selfSay(quest_no_comp_txt)
            end
        else
            -- квеста нет или он не начат
            -- showQuestWindow(noquest_txt, "", "npc_farko", QUEST_WINDOW_BTN_C)
            selfSay(noquest_txt)
        end
        
        talk_start = os.clock()
    end

end

function onCreatureChangeOutfit(creature)

end

function onThink()
    if (os.clock() - talk_start) > 30 then
        if focus > 0 then
            selfSay('До свидания, ' .. creatureGetName(focus) .. '!')
        end

        focus = 0
        talk_start = 0
    end
    
    if focus > 0 then
        dist = getDistanceToCreature(focus)
        if dist >= 6 then
            selfSay('До свидания, ' .. creatureGetName(focus) .. '!')
            focus = 0
            talk_start = 0
        end
    end
end

From the client side ( questwindow )

Lua:
QuestWindow = {}

local protocol = runinsandbox('questprotocol')

questWindow       = nil
questButton       = nil
questList         = nil
questTextLabel    = nil
questPrizeLabel   = nil
buttonQuestAccept = nil
buttonQuestCancel = nil
questImage        = nil

function online()
 
end

function offline()
  resetWindow()
end

function init()
  connect(g_game, { onGameStart = online,
                    onGameEnd   = offline })

  questWindow = g_ui.displayUI('questwindow', modules.game_interface.getRightPanel())
  questWindow:hide()
 
  --questButton = modules.client_topmenu.addRightGameToggleButton('questButton', tr('Darkonia quest'), '/images/topbuttons/guidebook', toggle)
  --questButton:setOn(false)
 
  questList = questWindow:getChildById('questList')
  questTextLabel = questList:getChildById('questTextLabel')
  questPrizeLabel = questList:getChildById('questPrizeLabel')
  buttonQuestAccept = questWindow:getChildById('buttonQuestAccept')
  buttonQuestCancel = questWindow:getChildById('buttonQuestCancel')
  questImage = questWindow:getChildById('questImage')
 
  g_keyboard.bindKeyPress('Down', function() guideList:focusNextChild(KeyboardFocusReason) end, questWindow)
  g_keyboard.bindKeyPress('Up', function() guideList:focusPreviousChild(KeyboardFocusReason) end, questWindow)
 
  --initializeGuidelist()
  protocol.initProtocol()
end

function terminate()
  protocol.terminateProtocol()
 
  questWindow:destroy()
  --treasureButton:destroy()
end

function accept_qw()
  modules.game_console.sendMessage("[accept]")
  questWindow:hide()
  questTextLabel:setText(" ")
  questPrizeLabel:setText(" ")
 
  buttonQuestAccept:show()
  buttonQuestCancel:show()
end

function close_qw()
  modules.game_console.sendMessage("[close]")
  questWindow:hide()
  questTextLabel:setText(" ")
  questPrizeLabel:setText(" ")
 
  buttonQuestAccept:show()
  buttonQuestCancel:show()
end

function resetWindow()
  questWindow:hide()
end

-- protocol callback functions
function QuestWindow.onQuestWindow(text, prizestr, imgname, btnsver)
  questTextLabel:setText(text .. "\n\n")
 
  if prizestr ~= "" then
    questPrizeLabel:setText(tr("Your reward") .. ":\n\n" .. prizestr)
  end
 
  questImage:setImageSource('/images/questwindow/' .. imgname .. '')
 
  if btnsver == 1 then
    buttonQuestAccept:hide()
  end
 
  if btnsver == 3 then
    buttonQuestCancel:hide()
  end
 
  questWindow:show()
  questWindow:raise()
  questWindow:focus()
end

when talking to the NPC for a word (quest or task), the dialog box does not open
if I find otclientv8-master I'll add a log from the console
 
Back
Top