Помощь - Поиск - Пользователи - Календарь
Полная версия: Вопросы новичков
Город Мастеров > РЕДАКТОРЫ > Neverwinter Nights Aurora Toolset
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103
Batkom
чтобы проверить весь список игроков можно сделать так:

Neverwinter Script Source
void main()
{
object oPC = GetFirstPC();
while (GetIsObjectValid(oPC) == TRUE)
{
/*

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

*/

oPC = GetNextPC();
}
}


Этот код хорошо вставлять в скрипт OnHeartbreath ибо он будет выполняться каждый ход, я так например реализовывал эффекты от выпивки, скрипты божеств(если рандом один из ста ляжет бог игрока может реснуть его, прибавить силы или сделать что нибудь другое полезное, эффекты различаются в отличие от выбраного божества), субрассы(например вампиры, которым днем если они не находятся в пещере или другом темном месте занижаются характеристики и наносится урон)
Сначала я думал будут лаги от кучи скриптов выполняемых каждый ход, но потомкак выяснилось все замечательно работает.


Вот еще вопрос, допустим у меня стоит нипись, которому можно дать денег на сохранность, игрок пишет сумму в чате, у него забирается голд и записывается в базу данных с помощью SetCampaignInt привязанок имени чара и сидикеям.
Проблема в том, что я не могу узнать что же такое написал игрок...просто не знаю как...
GoingPro)
Помогите пожалуйсто разобраться в диологах.
Я хотел зделать так что бы НПС поговорив с игроком, дает ему задание, а после следующих кликов на НПС он говорит мол "иди выполни задание потом поговорим"...Ты идешь к следующему НПС и он начинает с тобой говорить только после того как ты поговрил с тем что дал задание, а иначе говорит например "отстань я занят", потом ты возвращаешься обратно к первому после выполнения задания и он тебя благодарит и дает вознаграждение, как это зделать? помогите пожалуйста.
Я делал через проверку на шмотку, но это очень примитивно когда НПС все время дает вещь....
Плиз помогите this.gif
Dik Morris
А зачем через проверку, на шмотку? yes.gif Ты делай на проверку через локальные переменные.
-fenix-
GoingPro), прочитай монуал Айвана в файлах, составишь представление.
А на перввое время делай квесты через визорд - там все просто, разберешься.
В русской версии Волшебницы -> мастер сюжета.
Zirrex
GoingPro), скрипт смерти с трупом, сумочкой с вещами и деньгами, посмотри в модуле HCR. Конечно, в нем скрипт написан очень бездарно, но хоть какое-то представление о создании подобной смерти ты получишь.

Чтобы НПС говорил разные фразы до завершения квеста, необходимо в момент передачи квестовой вещи изменять переменные. Какие? Да любые, какие только могут придти на ум. Тут фантазия безгранична, одно условие, они не должны повторяться, иначе будет каша. И самое главное, не забывать их удалять, когда они более не нужны. Хотя в одиночной игре они не удаляются, а переходят в завершенный вариант, т.е. переключаются на те числа, которые уже не смогут дать первоначальный вариант диалога.

И еще, крайне советую анализировать существующие скрипты. Они могут здорово помочь в написании своих скриптов. Язык не сложный, к тому же созданы довольно понятные функции. Знай, создавай свои миры.

Batkom, чем меньше на Хертбите скриптов, тем лучше. Когда нет лагов с одним игроком, могут быть проблемы с большим количеством игроков. Поэтому скрипты, которые срабатывают в определенной момент, например при смерти, должны находиться только там.

Так ты заставь НПС слушать. Он услышит написанную цифру и преобразует ее в слова. А вообще банки на словах не самая лучшая вещь. Посмотри на Ваулте разные варианты банков, может быть один из них да приглянется.
Aiwan
QUOTE (Zirrex @ Jul 5 2005, 01:28)
Хотя в одиночной игре они не удаляются, а переходят в завершенный вариант, т.е. переключаются на те числа, которые уже не смогут дать первоначальный вариант диалога.

Neverwinter Script Source
void DeleteLocalInt(object oObject, string sVarName)

Все удаляется. И вообще. Обычно проверка на 0 (ноль) есть понятие того, что локалки нет. Можно локалку удалить так как внизу.
Neverwinter Script Source
SetLocalInt(OBJECT_SELF, "MESSAGE", FALSE);
Batkom
У меня он лайн мод, в принципе пока не лагает, хотя игроков не очень много, гдето около 20-25 одновременно

я функцию нужную найти не могу и систему выслушивания немного недопонимаю

если установка слушающего нипися пишется как SetListening(OBJECT_SELF, TRUE);
то как же узнать что же такое он наслушал? ну я понимаю типа string sFarse = а что дальше понятия не имею, я лексикон листал, чтот не понял ибо мои познания в английском невелики
из гетлистена я нашел GetListenPatternNumber(), но я так и не понял как это работает


а слушанье может понадобитьсяне только для банков, но допустим для реализации налогов на деревни(глава гильдии, если ему подчиняется деревня может установить налог, который собирается каждый игровой месяц) или для более эффективной торговли(игрок отдает ниписю вещь, устанавливает на нее цену а потом приходит и проверяет, купил ли ее кто другой из игроков)
dumbo
Batkom
поползай по форуму, пользуй поиск - много интересного узнаешь и большинство вопросов отпадут сами собой... wink.gif

пример "слушания" - http://www.wrg.ru/forums/index.php?showtop...st=0&#entry6707
Batkom
сенк пойду делать
Zirrex
Aiwan, я несколько не это подразумевал, что они не удаляются. Дело в том, что если их удалять, то в момент диалога может выполниться снова уже один раз прозвучавший диалог, который проверяется у этой переменной на ноль. Лучше уж эту переменную приравнять 2, и проверить на 2 вторую ветку диалога, чем создавать еще одну переменную, при проверке которой не будет выполняться первая ветвь диалога.

