Помощь - Поиск - Пользователи - Календарь
Полная версия: Вопросы новичков
Город Мастеров > РЕДАКТОРЫ > 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
zmeylsdn
я правильно понял. в палитре ищу нужных существ, у них будет приставка summon или в настройках что-то подобное, а тогда уже их меняю, добавляю как новые к палитре. Ищу скрипты сумона (где искать кстати) и добавляю теги новых существ? как именно экспортировать чтобы потом закинуть в override?

И тоже самое с формами друида\оборотня, они тоже считаются существами? или просто шкурками, которые изменить так же?
Aiwan
Цитата(zmeylsdn @ Dec 7 2018, 22:26) *
я правильно понял. в палитре ищу нужных существ, у них будет приставка summon или в настройках что-то подобное, а тогда уже их меняю, добавляю как новые к палитре.

Да. При создании существ они будут создаваться с новым ResRef-ом, вот его надо будет менять в скриптах.
Цитата(zmeylsdn @ Dec 7 2018, 22:26) *
Ищу скрипты сумона (где искать кстати) и добавляю теги новых существ?

Не добавляю, а меняю. Старые в скриптах удаляю и вставляю новые моих существ.
Цитата(zmeylsdn @ Dec 7 2018, 22:26) *
как именно экспортировать чтобы потом закинуть в override?

Есть кнопка экспорта в тулсете.
Цитата(zmeylsdn @ Dec 7 2018, 22:26) *
И тоже самое с формами друида\оборотня, они тоже считаются существами? или просто шкурками, которые изменить так же?

Не знаю, но если шкурки одеваются на них, то ищем шкурки, создаем их с нужными свойствами а дальше я уже сказал...
Опять же, я не утверждаю, что это самый правильный метод.
zmeylsdn
спасибо
denis0k
Полиморфы работают через эту штуку: http://nwn.wikia.com/wiki/Polymorph.2da
zmeylsdn
Меняю скрипт x2_s2_sumgrund (фит палемастера призвать сильную нежить), строка для условия 30лвл вписываю resref нового демилича demilich003.
Экспортирую ресурсы, 2 файла: x2_s2_sumgrund скрипт и demilich003 файл моба. получается файл "lsd.erf". Копирую этот файл из папки erf в папку override. Не работает в офиц кампании (проверено на прелюдии и на х2 2 глава).
При этом в модуле, в котором это было создано, работает.
В файле *.erf при попытке импорта вижу:
demilich003.utc -моб
itIcredlichpr001.uti -шкура(менялась)
itIcrewpdlich001.uti -когти(менялись)
x2_s2_sumgrund.ncs
x2_s2_sumgrund.nss -скрипты, не в курсе почему два файла.
В чем может быть проблема?

Нашел скрипт всех самонов 1-9 nw_s0_summon. Он вида
if(GetHasFeat(FEAT_ANIMAL_DOMAIN_POWER)) //WITH THE ANIMAL DOMAIN
{
if(nSpellID == SPELL_SUMMON_CREATURE_I)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1;
sSummon = "NW_S_BOARDIRE";
}
else if ====> дальше для самонов 2-9
else //WITOUT THE ANIMAL DOMAIN
{
if(nSpellID == SPELL_SUMMON_CREATURE_I)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1;
sSummon = "NW_S_badgerdire";
}
else if ====> дальше для самонов 2-9
Как туда воткнуть код для призыва новых самонов на эпич. лвлах (21й - 1й эпик сум, 23-2й и т.п.)
В начале добавить "int nCasterLevel = GetCasterLevel(OBJECT_SELF);"
Как в блок WITOUT THE ANIMAL DOMAIN добавлять
if (nCasterLevel >= 21)
{
eSummon = EffectSummonCreature("EPICbadgerdire");
}
и так же для 23 25 и т.д?

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

П.С.
Или для упрощение задачи, удалить условия для домена животного, но как тогда добавить блок для условий 21+ 23+ и т.д.?
Aiwan
Если не ошибаюсь, в override нужно класть ресурсы не запакованные. erf это уже в зипе упакован.
Насчет остального, нужно садится за тулсет и пробовать все варианты. Все что тут написано и создавалось на форуме делалось именно так. Универсальных ответов на все нет. Ставишь себе задачу, ищешь пути решения: фап, фап, фап... нашел! wink3.gif Делишься результатом с остальными. Как-то так.
zmeylsdn
Я нажал экспортировать, там есть только добавить ресурсы и далее сохранить, тип файла только *.erf. Как сделать не запакованные?

И еще помню есть фикс для тулсета, чтобы русский понимал и при ошибке скрипта не кракозябру выдавал.
zmeylsdn
Нашел как добавить в скрипты.
Осталось узнать как применить изменения к офиц кампании и при призые нового существа оно стоит неподвижно. Видимо нужен другой скрипт onspawn или еще что, ибо я не знаю как находить существ призыва по тегам(ресфам) и брал их из палитры, а там они враждебные мобы.
Aiwan
Цитата(zmeylsdn @ Dec 31 2018, 01:32) *
Я нажал экспортировать, там есть только добавить ресурсы и далее сохранить, тип файла только *.erf. Как сделать не запакованные?

Есть плагин для Тотал Коммандер.

Еще по файлам для тулсета сюда: http://www.wrg.ru/download.php?list.18
zmeylsdn
спс. распаковал 5 файлов. изменения работают в оригинале. Но самоны стоят на месте, на команды следовать не реагируют, как исправить?

