Помощь - Поиск - Пользователи - Календарь
Полная версия: Скрипты: Все вопросы
Город Мастеров > РЕДАКТОРЫ > Neverwinter Nights 2 Obsidian Toolset
Страницы: 1, 2, 3, 4, 5, 6, 7
Melshin
Реализую не стакающиеся бонусы к атаке разноименных типов (ДнД 3.5, ем буквы).

Вариант 1:

Код
effect MoraleBonus (effect eEffect)
{
    eEffect = SetEffectSpellId (eEffect, 1600);
    return eEffect;
}



Вариант 2 - хранение переменных/массивов на объекте-цели или в БД.

Вопрос - как сделать все так, чтобы и диспелл был меньше, чем на 20 страниц кода и длительность нескольких разных спеллов с одноименными эффектами выверялась нормально?

P.S. только что задумался о создании динамического списка на модуле...

Если что, у нас есть еще вот такой список своих функций:

void AppendArrayInt(object obj,string bufName,int value);
int GetArrayInt(object obj,string bufName,int index);
void SetArrayInt(object obj,string bufName,int index,int value);

void AppendArrayLoc(object obj,string bufName,location value);
location GetArrayLoc(object obj,string bufName,int index);
void SetArrayLoc(object obj,string bufName,int index,location value);

void AppendArrayString(object obj,string bufName,string value);
string GetArrayString(object obj,string bufName,int index);
void SetArrayString(object obj,string bufName,int index,string value);

void AppendArrayFloat(object obj,string bufName,float value);
float GetArrayFloat(object obj,string bufName,int index);
void SetArrayFloat(object obj,string bufName,int index,float value);


void AppendArrayObject(object obj,string bufName,object value);
object GetArrayObject(object obj,string bufName,int index);
void SetArrayObject(object obj,string bufName,int index,object value);


void DestroyArray(object obj,string bufName,int type=tINT);
int IsArraySet(object obj,string bufName);
int GetArrayIdxCount(object obj,string bufName);
void DestroyArrayIdx(object obj,string bufName,int index,int type=tINT);
int Split(object obj,string str,string bufName,int type=tSTR,string separator=",");
int SplitCount(string str,string separator=",");
void OutputArray(object obj,string bufName,int type,object oPC=OBJECT_INVALID);

void CreateMatrix(object obj,string bufName,int width,int height);
void DeleteMatrix(object obj,string bufName,int type=tINT);
void ExpandMatrix(object obj,string bufName,int xcount,int ycount);
int GetMatrixInt(object obj,string bufName,int x,int y);
string GetMatrixString(object obj,string bufName,int x,int y);
float GetMatrixFloat(object obj,string bufName,int x,int y);
object GetMatrixObject(object obj,string bufName,int x,int y);
void SetMatrixInt(object obj,string bufName,int x,int y,int value);
void SetMatrixString(object obj,string bufName,int x,int y, string value);
void SetMatrixFloat(object obj,string bufName,int x,int y,float value);
void SetMatrixObject(object obj,string bufName,int x,int y,object value);
Melshin
Цитата
P.S. только что задумался о создании динамического списка на модуле...


Начал. Вопрос к опытным мастерам: стоит ли? Будет ли у этого нормальная производительность?

Смысл вышенаписанного: при загрузке в модуль первого персонажа инициализируется рекурсивная (6 секунд) ProcessEffects (). На модуле хранится массив, в котором каждый элемент - объект, на котором находится эффект какого-то заклинания или еще чего. На каждом объекте хранится массив, в котором каждый элемент - какой-то SpellId. Для каждого существующего SpellId берутся локальные интеджеры: кастер лвл, длительность в раундах, ДЦ (если нужно, еще можно весь дамаг для ДОТ-ов сразу рассчитать, т.к. всякие эмповерд нехорошие). Если длительность не закончилась - держим на объекте эффект заклинания 6 секунд до следующего выполнения ProcessEffects. Если длительность закончилась - стираем нафиг спелл из массива и всю информацию о нем. Если объект подвергся диспеллу - работаем с соответствующим массивом.

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