Aiwan
Zirrex любая переменная проверенная на ноль выдасть TRUE, это движковое. Так что учи матчасть, прежде чем что-то утверждать.
Добавлено в [mergetime]1120622736[/mergetime]
Что бы проверить истинно существующую локалку. То просто проверяется на TRUE. Если она существует, то будет результат. И не важно, 1 или 20 она ровна.
Добавлено в [mergetime]1120623210[/mergetime]
Расскажи лучше чем занят? wink.gif
Zirrex
Aiwan, да, что-то немного ступил, и правда, изначально она равна 0, далее ее просто можно таким образом удалить, и меньше скриптов.

з.ы. На данный момент занимаюсь проектом Амен. Не знаю, слышал ли про такой онлайновый шард или нет. Существует уже 2,5 года.
GoingPro)
Помогите а что тут за ошибка ? плиз
CODE
void main()
{

object GetPlayerSpirit(object oPlayer);

object GetPlayerSpirit(object oPlayer)
{
object oItem = GetFirstItemInInventory(oPlayer);

if (GetResRef(oItem) == "spirit")
 return oItem;

while(oItem != OBJECT_INVALID)
 {
 oItem = GetNextItemInInventory(oPlayer);

 if (GetResRef(oItem) == "spirit")
   return oItem;
 }
return OBJECT_INVALID;
}
}


кричит на object GetPlayerSpirit(object oPlayer); первый который smile.gif
dumbo
GoingPro)
синтаксис NWN-script заимствован из C, а в нем, в отличие от Pascal'я, не допускаются вложенные описания процедур. да и вообще, каша какая-то...
Neverwinter Script Source
// опережающее объявление функции - применяется в случае,
// когда вызов функции идет в скрипте выше, чем ее описание (она сама)
object GetPlayerSpirit(object oPlayer);
// также применяется для удобства - если в начале скрипта
// сделать опережающие объявления всех содержащихся в скрипте функций,
// то можно не заботиться об порядке их описания.
// в данном случае оно не нужно - достаточно перенести описание функции
// в начало скрипта - до main()...

void main()
{
  object oPC = GetLastUsedBy(); // например
  object oSpirit = GetPlayerSpirit(oPC);
  // ...
}

// сама функция
object GetPlayerSpirit(object oPlayer)
{
  object oItem = GetFirstItemInInventory(oPlayer);
  while(GetIsObjectValid(oItem))
  {
    if (GetResRef(oItem) == "spirit")
      return oItem;
    oItem = GetNextItemInInventory(oPlayer);
  }
  return OBJECT_INVALID;
}
Zirrex
GoingPro), как я понял, ты решил сделать сохранение персонажей на локации после рестарта? Не делай так, как описано это в базе скриптов, т.е. не кидай скрипт сохранения локации персонажа на каждую локацию в эвент "OnEnter". Лучше повесь его на скрипт "default". Скрипт срабатывает каждый раунд, и постоянно перезаписывает координаты персонажа, в отличие от того, что установлен на "OnEnter". Какого-либо падения скорости это не вызовет. Единственное но, при входе на шард, скрипт чтения переменных и координат надо разместить на скрипт "OnClientEnter", и запретить работу скрипта "default" в стартовой локации, иначе сохранит координаты.

Да, и чтобы не было подобных казусов, который произошел у тебя, знакомься с чужими скриптами, смотри как они написаны и что следует писать в разных случаях. Потом научишься быстро делать свои скрипты. И не лишним будем знакомство с основами С++. Только, главное, не копировать чужие ошибки smile.gif
Aiwan
QUOTE (Zirrex @ Jul 7 2005, 00:08)
Aiwan, да, что-то немного ступил, и правда, изначально она равна 0, далее ее просто можно таким образом удалить, и меньше скриптов.

Да, забудь friends.gif Я там сам стальными яйцами погремел biggrin.gif
QUOTE (Zirrex @ Jul 7 2005, 00:08)
На данный момент занимаюсь проектом Амен. Не знаю, слышал ли про такой онлайновый шард или нет. Существует уже 2,5 года.

Слышал конечно. Ну, вливайся к нам на форум! wink.gif
Batkom
Я столкнулся с проблемой баланса.
Дело в том, что сорки и визарды в раскачанов состоянии являются грубо говоря читерскими классами ибо файтер против мага в пвп мало что может сделать(сжимающая бигби + исаак, если у файтера нет мегашмоток он труп).
Я уже и трусинг убрал и на исааки проверку на спасброски по реакции повесил и бигби по времениурезал, все равно сорки сильнее и даже самых крутых мобов не обладающих спелл имуном кладут только в путь, а обкаст делает ихнеуязвимыми в ближних атаках.
И тут родилась идея, а что если сорки и визарды будут получать 25% от опыта назначеного в настройках модуля, я слышал где-то это уже было реализовано, вот толлько как?
Если придется редактировать 2da дайте пожалуйста ссылочку на то, как это делать.




И вот еще вопрос:
скрипт отдыха я взял стандартный и поправил, добавив необходимость в еде и матрасе, но он почему то циклится, яубрал эту неприятность довольно примитивно заставив игрока самолично подбирать матрас, но тут появилась необходимость накладывать эффект сна в конце отдыха, чтобы персонаж во первых спал дольше, во вторых была возможность его убить одним удачным ударом.

Как это лучше сделать?
вот скрипт
Neverwinter Script Source
#include "nw_i0_generic"
#include "x2_inc_restsys"
#include "x2_inc_switches"
#include "nw_i0_plot"