Если враг в зоне видимости атакуют. в HoTU диалога с ними тоже нет.
Aiwan
Надо ковыряться, сравнивать скрипты спавна, возможно там затык.
zmeylsdn
Если бы можно было выковырять родных самонов я бы сделал по аналогии а так не с чем сравнивать. или может есть какой модуль с измененными самонами? взял бы оттуда
Aiwan
Попробуй узнать ресрефы существ, может они не те, что ты думаешь. Проверь все варианты, говорю же. Просто есть где-то ошибка. Может переменная стоит где-то и все...
zmeylsdn
Из скрипта на призыв существ 1-9 вот первые два ресфера (или тега):
NW_S_badgerdire
NW_S_BOARDIRE
Эти мобы есть в палитре, но с другими ресферами (или тегами). Как найти именно этих мобов я не знаю, поэтому юзал мобов с палитры для замены самонов.
Как я вижу решение:
- либо есть возможность найти именно этих мобов, тогда проблем нет. но я не знаю как их найти.
- либо найти скрипты, отвечающие за самонов игрока и добавить их в мобов с палитры. Для этого придется перебирать все скрипты (пока нашел ток один но он ничего не изменил).
denis0k
Саммоны в палитре не видны. Раньше был фикс, но сайт с ним закрыли.

Скрипт nw_s0_summon, там все рефы прописаны. У нпс для саммона должен быть нестандартный набор скриптов, на nwn.wikia.com можно поискать по слову summon.
zmeylsdn
Биг спс нашел там картинку со всеми скриптами на самона, проверил - работает.
zmeylsdn
Сейчас делаю, чтобы при наличии фита GREAT_SPELL_FOCUS_CONJURATION самонам добавлялось 4силы. Но делаю это через добавление нового самона с увеличенной силой. Есть ли возможность реализовать скрипт, чтобы наличие фита прибавляло силу уже существующему самону? Может даже просто через присвоение фита FEAT_EPIC_GREAT_STRENGTH_4.
denis0k
Цитата(zmeylsdn @ Jan 8 2019, 18:33) *
Сейчас делаю, чтобы при наличии фита GREAT_SPELL_FOCUS_CONJURATION самонам добавлялось 4силы. Но делаю это через добавление нового самона с увеличенной силой. Есть ли возможность реализовать скрипт, чтобы наличие фита прибавляло силу уже существующему самону? Может даже просто через присвоение фита FEAT_EPIC_GREAT_STRENGTH_4.
Можно просто эффект наложить. В заклинании Сила быка есть код, но надо тип эффекта сделать, кажется, supernatural, чтобы не диспелилось. Какой именно тип эффекта, можно подсмотреть в заклинании Проклятье smile.gif
zmeylsdn
А где найти эффекты заклинаний? Нашел только spells.2da, vco_lgsprnatr01 sco_lgsprnatr01

Так же хотелось бы не эффектом, чтобы сверху можно было бафать той же силой быка, а так будет кап в 12 ед.
denis0k
Цитата(zmeylsdn @ Jan 9 2019, 16:51) *
А где найти эффекты заклинаний? Нашел только spells.2da, vco_lgsprnatr01 sco_lgsprnatr01
https://nwnlexicon.com/index.php/EffectAbilityIncrease

В редакторе скрипта справа все функции можно пересмотреть, чтобы оценить возможности.

Цитата(zmeylsdn @ Jan 9 2019, 16:51) *
Так же хотелось бы не эффектом, чтобы сверху можно было бафать той же силой быка, а так будет кап в 12 ед.
Тогда только отдельная крича. Можно было бы давать итем, но он тоже входит в те 12 капа.
zmeylsdn
CODE
else if(nSpellID == SPELL_SUMMON_CREATURE_III)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1;
sSummon = "z_s3"; //NW_S_WOLFDIRE
if(nCasterLevel >= 25)
{
sSummon = "z_s13";
}
if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_CONJURATION
)) //WITH grCONJ +4 to str q
{
object oTarget = OBJECT_SELF; //OBJECT_SELF
// Create the effect to apply
effect eBonus = EffectAbilityIncrease(ABILITY_STRENGTH, 4);

// Create the visual portion of the effect. This is instantly
// applied and not persistant with wether or not we have the
// above effect.
effect eVis = EffectVisualEffect(VFX_IMP_IMPROVE_ABILITY_SCORE);

// Apply the visual effect to the target
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
// Apply the effect to the object
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBonus, oTarget);
}
}

В данный момент скирпт накидывает силу персу. существует ли константа для призванного монстра, чтобы вставить вместо OBJECT_SELF?
Еще заметил, что фокусировка и эпик фокусировка на оружии существо, а так же бонус к атаке и бонус усиления когтя существа не меняет отображаемый бонус атаки в окне призванного существа и судя по всему не действует. Можно ли это исправить? Как вариант решения нашел, можно добавить существу оружие с бонусом атаки\усиления.
denis0k
Уже после вступления в силу эффекта саммона его объект можно получить через GetAssociate.

Про атаку не знаю, но рекомендую смотреть подобные вещи не в чарнике, а в логе боя. Чарник в нвн не всегда соответствует действительности.
Melisse
Можно сделать в 2 разных подхода:

1. В скрипте, где вызываешь саммона после ApplyEffect с эффектом вызова саммона, получаешь саммона через object GetAssociate() и накладываешь на него эффекты через кастомную функцию, или просто. (как описал denis0k)
2. В скрипте спавна саммона ищешь мастера object GetMaster(), делаешь проверки и накладываешь эффекты на саммона уже как на OBJECT_SELF.