Так вот собственно объектов в модуле много, на каждом может быть несколько спеллов, а в каждом спелле разные эффекты...
Merkuta
Извините если не по теме, но есть ли русскоязычные статьи по основам скриптинга для nwn2? Я недавно взялся за тулсет. Освоил практически всё кроме скриптов и не знаю как к ним подступиться. С использованием готовых скриптов в диалогах вроде разобрался, но дальше никак.

Вот например, нужны такие скрипты:

1) Если переменная Local Int "XXXXX" принимает значение 1, начинается отсчёт времени, после которого переменная возвращается в значение 0.

2) Если игрок покидает локацию, все открытые двери в этой локации закрываются.

3) Если в сундуке А есть вещи, они переносятся в сундук Б.
Lorendroll
Merkuta,
1) Для этого переменная твоя должна быть локальной, и где-то храниться. Например на игроке. Для этого задавай ее так:
Neverwinter Script
object oPC = GetFirstPC(); //будет брать первого игрока в модуле. Если игрок один это сработает. Иначе придумай как нам найти нужного (зависит от того, откуда запускается скрипт)

SetLocalInt(oPC, "A", 1); //А = 1


В другом месте, где надо ее проверять и запускать таймер, пиши:

Neverwinter Script
object oPC = GetFirstPC();

int A = GetLocalInt(oPC, "A"); //берем с первого попавшегося игрока переменную А

if (A == 1)
{
float fTime = 10.0; //через сколько секунд занулять будем?
DelayCommand(fTime, SetLocalInt(oPC, "A", 0));
}


2) Это намного сложнее.

3) Здесь нужно организовать цикл перебора всех вещей в сундуке А и копирования их в сундук Б.

Напиши мне в аську/пм, подскажу по ходу дела, если нужно.


Melshin, думаю если воспользуешься NWNX и подрубишь внешнюю БД, то производительность будет норм. Если юзать стандартные скрипты для работы с массивами - загрузишь его серьезно. Но наверняка не могу говорить.
Kcapra
Здрасте.
Нужно на хартбит повесить функцию, которая будет отсчитывать внутриигровое время начиная с первой загрузки модуля.
Neverwinter Script
#include "inc_array_system"

void main()
{
object oPC = GetFirstPC(1);
//if (!GetIsPC(oPC)) return;
int nInt; int nDay; int nMin; int nHr;
nInt = array_get_int(oPC, "timer", 3);
nInt = nInt + 3; //изменяется в зависимости от текущего таймскейла
array_set_int(oPC, "timer", 3, nInt);
/*if (array_get_int(oPC, "timer", 4) == 60)     //seconds into minutes
    {
        nMin = array_get_int(oPC, "timer", 3);
        nMin = nMin + 1;
        array_set_int(oPC, "timer", 3, nMin);
        array_set_int(oPC, "timer", 4, 0);
    }*/

if (array_get_int(oPC, "timer", 3) == 60)     //minutes into hours
    {   
        nHr = array_get_int(oPC, "timer", 2);
        nHr = nHr + 1;
        array_set_int(oPC, "timer", 2, nHr);
        array_set_int(oPC, "timer", 3, 0);
    }
if (array_get_int(oPC, "timer", 2) == 24)    //hours into days
    {   
        nDay = array_get_int(oPC, "timer", 1);
        nDay = nDay + 1;
        array_set_int(oPC, "timer", 1, nDay);
        array_set_int(oPC, "timer", 2, 0);
    }
}


в качестве inc_array_system используется этот скрипт.