void main()
{
    object oBedroll;
    object oPC = GetLastPCRested();

    if (!HasItem(oPC, "food"))
              {
            AssignCommand(oPC, ClearAllActions());
            SendMessageToPC(oPC, "Вы не можете отдыхать на пустой желудок.");
                    }
                    else if (!HasItem(oPC, "bedrollitem"))
                    {
                    SendMessageToPC(oPC, "Вы не можете отдыхать без спальника.");
                    AssignCommand(oPC, ClearAllActions());
                    }
                    else
                    {
                object food =  GetItemPossessedBy(oPC ,"food");
                DestroyObject(food);
                object ibedroll =  GetItemPossessedBy(oPC ,"bedrollitem");
                DestroyObject(ibedroll);
                object item = GetItemPossessedBy(oPC, "deathtocken");//это токен означающий смерть игрока, в последствии я вставил изьятие итема при рессуректе и райздеде, но если лечить дмской силой, она спеллом не считается, потому надо отдохнуть, чтобы при перезаходе не умереть, позже я научился работать с базами данных, но проверку смерти по предмету все же решил оставить
                DestroyObject(item);
                oBedroll =  CreateObject(OBJECT_TYPE_PLACEABLE, "blueprint005", GetLocation(oPC));

    if (GetModuleSwitchValue(MODULE_SWITCH_USE_XP2_RESTSYSTEM) == TRUE)
    {

        /*  Georg, August 11, 2003
            Added this code to allow the designer to specify a variable on the module
            Instead of using a OnAreaEnter script. Nice new toolset feature!
            Basically, the first time a player rests, the area is scanned for the
            encounter table string and will set it up.
        */

        object oArea = GetArea (oPC);

        string sTable = GetLocalString(oArea,"X2_WM_ENCOUNTERTABLE") ;
        if (sTable != "" )
        {
            int nDoors = GetLocalInt(oArea,"X2_WM_AREA_USEDOORS");
            int nDC = GetLocalInt(oArea,"X2_WM_AREA_LISTENCHECK");
            WMSetAreaTable(oArea,sTable,nDoors,nDC);

            //remove string to indicate we are set up
            DeleteLocalString(oArea,"X2_WM_ENCOUNTERTABLE");
        }


        /* Brent, July 2 2003
          - If you rest and are a low level character at the beginning of the module.
            You will trigger the first dream cutscene
        */

        if (GetLocalInt(GetModule(), "X2_G_LOWLEVELSTART") == 10)
        {
            AssignCommand(oPC, ClearAllActions());
            if (GetHitDice(oPC) >= 12)
            {
                ExecuteScript("bk_sleep", oPC);


                return;
            }
            else
            {
                FloatingTextStrRefOnCreature(84141 , oPC);
                return;
            }
        }

        if (GetLastRestEventType()==REST_EVENTTYPE_REST_STARTED)
        {

            if (!WMStartPlayerRest(oPC))
            {
                // The resting system has objections against resting here and now
                // Probably because there is an ambush already in progress
                FloatingTextStrRefOnCreature(84142  ,oPC);
                AssignCommand(oPC,ClearAllActions());
            }
            if (WMCheckForWanderingMonster(oPC))
            {
                //This script MUST be run or the player won't be able to rest again ...
                ExecuteScript("x2_restsys_ambus",oPC);

            }
        }
        else if (GetLastRestEventType()==REST_EVENTTYPE_REST_CANCELLED)
        {

        // No longer used but left in for the community
        // WMFinishPlayerRest(oPC,TRUE); // removes sleep effect, etc
        }
        else if (GetLastRestEventType()==REST_EVENTTYPE_REST_FINISHED)
        {


        // No longer used but left in for the community
        //  WMFinishPlayerRest(oPC); // removes sleep effect, etc
        }
    }

}
}


Честно говоря я не понял назначения большинства функций, потому решил просто доплнить.
dumbo
Batkom
1. не видел пока шардов с оставленной по умолчанию системой выдачи опыта. везде применяется самостоятельная система выдачи опыта - при смерти кричи оценивается уровень оной, уровень игрока, количество народа в партии(соотношение уровней игроков в партии), количество нанесенного урона итд итп, и на основе всего этого игроку выдается опыт. ноги растут из nw_c2_default7(смерть кричи), nw_c2_default6(урон).
2. скрипт отдыха вызывается не только в начале оного - в начале, в конце, при отмене, и при неудачной попытке отдохнуть. какое именно событие произошло определяется функцией GetLastRestEventType(). эффект сна, накладываемый на начинающего отдыхать, отменяет отдых. дефолтную систему отдыха можно смело выкидывать, все равно ты ее не используешь. заготовка скрипта:
Neverwinter Script Source
void restDone(object oPC)
{
  effect eEffect = GetFirstEffect(oPC);
  while(GetIsEffectValid(eEffect))
  {
    int nType = GetEffectType(eEffect);
    if(nType == EFFECT_TYPE_BLINDNESS)
      RemoveEffect(oPC, eEffect);
    eEffect = GetNextEffect(GetFirstPC());
  }
}

void restStart(object oPC)
{
  effect eBlind =  EffectBlindness();
  effect eVis = EffectVisualEffect(VFX_IMP_SLEEP);
  // проверки еды, воды, спальника, плюшевого мишки итд.
  if (!GetIsObjectValid(GetItemPossessedBy(oPC, "bedrollitem")))
  {
    SendMessageToPC(oPC, "без подстилки не уснешь...");
    AssignCommand(oPC, ClearAllActions());
    return;
  }
  ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oPC, 5.0);
  ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, oPC, 60.0);
}