Оба варианта должны работать
zmeylsdn
Может кто в коде показать, как взять ассоциацию на сумона и применить к нему эффект увеличения силы или в скрипте onSpawn сделать то же самое (этот вариант предпочтительнее)? Или может есть какой модуль, где это можно подсмотреть и сделать по аналогии. Чутка погуглил, но так и не понял сам механизм, взял я object GetAssociate() или object GetMaster()
CODE
object GetMaster (object oAssociate=OBJECT_SELF)
object oAssociate
int GetAssociateType (object oAssociate)
object oAssociate

и дальше что? к чему применять
CODE
object oTarget = OBJECT_SELF;
effect eBonus = EffectAbilityIncrease(ABILITY_STRENGTH, 4);

?
И вопрос, чем извлечь 2да файлы из 2da.bif и после редактирования запаковать обратно? Пробовал разные проги из раздела НВнтул здесь, но там вроде ток просмотр. Или может это делается по другому, чтобы в игре был измененный базовый урон оружия из baseitems.2da например.
denis0k
В конце скрипта вызова:
CODE
object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED);
ApplyEffectToObject(DURATION_TYPE_*, effect, oSummon);


2da из бифов можно извлечь NWN Explorer, или вроде в папке с игрой есть 2da.zip. Запаковывать обратно не надо, нужно либо положить в override, либо создать hak и подключить к модулю.
zmeylsdn
-1- В скрипте nw_s0_summon первый вариант с OBJECT_SELF работает на перса, второй вариант с object oSummon не работает никак, в т.ч. и без DelayCommand(3.0). Использую одновременно только один из вариантов, тут объединил для наглядности.
CODE
else if(nSpellID == SPELL_SUMMON_CREATURE_III)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1;
sSummon = "NW_S_WOLFDIRE";
if(nCasterLevel >= 25)
{
sSummon = "z_s13qq";
}
if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_CONJURATION
))
{
object oTarget = OBJECT_SELF;
effect eBonus = EffectAbilityIncrease(ABILITY_STRENGTH, 4);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBonus, oTarget);

object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED);
effect eBonus = EffectAbilityIncrease(ABILITY_STRENGTH, 4);
DelayCommand(3.0, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBonus, oSummon));
}
}

-2- В скрипте самона на onSpawn добавил это внутри void main(), никакого эффекта
CODE
object oMaster = GetMaster();
if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_CONJURATION
, oMaster))
{
object oTarget = OBJECT_SELF;
effect eBonus = EffectAbilityIncrease(ABILITY_STRENGTH, 4);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBonus, oTarget);
}

-3-Пытаюсь изменить ДЦ всех спеллов на эпик лвлах. Ищу в формуле спела GetSpellSaveDC() и меняю на nSpellDC. Докидываю код:
CODE
int nSpellDC;
int nCasterLevel = GetCasterLevel(OBJECT_SELF);
if(nCasterLevel <= 20)
{
nSpellDC = GetSpellSaveDC();
}
if((nCasterLevel >= 21) && (nCasterLevel <= 21))
{
nSpellDC = GetSpellSaveDC() + 10;
}
if(nCasterLevel >= 22)
{
nSpellDC = GetSpellSaveDC() + 20;
}

и все работает (проверено на NW_S0_WailBansh). Вопрос - возможно ли одним кодом охватить все спеллы? Каждый спелл зависит от
#include "X0_I0_SPELLS"
#include "x2_inc_spellhook"
так что видимо этот код нужно добавлять в один из этих скриптов. Но как этим одним кодом заменить GetSpellSaveDC() каждого спела на nSpellDC? Или может есть другой путь.
denis0k
Саммон уже вызван на момент применения эффекта? Я вижу вверху строчку с рефом, такое чувство, что эффект вызова саммона ещё не применён.

Все скрипты придётся менять вручную. Даже если поправить инклуд, всё равно все скрипты надо будет перекомпилировать, а этого не сделать, если предварительно не изменить хоть как-то (создать модульную версию).
zmeylsdn
-1-Да самон вызван, добавил полный код. Плюс задержка в виде delay command (3.0).

-3-Возникли трудности с добавлением кода в x2_inc_spellhook. Если использую void nSpellDC() или int nSpellDC(), тогда пишет ERROR: NO LEFT BRACKET ON ARG LIST напротив строк "nSpellDC =". Через void main() сохраняет, но т.к. это есть и в каждом спеле, потом проблемы с ДЦ спелла на 21 и 22 лвле (0 или 1). Если вообще без первой строки и скобочек {} (c добавлением int nSpellDC;) пишет INVALID DECLARATION TYPE напротив строки "if" .
Neverwinter Script
void nSpellDC(){ // проблема в этой строке видимо
    int nCasterLevel = GetCasterLevel(OBJECT_SELF);

    if(nCasterLevel <= 20)
            {
            nSpellDC = GetSpellSaveDC();
            }
    if((nCasterLevel >= 21) && (nCasterLevel <= 21))
            {
            nSpellDC = GetSpellSaveDC() + 10;
            }
    if(nCasterLevel >= 22)
            {
            nSpellDC = GetSpellSaveDC() + 20;
            }
}

-4-Добавление класса сложности к спеллам избранной школы волшебника-специалиста и увеличение уровней кастера для престиж-классов с чего начинать искать?
denis0k
Цитата
Да самон вызван, добавил полный код.
Не вижу smile.gif sSummon = "z_s13qq"; есть, а вот его создания - не вижу.