Проблема в том, что нифига это ненадежно и недостоверно. Из-за фаст тревелов/возможных кастомных системах отдыхов и прочего. Может быть есть какой-нибудь более простой способ/функции о которых я даже не подозреваю?
Использоваться это будет в сингл модуле.
Lex
самый простой способ работы с игровым временем, имхо, это его пересчет в игровые секунды. Те текущий месяц, день и час пересчитывается в секунды и сравнивается с контрольным для определения, прошло ли нужное количество времени или нет. Этим решается проблема временных скипов в скриптах. Проверять можно не каждые 6 секунд, а лишь когда нужно (в диалоге, в скрипте и тд), что экономит ресурсы. И тд.
Kcapra
Цитата(Lex @ May 26 2010, 21:17) *
самый простой способ работы с игровым временем, имхо, это его пересчет в игровые секунды. Те текущий месяц, день и час пересчитывается в секунды и сравнивается с контрольным для определения, прошло ли нужное количество времени или нет. Этим решается проблема временных скипов в скриптах. Проверять можно не каждые 6 секунд, а лишь когда нужно (в диалоге, в скрипте и тд), что экономит ресурсы. И тд.

Не, для меня это не подходит, нужно чтобы все юзер-френдли было crazy.gif

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

Только топорно все это, и, ввиду малого опыта работы с большими модами, спрашиваю скажется ли это негативно на перфомансе?
denis0k
Почему бы не юзать аптайм в секундах в скриптах, а для юзерфрендли вывода не написать конвертер из секунд в остальное посредством деления с остатком?
Lex
Цитата(Kcapra @ May 26 2010, 18:01) *
Не, для меня это не подходит, нужно чтобы все юзер-френдли было crazy.gif

для юзерфрендлиности нужно все расчеты спрятать внутрь инклуда, оставив снаружи несколько управляющих функций. Например:
* SetTimer(string sTimerName); - запоминаем текущее время и привязываем число к sTimerName для последующей работы с ним пользователя
* CheckTimer(string sTimerName, int nTimeHour, int nTimeMinute = 0); - проверемя разницу между текущим временем и запомненым по идентификатору. Тру - если прошло больше времени, чем указано в nTimeHour/nTimeMinute
* DeleteTimer(string sTimerName); - удалить таймер

Довольно плотно в свое время работал с внутриигровым временем, по своему опыту скажу: в 90% случаев не нужно в каждый момент знать сколько прошло (те каждые 6 секунд ничего пересчитывать не нужно), проверки прохождения энного количества времени стоят в весьма конкретных местах: вход в локу, фраза диалога и тд. У меня было лишь 2-3 случая, когда пришлось повесить на ХБ, потому что отложенное событие было само по себе. В этой связи завязывать систему на постоянный пересчет считаю не совсем верным, пересчет должен быть вызываемым. И пусть в паре случаев вызов будет в ХБ, ничего страшного.
Kcapra
Lex, спасибо, момент с вызовом функции по требованию что-то совсем выпал из головы prankster2.gif
gennady
Тут для теста Аз написал скрипт подсчета игрового времени. Цикл вывода инфы 5 минут, подсчета 1 минута. Может пригодится...
Neverwinter Script
//::///////////////////////////////////////////////
//:: Скрип работает при загрузке модуля
//:: FileName: module_load
//:: auth: azathoth
////////////////////////////////////////////////////////////////////////////////
// *****  ПОДСЧЕТ ВРЕМЕНИ ДЛЯ ТЕСТА  *****
////////////////////////////////////////////////////////////////////////////////
void Count(int nTimer)
{
object oPC = GetFirstPC();
object oMod =  GetModule();
int iHB = GetLocalInt(oMod, "HB_TIME");

SetLocalInt(oMod, "HB_TIME", iHB+1);
if(iHB >= 4)
{
  int iTimeGameM = GetLocalInt(oMod, "Time_Game_M"); //минуты
  int iTimeGameH = GetLocalInt(oMod, "Time_Game_H"); //часы
   SetLocalInt(oMod, "HB_TIME", 0);
  if(iTimeGameM > 55)
   {
    iTimeGameH++;
    SetLocalInt(oMod, "Time_Game_H", iTimeGameH); //часы
    SetLocalInt(oMod, "Time_Game_M", 0); //минуты
   }
  else
   {
    iTimeGameM+=5;
    SetLocalInt(oMod, "Time_Game_M", iTimeGameM);
   }
  SendMessageToPC(oPC, "Длительность игры: "+IntToString(iTimeGameH)+" ч. "+IntToString(iTimeGameM)+" мин.");
}
  DelayCommand(60.0, Count(nTimer + 1));
}
////////////////////////////////////////////////////////////////////////////////
void main()
{

// ================= ДЛЯ ТЕСТА ====================
if (GetLocalInt(GetModule(), "START_TIME_TEST") == 0) // Проверить
  {
   SetLocalInt(GetModule(),"START_TIME_TEST",1);
   Count(0);
  }
}
Merkuta
Мне нужно было написать скрипт, который перемещает вещи из одного сундука в другой. Решил вопрос так:
Neverwinter Script
void main()