void main()
{
    object oPC = GetLastPCRested();
    int iRestEvent = GetLastRestEventType();
    switch (iRestEvent)
    {
      case REST_EVENTTYPE_REST_STARTED:
        restStart(oPC);
        break;
      case REST_EVENTTYPE_REST_CANCELLED:
        restDone(oPC);
        break;
      case REST_EVENTTYPE_REST_FINISHED:
        restDone(oPC);
        break;
      case REST_EVENTTYPE_REST_INVALID:
        //SendMessageToPC(oPC, "rest failed");
        break;
    }
}

GoingPro)
Где можно взять хак пак с замками и каменными стенами и всей этой ерундой если конечно такой есть, хотя я думаю должен быть 100%. Помогите пожалуйсто.

И ещо есть игроку присваивать SetLocalInt(oPc, "INT", 1); то после рестарта сервера оно сохраняеться?
Если нет то как одевать на персонажа шкуру, просто туда можно было бы поприсваивать че то smile.gif?


Молю о помощи, брожу в неведании и это мешает в работе smile.gif Помогите пожалуйсто.
Zirrex
GoingPro), искать какие-либо хак-паки стоит тут Neverwinter Vault. Также там много чего полезного для начинающего разработчика.

Нет, не сохранится. Все переменные хранятся на персонаже до рестарта. Рестарт же их затирает. Есть хорошие функции, которые пишут переменные в базу. Например, так:

Neverwinter Script Source
string sID = GetName(oPC) + GetPCPublicCDKey(oPC);
int iVariable = GetCampaignInt("player", "Variable" + sID) + 1;
SetLocalInt(oPC, "INT", iVariable);
SetCampaignInt("player", "Variable", iVariable);

а потом считываешь при входе:
Neverwinter Script Source
string sID = GetName(oPC) + GetPCPublicCDKey(oPC);
int iVariable = GetCampaignInt("player", "Variable" + sID);
SetLocalInt(oPC, "INT", iVariable);

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

Извиняюсь, если ошибся, мало работал с ними.

Одеть предмет на персонажа легко. Во-первых, нужен сам предмет, его тэг, а во-вторых, если это сервер, то в настройках его должна быть выключена опция "Item Level Restrictions", иначе вещь не по уровню просто не наденется на персонажа, а будет валяться в рюкзаке. Далее делаем так:
Neverwinter Script Source
object oChest = CreateItemOnObject("am_it_cchest",oPC);

if (GetItemPossessedBy(oPC,"am_it_cchest") != OBJECT_INVALID)
{
    AssignCommand(oPC, ActionEquipItem(oChest, INVENTORY_SLOT_CARMOUR));
}
Batkom
вот еще вопрос, делая алхимию, как один из эффектов при неудачном смешении ингридиентов игрок превращался в корову или пингвина. Дело в том, что после установки полиморфа игрок может его отменить нажав "отменить полиморф" как лишить игрока этой возможности?
я пробовал накладывать паралич, но игрок просто преврашается обратно и стоит в параличе может можно убрать как нибудь эту кнопку, или лишить игрока всех действий
Zirrex
Batkom, хехе, да все просто, ты не делай полиморфа, а просто изменяй облик. Смотри:

Neverwinter Script Source
void Penguin(object oTarget, object oUser)
{
    effect eParalyze = EffectCutsceneImmobilize();

    AssignCommand(oTarget, SetCreatureAppearanceType(oTarget,APPEARANCE_TYPE_PENGUIN));
    AssignCommand(oTarget, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eParalyze, oTarget));
    SetLocalInt(oTarget, "toaded", 1);
}

void RemovePenguin(object oTarget, object oUser)
{
    if (GetLocalInt(oTarget, "toaded") == 1)
    {
        effect eMyEffect = GetFirstEffect(oTarget);

        while (GetIsEffectValid(eMyEffect))
        {
            if (GetEffectType(eMyEffect) == EFFECT_TYPE_CUTSCENEIMMOBILIZE)
            {
                RemoveEffect(oTarget, eMyEffect);
                SetLocalInt(oTarget, "toaded", 0);
            }
            eMyEffect = GetNextEffect(oTarget);
        }

        if (GetRacialType(oTarget) == RACIAL_TYPE_ELF)
        {
            AssignCommand(oTarget, SetCreatureAppearanceType(oTarget,APPEARANCE_TYPE_ELF));
        }
        else if (GetRacialType(oTarget) == RACIAL_TYPE_GNOME)
        {
            AssignCommand(oTarget, SetCreatureAppearanceType(oTarget,APPEARANCE_TYPE_GNOME));
        }
        else if (GetRacialType(oTarget) == RACIAL_TYPE_DWARF)
        {
            AssignCommand(oTarget, SetCreatureAppearanceType(oTarget,APPEARANCE_TYPE_DWARF));
        }
        else if (GetRacialType(oTarget) == RACIAL_TYPE_HALFLING)
        {
            AssignCommand(oTarget, SetCreatureAppearanceType(oTarget,APPEARANCE_TYPE_HALFLING));
        }
        else if (GetRacialType(oTarget) == RACIAL_TYPE_HUMAN)
        {
            AssignCommand(oTarget, SetCreatureAppearanceType(oTarget,APPEARANCE_TYPE_HUMAN));
        }
        else if (GetRacialType(oTarget) == RACIAL_TYPE_HALFELF)
        {
            AssignCommand(oTarget, SetCreatureAppearanceType(oTarget,APPEARANCE_TYPE_HALF_ELF));
        }
        else if (GetRacialType(oTarget) == RACIAL_TYPE_HALFORC)
        {
            AssignCommand(oTarget, SetCreatureAppearanceType(oTarget,APPEARANCE_TYPE_HALF_ORC));
        }
    }
}

Переменная не обязательна, но можно и оставить, она у меня служила для выбора условий.
Batkom
сенк, сейчас опробую





ТHX все работает, чейчас буду разбираться с опытом