А вот с nSpellDC полная каша. Функция должна вернуть значение, значит, она должна быть int, а не void. Также скорее всего триггерит на одинаковое имя функции и переменной. В базе должно быть что-то типа:
CODE
int GetSpellDC() {
бла бла бла
spellDC = ххх;
бла бла бла
return spellDC;
}

Советую полистать книжки по программированию, самые простые smile.gif
Цитата
Добавление класса сложности к спеллам избранной школы волшебника-специалиста и увеличение уровней кастера для престиж-классов с чего начинать искать?
Не понял вопроса. Можно узнать этот уровень кастера и просто прибавить ДЦ. Не знаю, можно ли узнать специализацию, давно этим занимался, всё по памяти.
zmeylsdn
-1- да в конце скрипта были строки
Neverwinter Script
effect eSummonedMonster = EffectSummonCreature(sSummon, nFNF_Effect);
    return eSummonedMonster;

я закинул между ними, в конце, в первой части скрипта (там было ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eSummon, GetSpellTargetLocation(), HoursToSeconds(nDuration))wink3.gif но ничего не произошло.
Neverwinter Script
effect eSummonedMonster = EffectSummonCreature(sSummon, nFNF_Effect);
   if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_CONJURATION))
{
  object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED);
  effect eBonus = EffectAbilityIncrease(ABILITY_STRENGTH, 4);
  ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBonus, oSummon);
            }
    return eSummonedMonster;

-3-Сделал такой код в спелхук и в спеллах поменял "GetSpellSaveDC()" на "nDC()" - работает.
Neverwinter Script
int nDC() {
int nCasterLevel = GetCasterLevel(OBJECT_SELF);
    int nSpellDC;
    if(nCasterLevel <= 20)
            {
            nSpellDC = GetSpellSaveDC();
            }
    if((nCasterLevel >= 21) && (nCasterLevel <= 21))
            {
            nSpellDC = GetSpellSaveDC() + 10;
            }
    if(nCasterLevel >= 22)
            {
            nSpellDC = GetSpellSaveDC() + 20;
            }
    return nSpellDC;
}

-4-Сделал такой код для учета уровней ПМа в кастер лвл. Но для его работы придется во всех спелах изменить "nCasterLevel" на "nCasterLevel()" в т.ч. и в предыдущем скрипте.
Neverwinter Script
int nCasterLevel() {
int nCL = GetCasterLevel(OBJECT_SELF);
    int nEpicMod = GetLevelByClass(CLASS_TYPE_PALEMASTER,OBJECT_SELF);
    if (nEpicMod>0)
    {
        nCL += (nEpicMod/2);//missstorm1\2
    }
    return nCL;
}
denis0k
Можно всё-таки полный скрипт саммона, а не куски? От начала до конца.
StasMokos
Приветствую всех!
Обращаюсь к вам за помощью со следующей проблемой: не работает функция FadeFromBlack (ну или мы что-то неправильно делаем). Всегда с ней отлично работалось, а тут...
Суть вот в чем: ГГ разговаривает с объектом и спутником, в конце диалога они телепортируются на другие точки. Во время телепортации как раз таки нужен черный занавес.
Прикрепляю код. Скрипт стоит на разговоре с объектом.
Надеюсь на ваш совет!

Neverwinter Script
void main()
{
  object oPC = GetFirstPC();
  object oSarg = GetObjectByTag ("sargu_olu");
  int iECHO = GetLocalInt (oPC, "snov_echo_n");

//всякое не относящееся к сути вопроса
  int iECHOn = iECHO + 1;
  SetLocalInt (oPC, "snov_echo_n", iECHOn);
  DelayCommand (1.0, DestroyObject (OBJECT_SELF));
  GiveXPToCreature(oPC, 15);
  AddJournalQuestEntry ("DN_snov_echo", iECHOn+1, oPC);
  CreateObject(OBJECT_TYPE_PLACEABLE, "sno_echo", GetLocation(GetObjectByTag ("snov_krup")));

//удаление спутника, чтобы прыгнуть на разные точки с ГГ
  RemoveHenchman(oPC, oSarg);

//телепортация
  DelayCommand (1.0, AssignCommand(oPC, JumpToObject(GetObjectByTag("WP_sno_spawn1"))));
  DelayCommand (1.0, AssignCommand(oSarg, JumpToObject(GetObjectByTag("WP_sno_spawn2"))));
  SetLocalInt(oPC, "di_sargu_1", 2);

//экран
  AssignCommand(oPC, FadeToBlack(oPC, FADE_SPEED_FAST));
  DelayCommand (2.0, ClearAllActions());
  DelayCommand (4.0, FadeFromBlack(oPC, FADE_SPEED_FAST));
}
denis0k
Просто догадка. В катсценах фейдят как действие, мб объект надо разрушать не через секунду, а через пять, чтобы он последнюю строку успел сделать? smile.gif
Melisse
сделайте так

Neverwinter Script
//экран
  AssignCommand(oPC, FadeToBlack(oPC, FADE_SPEED_FAST));
  AssignCommand(oPC, DelayCommand (4.0, FadeFromBlack(oPC, FADE_SPEED_FAST)));