{
object oPC = GetFirstPC(),
      oChest_01 = GetObjectByTag("RC_chest_01"),
      oChest_02 = GetObjectByTag("RC_chest_02"),
      oItem = GetFirstItemInInventory(oChest_01),
      oItem_in;
     
//string sString = "скрипт сработал";

while(GetIsObjectValid(oItem))
  {             
  //FloatingTextStringOnCreature(sString, oPC);
  CopyItem(oItem, oChest_02);
  DestroyObject(oItem);
 
  //sString = "скрипт сработал более одного раза";
  oItem = GetNextItemInInventory(oChest_01);         
  }
 
//FloatingTextStringOnCreature("вещей нет", oPC); 
return
}


Однако выяснилось, что предметы типа контейнера не копируются, если в них что-то есть. Копируется только их содержимое.
Сам контейнер пропадает. Попробовал решить вопрос следующим образом(хотя ясно, что это не совсем то, что нужно):

Neverwinter Script
void main()

{
object oPC = GetFirstPC(),
      oChest_01 = GetObjectByTag("RC_chest_01"),
      oChest_02 = GetObjectByTag("RC_chest_02"),
      oItem = GetFirstItemInInventory(oChest_01),
      oItem_in;
     
//string sString = "скрипт сработал";

while(GetIsObjectValid(oItem))
  {             
  //FloatingTextStringOnCreature(sString, oPC);
 
  while(GetHasInventory(oItem)) 
      {      
      oItem_in =  GetFirstItemInInventory(oItem);
     
      while(GetIsObjectValid(oItem_in))     
        {       
        CopyItem(oItem_in, oChest_02);
        DestroyObject(oItem_in);
        oItem_in = GetNextItemInInventory(oItem);   
        }    
       
      CopyItem(oItem, oChest_02);
      DestroyObject(oItem);
      oItem = GetNextItemInInventory(oChest_01);       
      }   
     
  CopyItem(oItem, oChest_02);
  DestroyObject(oItem);
 
  //sString = "скрипт сработал более одного раза";
  oItem = GetNextItemInInventory(oChest_01);         
  }
 
//FloatingTextStringOnCreature("вещей нет", oPC); 
return
}


Но в этом случае предметы из контейнера копируются дважды, а сам контейнер опять же пропадает. Есть идеи, как скопировать контейнер с вложенными в него вещами?
denis0k
Никак. Sad, but true.
Laajin
ну по идеи нужно скопировать/создать сначала сам контейнер
а потом скопировать вещи из одного в другой

у тебя во всех скриптах копируются только вещи
Merkuta
Цитата(Laajin @ Jun 21 2010, 07:05) *
ну по идеи нужно скопировать/создать сначала сам контейнер