М.....э...а можно какой нибудь примерчик?
Я никак не могу найти, в каком именно месте игроку выдается опыт....
GoingPro)
Batkom На смерть моба форумулу зделай, и все будет путем.

Хотел ещо узнать вот что:
1) На лаги модуля или локации влияет большое количество юзибл объктов?
2) Как получить данные о игроке когда он использует придмет object oPC = ????();

Спасибо.

Со вторым я уже разобрался object oPC = GetLastUsedBy(); должно работать поидеи, но я ещо не проверял...
Zirrex
Batkom, выдается он обычно при срабатывании скрипта "nw_c2_default7", но в нем ты ничего не найдешь, потому что за опыт отвечает параметр "Xp Scale" в настройках модуля. Если ты хочешь использовать свою систему распределения опыта, то это значение надо ставить в 0. Правда есть одно но, даже если его убрать в 0, то все равно будет писаться опыт, только всегда будет иметь нулевое значение. Чтобы этого не было, надо в скрипте "nw_c2_default7" прописать следующее:

Neverwinter Script Source
void main()
{
    object oKiller = GetLastKiller();

    if (GetLastKiller() == OBJECT_SELF) return;

// и в самом конце скрипта, можно и перед флагом "NW_FLAG_DEATH_EVENT"
    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(), OBJECT_SELF);
    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(2000, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY), OBJECT_SELF);

Урон равен 2000, потому что есть монстры, у которых жизни больше 1000, если у тебя нет таких, то ставь максимум, который не превышается.

Дальше внутри скрипта ставишь ссылку на свой скрипт, который распределяет опыт, например так:
Neverwinter Script Source
if (GetStandardFactionReputation(STANDARD_FACTION_HOSTILE, OBJECT_SELF))
{
    ExecuteScript("pwfxp",OBJECT_SELF);
}
Batkom
я нашел функцию определения чегото GetChallengeRating
видимо это и есть CR, но что делать с ним?
он float, значит дробь, возможно нужно умножать его на не знаю что и делить на HD игрока или общий HD партии
или нет....
у меня получилась формула fXp = GetChallengeRating(oMonster) * X / GetHitDice(oPC);
откуда взяь множитель Х не знаю, хотя может я вообще все не так делаю...
dumbo
Batkom
одной формулой ты врядли обойдешся. возьми для примера систему из какого-нибудь hcr - сам "рожать" будешь долго... wink.gif float потому, что на маленьких значениях он бывает нецелый(0.5, 0.75)...

Zirrex
http://nwn.bioware.com/support/patchdetails164.html :
QUOTE
The game no longer displays the "Experience Points Gained:" message when the experience points gained was 0.


по поводу "ошибки алхимика":
Lexicon:
QUOTE
Neverwinter Script Source
effect EffectPolymorph(
    int nPolymorphSelection,
    int nLocked = FALSE
);
Parameters
nPolymorphSelection - POLYMORPH_TYPE_*
nLocked - If TRUE, player can't cancel polymorph (Default: FALSE)
Batkom
ясно сенк, сейчас попробую потырить скрипт с нордока170
Zirrex
dumbo, не знал, но у меня по старинке установлен этот скрипт. Теперь можно и убрать.

У полиморфов есть один побочный эффект. Если превращаешься в Балора, Голема, Дракона, и т.д., то, у кого в полиморфе становится в 2 раза выше жизни, чем у персонажа, при автосохранении на сервере происходит перенакладка полиморфа. В принципе, это у всех, но с "тяжелыми" полиморфами иная проблема. Т.е., если полиморфа ранили, но жизнь не опустилась ниже критического порога, например, была 500/300, а стала 301/300, то она восстановится. Явный баг, но как его исправить, я не знаю, в момент автосохранения полиморф как бы дергает.

К тому же я так еще сделал, чтобы избавиться от эффекта полиморфа.
Batkom
ух взял скрипт раздачи опыта с nordockpub170 вроде все правильно, но не работает вообще
посоветуйте какой нибудь простой во внедрении скрипт а я его дополню