как и сказал dens0k вы разрушаете объект и DelayCommand не срабатывает из-за этого, так как она не привязана к герою, а висит на хенче. Поэтому лучше вешать или на модуль или на PC
StasMokos
Спасибо большое, все получилось!
И заодно стала понятнее логика при работе с DelayCommand good.gif
zmeylsdn
-1- Задумал я бонус к ДЦ спелла брать из мейн стата кастера:
Neverwinter Script
int nDC() { // replace GetSpellSaveDC() to nDC() in all spells with DC .
int nCasterLevel = GetCasterLevel(OBJECT_SELF);
    int nSpellDC;

    if(nCasterLevel <= 39)
            {
            nSpellDC = GetSpellSaveDC() + (GetCasterAbMod())/2;
            }
    if(nCasterLevel >= 40)
            {
            nSpellDC = GetSpellSaveDC() + GetCasterAbMod();
            }
    return nSpellDC;
}

В x0_i0_spells есть подобное, но там проверка только для виза и сорка что меня смутило:
Neverwinter Script
/*
    Returns the modifier from the ability
    score that matters for this caster
*/

int GetCasterAbilityModifier(object oCaster)
{
    int nClass = GetLevelByClass(CLASS_TYPE_WIZARD, oCaster);
    int nAbility;
    if (nClass > 0)
    {
        nAbility = ABILITY_INTELLIGENCE;
    }
    else
        nAbility = ABILITY_CHARISMA;

    return GetAbilityModifier(nAbility, oCaster);
}

Я решил написать проверку для всех кастеров:
Neverwinter Script
int GetCasterAbMod(object oCaster)
{
    int nAbility;
    int nClass = GetLastSpellCastClass();
    if (nClass = CLASS_TYPE_WIZARD)
    {
        nAbility = ABILITY_INTELLIGENCE;
    }
    if (nClass == CLASS_TYPE_CLERIC || nClass == CLASS_TYPE_DRUID ||
        nClass == CLASS_TYPE_RANGER || nClass == CLASS_TYPE_PALADIN)
    {
        nAbility = ABILITY_WISDOM;
    }
    if (nClass == CLASS_TYPE_SORCERER || nClass == CLASS_TYPE_BARD)
    {
        nAbility = ABILITY_CHARISMA;
    }
    return GetAbilityModifier(nAbility, oCaster);
}

int nDC() { // replace GetSpellSaveDC() to nDC() in all spells with DC .
int nCasterLevel = GetCasterLevel(OBJECT_SELF);
    int nDiff = GetCasterAbMod(OBJECT_SELF);
    int nSpellDC;

    if(nCasterLevel <= 39)
            {
            nSpellDC = GetSpellSaveDC() + nDiff/2;
            }
    if(nCasterLevel >= 40)
            {
            nSpellDC = GetSpellSaveDC() + nDiff;
            }
    return nSpellDC;
}

Компилится но работает странно, не сходятся цифры и разный эффект для цепной молнии и крика баньши. Думаю проблема в функции "GetLastSpellCastClass()", но GetLevelByClass и GetClassByPosition единственное что нашел по этому поводу и выглядит неподходяще.

-2- Полный скрипт самона
Neverwinter Script
//::///////////////////////////////////////////////
//:: Summon Creature Series
//:: NW_S0_Summon
//:: Copyright © 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Carries out the summoning of the appropriate
    creature for the Summon Monster Series of spells
    1 to 9
*/

//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 8, 2002
//:://////////////////////////////////////////////

effect SetSummonEffect(int nSpellID);

#include "x2_inc_spellhook"

void main()
{

/*
  Spellcast Hook Code
  Added 2003-06-23 by GeorgZ
  If you want to make changes to all spells,
  check x2_inc_spellhook.nss to find out more

*/


    if (!X2PreSpellCastCode())
    {
    // If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
        return;
    }

// End of Spell Cast Hook


    //Declare major variables
    int nSpellID = GetSpellId();
    int nDuration = GetCasterLevel(OBJECT_SELF);
    nDuration = 24;
    if(nDuration == 1)
    {
        nDuration = 2;
    }
    effect eSummon = SetSummonEffect(nSpellID);

    //Make metamagic check for extend
    int nMetaMagic = GetMetaMagicFeat();
    if (nMetaMagic == METAMAGIC_EXTEND)
    {
        nDuration = nDuration *2;   //Duration is +100%
    }
    //Apply the VFX impact and summon effect

    ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eSummon, GetSpellTargetLocation(), HoursToSeconds(nDuration));
//добавленные строки
    if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_CONJURATION))
    {
    object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED);
    effect eBonus = EffectAbilityIncrease(ABILITY_STRENGTH, 12);
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBonus, oSummon);
    }
}