И как это сделать?
Во втором скрипте я исходил из того, что после перебора, копирования и удаления всех вещей в контейнере, он станет пустым и скопируется нормально. Но не получилось.
denis0k
Контейнеры вообще зло smile.gif
Цитата
я исходил из того, что после перебора, копирования и удаления всех вещей в контейнере, он станет пустым и скопируется нормально. Но не получилось.
Потому что дестрой только помечает на удаление, удаляются вещи после окончания работы скрипта. Пока скрипт работает, контейнер не пустой.
Цитата
у тебя во всех скриптах копируются только вещи
Нет, там и контейнер мелькает, он тоже ловится при переборе параллельно со своим содержимым.
greye
Цитата(Merkuta @ Jun 5 2010, 11:48) *
Есть идеи, как скопировать контейнер с вложенными в него вещами?

В первом это можно было сделать при помощи ActionGiveItem, но на втором не проверялось.
Хотя можно и с копированием извратиться при особом желании.
Merkuta
Цитата(greye @ Jun 21 2010, 16:54) *
В первом это можно было сделать при помощи ActionGiveItem, но на втором не проверялось.
Хотя можно и с копированием извратиться при особом желании.

Спасибо, контейнер действительно переносится со всеми вложенными вещами.
Neverwinter Script
void main()

{
object oPC = GetFirstPC(),
      oChest_01 = GetObjectByTag("RC_chest_01"),
      oChest_02 = GetObjectByTag("RC_chest_02"),
      oItem = GetFirstItemInInventory(oChest_01),
      oItem_in;
     
//string sString = "скрипт сработал";

while(GetIsObjectValid(oItem))
  {             
  //FloatingTextStringOnCreature(sString, oPC);
  AssignCommand(oChest_01, ActionGiveItem(oItem, oChest_02));
 
 
  //sString = "скрипт сработал более одного раза";
  oItem = GetNextItemInInventory(oChest_01);         
  }
 
//FloatingTextStringOnCreature("вещей нет", oPC); 
return
}

denis0k
Эпично smile.gif Помню даже на волте видел когда-то скрипт, где всё копировалось, а вот контейнер уничтожался, и в комментах было типа "так надо, иначе дюп" smile.gif
Aiwan
Да, здорово... Сразу вспоминается куча проблем при работе с рюкзаками. smile.gif
denis0k
Ну если ActionGiveItem() работает через стек действий, то с игроком может не прокатить (скажем, дроп при смерти, или забитый стек, или дикие лаги). Но вот между сундуками работает smile.gif
Ilerien
Если уж так приспичило, сундук всегда можно пересоздать с палитры rolleyes.gif
greye
Цитата(denis0k @ Jun 22 2010, 08:08) *
то с игроком может не прокатить (скажем, дроп при смерти, или забитый стек, или дикие лаги)

Разве что дикие лаги, потому что остальное обходится без проблем.=)
GoodLuc
Извините, если вопрос не по теме. Я видел, как в обе NWN прикручивали новые навыки (feats). Я понял, что это делали через скрипт, но как?
Кто-нибудь так делал?
Lex
нужно 2da таблицы ковырять: feats + spells + еще пара по мелочи, и конечно же скрипты. Все это довольно подробно описано в разделе Кастом Контент в категории тулсета первого НВН (во втором суть та же, мб чуток больше параметров).
Новые фиты могут быть только активными. Пассивные вещи типа (+1 атака всегда) сделать нельзя, к сожалению. Те можно, но коряво и через попу. Или через nwnx - но это только для мультиплеера.
GoodLuc
Цитата
Все это довольно подробно описано в разделе Кастом Контент в категории тулсета первого НВН

А где именно?
Lex
где-то в этой теме: 2ДА таблицы
PaiNt
Хотел поделится скриптом строкового массива, может мне бы его оптимизировали..


Neverwinter Script
azathoth
Neverwinter Script
if(GetStringLength(sDevider)!=1) sDevider=",";

Ага, незадокумментированная фича!
PaiNt
Цитата(azathoth @ Jul 16 2010, 01:40) *
Neverwinter Script
if(GetStringLength(sDevider)!=1) sDevider=",";

Ага, незадокумментированная фича!

Да, smile.gif вот бы вспомнить как вообще все это работает smile.gif