вот что у меня получилось
Neverwinter Script Source
float fCR = GetChallengeRating(OBJECT_SELF);
    int nMonsterXP;
    object oMod = GetModule();




    int nPartyMembers;
    int nPartyLevelSum;
    int nHighestLevel=0;
    float fAvgPartyLevel;

    object oKilledArea = GetArea(OBJECT_SELF);
    object oPC = GetFirstFactionMember(oKiller);

    while(GetIsObjectValid(oPC)) {
        if(oKilledArea == GetArea(oPC)) nPartyMembers++;
        if(GetIsDM(oPC)) nPartyMembers--;
        else nPartyLevelSum += GetCharacterLevel(oPC);
        if (GetCharacterLevel(oPC)> nHighestLevel)
            nHighestLevel=GetCharacterLevel(oPC);
        oPC = GetNextFactionMember(oKiller, TRUE);
    }

    if (nPartyMembers == 0)
    return;

    fAvgPartyLevel = IntToFloat(nPartyLevelSum) / IntToFloat(nPartyMembers);


    if (FloatToInt(fAvgPartyLevel) < 3) fAvgPartyLevel = 3.0;
    PrintString ("party level "+FloatToString(fAvgPartyLevel,3,1));

    if ((FloatToInt(fAvgPartyLevel) <= 6) && (fCR < 1.5))
        nMonsterXP = GetLocalInt(oMod,"BASEXP");
    else
    {
        nMonsterXP = GetLocalInt(oMod,"BASEXP") * FloatToInt(fAvgPartyLevel/2);
        int nDiff = FloatToInt(((fCR < 1.0) ? 1.0 : fCR) - fAvgPartyLevel);
        switch (nDiff)
        {
        case -7:
            nMonsterXP /= 12;
            break;

        case -6:
            nMonsterXP /= 8;
            break;
        case -5:
            nMonsterXP = nMonsterXP * 3 / 16;
            break;
        case -4:
            nMonsterXP /= 4;
            break;
        case -3:
            nMonsterXP /= 3;
            break;
        case -2:
            nMonsterXP /= 2;
            break;
        case -1:
            nMonsterXP = nMonsterXP * 2 / 3;
            break;
        case 0:
            break;
        case 1:
            nMonsterXP = nMonsterXP * 3 / 2;
            break;
        case 2:
            nMonsterXP = nMonsterXP * 3 / 2;
            break;
        case 3:
            nMonsterXP = nMonsterXP * 3 / 2;
            break;
        case 4:
            nMonsterXP *= 2;
            break;
        case 5:
            nMonsterXP *= 2;
            break;
        case 6:
            nMonsterXP *= 2;
            break;
        case 7:
            nMonsterXP *= 3;
            break;
        case 8:
            nMonsterXP *= 3;
            break;
        case 9:
            nMonsterXP *= 3;
            break;
        case 10:
            nMonsterXP *= 4;
            break;
        case 11:
            nMonsterXP *= 4;
            break;
        case 12:
            nMonsterXP *= 4;
            break;
        case 13:
            nMonsterXP *= 5;
            break;
        case 14:
            nMonsterXP *= 5;
            break;
        case 15:
            nMonsterXP *= 5;
            break;
        case 16:
            nMonsterXP *= 6;
            break;
        case 17:
            nMonsterXP *= 6;
            break;
        case 18:
            nMonsterXP *= 6;
            break;
        case 19:
            nMonsterXP *= 7;
            break;
        case 20:
            nMonsterXP *= 7;
            break;
        case 21:
            nMonsterXP *= 7;
            break;
        case 22:
            nMonsterXP *= 8;
            break;
        case 23:
            nMonsterXP *= 8;
            break;
        case 24:
            nMonsterXP *= 8;
            break;
        case 25:
            nMonsterXP *= 9;
            break;
        case 26:
            nMonsterXP *= 9;
            break;
        case 27:
            nMonsterXP *= 9;
            break;
        case 28:
            nMonsterXP *= 10;
            break;
        case 29:
            nMonsterXP *= 10;
            break;
        case 30:
            nMonsterXP *= 10;
            break;
        case 31:
            nMonsterXP *= 11;
            break;
        case 32:
            nMonsterXP *= 11;
            break;
        case 33:
            nMonsterXP *= 11;
            break;
        case 34:
            nMonsterXP *= 12;
            break;
        case 35:
            nMonsterXP *= 12;
            break;
        default:
            nMonsterXP = 0;
        }
    }    if (fCR < 0.76 && nMonsterXP)
    {
        if (fCR <= 0.11)
            nMonsterXP = nMonsterXP / 10;
        else if (fCR <= 0.13)
            nMonsterXP = nMonsterXP / 8;
        else if (fCR <= 0.18)
            nMonsterXP = nMonsterXP / 6;
        else if (fCR <= 0.28)
            nMonsterXP = nMonsterXP / 4;
        else if (fCR <= 0.4)
            nMonsterXP = nMonsterXP / 3;
        else if (fCR <= 0.76)
            nMonsterXP = nMonsterXP /2;
       

        if (nMonsterXP == 0) nMonsterXP = 1;
    }


    nMonsterXP += GetLocalInt(oMod,"BONUSXP");
    int nCharXP;
    PrintString("Monster XP = "+IntToString(nMonsterXP));
    if (nPartyMembers < 5)
    {
        nCharXP = FloatToInt((nMonsterXP*(1+(0.3*(nPartyMembers-1))))/nPartyMembers);
    }
    else
    {
        nCharXP = FloatToInt((nMonsterXP*(1+(0.5*(nPartyMembers-1))))/nPartyMembers);
    }








    PrintString("Char XP = "+IntToString(nCharXP));
    oPC = GetFirstFactionMember(oKiller);
    while(GetIsObjectValid(oPC))
    {

        if(!GetIsDM(oPC) && oKilledArea == GetArea(oPC))
        {
            int nCurExp=GetXP(oPC);
            int modXP;
            if (nCharXP>0)
            {
                if(GetHitDice(oPC)<12)
                {
                    modXP=nCharXP;
                    if ((abs(GetHitDice(oPC)-FloatToInt(fAvgPartyLevel))>5) || (nHighestLevel-GetHitDice(oPC)>5))
                        modXP=modXP/4;

                                        if ((GetLevelByClass(CLASS_TYPE_SORCERER, oPC) == TRUE)||(GetLevelByClass(CLASS_TYPE_WIZARD, oPC) == TRUE))
                    modXP = modXP / 3;
                    if ((GetLevelByClass(CLASS_TYPE_SHIFTER, oPC) == TRUE)||((GetLevelByClass(CLASS_TYPE_RANGER, oPC) == TRUE)))
                    modXP = modXP * 2;
                    GiveXPToCreature(oPC, modXP);
                    PrintString("Rewarded "+GetName(oPC)+ " XP = "+IntToString(nCharXP));
                }
                else
                {
                    switch (GetHitDice(oPC))
                    {
                        case 12:modXP=nCharXP* 7 / 8;
                                break;
                        case 13:modXP=nCharXP* 13 / 16;
                                break;
                        case 14:modXP=nCharXP* 6 / 8;
                                break;
                        case 15:modXP=nCharXP* 11 / 16;
                                break;
                        case 16:modXP=nCharXP* 5 / 8;
                                break;
                        case 17:modXP=nCharXP* 9 / 16;
                                break;
                        case 18:modXP=nCharXP* 4 / 8;
                                break;
                        case 19:modXP=nCharXP* 7 / 16;
                                break;
                        case 20:modXP=nCharXP* 3 / 8;
                                break;
                        default: modXP=nCharXP* 3 /8;
                                break;
                    }
                    if (abs(GetHitDice(oPC)-FloatToInt(fAvgPartyLevel))>5 || (nHighestLevel-GetHitDice(oPC)>5))
                        modXP=modXP/4;

                                        if ((GetLevelByClass(CLASS_TYPE_SORCERER, oPC) == TRUE)||(GetLevelByClass(CLASS_TYPE_WIZARD, oPC) == TRUE))
                    modXP = modXP / 3;
                    if ((GetLevelByClass(CLASS_TYPE_SHIFTER, oPC) == TRUE)||((GetLevelByClass(CLASS_TYPE_RANGER, oPC) == TRUE)))
                    modXP = modXP * 2;
                    GiveXPToCreature(oPC, modXP);
                    PrintString("Rewarded "+GetName(oPC)+ " XP = "+IntToString(modXP)+ " (level "+IntToString(GetHitDice(oPC))+")");
                }
            }
        }
        oPC = GetNextFactionMember(oKiller, TRUE);
    }