effect SetSummonEffect(int nSpellID)
{
    int nFNF_Effect;
    int nRoll = d3();
    int nCasterLevel = GetCasterLevel(OBJECT_SELF);   //21+ caster lvl +20lvls to each mob
    string sSummon;
        if(nSpellID == SPELL_SUMMON_CREATURE_I)
        {
            nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1;
            sSummon = "NW_S_badgerdire"//NW_S_badgerdire
            if(nCasterLevel >= 21)
            {
            sSummon = "z_s11";
            }
        }
        else if(nSpellID == SPELL_SUMMON_CREATURE_II)
        {
            nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1;
            sSummon = "z_s2"//NW_S_BOARDIRE
            if(nCasterLevel >= 23)
            {
            sSummon = "z_s12";
            }
        }
        else if(nSpellID == SPELL_SUMMON_CREATURE_III)
        {
            nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1;
            sSummon = "z_s3"//NW_S_WOLFDIRE
            if(nCasterLevel >= 25)
            {
            sSummon = "z_s13";
            }
        }
        else if(nSpellID == SPELL_SUMMON_CREATURE_IV)
        {
            nFNF_Effect = VFX_FNF_SUMMON_MONSTER_2;
            sSummon = "z_s4"//NW_S_SPIDDIRE
            if(nCasterLevel >= 27)
            {
            sSummon = "z_s14";
            }
        }
        else if(nSpellID == SPELL_SUMMON_CREATURE_V)
        {
            nFNF_Effect = VFX_FNF_SUMMON_MONSTER_2;
            sSummon = "z_s5"//NW_S_beardire
            if(nCasterLevel >= 29)
            {
            sSummon = "z_s15";
            }
        }
        else if(nSpellID == SPELL_SUMMON_CREATURE_VI)
        {
            nFNF_Effect = VFX_FNF_SUMMON_MONSTER_2;
            sSummon = "z_s6"//NW_S_diretiger
            if(nCasterLevel >= 31)
            {
            sSummon = "z_s16";
            }
        }
        else if(nSpellID == SPELL_SUMMON_CREATURE_VII)
        {
            nFNF_Effect = VFX_FNF_SUMMON_MONSTER_3;
            switch (nRoll)
            {
                case 1:
                    sSummon = "NW_S_AIRHUGE";   //NW_S_AIRHUGE
                break;

                case 2:
                    sSummon = "NW_S_WATERHUGE"; //NW_S_WATERHUGE
                break;

                case 3:
                    sSummon = "NW_S_FIREHUGE"//W_S_FIREHUGE
                break;
            }
            if(nCasterLevel >= 33)
            {
            sSummon = "z_s17";
            }
        }
        else if(nSpellID == SPELL_SUMMON_CREATURE_VIII)
        {
            nFNF_Effect = VFX_FNF_SUMMON_MONSTER_3;
            switch (nRoll)
            {
                case 1:
                    sSummon = "NW_S_AIRGREAT";   //NW_S_AIRGREAT
                break;

                case 2:
                    sSummon = "NW_S_WATERGREAT"//NW_S_WATERGREAT
                break;

                case 3:
                    sSummon = "NW_S_FIREGREAT"; //NW_S_FIREGREAT
                break;
            }
            if(nCasterLevel >= 35)
            {
            sSummon = "z_s18";
            }
        }
        else if(nSpellID == SPELL_SUMMON_CREATURE_IX)
        {
            nFNF_Effect = VFX_FNF_SUMMON_MONSTER_3;
            switch (nRoll)
            {
                case 1:
                    sSummon = "NW_S_AIRELDER"//NW_S_AIRELDER
                break;

                case 2:
                    sSummon = "NW_S_WATERELDER";    //NW_S_WATERELDER
                break;

                case 3:
                    sSummon = "NW_S_FIREELDER"; //NW_S_FIREELDER
                break;
            }
            if(nCasterLevel >= 37)
            {
            sSummon = "z_s19";
            }
        }
    //effect eVis = EffectVisualEffect(nFNF_Effect);
    //ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetSpellTargetLocation());
    effect eSummonedMonster = EffectSummonCreature(sSummon, nFNF_Effect);
    return eSummonedMonster;
}


П.С. Мне кажется через OnSpawn реалиация была бы более экономичной, так что вопрос остается открытым, что же здесь не так:
Neverwinter Script
object oMaster = GetMaster(); //в OnSpawn
if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_CONJURATION, oMaster))
{
  object oTarget = OBJECT_SELF;
  effect eBonus = EffectAbilityIncrease(ABILITY_STRENGTH, 4);
  ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBonus, oTarget);
  }
denis0k
Neverwinter Script
if (nClass = CLASS_TYPE_WIZARD)
Это баг, условие всегда возвращает 1, т.к. одно "=" smile.gif
Цитата
Компилится но работает странно, не сходятся цифры и разный эффект для цепной молнии и крика баньши. Думаю проблема в функции "GetLastSpellCastClass()", но GetLevelByClass и GetClassByPosition единственное что нашел по этому поводу и выглядит неподходяще.
Ну не зная всех условий и имея гадалку в отпуске, помочь вряд ли чем-то можно smile.gif

По саммону непонятно. Я в таких случаях начинаю усиленно дебажить - ставлю по коду кучу sendmessage с выводом в лог значений переменных и проходов по условиям/циклам.
zmeylsdn
-1- По бонусу к ДЦ спела от основной кастерской характеристики.
Добавил "=", теперь определяет мейн стат верно, проверено на сорке и визе.
Условия: оба (сорк и виз) имеют базу мейнстата 18, все апы в мейнстат, итого на 40м 50 мейнстата = +20 модификатор. Взяты ЭпикФокусы на Разрушении и некромантии.

Согласно добавленному коду, до 39го уровня включительно к ДЦ спелла должен добавлятся 150% мейнстата: 100% согласно оригиналу и 50% от кода (+ (GetCasterAbMod())/2).
С 40го - 200% мейнстата: 100% согласно оригиналу и 100% от кода (+ (GetCasterAbMod())).

ДЦ оригинального нвн:
ЦепьМолний, ЦМ (6круг) = (10 база +6 ЭпикФокус +6 круг =22) +20 мод стата =42 (22+20*2=62 на 40м с бонусом либо 22+19*1,5=50 на 39м с бонусом)
Баньша, Б (9круг) = (10 база +6 ЭпикФокус +9 круг =25) +20 мод стата =45 (25+20*2=65 на 40м с бонусом либо 25+19*1,5=53 на 39м с бонусом)