Поидее функция позволяяет добавлять элемент в конец массива (удлинять массив).
Как и было замечено разделитель предусматривается только односимвольный.
azathoth
Цитата
вот бы вспомнить как вообще все это работает

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

п.с. я не чужд программированию и т.д. т.п., но синтаксиса тулсета не знаю. И на русском ничего не нашел. (А с английским я провожусь не один месяц...)
Lex
на русском есть лишь пара совсем нубских гайдов и пару глав про скрипты в НВН1. Если не чужд программированию, то тебе по сути только функции изучить (циклы, условия, объявление переменных и тд тебе должно быть знакомо, синтаксис си тоже не должен вызвать трудностей). А тут никакой гайд не поможет, только ковыряние.

Более менее приличные гайды есть на английском. Но тоже не фонтан, если честно. Начни изучение с ковыряния уже готовых скриптов (точно зная что они делают), потом пробуй крутить параметры и оценивать результаты. Потом небольшая переделка. И тд. Функции лучше всего изучаются именно так, когда их использовать пытаешься.
Lorendroll
Мне в своё время очень помогли ресурсы www.nwnlexicon.com / nwn1.nwn2lexicon.com и nwn2.wikia.com. Легко переводятся при помощи Google Translate, хотя там довольно просто все написано и так.
А в самом начале мне жутко помогла тулза под названием ScriptGen. Разбирая то, как она генерит скрипты, можно быстро научиться приемам работы.
DilanZendal
Есть у Священника заклинание 4-го круга, называется "Декламация". Действует на всех союзников, давая бонус к атаке, спасброскам и КЗ +2, если божество у цели то же, что у заклинателя, то +3.
Выглядит так:

Neverwinter Script
#include "nwn2_inc_spells"


#include "x2_inc_spellhook"

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

    // Declare major variables
    object oCaster = OBJECT_SELF;
    int nCasterLvl = GetCasterLevel(oCaster);
    float fDuration = RoundsToSeconds(nCasterLvl);
    fDuration = ApplyMetamagicDurationMods(fDuration);
    int nDurType = ApplyMetamagicDurationTypeMods(DURATION_TYPE_TEMPO
RARY);
    location lTarget = GetLocation(oCaster);

    // effects
    effect eAC;
    effect eAttack;
    effect eSave;
    effect eVis = EffectVisualEffect(VFX_DUR_SPELL_RECITATION);
    effect eLink;
   
    // find the first target
    object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_VAST, lTarget, TRUE, OBJECT_TYPE_CREATURE);
   
    while (GetIsObjectValid(oTarget)) {
       if (spellsIsTarget(oTarget, SPELL_TARGET_ALLALLIES, oCaster)) {
      
          //Fire cast spell at event for the specified target
          SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
         
          int nBonus = 2;
          if (GetStringLowerCase(GetDeity(oTarget)) == GetStringLowerCase(GetDeity(oCaster))) {
             nBonus = 3;
          }
          eAC = EffectACIncrease(nBonus, AC_DODGE_BONUS, AC_VS_DAMAGE_TYPE_ALL);
          eAttack = EffectAttackIncrease(nBonus);
          eSave = EffectSavingThrowIncrease(SAVING_THROW_ALL, nBonus, SAVING_THROW_TYPE_ALL);
          eLink = EffectLinkEffects(eAC, eAttack);
          eLink = EffectLinkEffects(eLink, eSave);
          eLink = EffectLinkEffects(eLink, eVis);
      
          RemoveEffectsFromSpell(oTarget, GetSpellId());
      
             //Apply the VFX impact and effects
             ApplyEffectToObject(nDurType, eLink, oTarget, fDuration);
       }
       oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_VAST, lTarget, TRUE, OBJECT_TYPE_CREATURE);
    }      
}