откуда брать basexp и bonusxp понятия не имею
Aiwan
Batkom вопросы по скриптингу в другой теме. Тут вопросы новичков. Еще раз увижу обсуждение кода, влеплю пред.
Batkom
сорри
Zirrex
Batkom, не бери из Нордока, там паршивая система распределения опыта. Она мне не понравилась. Лучше попробуй этот скрипт Neverwinter Vault - PWFXP.

Самое главное, правильно его настроить. Подробно расписывать не буду, что он умеет, разбирайся сам. Вкратце скажу, он не позволяет бегать в партии высокоуровневому персонажу и низкоуровневому. Последнему просто не будет идти опыт. Я с этим уже сталкивался, на шардах первого поколения очень широко были распространены так называемые "качели".
Batkom
То что качелей и паравозов нету есть гут, ибо я чего толкьо не делал и как только не извращался.
Сейчас попробую внедрить.

Все работает, пока не совсем так как хотелось бы, но это вопрос времени.

Огромное спасибо. biggrin.gif
Добавлено в [mergetime]1120956151[/mergetime]
Еще раз спасибо, скрипт отлично работает, все настроил, теперь прусь biggrin.gif

..ээм...вот еще пара вопросиков unsure.gif
1 как увеличить продолжительность сна
2 как проверить есть ли в пределах 5 метров от игрока плсбл обьект с известным тегом?
Хочу сделать, чтобы без разведенного рядом костра восстанавливались не все хит поинты и просто увеличить продолжительность отдыха в 2 или 3 раза
Aiwan
QUOTE (Batkom @ Jul 10 2005, 01:46)
2 как проверить есть ли в пределах 5 метров от игрока плсбл обьект с известным тегом?

Сделай перебор объектов рядом в кубе. Если в кубе бушь перебирать, укажи размер куба и не нужно писать третий параметр в строках снизу.
Neverwinter Script Source
object GetFirstObjectInShape(int nShape, float fSize, location lTarget, int bLineOfSight=FALSE, int nObjectFilter=OBJECT_TYPE_CREATURE, vector vOrigin=[0.0,0.0,0.0])

Neverwinter Script Source
if (GetObjectType(oPlsb) == OBJECT_TYPE_PLACEABLE && GetTag(oPlsb) == "TAG_ОБЪЕКТА"
      && GetDistanceBetween(OBJECT_SELF, oPlsb)<=5.0)
      {
        // Делай с ним что хошь...
        }

Добавлено в [mergetime]1120971414[/mergetime]
Если через перебор всех объектов то
Neverwinter Script Source
GetDistanceBetween(OBJECT_SELF, oPlsb)<=5.0

Оставь это. Но лучше через ту функцию что дал выше.
Batkom
хм, перед тем как посмотреть на форум успел додуматься до своего решения
Neverwinter Script Source
object oPlsbl = GetNearestObjectByTag("Тег" ,oPC, 1);


Neverwinter Script Source
if ((GetIsObjectValid(oPlsbl) == TRUE) && (GetDistanceBetween(oPC, oPlsbl) <= 5.0))
{
// действия
}


Помоему попроще чем с пееребором, но пока не знаю как будет работать в мультиплеере или когда костров несколько
Zirrex
Batkom, а ты сделай в скрипте условие, что если рядом уже есть костер, вторично создавать его нельзя. Точно такая же проверка, которая отображена выше.

Работать будет нормально, я в своем модуле использую одинаковые тэги для портала, чтобы не городить кучу скриптов. Скрипт ищет ближайшие объекты, если находит, использует на них эффекты, и срабатывает сам портал. Соответственно все остальные порталы, что находятся на других локациях, не активны.

Тебе все же лучше искать не просто тэг на локации, а именно требуемый объект в определенном месте. Например, как по скрипту выше, что от Aiwana, в радиусе игрока. Если ты будешь использовать свой скрипт, он будет искать все объекты с подобным тэгом на всей локации, что может привести к совершенно не тем результатам.

Сам хочу в скором времени перейти на костровый отдых, так что буду еще делать smile.gif
Batkom
Все нормально работает, никаких багов.
я же там не зря поставил после нахождения обьекта с тегом проверку расстояния
к тому же GetNearestObjectByTag ищет ближайший обьект.
еще добавил палатки, теперь если партия из 10-15 человек останавливается на ночлег начинается форменое строительство огромного лагеря, выглядит потрясающе, + той же функцией добавляется проверка на дальность, чтобы палатки не ставились друг вдруга
если таргетлокейшн слишком близко, высвечивается сообщение в логе
все отлично работает
осталось только как то увеличить продолжительность отдыха.