Тесты показали следующие ДЦ спелов:
40й сорк\виз 20 мод хари\инты: ЦМ-62 (правильно), Б-62 (меньше, должно быть 65 =25+20*2)
40й сорк\виз 14 мод хари\инты: ЦМ-50 (правильно), Б-56 (больше, должно быть 53 =25+14*2)

39й сорк 19 мод хари: ЦМ-50 (правильно), Б-54 (больше, должно быть 53 =25+19*1,5)
39й сорк 13 мод хари: ЦМ-41(правильно), Б-48 (больше, должно быть 44 =25+13*1,5)

Проверил так же Перст Смерти и обычную Молнию, их ДЦ работает правильно. В спеллах менялось только GetSpellSaveDC() на nDC(). С предыдущей формулой где давался фиксированный бонус или в зависимости от уровня ((nCasterLevel - 19)/2), оба спела работали корректно.
denis0k
В таких случаях только дебаг smile.gif Выводить все этапы в лог и смотреть, где начинают идти не те цифры.
zmeylsdn
А как вообще делать дебаг и смотреть цифры?
denis0k
Поскольку дебагера в нвн нет, приходится тупо делать sendmessagetopc(getfirstpc(), ***) в разных местах кода. Так можно выводить переменные, показывать, что скрипт вошёл в условие/цикл и т.п. Потом эти строки можно закомментить, пока снова баг не вылезет smile.gif
zmeylsdn
Как сделать ограничение по уровню для предмета? И задать свою стоимость например
Melisse
Ограничение по уровню вроде бы работает только для серверной части - шардов.
Задать свою стоимость предмета вы не можете обычными для игры способами, т.к. она зависит от кол-ва свойств, можно разве что дополнить через строчку в свойствах - "дополнительная" или как-то так на русском. Есть несколько вариантов шаманства с 2да файлами, но это все костыль.


Там в *.ini надо что-то настроить - и можно выводить ошибки скриптов и функций, но ограничено, в основном пользуются SendMessageToPC(GetFirstPC(), "бла-бла");
denis0k
Цитата(zmeylsdn @ Feb 5 2019, 17:25) *
Как сделать ограничение по уровню для предмета? И задать свою стоимость например
Стоимость можно только увеличивать, если без гемора. Ограничение можно сделать скриптово - на одевание вставить проверку и снимать, если не дорос.

Иначе там адъ и израиль smile.gif На цену влияют коэффициенты свойств из 2да-таблиц, я даже не рисковал пытаться в них разбираться.
zmeylsdn
Большой спасибо за помощь
zmeylsdn
-1- в NW_S0_Summon
CODE
object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED);
effect eBonus = EffectAbilityIncrease(ABILITY_STRENGTH, 10);
if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_CONJURATION
))
{
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBonus, oSummon);
}
SendMessageToPC(GetFirstPC(), "oSummon: " + GetName(oSummon)); //в игре "oSummon: " или "oSummon: Ужасный барсук"
(имя предыдущего вызванного существа).

}

Видимо не успевает найти самона.
-2- в OnSpawn существа
CODE
object oMaster = GetMaster(OBJECT_SELF);
if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_CONJURATION
, oMaster))
{
object oTarget = OBJECT_SELF;
effect eBonus = EffectAbilityIncrease(ABILITY_STRENGTH, 10);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBonus, oTarget);
}
SendMessageToPC(GetFirstPC(), "oMaster: " + GetName(oMaster)); //в игре "oMaster: "
//SendMessageToPC(GetFirstPC(), "I`m: " + GetName(OBJECT_SELF)); в игре "I`m: Ужасный барсук"
}

видимо не находит мастера. нашел в nwn lexicon такую инфу: "Known bugs. This function (GetMaster()) always returns OBJECT_INVALID when used in creature OnSpawn event. To get correct results, use this function with slight delay or in signal event."
Вопрос теперь как эту строку "object oMaster = GetMaster(OBJECT_SELF);" выполнить с задержкой?
//ActionWait(2.0);
//AssignCommand(OBJECT_SELF, ActionWait(2.0));
не оказали эффекта, а как применить DelayCommand(2.0)); с сохранением привязки к переменной oMaster идей нет.
denis0k
Тогда предлагаю сделать отдельный скрипт и запускать его из спавна как delaycommand(executescript).
zmeylsdn
Оба варианта, и OnSpawn, и внутри скрипта вызова, работают с DelayCommand(1.0, ExecuteScript("z_sbuff_onspawn", OBJECT_SELF));
Биг, биг спс.
Нашел как применить несколько эффектов сразу. Но не получается оптимизировать код.
CODE
void main()
{
object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED);
if(GetHasFeat(FEAT_EPIC_SPELL_FOCUS_CONJURATION))
{
effect eStr = EffectAbilityIncrease(ABILITY_STRENGTH, 6);
effect eCon = EffectAbilityIncrease(ABILITY_CONSTITUTION, 6);
effect eDam = EffectDamageIncrease(DAMAGE_BONUS_6, DAMAGE_TYPE_BLUDGEONING);
effect eAtt = EffectAttackIncrease(6);
effect eAC = EffectACIncrease(6, AC_DODGE_BONUS, AC_VS_DAMAGE_TYPE_ALL);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eStr, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eCon, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDam, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAtt, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAC, oSummon);
}
else if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_CONJURATION
))
{
effect eStr = EffectAbilityIncrease(ABILITY_STRENGTH, 4);
effect eCon = EffectAbilityIncrease(ABILITY_CONSTITUTION, 4);
effect eDam = EffectDamageIncrease(DAMAGE_BONUS_4, DAMAGE_TYPE_BLUDGEONING);
effect eAtt = EffectAttackIncrease(4);
effect eAC = EffectACIncrease(4, AC_DODGE_BONUS, AC_VS_DAMAGE_TYPE_ALL);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eStr, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eCon, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDam, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAtt, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAC, oSummon);
}
else if(GetHasFeat(FEAT_SPELL_FOCUS_CONJURATION))
{
effect eStr = EffectAbilityIncrease(ABILITY_STRENGTH, 2);
effect eCon = EffectAbilityIncrease(ABILITY_CONSTITUTION, 2);
effect eDam = EffectDamageIncrease(DAMAGE_BONUS_2, DAMAGE_TYPE_BLUDGEONING);
effect eAtt = EffectAttackIncrease(2);
effect eAC = EffectACIncrease(2, AC_DODGE_BONUS, AC_VS_DAMAGE_TYPE_ALL);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eStr, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eCon, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDam, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAtt, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAC, oSummon);
}
}