Помогите поправить, пожалуйста. Нужно чтобы под действие заклинания попадали только дружественные аутсайдеры, плюс чтобы не было бонуса для них, если божество совпадает с божеством заклинателя. Как это сделать?
Alian REXis
Цитата(DilanZendal @ Aug 14 2010, 16:35) *
Помогите поправить, пожалуйста. Нужно чтобы под действие заклинания попадали только дружественные аутсайдеры, плюс чтобы не было бонуса для них, если божество совпадает с божеством заклинателя. Как это сделать?

вроде так
Neverwinter Script
#include "nwn2_inc_spells"


#include "x2_inc_spellhook"

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

    // Declare major variables
    object oCaster = OBJECT_SELF;
    int nCasterLvl = GetCasterLevel(oCaster);
    float fDuration = RoundsToSeconds(nCasterLvl);
    fDuration = ApplyMetamagicDurationMods(fDuration);
    int nDurType = ApplyMetamagicDurationTypeMods(DURATION_TYPE_TEMPO
RARY);
    location lTarget = GetLocation(oCaster);

    // effects
    effect eAC;
    effect eAttack;
    effect eSave;
    effect eVis = EffectVisualEffect(VFX_DUR_SPELL_RECITATION);
    effect eLink;
   
    // find the first target
    object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_VAST, lTarget, TRUE, OBJECT_TYPE_CREATURE);
   
    while (GetIsObjectValid(oTarget)) {
      if (spellsIsTarget(oTarget, SPELL_TARGET_ALLALLIES, oCaster)) {
     
          //Fire cast spell at event for the specified target
          SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
         
          int nBonus = 2;
          /*if (GetStringLowerCase(GetDeity(oTarget)) == GetStringLowerCase(GetDeity(oCaster))) {
            nBonus = 3;
          } */

          eAC = EffectACIncrease(nBonus, AC_DODGE_BONUS, AC_VS_DAMAGE_TYPE_ALL);
          eAttack = EffectAttackIncrease(nBonus);
          eSave = EffectSavingThrowIncrease(SAVING_THROW_ALL, nBonus, SAVING_THROW_TYPE_ALL);
          eLink = EffectLinkEffects(eAC, eAttack);
          eLink = EffectLinkEffects(eLink, eSave);
          eLink = EffectLinkEffects(eLink, eVis);
     
          RemoveEffectsFromSpell(oTarget, GetSpellId());
     
            //Apply the VFX impact and effects
          if ((GetRacialType(oTarget)==RACIAL_TYPE_OUTSIDER)&&(!GetIsEnemy(oTarget)))
            ApplyEffectToObject(nDurType, eLink, oTarget, fDuration);
      }
      oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_VAST, lTarget, TRUE, OBJECT_TYPE_CREATURE);
    }     
}
DilanZendal
Несложный скрипт, эффект схож с эпическим "Пламенная аура", но есть еще усиления. Вроде написал все правильно, однако редактор напрочь отказывается компилировать. Помогите, пожалуйста, понять, где я ошибся.

Neverwinter Script
void main()
{
    int nWisdomBonus  = GetAbilityModifier(ABILITY_WISDOM);
    int nDuration = 5 + GetAbilityModifier(ABILITY_WISDOM);
    int nBonus = nWisdomBonus;

    effect eBonAttack = EffectAttackIncrease(nBonus);
    effect eBonDamFire = EffectDamageIncrease(nBonus, DAMAGE_TYPE_FIRE);
    effect eDodgeAc = EffectACIncrease(nBonus, AC_DODGE_BONUS)
    effect eFists = EffectVisualEffect(VFX_DUR_SACRED_FLAMES);
    effect eBody = EffectVisualEffect(VFX_DUR_INNER_ARMOR);

    effect eLink = EffectLinkEffects(eBonAttack, eBonDamPhysic);
    eLink = EffectLinkEffects(eLink, eDodgeAc);
    eLink = EffectLinkEffects(eLink, eFists);
    eLink = EffectLinkEffects(eLink, eBody);

    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, OBJECT_SELF, RoundsToSeconds(nDuration));
}
Merkuta
А у тебя редактор разве не указывает строчку, в которой допущена ошибка? Всего-то точки с запятой нет вот здесь: effect eDodgeAc = EffectACIncrease(nBonus, AC_DODGE_BONUS)
DilanZendal
блин, точно. Вот это называется "невнимательность". Кажется, пора выспаться.
Merkuta, спасибо.
Orochi
Где в 2d прописывать свои названия расс и классов?
Orochi
А? shout.gif
Ghost
Бэ. Когда же вы научитесь искать по форуму, писать в соответствующих темах и не флудить? sad.gif
Orochi
Чувак,ответь на все мои вопросы и я больше не буду писать не в тему,ОК? rolleyes.gif
denis0k
Извините, не удержался. "Чувак" - это кастрированный баран. А "чувиха" - "проститутка" на воровском жаргоне начала 20го века.
Ghost
Цитата(Orochi @ Sep 22 2010, 16:02) *
Чувак,ответь на все мои вопросы и я больше не буду писать не в тему,ОК? rolleyes.gif