Hassan
Вопросы:
Можно ли добавить ПС конкретный Фит? Ну к примеру дать ему Дарквижн, если он чел?
Как сделать вещь, с помощью которой можно раз в день вызывать существо, к примеру статуэтку паука - и соотв-но чтоб вызывался паук?

пока все... dntknw.gif
Zirrex
Batkom, с продолжительностью у тебя ничего не получится. Стандартный отдых заскриптован на определенное время. Если только ты сам не заставишь партийцев отдыхать столько, сколько тебе нужно. Например, в момент сна лишить их возможности двигаться, и оставлять в таком состоянии несколько игровых часов. Правда, не уверен, что сему явлению обрадуются игроки smile.gif

Если они любят ролеплей, то сами посидят у костра, если же важнее опыт и монстры, то не заставишь, а скриптовое насилие не самое лучшее решение.
Batkom
мда, жаль жаль

Добавлено в [mergetime]1121096583[/mergetime]
Кстати воимя РП я хотел бы отключить шаут.
На Gem pf the North я видел подобную фичу, там шаута нет и вместо него пишутся обычные фразы , "орать" может только ДМ. Это очень удобно нежели ограничивать игроков правилами и наказывать таковых делевелами. К тому же ДМ не всегда присутствует на шарде и не всегда может уличить игрока в нарушении.
И еще всекоманды макро текста тоже автоматом пишутся в шаут, возможно он отключается гдето в настройках тулсета? Или всеже придется писать скрипт на какой нить евент?
dumbo
Batkom
nwnplayer.ini
CODE
...
[Server Options]
...
Disallow Shouting=1
...
Zirrex
Batkom, всегда можно написать скрипт, который бы штрафовал за количество фраз в шаут smile.gif Одно время писали для шарда, а потом идея заглохла, хотя работала отлично, потому что выключили по этой опции шаут. Вначале игроки ворчали, что дескать нельзя использовать шаут, даже голосование устраивали, нужен ли он им, а потом привыкли. Для ролейплея это, и правда, незаменимая вещь, когда она выключена. Ранее постоянно были возгласы, да успокойтесь вы, или замолчите, но новичков хватает, и часто им все по барабану.
Batkom
yes.gif истинно так, опробовал, действительно с этой опцией орать в шаут может только ДМ делая обьявления, потрясающе yahoo.gif одним правилом сервера меньше.

Добавлено в [mergetime]1121182743[/mergetime]
Скачал отличный хак с красивыми лошадками, но не могу их вставить, по причине СЕПа. Если вставлять хак к новому модулю, то все пучком, а если к тому, что уже стоит на сепе, ничего не получается, я так думаю, что нужно написать tlk с дескриптом моделек, но как это сделать и это ли нужно сделать, чтобы модельки встали на свои места?
Zirrex
Странно, что про опцию шаута ты узнал только сейчас. Иногда не мешает повозиться с настройками ini файла smile.gif Уверен, что ты не знаешь еще таких команд, как эти:

ClientChatLogging=1
ClientEntireChatWindowLogging=1

Прописываются в файл "nwnplayer.ini" в разделе "Game Options". Как видно из написанного, позволяют вести логи чата, а также записывать информацию в текстовый файл, которая вносится через закладку игрового журнала.

Также еще ранее можно было легко разблокировать камеру, пока не появилась подобная возможность открыто в дополнении Соу, данной командой, прописанной в том же файле, а именно:

Unlockcamera=1

Прописывается в разделе "Control Options". Ладно, все это тонкости, давно уже описанные в различных faq листах, зачитанных до дыр smile.gif

Разработчики Cep-а забавные ребята, добавили много чего интересного, но не внесли лошадей, даже как-то не понятно это сознавать. Тем более сами лошади существуют еще с времен оригинального НВН, в том время, когда не было даже Соу.

Не совсем понял, причем тут tlk? Если ты добавляешь модельки лошадей в модуль, то они являются существами, в данном случе, хенчманами, позволяющими на себя садиться верхом и ездить по локациям точно также, как и пешком или бегом. В чем конкретная проблема, занята ниша или не желает устанавливаться в модуль с подключенным Cep?
Batkom
похоже ниша зенята, ибо создаю крича, устанавливаю модельку лошади, подключаю сеп и вижу инвизибл обжект
Aiwan
QUOTE (Batkom @ Jul 13 2005, 03:18)
похоже ниша зенята, ибо создаю крича, устанавливаю модельку лошади, подключаю сеп и вижу инвизибл обжект

Ты 2Да файл посмотри. Может конфликт там скорее всего.
-fenix-
QUOTE (Zirrex @ Jul 12 2005, 20:41)
Ладно, все это тонкости, давно уже описанные в различных faq листах, зачитанных до дыр

Не подскажешь, где их можно почитать?
GoingPro)
Добрый день!

У меня к вам вопрос:
Как зделать так что бы НПС считывала фразы с чата, ты пишешь например ей дай мне стрел и она тебе дает стрелы...??
-fenix-
Кажись вот функции
Задать фразу
Neverwinter Script Source
SetListenPattern(object oObject, string sPattern, int nNumber=0)



Сравнить фразу игрока
Neverwinter Script Source
GetListenPatternNumber()


Значит На OnSpawn НПС
Neverwinter Script Source
void main()
{
SetListening(OBJECT_SELF, 1);
SetListenPattern(OBJECT_SELF,"дай мне стрел",1);
}


А на OnConversation

Neverwinter Script Source
void main()
{
object oPC = GetLastSpeaker();

  if (GetListenPatternNumber()==1 && GetIsListening(OBJECT_SELF))
      {
      CreateItemOnObject("Strela", oPC, 99);
      }

}
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Invision Power Board © 2001-2024 Invision Power Services, Inc.