Например, такой вариант не срабатывает:
CODE
void main()
{
object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED);
int eBonus;
effect eStr = EffectAbilityIncrease(ABILITY_STRENGTH, eBonus);
effect eCon = EffectAbilityIncrease(ABILITY_CONSTITUTION, eBonus);
effect eDam = EffectDamageIncrease(eBonus, DAMAGE_TYPE_BLUDGEONING);
effect eAtt = EffectAttackIncrease(eBonus);
effect eAC = EffectACIncrease(eBonus, AC_DODGE_BONUS, AC_VS_DAMAGE_TYPE_ALL);
if(GetHasFeat(FEAT_EPIC_SPELL_FOCUS_CONJURATION))
{
eBonus = 6;
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eStr, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eCon, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDam, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAtt, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAC, oSummon);
}
}
ud4ever
Цитата(zmeylsdn @ Feb 22 2019, 11:53) *
Оба варианта, и OnSpawn, и внутри скрипта вызова, работают с DelayCommand(1.0, ExecuteScript("z_sbuff_onspawn", OBJECT_SELF));
Биг, биг спс.
Нашел как применить несколько эффектов сразу. Но не получается оптимизировать код.


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

CODE

// в подключаемом стандартном инклюде NWN содержится нужный скрипт который привожу ниже закомментированным на всякий случай
#include "x2_inc_itemprop"

/*

int IPGetDamageBonusConstantFromNumber(int nNumber)
{
switch (nNumber)
{
case 1: return DAMAGE_BONUS_1;
case 2: return DAMAGE_BONUS_2;
case 3: return DAMAGE_BONUS_3;
case 4: return DAMAGE_BONUS_4;
case 5: return DAMAGE_BONUS_5;
case 6: return DAMAGE_BONUS_6;
case 7: return DAMAGE_BONUS_7;
case 8: return DAMAGE_BONUS_8;
case 9: return DAMAGE_BONUS_9;
case 10: return DAMAGE_BONUS_10;
case 11: return DAMAGE_BONUS_11;
case 12: return DAMAGE_BONUS_12;
case 13: return DAMAGE_BONUS_13;
case 14: return DAMAGE_BONUS_14;
case 15: return DAMAGE_BONUS_15;
case 16: return DAMAGE_BONUS_16;
case 17: return DAMAGE_BONUS_17;
case 18: return DAMAGE_BONUS_18;
case 19: return DAMAGE_BONUS_19;
case 20: return DAMAGE_BONUS_20;

}

if (nNumber>20)
{
return DAMAGE_BONUS_20;
}
else
{
return -1;
}
}

*/

void EmpowerMySummon(int iBonus, object oSummon)
{
effect eSummonBonuses=EffectAbilityIncrease(ABILITY_STREN
GTH, iBonus);
eSummonBonuses= EffectLinkEffects(EffectAbilityIncrease(ABILITY_CO
NSTITUTION, iBonus),eSummonBonuses);
eSummonBonuses = EffectLinkEffects(EffectDamageIncrease(IPGetDamage
BonusConstantFromNumber(iBonus), DAMAGE_TYPE_BLUDGEONING),eSummonBonuses);
eSummonBonuses = EffectLinkEffects(EffectAttackIncrease(iBonus),eSu
mmonBonuses);
eSummonBonuses = EffectLinkEffects(EffectACIncrease(iBonus, AC_DODGE_BONUS, AC_VS_DAMAGE_TYPE_ALL),eSummonBonuses);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eSummonBonuses, oSummon);
}

void main()
{
object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED);
if(GetHasFeat(FEAT_EPIC_SPELL_FOCUS_CONJURATION))
{
EmpowerMySummon(6,oSummon);
}
else if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_CONJURATION
))
{
EmpowerMySummon(4,oSummon);
}
else if(GetHasFeat(FEAT_SPELL_FOCUS_CONJURATION))
{
EmpowerMySummon(2,oSummon);
}
}
zmeylsdn
Спасибо, работает.
Существует ли способ определить школу волшебника-специалиста и применить к ней же какие либо бонусы, например +2 spellDC?
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Invision Power Board © 2001-2025 Invision Power Services, Inc.