Ооо... На "все"(!) ваши вопросы отвечать это дело неблагодарное. И дело даже не в том что я и сам многого не знаю. Вы задали вопрос не по теме, я указал нужную тему где "возможно" эта проблема уже обсуждалась, но Вам мало... Разжевать и в рот положить? Уж пардон за слегка резкий тон... Хотя если честно вообще не вижу с чего вдруг мне оправдываться.
Цитата(denis0k @ Sep 22 2010, 19:55) *
Извините, не удержался...

Забавно. smile.gif Не знал этого. Но так уж и быть, разрешаю администрации и модераторам не бить банхаммером товарища за оскорбление меня. smile.gif
Lex
Цитата(Orochi @ Sep 22 2010, 15:02) *
Чувак,ответь на все мои вопросы и я больше не буду писать не в тему,ОК? rolleyes.gif

Не, чувак, все немного не так. Будешь писать не в тему (или в такой же нагловатой манере, как сейчас) - схлопочешь пред.
Kcapra
Здрасте, мастера.
Либо я вконец отупел за лето, либо садиться за тулсет после сурового рабочего дня не такая уж и хорошая идея.
Суть вот в чем, нужен скрипт, который вешается на хартбит и заставляет непися вещать каждые две минуты какую-нибудь стринговую строку.

Neverwinter Script
void main()

{

if (GetLocalInt(OBJECT_SELF, "script_fired") != TRUE)
    {
        SetLocalInt(OBJECT_SELF, "script_fired", TRUE);
       
        ClearAllActions();
       
        //AssignCommand(OBJECT_SELF, (ActionWait(2.0)));
       
        AssignCommand(OBJECT_SELF, (ActionSpeakString("строка1")));
       
        AssignCommand(OBJECT_SELF, (ActionWait(120.0)));
       
        AssignCommand(OBJECT_SELF, (ActionSpeakString("строка2")));
       
        AssignCommand(OBJECT_SELF, (ActionWait(120.0)));
       
        AssignCommand(OBJECT_SELF, (ActionSpeakString("строка3")));
       
        SetLocalInt(OBJECT_SELF, "script_fired", FALSE);
       
    }


}

Проблема в том, что несмотря на проверку в начале, непись все равно говорит лишь только первую строку каждые шесть секунд...
denis0k
Wait-ы тормозят непися, а не исполнение скрипта. Флаг запуска скидывается сразу же после установки, поэтому через 6 сек скрипт срабатывает по новой.
Kcapra
Ну и как же мне тогда поступить?
А то я хз вообще.
PaiNt
Делай удаление переменной таймера с какии-то периодом. Типа
Neverwinter Script
void main()
{
if(GetLocalInt(OBJECT_SELF, "TIMEOUT"))  return;
SetLocalInt(OBJECT_SELF, "TIMEOUT", TRUE);
DelayCommand(3600.0, DeleteLocalInt(OBJECT_SELF, "TIMEOUT"));


...Твой код
}


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