Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Город Мастеров _ Neverwinter Nights Aurora Toolset _ База скриптов

Автор: Lex Mar 27 2004, 22:00

Сюда выкладывать ваши скрипты и системы скриптов с описанием.
ОБСУЖДЕНИЕ, ВОПРОСЫ И ПРОСЬБЫ О ПОМОЩИ НЕ В ЭТОЙ ТЕМЕ.

ОГЛАВЛЕНИЕ:

-- страница 1 --

* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=42
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=66
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=82
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=764
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=1227
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=1653
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=1833
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=1972
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=2291
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=3216
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=3599
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=5772
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=5811* http://www.wrg.ru/forums/index.php?s=&showtopic=5&view=findpost&p=5833
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=6133
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=6571
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=6707
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=7958
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=8406

-- страница 2 --

*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=8620
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=8736
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=9892
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=9967
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=12810
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=13388
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=13557
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=13562
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=15164
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=16035
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=16055
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=16340
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=16468
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=16487
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=16837
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=17402
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=17576
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=24059
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=24073
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=30675
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31337
*http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31367

-- страница 3 --

* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31599
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31610
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31616
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31671
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31684
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31689
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31691
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31694
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31698
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31700
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31702
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31704
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31706
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31708
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31710
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31712
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31714
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=31716
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=32649
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=33153
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=37456
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=43312
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=44889
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=44977
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=47644

-- страница 4 --
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=47751
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=49250
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=51168
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=55597
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=56638
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=57679
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=58841
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=59145
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=62052
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=68679
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=76917
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=79397
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=79452
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=79471
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=80131
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=81330
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=84401
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=89000
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=90112
* http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=94460




Автор: Tarre T. Apr 2 2004, 15:08

Скрипт мой, все совпадения случайны. Синьки: "blood"-пятно крови.
Так как в ДнД не описано, при каком дамаге и сколько должно выливаться крови у ПС, я буду руководствоваться практическими соображениямиsmile.gif
На онДамагет неписи:

Neverwinter Script Source
#include "damage_system"
void main()
{
BloodEffect();
Talking();
}
.
.................................................
cам инклюд:
..................................................
Neverwinter Script Source
location RandomLocation(object oTarget, float fRadius, int iLine = TRUE)
{
if(!iLine)
fRadius=IntToFloat(Random(FloatToInt(fRadius)));
float iXO=VectorMagnitude(GetPosition(oTarget))*cos(VectorToAngle(GetPosition(oTarget)));
float iYO=VectorMagnitude(GetPosition(oTarget))*sin(VectorToAngle(GetPosition(oTarget)));
float fRndomAngle=IntToFloat(Random(360));
location lNewLoc=Location(GetArea(oTarget),Vector(iXO+fRadius*cos(fRndomAngle), iYO+fRadius*sin(fRndomAngle)), 360.0);
return lNewLoc;}

void BloodEffect()
{
location lRandom1 = RandomLocation(OBJECT_SELF, 4.4, TRUE);
location lRandom2 = RandomLocation(OBJECT_SELF, 3.5, TRUE);
location lRandom3 = RandomLocation(OBJECT_SELF, 1.9, TRUE);
location lOS = GetLocation(OBJECT_SELF);
int iChL;
int iChM;
int iChS;
int iBS;
if (GetRacialType(OBJECT_SELF)==RACIAL_TYPE_HALFORC||
RACIAL_TYPE_HUMANOID_ORC||
RACIAL_TYPE_ABERRATION)
{
iChL = 99;
iChM = 49;
iChS = 19;
iBS = 9;}
else if (GetRacialType(OBJECT_SELF)==RACIAL_TYPE_HUMAN||
RACIAL_TYPE_GNOME||
RACIAL_TYPE_HALFELF)
{
iChL = 131;
iChM = 46;
iChS = 17;
iBS = 6;}
else if (GetRacialType(OBJECT_SELF)==RACIAL_TYPE_ELF||
RACIAL_TYPE_FEY||
RACIAL_TYPE_HALFLING||
RACIAL_TYPE_DWARF)
{
iChL = 9999;
iChM = 43;
iChS = 11;
iBS = 5;}
else
{
iChL = 99;
iChM = 49;
iChS = 19;
iBS = 9;
}
if (GetTotalDamageDealt()>iChL)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_CHUNK_RED_LARGE), OBJECT_SELF);
CreateObject(OBJECT_TYPE_PLACEABLE, "blood", lRandom1);
}
if (GetTotalDamageDealt()>iChM)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_CHUNK_RED_MEDIUM), OBJECT_SELF);
CreateObject(OBJECT_TYPE_PLACEABLE, "blood", lRandom2);
}
if (GetTotalDamageDealt()>iChS)
{
switch (Random(2))
{
case 1:
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_CHUNK_RED_SMALL), OBJECT_SELF);break;
}
case 2:
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_BLOOD_SPARK_MEDIUM), OBJECT_SELF);
break;
}
}
CreateObject(OBJECT_TYPE_PLACEABLE, "blood", lRandom3);
}
if (GetTotalDamageDealt()>iBS)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_BLOOD_SPARK_SMALL), OBJECT_SELF);
}
}

void Talking()
{
string iP;
string sYa = GetName(GetObjectByTag("ax_letter_ya"));
if (GetAlignmentGoodEvil(OBJECT_SELF)==ALIGNMENT_EVIL)
{
switch(Random(6))
{
case 1: iP = "Твои кишки будут мне гарниром!"; break;
case 2: iP = "Тебе не одолеть менz, тварь!"; break;
case 3: iP = "Аа! Мои ноги!Z сдеру с тебz твою шкуру!"; break;
case 4: iP = "Ублюдок, мое лицо!"; break;
case 5: iP = "Сасфанеф! Мои фубы!!"; break;
case 6: iP = "А, рука, рука!"; break;
}
}
else if (GetAlignmentGoodEvil(OBJECT_SELF)==ALIGNMENT_GOOD)
{
switch(Random(6))
{
case 1: iP = "Ааа! Зло будет повержено!"; break;
case 2: iP = "Свет добра обратит тебz в пепел!"; break;
case 3: iP = "Каждаz царапина на мне будет твоей мукой!"; break;
case 4: iP = "Боль! Мне больно! Боги света, взываю к вам!"; break;
case 5: iP = "Ах! моz нога! Латандер накажет тебz за это! "; break;
case 6: iP = "А, рука, рука!"; break;
}
}
if (GetAlignmentLawChaos(OBJECT_SELF)==ALIGNMENT_LAWFUL)
{
switch(Random(6))
{
case 1: iP = "Ааа! эта рана будет стоить тебе дорого!"; break;
case 2: iP = "Мои фубы! Ты отфетеф за это!"; break;
case 3: iP = "Аа! Мои ноги!Z сдеру с тебz твою шкуру!"; break;
case 4: iP = "Гад! Только женщины бьют в пах!"; break;
case 5: iP = "Сасфанеф! Мои фубы!!"; break;
case 6: iP = "А, рука, рука! Где твой здравый смысл?!"; break;
}
}
else if (GetAlignmentLawChaos(OBJECT_SELF)==ALIGNMENT_CHAOTIC)
{
switch(Random(6))
{
case 1: iP = "Твои кишки будут мне гарниром!"; break;
case 2: iP = "Тебе не одолеть менz"; break;
case 3: iP = "Аа! Мои ноги!Z сдеру с тебz твою шкуру!"; break;
case 4: iP = "Гад! мое лицо!"; break;
case 5: iP = "Сасфанеф! Мои фубы!!"; break;
case 6: iP = "А, рука, рука!"; break;
}
}
else if (GetAlignmentLawChaos(OBJECT_SELF)==ALIGNMENT_NEUTRAL)
{
switch (Random(6))
{
case 1: iP = "ааа! Ты нарушаешь равновесие и умрешь за это!"; break;
case 2: iP = "Тебе не одолеть менz"; break;
case 3: iP = "Аа! Мои ноги!Z сдеру с тебz шкуру!"; break;
case 4: iP = "мое лицо! Тир покарает тебz за это!"; break;
case 5: iP = "Нелюфь, мои фубы!!"; break;
case 6: iP = "А, рука, моz рука!!"; break;
}
}
switch (Random(2))
{
case 0: SpeakString(iP);break;
case 1: SpeakString(iP);break;
case 2: break;
}}

Автор: Bot Apr 3 2004, 16:37

Да, РэндомЛокэйшн в предыдущем скрипте взят с форумов рилмс.ру.
Lex: RandomLocation - Бааловский скрипт.
Еще один скрипт. Посмертныйsmile.gifСкрипт мой, все совпадения случайны. Ставится на онДайинг модуля. При смерти ПС ложится на землю и орет, чтобы его лечили. Лечат - выфил, нелечат - постепенно погибает. Когда хп остается меньше (-10) - менять по желанию.

Neverwinter Script Source
void bleed(int iBleedAmt)
{
    effect eBleedEff;
    if (GetCurrentHitPoints() <= 0) {
        if (iBleedAmt > 0) {
            eBleedEff = EffectDamage(iBleedAmt);
        } else {
            eBleedEff = EffectDamage(iBleedAmt);
        }
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eBleedEff, OBJECT_SELF);
        if (GetCurrentHitPoints() <= -10) {
            PlayVoiceChat(VOICE_CHAT_DEATH);
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_DEATH), OBJECT_SELF);
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), OBJECT_SELF);
            return;
        }

        if (iBleedAmt > 0) {
            if (d10(1) == 1) {
                iBleedAmt = -iBleedAmt;
                PlayVoiceChat(VOICE_CHAT_LAUGH);
            } else {
                switch (d6()) {
                    case 1: PlayVoiceChat(VOICE_CHAT_PAIN1); break;
                    case 2: PlayVoiceChat(VOICE_CHAT_PAIN2); break;
                    case 3: PlayVoiceChat(VOICE_CHAT_PAIN3); break;
                    case 4: PlayVoiceChat(VOICE_CHAT_HEALME); break;
                    case 5: PlayVoiceChat(VOICE_CHAT_NEARDEATH); break;
                    case 6: PlayVoiceChat(VOICE_CHAT_HELP);
                }
            }
        }
        DelayCommand(6.0,bleed(iBleedAmt));
    }
}
void main()
{
    object oDying = GetLastPlayerDying();
    AssignCommand(oDying, ClearAllActions());
    AssignCommand(oDying, bleed(1));
    CreateObject(OBJECT_TYPE_CREATURE, "blood", GetLocation(oDying));
}


'blood' -синька крови.

ДЛЯ ВСЕХ: Просьба пользоваться кнопкой NSS. Так удобнее читать и разбираться в скриптах.

Автор: Aiwan Apr 4 2004, 19:31

В общем простой скриптик, экономящий кучу времени и ресурсов. На OnFailToOpen двери. Если дверь закрыта, то при попытке открыть будет стринг из имени вейпоинта WP_DOOR_TXT. Желательно ставить сразу под дверь. Если вы забудете его поставить, то будет сообщение об ошибке.

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Copyright © 2004 WRG!
//:: OnFailToOpen
//:://////////////////////////////////////////////
/*
  WP_DOOR_TXT - вейп с именем нашего текста.
     Ставим его сразу перед нужной дверью.
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 10.01.2004
//:://////////////////////////////////////////////
void main()
{
object oWp = GetNearestObjectByTag("WP_DOOR_TXT"); // БЕРЕМ БЛИЖАЙШИЙ
string sDoor = GetName(oWp);

    if (GetIsObjectValid(oWp) && GetDistanceBetween(oWp, OBJECT_SELF) <= 10.0f)
        //  ЕСЛИ ЕСТЬ ТАКОЙ WP И ОН НЕ ДАЛЬШЕ 10 МЕТРОВ
        {
        SpeakString(sDoor); // ПРОИЗНОСИМ ЕГО ИМЯ
         return;
        }
        else
           {
           SpeakString("Ошибка! Не могу найти WP_DOOR_TXT!");// ЕСЛИ МЫ ЗАБЫЛИ ПОСТАВИТЬ
           return;
           }
}

Автор: Aiwan Apr 23 2004, 08:12

Я тут задумался о пиратах, выползающих из шахт и убивающих мирных жителей Андра-Дуна. :cruel: Вот простенький скрипт на OnAreaTransitionClick . Теперь пираты ждут вас и курят бамбук там где должны biggrin.gif

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Copyright © 2004 WRG!  [URL=http://wrg.ru]http://wrg.ru[/URL]
//:: am_oa_stop
//:://////////////////////////////////////////////
/*
     СКРИПТ ЗАПРЕЩАЮЩИЙ МОНСТРАМ ВЫХОДИТЬ
         ИЗ ЛОКАЦИИ ВСЛЕД ЗА ИГРОКОМ
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan    Aiwan@e-mail.ru
//:: Created On: 21.04.2004
//:://////////////////////////////////////////////
void main()
{
  object oPC = GetEnteringObject();
  object oAnimal = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oPC);
  object oDominated = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oPC);
  object oFamiliar = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oPC);
  object oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC);
  object oSummoned = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC);
  object oJamp = GetTransitionTarget(OBJECT_SELF);

  if (GetIsPC(oPC))
  {
  AssignCommand(oPC, JumpToObject(oJamp));
  AssignCommand(oAnimal, JumpToObject(oJamp));
  AssignCommand(oDominated, JumpToObject(oJamp));
  AssignCommand(oFamiliar, JumpToObject(oJamp));
  AssignCommand(oHenchman, JumpToObject(oJamp));
  AssignCommand(oSummoned, JumpToObject(oJamp));
  }
}

Автор: Baal May 4 2004, 13:28

Neverwinter Script Source
float GetX(location lTarget)
{
return GetPositionFromLocation(lTarget).x;
}

float GetY(location lTarget)
{
return GetPositionFromLocation(lTarget).y;
}

float GetZ(location lTarget)
{
return GetPositionFromLocation(lTarget).z;
}

// lWizLoc - ЛОКАЦИЯ КАСТУЮЩЕГО
// lSpelLoc - ЛОКАЦИЯ ЦЕНТРА СТЕНЫ
// nCount - КОЛЛИЧЕСТВО СИГМЕНТОВ - ПЛЭЙСИБЛОВ
// fSpellTime - ПРОДОЛЖИТЕЛЬНОСТЬ СПЕЛЛА
void IceWallSpell(location lWizLoc, location lSpelLoc, int nCount, float fSpellTime)
{
vector vAB = GetPositionFromLocation(lSpelLoc) - GetPositionFromLocation(lWizLoc);
vAB = Vector(vAB.x,vAB.y);
float fAlfa = VectorToAngle(vAB);
float fAB = VectorMagnitude(vAB);
float fBC = 0.0;
float fX1, fX2, fY1, fY2;
location lLoc1, lLoc2;
object oPlaceable1, oPlaceable2;
string sVR;
int bTrueFalse = TRUE;
///  РЕСРЕФЫ ПЛЭЙСИБЛОВ
string sResRef1 = "plc_box2";
string sResRef2 = "plc_box3";
///  РАЗМЕР ПЛЭЙСИБЛА (РАССТОЯНИЕ МЕЖДУ ЛОКАЦИЯМИ)
float fSize = 1.1;
nCount--;
while(nCount >= 0)
  {
  fBC = fSize*nCount/2;
  fX1 = GetX(lWizLoc) + fAB*cos(fAlfa) + fBC*sin(fAlfa);
  fX2 = GetX(lWizLoc) + fAB*cos(fAlfa) - fBC*sin(fAlfa);
  fY1 = GetY(lWizLoc) + fAB*sin(fAlfa) - fBC*cos(fAlfa);
  fY2 = GetY(lWizLoc) + fAB*sin(fAlfa) + fBC*cos(fAlfa);
  sVR = (bTrueFalse) ? sResRef1 : sResRef2;
  bTrueFalse = !bTrueFalse;
  /// ЛОКАЦИИ
  lLoc1 = Location(GetAreaFromLocation(lWizLoc), Vector(fX1, fY1, GetZ(lSpelLoc)), fAlfa);
  oPlaceable1 = CreateObject(OBJECT_TYPE_PLACEABLE, sVR, lLoc1);
  AssignCommand(oPlaceable1, DelayCommand(fSpellTime, DestroyObject(OBJECT_SELF)));
  if(nCount !=0)
    {
    /// ЛОКАЦИИ
    lLoc2 = Location(GetAreaFromLocation(lWizLoc), Vector(fX2, fY2, GetZ(lSpelLoc)), fAlfa);
    oPlaceable2 = CreateObject(OBJECT_TYPE_PLACEABLE, sVR, lLoc2);
    AssignCommand(oPlaceable2, DelayCommand(fSpellTime, DestroyObject(OBJECT_SELF)));
    }
  nCount = nCount - 2;
  }
return;
}


Этот скрипт я писал для Айс Блэйда, для его проекта ледяной стены. Скрипт должен создавать заданное количество плэйсиблов (сигментов ледяной стены) напротив игрока и дестроить их через заданное время. Пока я использовал синьки сдандартных ящиков smile.gif Всего два вида чередующихся плэйсиблов.

Автор: Lord of V@MPIRES May 8 2004, 15:57

Вы хотите добавить суб-расы в игру ? Пожайлуста ! Пока я еще не добавил им доп. умений, но скоро сделаю... надеюсь... Пока скрипт дает только спец-предмет в зависимости от суб-расы.
Инклуд суб-рас:

Neverwinter Script Source
void GiveSubRaceCWeaponL(string sSubRaceWeapon, object oPC)
{
    object oPC = GetEnteringObject();
    object oRacialWeapon = CreateItemOnObject(sSubRaceWeapon, oPC);
    AssignCommand(oPC, ActionEquipItem(oRacialWeapon, INVENTORY_SLOT_CWEAPON_R));
}

string SR_SubRace(object oPC)
{
    if (GetIsPC(oPC)) {
        object oItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oPC);
        if (GetIsObjectValid(oItem))
        string sSubRace = GetSubRace(oPC);
        string sSRItem = "None";
        int iRace = GetRacialType(oPC);
        if (iRace == RACIAL_TYPE_DWARF) {
            if (sSubRace == "Gold Dwarf") {
                sSRItem = "golddwarfsubitem";
                GiveSubRaceCWeaponL(sSRItem, oPC);
                return sSRItem;
            }
            if (sSubRace == "Gray Dwarf") {
                sSRItem = "graydwarfsubitem";
                GiveSubRaceCWeaponL(sSRItem, oPC);
                return sSRItem;
            }
            if (sSubRace == "Shield Dwarf")
                return sSRItem;
        } // Dwarf
        if (iRace == RACIAL_TYPE_ELF) {
            if (sSubRace == "Moon Elf")
                return sSRItem;
            if (sSubRace == "Sun Elf") {
                sSRItem = "sunelfsubitem";
                GiveSubRaceCWeaponL(sSRItem, oPC);
                return sSRItem;
            }
            if (sSubRace == "Wild Elf") {
                sSRItem = "wildelfsubitem";
                GiveSubRaceCWeaponL(sSRItem, oPC);
                return sSRItem;
            }
            if (sSubRace == "Wood Elf") {
                sSRItem = "woodelfsubitem";
                GiveSubRaceCWeaponL(sSRItem, oPC);
                return sSRItem;
            }
            if (sSubRace == "Drow Elf") {
                sSRItem = "drowsubitem";
                GiveSubRaceCWeaponL(sSRItem, oPC);
                return sSRItem;
            }
        } // Elf
        if (iRace == RACIAL_TYPE_HALFLING) {
            if (sSubRace == "Strongheart Halfling") {
                sSRItem = "";
                GiveSubRaceCWeaponL(sSRItem, oPC);
                return sSRItem;
            }
            if (sSubRace == "Ghostwise Halfling") {
                sSRItem = "";
                GiveSubRaceCWeaponL(sSRItem, oPC);
                return sSRItem;
            }
            if (sSubRace == "Lightfoot Halfling")
                return sSRItem;
        } // Halfling
        if (iRace == RACIAL_TYPE_GNOME) {
            if (sSubRace == "Deep Gnome") {
                sSRItem = "deepgnomesubitem";
                GiveSubRaceCWeaponL(sSRItem, oPC);
                return sSRItem;
            }
            if (sSubRace == "Rock Gnome")
                return sSRItem;
        } // Gnome
     }
    return "None";
}


Теперь скрипт, который ложится в onClientEnter модуля:
Neverwinter Script Source
#include "subrace"
void main()
{
    object oPC = GetEnteringObject();
    AddJournalQuestEntry("sub",0001, oPC);
    string sSubItem = SR_SubRace(oPC);
    if (sSubItem != "None")
    {
    SendMessageToPC(oPC, "Ваш персонаж получает под-расу " + GetSubRace(oPC));
    }
}


Вся фишка моего скрипта суб-расы в том, что он не дает оружие или предмет, а экиптрует, т.е. он на тебе, но в инвентаре его нет ! Например делаем предмет для суб-расы дроу (это темные эльфы, кто не знает):
Создаем кинжал и наделяем его +2 Ловкость, -1 Харизма и -1 Сила.
После этого он одевается ему в слот, которого в интвентаре нет, а х-ки остаются на персонаже.

Автор: Aiwan May 8 2004, 22:02

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

Вешается это добро на разные слоты, либо на OnUnlocked либо на OnDisarm ловушки.

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Copyright © 2004 WRG!  www.wrg.ru
//:://////////////////////////////////////////////
/*
    РАЗДЕЛЕНИЕ ХР ЗА ОТКРЫТИЕ - ОБЕЗВРЕЖИВАНИЕ
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan    Aiwan@e-mail.ru
//:: Created On: 09.05.2004
//:://////////////////////////////////////////////

#include "nw_i0_tool"
void main()
{
//================ ОТКРЫВАЕМ ЗАМОК ================
object oUnlocked = GetLastUnlocked();
if (!GetLocalInt(OBJECT_SELF, "UNLOCKED"))
{
   if (GetIsPC(oUnlocked))
    {
    SetLocalInt(OBJECT_SELF, "UNLOCKED", TRUE);
    GiveXPToCreature(oUnlocked, 100);
    return;
    }
    else
    RewardPartyXP(10, GetFirstPC());
}
//=============== ОБЕЗВРЕЖИВАЕМ ЛОВУШКУ ============
      object oDisarmed = GetLastDisarmed();
      if (!GetLocalInt(OBJECT_SELF, "DISARMED"))
        {
        if (GetIsPC(oDisarmed))
          {
          SetLocalInt(OBJECT_SELF, "DISARMED", TRUE);
          GiveXPToCreature(oDisarmed, 100);
          return;
          }
          else
          RewardPartyXP(10, GetFirstPC());
       }
}

Автор: Aiwan May 9 2004, 12:13

Вот немного переделанный скрипт, кому то понравится больше чем первый.
LEX:Айв, тут у тебя пара косяков есть в коде. Я исправил и дополнил. Не сердись.
СПАСИБО ДБу за идею! good.gif

Neverwinter Script Source
#include "nw_i0_tool"
void main()
{
int iL = GetLockUnlockDC(OBJECT_SELF);
int iT = GetTrapDisarmDC(OBJECT_SELF);
object oDisarmed = GetLastDisarmed();
object oUnlocked = GetLastUnlocked();

//================ ОТКРЫВАЕМ ЗАМОК ================
if ((!GetLocalInt(OBJECT_SELF, "UNLOCKED"))&&(GetIsObjectValid(oUnlocked)))
   {
   SetLocalInt(OBJECT_SELF, "UNLOCKED", TRUE);
   if (HasItem(oUnlocked,GetLockKeyTag(OBJECT_SELF))) return;
   if (GetIsPC(oUnlocked)) // Если замок вскрыл РС
    {
    GiveXPToCreature(oUnlocked, (iL * GetHitDice(oUnlocked)/3));
    // XP = DC двери умноженное на 1/3 уровень РС
    return;
    }
   else // Если замок вскрыл Henchman
    RewardPartyXP((iL*2), GetMaster(oUnlocked));
    // XP = DC двери умноженное на 2
   return;
   }
//=============== ОБЕЗВРЕЖИВАЕМ ЛОВУШКУ ============
if ((!GetLocalInt(OBJECT_SELF, "DISARMED"))&&(GetIsObjectValid(oDisarmed)))
   {
   SetLocalInt(OBJECT_SELF, "DISARMED", TRUE);
   if (HasItem(oDisarmed,GetTrapKeyTag(OBJECT_SELF))) return;
   if (GetIsPC(oDisarmed)) // Если ловушку обезвредил РС
    {
    GiveXPToCreature(oDisarmed, (iT * GetHitDice(oDisarmed)/3));
    // XP = DC ловушки умноженное на 1/3 уровень РС
    return;
    }
   else // Если ловушку обезвредил Henchman
    RewardPartyXP((iT*2), GetMaster(oDisarmed));
    // XP = DC ловушки умноженное на 2
   }
}

Автор: Aiwan May 10 2004, 20:53

Удалить не получается.... smile.gif

Автор: Tarre Talliorne May 13 2004, 15:27

В процессе всем нам часто приходится кидать дайсы. А юзать Рандом+1 неудобно в случае, когда надо, скажем, бросить 3д5. Решил написать скриптину:

Neverwinter Script Source
int XdY(int nX, int nY)
{
int iN=0;
int iResult=0;
    while (iN<nX)
    {
    iResult=iResult+Random(nY)+1;
    iN++;
    }
return iResult;
}

<small>Добавлено в 15:30</small>
Прототип:
Neverwinter Script Source
// get the total from rolling [1]- [nX*Random(xY)+1]
// scripted by TARRE T.
int XdY(int nX, int nY);

Автор: Aiwan May 23 2004, 09:13

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

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Copyright © 2004 WRG!  www.wrg.ru
//:: Name: am_doorlock_d_n
//:://////////////////////////////////////////////
/*
           ЗАПИРАЕТ ДВЕРЬ НА НОЧЬ
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan    Aiwan@e-mail.ru
//:: Created On: 21.05.2004
//:://////////////////////////////////////////////
void main()
{
if((GetIsNight() && GetLocked(OBJECT_SELF))||(GetIsDay() && !GetLocked(OBJECT_SELF)))
      {
      return;
      }
    if (GetIsNight())
        {
        SetLocked(OBJECT_SELF, TRUE);
        return;
        }
      if (GetIsDay())
           {
           SetLocked(OBJECT_SELF, FALSE);
           return;
           }
}

Автор: DBColl May 23 2004, 10:59

Поправлю.

Код
//:://////////////////////////////////////////////
//:: Copyright (c) 2004 WRG!  www.wrg.ru
//:: Name: am_doorlock_d_n
//:://////////////////////////////////////////////
/*
          ЗАПИРАЕТ ДВЕРЬ НА НОЧЬ
*/
//:://////////////////////////////////////////////
//:: Created By: Aiwan    Aiwan@e-mail.ru
//:: Created On: 21.05.2004
//:://////////////////////////////////////////////
void main()
{
  if (GetArea(OBJECT_SELF) != GetArea(GetFirstPC())) //
       return;  // PS. ТОЛЬКО ДЛЯ СИНГЛОВ!!!
// if((GetIsNight() && GetLocked(OBJECT_SELF))||(GetIsDay() && !GetLocked(OBJECT_SELF)))
//     {
//     return;   // [b]Эта проверка 4-х условий будет жрать больше ресурсов, чем "перезакрытие" дверей!
//     }         // Так что она не нужна.[/b]
   if (GetIsNight())
       {
       SetLocked(OBJECT_SELF, TRUE);
       return;
       }
     if (GetIsDay())
          {
          SetLocked(OBJECT_SELF, FALSE);
          return;
          }
}

Автор: Sir_Sarles May 26 2004, 08:21

Цитата

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


Имхо, логичнее экспу уменьшать с уровнем. Обосновать? А за хенчмена - чисто
формальные 10 очков. smile.gif Все цифры взяты наобум, тут надо корректировать.

Neverwinter Script Source
void main()
{
int iL = GetLockUnlockDC(OBJECT_SELF);
object oUnlocked = GetLastUnlocked();
int iDice;

if GetHitDice(oUnlocked) < 15
  {
  iDice = 15 - GetHitDice(oUnlocked);
  }
else
  {
  iDice = 1;
  }


//================ ОТКРЫВАЕМ ЗАМОК ================
if (!GetLocalInt(OBJECT_SELF, "UNLOCKED"))
{
  SetLocalInt(OBJECT_SELF, "UNLOCKED", TRUE);
  if (GetIsPC(oUnlocked)) // Если замок вскрыл РС
  {
//  GiveXPToCreature(oUnlocked, (iL * GetHitDice(oUnlocked)/3));
  GiveXPToCreature(oUnlocked, (iL * iDice/3));
  return;
  }
  else // Если замок вскрыл Henchman
  // RewardPartyXP((iL*2), GetMaster(oUnlocked));
  GiveXPToCreature(oUnlocked, 10);
}

}


------
Что касается ловушек, то Ой! Разве воришка не может ставить и обезвреживать
собственные ловушки? wink3.gif (Вспоминается Jagged Alliance, где можно было поднять
саперское умение с 1 до 100, с одной миной. smile.gif ) Проверку на Hostile?

Автор: Tarre Talliorne May 27 2004, 19:18

Очередная порция скриптов(начал писать АИ, вот, так сказать, начальные наработки, может, кому-нить и пригодится). Как всегда все(кроме 7 - этот скрипт взят из кампании СоУ) мое, совпадения случайны.

1. Проверяет, оружие ли вещь oWeapon. Можно использовать в скрипте-проверке, вооружен ли обьект(ведь при простом перебирании обьектов в руках у ПС(НПС) как оружие возвращается и факел).

Neverwinter Script Source
int GetIsWeapon(object oWeapon)
{
    int iType = GetBaseItemType(oWeapon);
    if (GetIsObjectValid(oWeapon)&&iType!=BASE_ITEM_INVALID)
    {
        if (iType == BASE_ITEM_BASTARDSWORD ||
            iType == BASE_ITEM_BATTLEAXE ||
            iType == BASE_ITEM_CLUB ||
            iType == BASE_ITEM_DAGGER ||
            iType == BASE_ITEM_DART ||
            iType == BASE_ITEM_DIREMACE ||
            iType == BASE_ITEM_DOUBLEAXE ||
            iType == BASE_ITEM_GREATAXE ||
            iType == BASE_ITEM_GREATSWORD ||
            iType == BASE_ITEM_HALBERD ||
            iType == BASE_ITEM_HANDAXE ||
            iType == BASE_ITEM_HEAVYCROSSBOW ||
            iType == BASE_ITEM_HEAVYFLAIL ||
            iType == BASE_ITEM_KAMA ||
            iType == BASE_ITEM_KATANA ||
            iType == BASE_ITEM_KUKRI ||
            iType == BASE_ITEM_LIGHTFLAIL ||
            iType == BASE_ITEM_LIGHTHAMMER ||
            iType == BASE_ITEM_LIGHTMACE ||
            iType == BASE_ITEM_LONGBOW ||
            iType == BASE_ITEM_LONGSWORD ||
            iType == BASE_ITEM_MAGICSTAFF ||
            iType == BASE_ITEM_MORNINGSTAR ||
            iType == BASE_ITEM_QUARTERSTAFF ||
            iType == BASE_ITEM_RAPIER ||
            iType == BASE_ITEM_SCIMITAR ||
            iType == BASE_ITEM_SCYTHE ||
            iType == BASE_ITEM_SHORTBOW ||
            iType == BASE_ITEM_SHORTSPEAR ||
            iType == BASE_ITEM_SHORTSWORD ||
            iType == BASE_ITEM_SHURIKEN ||
            iType == BASE_ITEM_SICKLE ||
            iType == BASE_ITEM_SLING ||
            iType == BASE_ITEM_THROWINGAXE ||
            iType == BASE_ITEM_TORCH ||
            iType == BASE_ITEM_TWOBLADEDSWORD ||
            iType == BASE_ITEM_WARHAMMER
            )
        {
            return TRUE;
        }
    }
}


2. Проверяет способность обьекта oObject(=OBJECT_SELF) произносить заклинания.

Neverwinter Script Source
int GetIsCaster(object oObject=OBJECT_SELF)
{
    if((GetLevelByClass(CLASS_TYPE_BARD, oObject)||
        GetLevelByClass(CLASS_TYPE_CLERIC, oObject)||
        GetLevelByClass(CLASS_TYPE_DRUID, oObject)||
        GetLevelByClass(CLASS_TYPE_PALADIN, oObject)> 4||
        GetLevelByClass(CLASS_TYPE_RANGER, oObject)> 4||
        GetLevelByClass(CLASS_TYPE_SORCERER, oObject)||
        GetLevelByClass(CLASS_TYPE_WIZARD, oObject))&&
        GetObjectType(oObject)==OBJECT_TYPE_CREATURE)
    {
        return TRUE;
    }
}


3. Возвращает ближайшее энеми-создание, способное творить заклы. Использует скрипт 2. Из этого скрипта вытекает скрипт 4.

Neverwinter Script Source
object GetNearestEnemyCaster(int iMaxLvl=20, int iMinLvl=1, object oObject=OBJECT_SELF)
{
    int i = 1;
    object oCreature = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oObject, i++, CREATURE_TYPE_IS_ALIVE, TRUE);
    while (GetIsObjectValid(oCreature))
    {
        if (GetIsCaster(oCreature)&&
            GetPCLevel(oCreature)>=iMinLvl&&
            GetPCLevel(oCreature)<=iMaxLvl)
        {
            break;
        }
        oCreature = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oObject, i++, CREATURE_TYPE_IS_ALIVE, TRUE);
    }
    return oCreature;
}


4. См. 3.

Neverwinter Script Source
object GetNearestFriedlyCaster(int iMaxLvl=20, int iMinLvl=1, object oObject=OBJECT_SELF)
{
    int i = 1;
    object oCreature = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, oObject, i++, CREATURE_TYPE_IS_ALIVE, TRUE);
    while (GetIsObjectValid(oCreature))
    {
        if (GetIsCaster(oCreature)&&
            GetPCLevel(oCreature)>=iMinLvl&&
            GetPCLevel(oCreature)<=iMaxLvl)
        {
            break;
        }
        oCreature = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, oObject, i++, CREATURE_TYPE_IS_ALIVE, TRUE);
    }
    return oCreature;
}



5. Проверяет, метательное ли оружие oWeapon.

Neverwinter Script Source
int GetIsRangedWeapon(object oWeapon)
{
    if (GetIsObjectValid(oWeapon))
    {
        int iBIT = GetBaseItemType(oWeapon);
        if (iBIT == BASE_ITEM_DART||
            iBIT == BASE_ITEM_HEAVYCROSSBOW||
            iBIT == BASE_ITEM_LIGHTCROSSBOW||
            iBIT == BASE_ITEM_LONGBOW||
            iBIT == BASE_ITEM_SHORTBOW||
            iBIT == BASE_ITEM_SHURIKEN||
            iBIT == BASE_ITEM_SLING||
            iBIT == BASE_ITEM_THROWINGAXE)
        {
            return TRUE;
        }
    }
}


6. Скрипт, вытекающий из скрипта 1: если стоит 0 (по умолч.) проверяет у обьекта наличие оружитя в слотах инвентаря, если 1- в инвентаре, если 2 - и там, и там.

Neverwinter Script Source
int GetHasWeapon(object oTarget, int nType)
{
    int WInv = FALSE;
    int WSlot= FALSE;
    int iResult;
    object oItem = GetFirstItemInInventory(oTarget);
    while (GetIsObjectValid(oItem))
    {
        if (GetIsWeapon(oItem))
        {
        WInv = TRUE;
        break;
        }
    oItem = GetNextItemInInventory(oTarget);
    }
    int i;
    for (i=4; i<=5; i++)
    {
    oItem = GetItemInSlot(i, oTarget);
        if (GetIsWeapon(oItem))
        {
        iWSlot = TRUE;
        break;
        }
    }
    if (nType==0) { iResult = iWSlot;         }
    else
    if (nType==1) { iResult = iWInv;          }
    else
    if (nType==2)
    {
        if (iWSLot==TRUE||iWInv==TRUE)
        { return TRUE; } else { return FALSE; }
    }
    else { return -1; }
    return iResult;
}


7. Скрипт, аналогичный второму: определяет, присутствуют ли в его классах классы бойца.

Neverwinter Script Source
int GetHasFighterClass(object oObject)
{
    int nClass1 = GetLevelByClass(CLASS_TYPE_BARBARIAN, GetPCSpeaker());
    int nClass2 = GetLevelByClass(CLASS_TYPE_FIGHTER, GetPCSpeaker());
    int nClass3 = GetLevelByClass(CLASS_TYPE_MONK, GetPCSpeaker());
    int nClass4 = GetLevelByClass(CLASS_TYPE_RANGER, GetPCSpeaker());
    if ((nClass1 > 0) || (nClass2 > 0) || (nClass3 > 0) || (nClass4 > 0))
    {
        return TRUE;
    }
    else return FALSE;
}


8. Рэндомная задержка. Вообще может использоваться для генерации случайного флоата.

Neverwinter Script Source
float GetRandomDelay(float fMinimumTime = 0.4, float MaximumTime = 1.1)
{
    float fRandom = MaximumTime - fMinimumTime;
    int nRandom;
    if(fRandom < 0.0)
    {
        return 0.0;
    }
    else
    {
        nRandom = FloatToInt(fRandom  * 10.0);
        nRandom = Random(nRandom) + 1;
        fRandom = IntToFloat(nRandom);
        fRandom /= 10.0;
        return fRandom + fMinimumTime;
    }
}


9. Возвращает кол-во предметов в инвентаре oTarget.

Neverwinter Script Source
int GetNumItems(object oTarget,string sItem)
{
    int nNumItems = 0;
    object oItem = GetFirstItemInInventory(oTarget);
    while (GetIsObjectValid(oItem))
    {
        if (GetTag(oItem) == sItem)
        {
            nNumItems = nNumItems + GetNumStackedItems(oItem);
        }
        oItem = GetNextItemInInventory(oTarget);
    }
    return nNumItems;
}


Удачи!

PS: про реплы Сэрлеса: восрешение вообще есть лажа и неДнДэшно к тому ж. Ну, не пропаать же скриптуsmile.gif

Автор: Аваддон Jun 24 2004, 00:53

LEX: Ты бы описал в общих чертах, что эти скрипты делают.
Описываю: Если Хит поинты игрока < 0 >-11 то он падает наземь.корчится, кричит и у него отнимаются хит поинты. Если его не успеют вылечить - он умрет. А когда умрет - станет призраком и перенесется в фугу. А еще экран гаснет...ну вроде как: В глазах потемнело.

За основу взят скрипт Tarre

OnPlayerDying

Neverwinter Script Source
void bleed(int iBleedAmt)
{

  effect eShake=EffectVisualEffect(VFX_FNF_SCREEN_SHAKE);
  effect eBleedEff;
  if (GetCurrentHitPoints() <= 0) {
      if (iBleedAmt > 0) {
          eBleedEff = EffectDamage(iBleedAmt);
      } else {
          eBleedEff = EffectDamage(iBleedAmt);
      }
      ApplyEffectToObject(DURATION_TYPE_INSTANT, eBleedEff, OBJECT_SELF);
      if (GetCurrentHitPoints() <= -10) {
          PlayVoiceChat(VOICE_CHAT_DEATH);
          ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), OBJECT_SELF);
          return;
      }

      if (iBleedAmt > 0) {
          if (d10(1) == 1) {
              iBleedAmt = -iBleedAmt;
          } else {
              switch (d6()) {
                  case 1: PlayVoiceChat(VOICE_CHAT_PAIN1);
                                               ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eShake,OBJECT_SELF,10.0);
                                               DelayCommand(1.5,FadeToBlack(OBJECT_SELF));
                                               BlackScreen(OBJECT_SELF);
                                               DelayCommand(3.0, FadeFromBlack(OBJECT_SELF,FADE_SPEED_SLOWEST));
                  break;
                  case 2: PlayVoiceChat(VOICE_CHAT_PAIN2);
                                              ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eShake,OBJECT_SELF,10.0);
                                              DelayCommand(1.5,FadeToBlack(OBJECT_SELF,FADE_SPEED_SLOWEST));
                                              BlackScreen(OBJECT_SELF);
                                              DelayCommand(3.0, FadeFromBlack(OBJECT_SELF,FADE_SPEED_SLOWEST));
                  break;
                  case 3: PlayVoiceChat(VOICE_CHAT_PAIN3);
                                              ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eShake,OBJECT_SELF,10.0);
                                              DelayCommand(1.5,FadeToBlack(OBJECT_SELF,FADE_SPEED_SLOWEST));
                                              BlackScreen(OBJECT_SELF);
                                              DelayCommand(3.0, FadeFromBlack(OBJECT_SELF,FADE_SPEED_SLOWEST));
                  break;
                  case 4: PlayVoiceChat(VOICE_CHAT_HEALME);
                                              ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eShake,OBJECT_SELF,10.0);
                                              DelayCommand(1.5,FadeToBlack(OBJECT_SELF,FADE_SPEED_SLOWEST));
                                              BlackScreen(OBJECT_SELF);
                                              DelayCommand(3.0, FadeFromBlack(OBJECT_SELF,FADE_SPEED_SLOWEST));
                  break;
                  case 5: PlayVoiceChat(VOICE_CHAT_NEARDEATH);
                                              ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eShake,OBJECT_SELF,10.0);
                                              DelayCommand(1.5,FadeToBlack(OBJECT_SELF,FADE_SPEED_SLOWEST));
                                              BlackScreen(OBJECT_SELF);
                                              DelayCommand(3.0, FadeFromBlack(OBJECT_SELF,FADE_SPEED_SLOWEST));
                  break;
                  case 6: PlayVoiceChat(VOICE_CHAT_HELP);
                                              ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eShake,OBJECT_SELF,10.0);
                                              DelayCommand(1.5,FadeToBlack(OBJECT_SELF,FADE_SPEED_SLOWEST));
                                              BlackScreen(OBJECT_SELF);
                                              DelayCommand(3.0, FadeFromBlack(OBJECT_SELF,FADE_SPEED_SLOWEST));


              }
          }
      }
      DelayCommand(6.0,bleed(iBleedAmt));
  }
  {

       }
}
void main()
{
  effect eBlood=EffectVisualEffect(VFX_COM_CHUNK_RED_MEDIUM);
  object oDying = GetLastPlayerDying();
  object oEnemy = GetLastAttacker();
  float fWho = (GetFacing(oEnemy));
  ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY,eBlood, GetLocation(oDying), 10.0);
  AssignCommand(oDying, ClearAllActions());
  AssignCommand(oDying, bleed(1));
  CreateObject(OBJECT_TYPE_PLACEABLE,"bloody",GetLocation(oDying),TRUE);

}


"bloody" - синька с кровью.
З.Ы. Tarre там с Object_Type перепутал кажетсяsmile.gif

Далее OnPlayerDeath
Neverwinter Script Source
void main()
{
   object oPlayer = GetLastPlayerDied();
   ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_DEATH), GetLocation(oPlayer));
   ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_GHOSTLY_VISAGE), oPlayer); //превращается уже тут в призрака, и в фуге появляется как душа.
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PROTECTION_GOOD_MAJOR), oPlayer,6.0);
   DelayCommand(2.0,FadeToBlack(oPlayer));
   DelayCommand(5.0,BlackScreen(oPlayer));

    DelayCommand(5.5,ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectResurrection(),oPlayer));
    DelayCommand(5.8,ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectHeal(GetMaxHitPoints(oPlayer)), oPlayer));
    DelayCommand(6.0,AssignCommand(oPlayer,ClearAllActions()));
    DelayCommand(6.2,AssignCommand(oPlayer,JumpToLocation(GetLocation(GetObjectByTag("WP_RAISE")))));
}

WP_RAISE - вейпоинт в фуге

И еще в локации фуги - куда перемещается мертвый игрок OnEnter
Neverwinter Script Source
void main()
{
object oPC = GetEnteringObject();
DelayCommand(2.0,FadeFromBlack(oPC,FADE_SPEED_SLOWEST));
}

Автор: Tarre Talliorne Jul 3 2004, 19:16

Скрипты: удаляющий эффект (1) и сканирующий эффект (2).

Neverwinter Script Source
void ActionRemoveEffect(object oCreature, effect eEffect)
    {
        effect eMSD = GetFirstEffect(oCreature);
        while (GetIsEffectValid(eMSD))
        {
            if (GetEffectType(eMSD) == GetEffectType(eEffect))
            {
            RemoveEffect(oCreature, eMSD);
            }
        eMSD = GetNextEffect(oCreature);
        }
    }


Neverwinter Script Source
int HasEffect(object oCreature, effect eEffect)
    {
        int iResult = 0;
        effect eMSD = GetFirstEffect(oCreature);
        while (GetIsEffectValid(eMSD))
        {
            if (GetEffectType(eMSD) == GetEffectType(eEffect))
            {
            iResult = 1;
            }
        eMSD = GetNextEffect(oCreature);
        }
        return iResult;
    }

Обещанный скрипт-реакция грарда на нападение на оного ПС... Впихивается в онАтакед. Скрипт делает следущее: охранник вырубает ПС и начинает с ним диалог(лтбо что-то иное smile.gif )
Neverwinter Script Source
object oFPC = GetLastAttacker();
        object OS = OBJECT_SELF;     
        DelayCommand(0.10, ClearAllActions(TRUE));
        DelayCommand(0.60, ActionUseFeat(FEAT_KNOCKDOWN, oFPC));
        DelayCommand(0.61, ApplyEffectToObject(1, EffectKnockdown(), oFPC, 3.0));
        DelayCommand(1.00, ClearAllActions(TRUE));
        if (GetCurrentHitPoints(OS)<=0)
        {
        // если гвард умер с первого удара... можно оставить пустым, можно написать реакции другим охранникам... в любом случае, если мне написать тут родной код (т.е. тот, который был у меня), то пришлось бы писать всю немаленькую систему моих кастомных реакций, что геморно...
        }
        else
        {
        DelayCommand(1.04, SetStandardFactionReputation(REPUTATION_TYPE_ENEMY, 50, oFPC));
        DelayCommand(5.10, ClearAllActions(TRUE));
        DelayCommand(5.20, ActionMoveToObject(oFPC, FALSE, 1.4));
        }
        // диалог, либо что-то иное - на ваше усмотрение.

Автор: Tarre Talliorne Jul 4 2004, 13:39

Neverwinter Script Source
object oFPC = GetLastAttacker();
      object OS = OBJECT_SELF;     
      effect eEffect = EffectImmunity(IMMUNITY_TYPE_KNOCKDOWN);
      if (HasEffect(oFPC))
      {
      ActionRemoveEffect(oFPC, eEffect);
      }
      DelayCommand(0.10, ClearAllActions(TRUE));
      DelayCommand(0.60, ActionUseFeat(FEAT_KNOCKDOWN, oFPC));
      DelayCommand(0.61, ApplyEffectToObject(1, EffectKnockdown(), oFPC, 3.0));
      DelayCommand(1.00, ClearAllActions(TRUE));
      if (GetCurrentHitPoints(OS)<=0)
      {
      // если гвард умер с первого удара... можно оставить пустым, можно написать реакции другим охранникам... в любом случае, если мне написать тут родной код (т.е. тот, который был у меня), то пришлось бы писать всю немаленькую систему моих кастомных реакций, что геморно...
      }
      else
      {
      DelayCommand(1.04, SetStandardFactionReputation(REPUTATION_TYPE_ENEMY, 50, oFPC));
      DelayCommand(5.10, ClearAllActions(TRUE));
      DelayCommand(5.20, ActionMoveToObject(oFPC, FALSE, 1.4));
      }
      // диалог, либо что-то иное - на ваше усмотрение.
По идеи должно работать... Хотел еще вставить фичу, чтобы в конце убранный эффект восстанавливался, но потом передумал - ибо нехрен на охранника с иммуной наезжать :-)
Возможный баг - если на криче будет много иммунитетов, то ремувится только один (возможно, не нокдаун, т.к. эффекттип есть только EFFECT_TYPE_IMMUNITY). Хотя не знаю, я сейчас в ж...пе полнейшей, до ближайшего тулсета километры, посему могу и ошибаться ...

Автор: Tarre Talliorne Jul 4 2004, 20:05

Да, я добрался-таки до тулсы, проверил: все работает (исходя из оргинзации цикла ActionRemoveObject(. . .) ), уничтожает ВСЕ эффекты иммунитета на криче... Теперь в поярдке садомазохизма попытаюсь сделать, чтобы эффект возвращался после прозхождения процедуры "валяния" ПС на земле. Загвоздка в том - как фиксировать длительность начального эффекта и наложить новый эффект с такой же длительностью... ДБ, помоги :-)
Да, и еще: обнаружилась досадная бага - атакующие перса кричи не меняют свое отношение к ПС, когда гвард уже поменял отношение. Попробую исправить.

-----------------------------------------------------
Еще одна вещь: полезная для купцов фишка - не знаю как у других, но у нас в моде преобладают торговцы специфического назначения: напр., продающий только зелья, или только броню и оружие и т.д. Но игроки в процессе имеют привычку продавать в магазине всякую дрянь - она забивает инвентарь магазина... Проблему решает простой скриптик на он_опн_стор... Скрипт универсальный.

Neverwinter Script Source
void main()
{
    SpeakString("This is what would happen if the store started"); // оригинальная строчка на исходном Store Open Script
    object oInv = GetFirstItemInInventory();
        while (GetIsObjectValid(oInv)) // стандартная организация цикла для удаления неограниченного кол-ва вещей
        {
            string sOS = GetTag(OBJECT_SELF); // в зависимости от тега магазина разные критерии удаления
            if  (sOS == "store1") // к примеру весли тег магазина - "store1", то удаляются все предметы, если их типы не BASE_ITEM_POTIONS и не BASE_ITEM_SCROLL...
            {
                if (GetBaseItemType(oInv)!=BASE_ITEM_POTIONS&&
                    GetBaseItemType(oInv)!=BASE_ITEM_SCROLL  )
                {
                DestroyObject(oInv);
                }
            }
            else if (sOS == "store2")
            {
            // аналогично, если "store2", то фильтр можно изменить на подходящий вам
            }
        oInv = GetNextItemInInventory();
        }
}

Автор: Tarre Talliorne Jul 7 2004, 15:45

Neverwinter Script Source
const string TXT_COLOR_GRAY    = "<c°°°>"; // Gray
const string TXT_COLOR_WHITE    = "<cууу>"; // White
const string TXT_COLOR_CYAN    = "<c уу>"; // Light Cyan
const string TXT_COLOR_MAGENTA  = "<cу у>"; // Magenta
const string TXT_COLOR_YELLOW   = "<cуу >"; // Yellow
const string TXT_COLOR_RED      = "<cу  >"; // Red
const string TXT_COLOR_GREEN    = "<c у >"; // Green
const string TXT_COLOR_BLUE    = "<c  у>"; // Blue
const string TXT_COLOR_NONE    = "";       // Default (no color)
const string TXT_COLOR_END      = "</c>";   // (color end TAG)
const string TXT_COLOR_DEFAULT  = TXT_COLOR_CYAN;


// Function changes color of the string
// * Param sText - text to color
// * Param sColor - parse a color constant here
// * Returns colored string
string colorText(string sText, string sColor);


string colorText(string sText, string sColor)
{
  return sColor + sText + TXT_COLOR_END;
}


Выдрана из буржуйского мода. Код _каа_ предусматривал только 4 цвета. здесь больше. пользуйтесь.

Автор: Tarre Talliorne Jul 7 2004, 21:00

Цветной текст. Пример:
Называешь мой инклюд "lib_colortext". Скрипт на он_ентер локи.
На входе ПС говорит фразу you are entering object, и она отображается не стандартным белым, а красным (TXT_COLOR_RED). Если бы на месте TXT_COLOR_RED стояло бы TXT_COLOR_YELLOW , она отобразилась бы желтым. Проверь.

Neverwinter Script Source
#include "lib_colortext"
void main()
{
object oPC = GetEnteringObject();
if (!GetIsPC(oPC)) return;
AssignCommand(oPC, SpeakString(colorText("you are entering object", TXT_COLOR_RED)));
}

Автор: Аваддон Jul 10 2004, 06:22

Скриптики на головоломку. Тоесть не совсем головоломку... На закодированную дверь. У вас есть локация в которой есть дверь. Эта дверь изначально закрыта.
Еще там есть N-ое количество плиток (Plate) на полу с любыми тегами, но именами букв. Например, плита с именем "р" и тегом..ну допустим "letter_r". И надо столько плит - из скольки букв состоит кодовое слово двери. Или можно больше чтоб запутать игрока. Если у вас на двери не кодовое слово, а целая фраза, тогда чтобы сделать пробел надо содать плиту с именем - "пробел". Все плиты должны быть Юзабельные(Usable).
Еще там есть рычаг после дерганья которого проверяется тот код, который вы набрали наступая на плитки. Если он правильный - закодированная дверь открывается, если нет - набранный код сбрасывается и игрока ударяет током.

OnUsed любой плиты с именем-буквой

Neverwinter Script Source
     /////////////////////////////////////////
    ////// Script for Coded Door ////////////
   /////// OnUsed any plate ////////////////
  //////// Date: 10.07.2004 ///////////////
 ///////// Created by Avaddon ////////////
/////////////////////////////////////////

void main()
{
string sCode = GetLocalString(GetObjectByTag("code_lock"),"code"); //code_lock - тэг рычага.
string sName = GetName(OBJECT_SELF);
object oCodedDoor = GetObjectByTag("coded_door"); //тэг запертой двери
if (GetLocked(oCodedDoor)==TRUE)
{
if (sName=="пробел")
{
//прибавлЯет к набраному коду пробел.
SetLocalString(GetObjectByTag("code_lock"), "code", sCode+" ");
SendMessageToPC(GetLastUsedBy(),"Вы наступили на символ ["+sName+"]");
SendMessageToPC(GetLastUsedBy(),"Набранный код: ["+sCode+" ]");
ApplyEffectAtLocation(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_IMP_MAGIC_RESISTANCE_USE), GetLocation(OBJECT_SELF));  //создает эффект нажатиЯ плиты.
}
else
{
//прибавлЯет к набронному коду ту букву, которой называетсЯ плита.
SetLocalString(GetObjectByTag("code_lock"), "code", sCode+sName);
SendMessageToPC(GetLastUsedBy(),"Вы наступили на символ ["+sName+"]");
SendMessageToPC(GetLastUsedBy(),"Набранный код: ["+sCode+sName+"]");
ApplyEffectAtLocation(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_IMP_MAGIC_RESISTANCE_USE), GetLocation(OBJECT_SELF));
//создает эффект нажатиЯ плиты.
}
}
else
{
SendMessageToPC(GetLastUsedBy(),"Хм..Эта плита запала в пол."); //если дверь уже открыта.
}
}


OnUsed рычага с тэгом "code_lock"
Neverwinter Script Source
     /////////////////////////////////////////
    ////// Script for Coded Door ////////////
   /////// OnUsed some Lever ///////////////
  //////// Date: 10.07.2004 ///////////////
 ///////// Created by Avaddon ////////////
/////////////////////////////////////////

void main()
{
string sNull=""; //пустой стринг на случай сброса кода.
string sCode = GetLocalString(OBJECT_SELF,"code"); //стринг набранного кода
object oCodedDoor = GetObjectByTag("coded_door"); //тэг запертой двери
object oPC = GetLastUsedBy();
effect eOpen = EffectVisualEffect(VFX_IMP_REMOVE_CONDITION); //эффект снЯтиЯ волшебных чар с двери.

if (GetLocked(oCodedDoor)==TRUE)
{
//кодовое слово-фраза длЯ открытиЯ двери - можете вписывать свое.
   if (sCode=="правильный код")    
   {
   PlayAnimation(ANIMATION_PLACEABLE_ACTIVATE);//анимациЯ рычага
   DelayCommand(2.0,PlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE));
   SetLocked(oCodedDoor, FALSE); //открывает дверь.
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eOpen,oCodedDoor,5.0); //эффект снЯтиЯ волшебных чар с двери.
   SendMessageToPC(GetLastUsedBy(),"Вы набрали правильный код. Волшебные чары пали и дверь открылась");
   ActionOpenDoor(oCodedDoor); //анимациЯ открытиЯ двери
   SetLocalString(OBJECT_SELF,"code",sNull); //сброс кода
   }
   else
   {
   SendMessageToPC(GetLastUsedBy(),"Вы набрали неверный код.");
   AssignCommand (OBJECT_SELF, ActionCastSpellAtObject(SPELL_ELECTRIC_JOLT, oPC, PROJECTILE_PATH_TYPE_DEFAULT)); //ударЯет игрока током если код неверный.
   PlayAnimation(ANIMATION_PLACEABLE_ACTIVATE);//анимациЯ рычага
   DelayCommand(2.0,PlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE));
   SetLocalString(OBJECT_SELF,"code",sNull); //сброс кода
   }
}
else
{
SendMessageToPC(oPC,"Дверь уже открыта."); //без комментариев
}
}


Тестовый модуль можете скачать http://saigh.fatal.ru/files/Coded_Door.rar. Размер файла 9кб.

Автор: Аваддон Jul 11 2004, 04:01

Небольшой, совсем простой скриптик банка.
В нем нет никаких паролей для снятия золота, проверок на CDKey или имя игрока. Это если вам надо сами добавите как SetLocalString и проверки тожеsmile.gif Или можно например на предмет-договор поставить Undropable. Чтоб воры не украли и игрок не передал.

Итак, у нас есть НПС - заведующий банком. Наш игрок заходит в банк и у него есть 3 действия: "балланс", "положить", "забрать". Все эти действия а так же ответы ДА и НЕТ производятся посредством обыкновенного чата(НЕ диалога). Если у него нет договора с банком то ему предлагают его завести и дают 1 минуту чтобы сказать да или нет. Если договор заведен - игрок может снять деньги со счета, положить на счет или узнать свой балланс.
Система основанна на LocalInt которые сохраняются на предметах вместе с игроком.

Скрипт ставится на OnSpawn НПС заведующего банком

Neverwinter Script Source
     /////////////////////////////////////////
    ////// Script for Interactive ///////////
   ///////// Mini Bank System //////////////
  /////// OnSpawn NPC Banker //////////////
 //////// Date: 11.07.2004 ///////////////
///////// Created by Avaddon ////////////
/////////////////////////////////////////

void main()
{
object oPC = GetLastSpeaker();
SetListening(OBJECT_SELF, 1);
SetListenPattern(OBJECT_SELF,"положить",1);
SetListenPattern(OBJECT_SELF,"забрать",2);
SetListenPattern(OBJECT_SELF,"балланс",3);
SetListenPattern(OBJECT_SELF,"да",4);
SetListenPattern(OBJECT_SELF,"нет",5);
}


Этот скрипт ставится на OnConversation НПС заведующего банком

Neverwinter Script Source
     /////////////////////////////////////////
    ////// Script for Interactive ///////////
   ///////// Mini Bank System //////////////
  /////// OnConversarion NPC Banker ///////
 //////// Date: 11.07.2004 ///////////////
///////// Created by Avaddon ////////////
/////////////////////////////////////////

#include "nw_i0_tool"
void main()
{
object oPC = GetLastSpeaker();
object oOffer = GetItemPossessedBy(oPC, "bank_offer"); // bank_offer - тэг договора.
int iAmount = StringToInt (GetMatchedSubstring (0));
int iAccount = GetLocalInt(oOffer, "money");
string sBallance = IntToString(iAccount);
string sBallancePlus = IntToString(iAccount+iAmount);
string sBallanceMinus = IntToString(iAccount-iAmount);
if(HasItem(oPC, "bank_offer"))
{
   if (GetListenPatternNumber()==10 && GetIsListening(OBJECT_SELF) && GetLocalInt(oPC,"account")==1)
   {
     if (iAmount>0)
       {
           if (iAmount<=GetGold(oPC))
           {
           SpeakString("Вы положили на счет "+GetMatchedSubstring(0)+"золотых монет.");
           TakeGoldFromCreature(iAmount,oPC,TRUE);
           SetLocalInt(oOffer,"money",iAccount+iAmount);
           SpeakString ("Ваш баланс на счете = "+sBallancePlus+" золотых монет.");
           DeleteLocalInt(oPC,"account");
           SetListenPattern(OBJECT_SELF,"DELETED",10);
           }
           else
           {
           SpeakString("У вас нет столько золота");
           }
       }
       else
       {
       SpeakString("Вы ввели неправильную величину");
       }
   }

    if (GetListenPatternNumber()==10 && GetIsListening(OBJECT_SELF) && GetLocalInt(oPC,"account")==2)
   {
     if (iAmount>0)
       {

           if (iAmount<=GetLocalInt(oOffer,"money"))
           {
           SpeakString("Вы забрали зо счета "+GetMatchedSubstring(0)+" золотых монет.");
           GiveGoldToCreature(oPC,iAmount);
           SetLocalInt(oOffer,"money",iAccount-iAmount);
           SpeakString ("Ваш баланс на счете = "+sBallanceMinus+" золотых монет.");
           DeleteLocalInt(oPC,"account");
           SetListenPattern(OBJECT_SELF,"DELETED",10);
           }
           else
           {
           SpeakString("На вашем счете нет столько золота");
           }
       }
       else
       {
       SpeakString("вы ввели неправильную величину");
       }
   }

   if (GetListenPatternNumber()==1 && GetIsListening(OBJECT_SELF))
   {

       SpeakString ("Сколько денег вы хотите положить на счет?");
       SetListenPattern(OBJECT_SELF,"**",10);
       SetLocalInt(oPC,"account",1);

   }
   if (GetListenPatternNumber()==2 && GetIsListening(OBJECT_SELF))
   {
   SetListenPattern(OBJECT_SELF,"DELETED",10);
   SpeakString ("Сколько денег вы хотите забрать?");
   SetListenPattern(OBJECT_SELF,"**",10);
   SetLocalInt(oPC,"account",2);
   }

   if (GetListenPatternNumber()==3 && GetIsListening(OBJECT_SELF))
   {
   SpeakString ("Ваш баланс на счете = "+sBallance+" золотых монет.");
   }
}
else
{
   if (GetListenPatternNumber()==1 && GetIsListening(OBJECT_SELF))
   {
   SpeakString ("Хм, разве мы подписывали с вами договор? Хотите завести счет? Даю вам минуту на размышление. Просто скажите [да] или [нет]");
   SetLocalInt(oPC,"new_account", TRUE);
   DelayCommand(60.0 , DeleteLocalInt(oPC,"new_account"));
   }
   if (GetListenPatternNumber()==2 && GetIsListening(OBJECT_SELF))
   {
   SpeakString ("Хм, разве мы подписывали с вами договор? Хотите завести счет? Даю вам минуту на размышление. Просто скажите [да] или [нет]");
   SetLocalInt(oPC,"new_account", TRUE);
   DelayCommand(60.0 , DeleteLocalInt(oPC,"new_account"));
   }
   if (GetListenPatternNumber()==3 && GetIsListening(OBJECT_SELF))
   {
   SpeakString ("Хм, разве мы подписывали с вами договор? Хотите завести счет? Даю вам минуту на размышление. Просто скажите [да] или [нет]");
   SetLocalInt(oPC,"new_account", TRUE);
   DelayCommand(60.0 , DeleteLocalInt(oPC,"new_account"));
   }
   if (GetListenPatternNumber()==4 && GetIsListening(OBJECT_SELF) && GetLocalInt(oPC,"new_account")== TRUE)
   {
   CreateItemOnObject("bank_offer", oPC, 1);
   SetLocalInt(oOffer, "money", 0);
   SpeakString("Большое спасибо, что воспользовались услугами нашего банка! Вот ваш договор!");
   SetListenPattern(OBJECT_SELF,"DELETED",10);
   }
   if (GetListenPatternNumber()==5 && GetIsListening(OBJECT_SELF) && GetLocalInt(oPC,"new_account")== TRUE)
   {
   SpeakString ("Ну нет, так нет.");
   DeleteLocalInt(oPC,"new_account");
   }


}
}


Айван: Молодец good.gif

Автор: Tarre Talliorne Jul 17 2004, 20:55

Часть скрипта из нашей демки. У нас будет более продвинутая(в демо, думаю, включать не будем, но в релизе всего мода будет точно), чем в обыкновенном НВН система кастомных разговоров. Сейчас я (параллельно с лтом и АИ :-) ) пишу систему разговоров. Итак, решил бросить в Базу Скриптов коротенький скриптик. Суть: он ставит любое сцществительное в родительный падеж (string RusGenetiv). Параметр nSex - род: 1 - мужской, 2 - женский, 3 - средний.
Скрипт протестирован на 150 словах. Хотя, сами понимаете, русский язык сложен и этого кол-ва слов явно мало, посему если найдете ошибки, тут же сообщите.
ЗЫ: сейчас пишу Dativ & Akkusativ (наряду с Genetic самые употребительные) (на немецкий манер называю - мне языки германской группы вообще в последнее время ОЧЕНЬ нравятся :-) ), подумываю над прилагательными. (просто надо грамотно реализовать стековку имени + фамилии + прозвища)
ЗЫЫ: при использовании указание авторства обязательно

Neverwinter Script Source
// ПРОИЗВОДИТСЯ ОРФОГРАФИЧЕСКАЯ ПРОВЕРКА НА НЕЛЕКСИЧЕСКИЕ СОЧЕТАНИЯ
//   [SCRIPTED BY TARRE TALLIORNE! (TARRE@list.ru)]
string OrfographieTest(string sString);

// СТАВИТ СЛОВО sWord В РОДИТЕЛЬНЫЙ ПАДЕЖ;
// - ПАРАМЕТР "РОД" ( nSex ):
// 1 - МУЖСКОЙ,
// 2 - ЖЕНСКИЙ,
// 3 - СРЕДНИЙ.
//   [SCRIPTED BY TARRE TALLIORNE! (TARRE@list.ru)]
string RusGenetiv(string sWord, int nSex);

string ya()
{
return GetName(GetWaypointByTag("ya"));
}

int GetIsSound(string sLetter)
{
    int iResult = 0;
    //:://
    if (sLetter != "ь"&&
        sLetter != "ъ"&&
        sLetter != "" &&
        GetStringLength(sLetter)==1)
        {
        iResult = 1;
        }
    return iResult;
}

int GetIsVowel(string sLetter)
{
    int iResult = 0;
    if (!GetIsSound(sLetter))
        return iResult = -1;
    if (sLetter=="а" ||
        sLetter=="е" ||
        sLetter=="ё" ||
        sLetter=="и" ||
        sLetter=="о" ||
        sLetter=="у" ||
        sLetter=="э" ||
        sLetter=="ю" ||
        sLetter==ya() )
        {
        iResult = 1;
        }
    return iResult;
}

/*int GetIsSoft(string sLetter, string sNextLetter)
{
    int iResult;
    if (!GetIsSound(sLetter)                ||
       ( GetStringLength(sNextLetter)!=0    &&
         GetStringLength(sNextLetter)!=1)   ||
         GetIsVowel(sLetter))
         return iResult = -1;
    else if (sLetter == "й")
         return iResult = 1;
    else if (sNextLetter == "ь")
         return iResult = 1;
}*/


string OrfographieTest(string sString)
{
    //:://///////////:://
    //::// ЖИ - ШИ //:://
    //:://///////////:://

    //::// ОПРЕДЕДЯЕМ ПЕРЕМЕННЫЕ
    string sNew;
    int nZHi = FindSubString(sString, "Жы");
    int nzhi = FindSubString(sString, "жы");
    int nSHi = FindSubString(sString, "Шы");
    int nshi = FindSubString(sString, "шы");

    //::// "Жы"
    if (nZHi!=-1)
    {
    int nZH = nZHi;
    int nI = nZH + 1;
    string s1 = GetStringLeft(sString, nI);
    string s2 = GetStringRight(sString, GetStringLength(sString)-nI-1);
    sNew = s1+"и"+s2;
    }

    //::// "жы"

    else if (nzhi!=-1)
    {
    int nzh = nzhi;
    int nI = nzh + 1;
    string s1 = GetStringLeft(sString, nI);
    string s2 = GetStringRight(sString, GetStringLength(sString)-nI-1);
    sNew = s1+"и"+s2;
    }

    //::// "Шы"
    else if (nSHi!=-1)
    {
    int nSH = nSHi;
    int nI = nSH + 1;
    string s1 = GetStringLeft(sString, nI);
    string s2 = GetStringRight(sString, GetStringLength(sString)-nI-1);
    sNew = s1+"и"+s2;
    }

    //::// "шы"
    else if (nshi!=-1)
    {
    int nsh = nshi;
    int nI = nsh + 1;
    string s1 = GetStringLeft(sString, nI);
    string s2 = GetStringRight(sString, GetStringLength(sString)-nI-1);
    sNew = s1+"и"+s2;
    }

    //::// ЕСЛИ ЗНАКОМЫХ ОШИБОК НЕТ, ВОЗВРАЩАЕМ ИЗНАЧАЛЬНЫЙ sString
    else sNew = sString;
    return sNew;
}

string RusGenetiv(string sWord, int nSex)
{
    string sGenLast;
    string sOsnov;
    string sGenetiv;
    string sLast = GetStringRight(sWord, 1);
    //::////////////////////////////////////////////////:://
    //::// DEBUGGING [ deleted by author at 17.07.04 ]//:://
    //::// SpeakDebugString(OBJECT_SELF, sLast);////////:://
    //::////////////////////////////////////////////////:://
    switch (nSex)
    {
    //:://///////////////:://
    //::// МУЖСКОЙ РОД //:://
    //:://///////////////:://
    case 1:
        //::// ПОСЛЕДНЯЯ БУКВА ЗАМЕНЯЕТСЯ
        if (sLast=="а"||sLast==ya()||sLast=="й"||sLast=="ь")
        {
            if (sLast=="а")
                sGenLast = "ы";
                    else if (sLast==ya())
                        sGenLast = "и";
                            else if (sLast=="й"||
                                sLast=="ь")
                                    sGenLast = ya();
        sOsnov = GetStringLeft(sWord, GetStringLength(sWord)-1);
        sGenetiv = sOsnov + sGenLast;
        }
        //::// СЛОВО НЕ ИЗМЕНЯЕТ ФОРМУ
        else if (sLast=="е"||
                 sLast=="ё"||
                 sLast=="и"||
                 sLast=="о"||
                 sLast=="у"||
                 sLast=="э")
                 {
                 sGenetiv = sWord;
                 }
                 //::// В ДРУГИХ СЛУЧАЯХ СЛОВО ПРИБАВЛЯЕТ К СЕБЕ "А"
        else {
        sGenLast = "а";
        sOsnov = GetStringLeft(sWord, GetStringLength(sWord));
        sGenetiv = sOsnov + sGenLast;
        }
    break;

    //:://///////////////:://
    //::// ЖЕНСКИЙ РОД //:://
    //:://///////////////:://
    case 2:
        //::// ПОСЛЕДНЯЯ БУКВА ЗАМЕНЯЕТСЯ
        if (sLast=="а")
        {
        sGenLast = "ы";
        sOsnov = GetStringLeft(sWord, GetStringLength(sWord)-1);
        sGenetiv = sOsnov + sGenLast;
        }
        else if (sLast==ya()||sLast=="ь")
        {
        sGenLast = "и";
        sOsnov = GetStringLeft(sWord, GetStringLength(sWord)-1);
        sGenetiv = sOsnov + sGenLast;
        }
        //::// СЛОВО НЕ ИЗМЕНЯЕТ ФОРМУ
        else
        {
        sGenetiv = sWord;
        }
    break;

    //:://///////////////:://
    //::// СРЕДНИЙ РОД //:://
    //:://///////////////:://
    case 3:
        if (sLast=="о")
        {
        sGenLast = "а";
        sOsnov = GetStringLeft(sWord, GetStringLength(sWord)-1);
        sGenetiv = sOsnov + sGenLast;
        }
        if (sLast=="е")
        {
        sGenLast = ya();
        sOsnov = GetStringLeft(sWord, GetStringLength(sWord)-1);
        sGenetiv = sOsnov + sGenLast;
        }
        else sGenetiv = sWord;
    break;
    }
    sGenetiv = OrfographieTest(sGenetiv);
    return sGenetiv;
}

Автор: Valleo Jul 21 2004, 19:58

Ладно думал я думал и решил тут отпостить простенький скриптик на отрыскивание изначально дисбалансированных фишек вещей и замену их другими, более сбалансированными.
Тут заменяются: хаст, трусинг, иммунитеты, фридум.
Хорошо для шарда =)

Neverwinter Script Source
//############################################################################//
//*    Система замены перманентных фишек вещи на более сбалансированные    *//
//*      Копирайт Valleo, созданно "непомню", и все такое в таком духе      *//
//############################################################################//

//* Эта функциЯ заменЯет старые свойства на новые
void NoCheatDeleteAndSetItemProperty(object oItem, itemproperty iItemProperty);

//* ФункциЯ проверЯет, допустимо ли это свойство, и если нет - возвращает FALSE
int NoCheatCheckItemProperty(itemproperty iItemProperty);

//* ПроверЯет все свойства вещи поочередно
void NoCheatItemProperty(object oItem);

//* Старт системы
void NoCheatStarting(object oPC);

//############################################################################//

void NoCheatDeleteAndSetItemProperty(object oItem, itemproperty iItemProperty)
{
itemproperty iNewItemPropert;
int iItemPropertyType = GetItemPropertyType(iItemProperty);
int iItemPropertySubType;
if(iItemPropertyType == ITEM_PROPERTY_IMMUNITY_MISCELLANEOUS)
  {
  iItemPropertySubType = GetItemPropertySubType(iItemProperty);
  if(iItemPropertySubType == IP_CONST_IMMUNITYMISC_DEATH_MAGIC)
   {
   iNewItemPropert = ItemPropertyCastSpell(IP_CONST_CASTSPELL_DEATH_WARD_7, IP_CONST_CASTSPELL_NUMUSES_3_USES_PER_DAY);
   RemoveItemProperty(oItem,iItemProperty);
   AddItemProperty(DURATION_TYPE_PERMANENT,iNewItemPropert,oItem);
   }
  if(iItemPropertySubType == IP_CONST_IMMUNITYMISC_KNOCKDOWN)
   {
   iNewItemPropert = ItemPropertySkillBonus(SKILL_DISCIPLINE,10);
   RemoveItemProperty(oItem,iItemProperty);
   AddItemProperty(DURATION_TYPE_PERMANENT,iNewItemPropert,oItem);
   }
  if(iItemPropertySubType == IP_CONST_IMMUNITYMISC_CRITICAL_HITS)
   {
   iNewItemPropert = ItemPropertySkillBonus(SKILL_TUMBLE,10);
   RemoveItemProperty(oItem,iItemProperty);
   AddItemProperty(DURATION_TYPE_PERMANENT,iNewItemPropert,oItem);
   }
  }
if(iItemPropertyType == ITEM_PROPERTY_HASTE)
  {
  iNewItemPropert = ItemPropertyCastSpell(IP_CONST_CASTSPELL_HASTE_5, IP_CONST_CASTSPELL_NUMUSES_3_USES_PER_DAY);
  RemoveItemProperty(oItem,iItemProperty);
  AddItemProperty(DURATION_TYPE_PERMANENT,iNewItemPropert,oItem);
  }
if(iItemPropertyType == ITEM_PROPERTY_TRUE_SEEING)
  {
  iNewItemPropert = ItemPropertyCastSpell(IP_CONST_CASTSPELL_TRUE_SEEING_9, IP_CONST_CASTSPELL_NUMUSES_3_USES_PER_DAY);
  RemoveItemProperty(oItem,iItemProperty);
  AddItemProperty(DURATION_TYPE_PERMANENT,iNewItemPropert,oItem);
  }
if(iItemPropertyType == ITEM_PROPERTY_FREEDOM_OF_MOVEMENT)
  {
  iNewItemPropert = ItemPropertyCastSpell(IP_CONST_CASTSPELL_FREEDOM_OF_MOVEMENT_7, IP_CONST_CASTSPELL_NUMUSES_3_USES_PER_DAY);
  RemoveItemProperty(oItem,iItemProperty);
  AddItemProperty(DURATION_TYPE_PERMANENT,iNewItemPropert,oItem);
  }
}

int NoCheatCheckItemProperty(itemproperty iItemProperty)
{
int iDurationType = GetItemPropertyDurationType(iItemProperty);
if(iDurationType != DURATION_TYPE_PERMANENT)return FALSE;

int iItemPropertyType = GetItemPropertyType(iItemProperty);
if(iItemPropertyType == ITEM_PROPERTY_HASTE) return TRUE;
if(iItemPropertyType == ITEM_PROPERTY_TRUE_SEEING) return TRUE;
if(iItemPropertyType == ITEM_PROPERTY_IMMUNITY_MISCELLANEOUS) return TRUE;
if(iItemPropertyType == ITEM_PROPERTY_FREEDOM_OF_MOVEMENT) return TRUE;
return FALSE;
}

void NoCheatItemProperty(object oItem)
{
itemproperty iItemProperty = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(iItemProperty))
  {
  if(NoCheatCheckItemProperty(iItemProperty) && !GetPlotFlag(oItem)) NoCheatDeleteAndSetItemProperty(oItem, iItemProperty);
  iItemProperty = GetNextItemProperty(oItem);
  }
}

void NoCheatStarting(object oPC)
{
object oItem;
oItem = GetFirstItemInInventory(oPC);
while(oItem != OBJECT_INVALID)
  {
  NoCheatItemProperty(oItem);
  oItem = GetNextItemInInventory(oPC);
  }
int iSlot = 0;
for (iSlot; iSlot<14; iSlot++)
{
oItem = GetItemInSlot(iSlot, oPC);
if(GetIsObjectValid(oItem)) NoCheatItemProperty(oItem);
}
}

//############################################################################//

void main()
{
object oPC = GetEnteringObject(); //* ну тут что хотите, Я на On Enter модуля
NoCheatStarting(oPC);
}

Автор: Aiwan Jul 23 2004, 22:41

Вот простенький скриптик, если НПС отойдет от своего POST_-а дальше 15 метров, то появится строка в диалоге.

Neverwinter Script Source
//::///////////////////////////////////////////////
//:: Copyright © 2004 WRG!
//:://////////////////////////////////////////////
/*
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 23.07.2004
//:://////////////////////////////////////////////

int StartingConditional()
{
    string sTag = ("POST_"+GetTag(OBJECT_SELF));
    object oWp = GetWaypointByTag(sTag);

    if (GetIsObjectValid(oWp) && GetDistanceBetween(oWp, OBJECT_SELF) > 15.0f)
        return TRUE;
    return FALSE;
}

Автор: Valleo Jul 25 2004, 18:31

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

Neverwinter Script Source
object oPC = GetLastPCRested();
if(GetLastRestEventType() == REST_EVENTTYPE_REST_STARTED)
  {
  SendMessageToPC(oPC,"Рест через кнопку реста отменен."); //Это можно и убрать
  AssignCommand(oPC, ClearAllActions());
  }

Автор: Lex Aug 12 2004, 20:15

автор: _kaa_

Вот стандартный файл для алкоголя:

Neverwinter Script Source
//::///////////////////////////////////////////////
//:: NW_S3_Alcohol.nss
//:: Copyright © 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
  Makes beverages fun.
  May 2002: Removed fortitude saves. Just instant intelligence loss
*/

//:://////////////////////////////////////////////
//:: Created By:   Brent
//:: Created On:   February 2002
//:://////////////////////////////////////////////

void DrinkIt(object oTarget)
{
   // AssignCommand(oTarget, ActionPlayAnimation(ANIMATION_FIREFORGET_DRINK));
   AssignCommand(oTarget,ActionSpeakStringByStrRef(10499));
}

void MakeDrunk(object oTarget, int nPoints)
{
    if (Random(100) + 1 < 40)
        AssignCommand(oTarget, ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING));
    else
        AssignCommand(oTarget, ActionPlayAnimation(ANIMATION_LOOPING_PAUSE_DRUNK));

    effect eDumb = EffectAbilityDecrease(ABILITY_INTELLIGENCE, nPoints);
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDumb, oTarget, 60.0);
//   AssignCommand(oTarget, SpeakString(IntToString(GetAbilityScore(oTarget,ABILITY_INTELLIGENCE))));
}
void main()
{
    object oTarget = GetSpellTargetObject();
   // SpeakString("here");
    // * Beer
    if (GetSpellId() == 406)
    {
        // *burp*
        //AssignCommand(oTarget, SpeakString("Beer"));
        DrinkIt(oTarget);
//        if (FortitudeSave(oTarget, d20()+10) == TRUE)
        {
            MakeDrunk(oTarget, 1);
        }
    }
    else
    // *Wine
    if (GetSpellId() == 407)
    {
        DrinkIt(oTarget);
//        if (FortitudeSave(oTarget, d20()+10 +2) == TRUE)
        {
            MakeDrunk(oTarget, 2);
        }
    }
    else
    // * Spirits
    if (GetSpellId() == 408)
    {
        DrinkIt(oTarget);
//        if (FortitudeSave(oTarget, d20()+10) == TRUE)
        {
            MakeDrunk(oTarget, 3);
        }
     }

}


Самый простой способ добавить что-то:

Так была реализованна отрава на Экзисе по заказу Илэссэ smile.gif
Обрабатывался тег бутылки. Последние цифры преобразовывались в задержку, после который выпивший эту гадость умирал, дрыгая ногами.

Neverwinter Script Source
object oItem = GetSpellCastItem();
    if (GetStringUpperCase(GetStringLeft(GetTag(oItem),13))=="AX_IT_POISON_"){
        float PoisonType = StringToFloat(GetStringRight(GetTag(oItem),GetStringLength(GetTag(oItem))-13));
        DelayCommand(PoisonType, ExecuteScript("lg_anim_death",oTarget));

Вот вызываемый скрипт смерти: `lg_anim_death`
Neverwinter Script Source
void main()
{
    AssignCommand(OBJECT_SELF,ClearAllActions());
    AssignCommand(OBJECT_SELF,ActionPlayAnimation(ANIMATION_LOOPING_SPASM));
    DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectKnockdown(),OBJECT_SELF,4.0));
    DelayCommand(3.0, ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectDeath(TRUE),OBJECT_SELF));
    DelayCommand(4.0, SendMessageToPC(OBJECT_SELF,"Âàñ îòðàâèëè"));


Добавлено в [mergetime]1092332152[/mergetime]
<small>Добавлено в 17:26</small>
Шпаргалка Айвана по скриптам

Код

дело в том, что при

object oJamp = GetTransitionTarget(OBJECT_SELF);
if (GetIsPC(oPC))
{
AssignCommand(oPC, JumpToObject(oJamp));

НЕ ВСЕГДА МОЖЕТ ПРОИЗОЙТИ СКАЧОК
надо делать так:

string sJamp = GetTag(GetTransitionTarget(OBJECT_SELF));
....
JumpToObject(GetObjectByTag(sJamp));


************************************************
tag = mask + INtToString(Number);
mask = "WP_NPCTAG_"
Number = 1..12

*************************************************

DestroyObject(GetItemInSlot(INVENTORY_SLOT_CARMOR,oPC));

*************************************************
>    ЖУРНАЛЬНЫЕ ЗАПИСИ ПО КВЕСТОВЫМ ПРЕДМЕТАМ

object oItem=GetModuleItemAcquired();
if(GetTag(oItem)=="SEAMAGAZIN_PIRAT")
{
 if(GetLocalInt(oItem,"DO_ONCE")!=1 && GetItemPossessor(oItem) == GetFirstPC())
  {
 AddJournalQuestEntry("ANDRA_PIRATES", 4, GetFirstPC());
 SetLocalInt(oItem,"DO_ONCE",1);
  }
}

*****************************************************
> Увеличение числа переменной на единицу за раз.
SetLocalInt(объект_1, "переменная_1", GetLocalInt(объект_1, "переменная_1") + 1);

На кого ставится переменная?
объект_1 = OBJECT_SELF - если на сам триггер
            или
GetEnteringObject() - если на наступившего

********************************          
> Рандом на начало строки
int StartingConditional()
{

  // Add the randomness
  if(Random(100) >= 15)
      return FALSE;

  return TRUE;
}

*************************************************
> Дестрой нескольких объектов по одинаковому тэгу.
при СreateObject укажи новый тэг "new_tag"
а потом, когда условие соблюдено, делаешь так:
void main()
{
int i=0;
object oScelet = GetObjectByTag("new_tag",i);
while (oScelet!=OBJECT_INVALID)
 {
 DestroyObject(oScelet);
 i++;
 oScelet = GetObjectByTag("new_tag",i)
 }
}

****************************************************
> Проверка шмотки на игроке

if (GetTag(GetItemInSlot(INVENTORY_SLOT_CARMOUR,GetPCSpeaker())=="тэг нужной шмотки")

>***************************************
> ВХОД в локацию по проверке переменной
object oPC = GetEnteringObject();
object oDoor = GetObjectByTag("тэг_двери1"); // до затопления
if (!GetIsPC(oPC))
   return;
if (GetLocalInt(oPC, "FLOODED") == 1)
  oDoor = GetObjectByTag("тэг_двери2"); // после затопления
AssignCommand(oDoor, ActionOpenDoor(oDoor));
AssignCommand(oPC, JumpToObject(oDoor));

>***************************************
// Скрипт может стоять НА PC в диалоге!!!

void main()
{
object oPC = GetPCSpeaker();
object oItem = GetItemPossessedBy(oPC, "ZAVTRAK");
if (GetTag(oItem) == "ZAVTRAK")
{
 SpeakString("Смотри не лопни!");
 DestroyObject(oItem); // УБИВАЕТ ПРЕДМЕТ
}
else
{
 SpeakString("Ой! Да где же оно?");
}
}
>******************************************
// Скрипт должен стоять НА НЕПИСЕ!!!

void main()
{
object oPC = GetPCSpeaker();
object oItem = GetObjectByTag("ZAVTRAK");
if (GetTag(GetItemPossessedBy(oPC, "ZAVTRAK")) == "ZAVTRAK")
{
 SpeakString("Смотри не лопни!");
 ActionGiveItem(oItem, oPC);  // ОТДАЕТ ПРЕДМЕТ
}
else
{
 SpeakString("Ой! Да где же оно?");
}
}

>******************************************
void main()
{
object oPC = GetPCSpeaker();
object oItem = GetItemPossessedBy(oPC, "MINERS_PISMO");
object oNos = GetObjectByTag("SUPER_NOS_IN_MARKET");
AssignCommand (oNos, JumpToObject(GetObjectByTag("POISON_SUPER_NOS")));
if (GetTag(oItem) == "MINERS_PISMO")
{
 DestroyObject(oItem); // УБИВАЕТ ПРЕДМЕТ
 SpeakString("Отлично, Грэмм у нас в руках!");
}
}
>******************************************
> Дает вещь из палитры, а не из инвентаря
object oPC = GetFirstPC();
CreateItemOnObject("ResRef-вещи", oPC, число);

Последний параметр нужен только если ты даешь типа стрел или пуль...
короче количество в ячейке инвентаря. Само собой 2 меча ты дать
таким образом не сможешь :)...
>******************************************

<small>Добавлено в 17:29</small>
автор Valleo

Маленький скриптик для реализации болота:
Neverwinter Script Source
void StartBog()
{
object oBog = OBJECT_SELF;
object oArea = GetArea(oBog);
location lLocation = GetLocation(oBog);
location lLoc;
location lLocat;
object oObject = GetFirstObjectInShape(SHAPE_SPHERE,100.0,lLocation,FALSE,OBJECT_TYPE_CREATURE);
while(GetIsObjectValid(oObject))
{
lLoc = GetLocation(oObject);
lLocat = GetLocalLocation(oObject,"BOGLOC");
if(GetIsObjectValid(GetAreaFromLocation(lLocat)))
  {
  float fDist = GetDistanceBetweenLocations(lLoc,lLocat);
  if(fDist < 5.0)
   {
   effect eSlow = EffectMovementSpeedDecrease(75);
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSlow,oObject,70.0);
   FloatingTextStringOnCreature("Вас засасывает в бололто...",oObject,FALSE);
   }
  }
SetLocalLocation(oObject,"BOGLOC",lLoc);
oObject = GetNextObjectInShape(SHAPE_SPHERE,100.0,lLocation,FALSE,OBJECT_TYPE_CREATURE);
}
}
void main()
{
object oBog = OBJECT_SELF;
int iTimer = GetLocalInt(oBog,"TIMER");
if(iTimer <= 9)
{
iTimer = iTimer + 1;
SetLocalInt(oBog,"TIMER",iTimer);
return;
}
SetLocalInt(oBog,"TIMER",0);
StartBog();
}

Автор: Aiwan Aug 14 2004, 01:50

Вот простой скриптик, ставится на строку НПС и во время длинного расказа, происходит, как бы временной интервал с потухшим экраном. Что то навроде, как в кино: "Прошло два года..." :?)

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Created By: WRG! Aiwan aiwan@e-mail.ru
//:: Created On: 21.12.2003
//:://////////////////////////////////////////////
/*
            ПАУЗА В РАЗГОВОРЕ С НПС
*/

//:://////////////////////////////////////////////
void main()
{
    object oPC = GetPCSpeaker();
    AssignCommand(OBJECT_SELF, ActionPauseConversation());
    AssignCommand(OBJECT_SELF, FadeToBlack(oPC, FADE_SPEED_SLOW));
    AssignCommand(OBJECT_SELF, ActionWait(4.0));
    AssignCommand(OBJECT_SELF, FadeFromBlack(oPC, FADE_SPEED_SLOW));
    SetTime(GetTimeHour()+(Random(4)), GetTimeMinute()+(Random(60)), 0, 0);
    AssignCommand(OBJECT_SELF, ActionResumeConversation());
}

Автор: Twin Oct 2 2004, 15:12

Благодаря советам вышестоящих модераторов в другом топике, я таки дописал респаунинг NPC по событию их смерти, без использования энкаунтеров. wink.gif Это может кому-нибудь пригодиться, т.к. нет проблемы с "пересечением" области энкаунтера игроком и т.п., NPC может появится прямо перед носом игрока.

Для работы скрипта нам потребуется создать плейс с тэгом PLC_AUTORESPAWN. Любой плейс, он нужен лишь для того, чтобы на него вешать DelayCommand. Лично я ставил этот плейс в "системную" локу 8x8, которая только для подобных целей и была создана. У меня не получилось повесить DelayCommand на вейпоинт, иначе бы плейс создавать и не потребовалось бы. wink.gif
Создаем новый файл скрипта, который будет инклюдится к событию смерти:

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Created By: Twin
//:: Communication:
//::  E-mail: twin_quad@hotmail.com
//::  IRC: Twin@irc.rinet.ru:6669
//::
//:: Created On: 2004.10
//:://////////////////////////////////////////////

void doSpawn(string sResRef, string sTag, location locWhere, int nRespawnTime, int nMaxSpawns, int nCurrent, int bAnimation);

void cycleSpawn(object oNPC)
{
    object oRespawner = GetObjectByTag("PLC_AUTORESPAWN");
    if ( !GetIsObjectValid(oRespawner) )
        return;

    int nRespawnTime = GetLocalInt(oNPC, "respawn_time");
    if ( nRespawnTime <= 0 )
        return;

    string sWaypoint = GetTag(oNPC);
    if ( FindSubString(sWaypoint, "NPC_") == 0 )
        sWaypoint = GetStringRight(sWaypoint, GetStringLength(sWaypoint) - 4);
    sWaypoint = "WPR_" + sWaypoint;

    int bAnimation = GetLocalInt(oNPC, "respawn_animation");
    int nMaxSpawns = GetLocalInt(oNPC, "respawn_max");
    int nCurrent  = GetLocalInt(oNPC, "respawn_current");
    if ( nCurrent == 0 )
        nCurrent = 1;

    if ( (nMaxSpawns <= 0 || nCurrent < nMaxSpawns) && GetIsObjectValid(GetObjectByTag(sWaypoint)) )
    {
        //SendMessageToPC(GetFirstPC(), "Next respawn in "+ IntToString(nRespawnTime) +" seconds.");
        //SendMessageToPC(GetFirstPC(), "Current/Max: "+ IntToString(nCurrent) +"/"+ IntToString(nMaxSpawns));

        string sResRef = GetResRef(oNPC);
        string sTag = GetTag(oNPC);
        location locWhere = GetLocation(GetObjectByTag(sWaypoint));

        AssignCommand(oRespawner,
            DelayCommand(IntToFloat(nRespawnTime),
                doSpawn(sResRef, sTag, locWhere, nRespawnTime, nMaxSpawns, nCurrent, bAnimation)
            )
        );
    }
}

void doSpawn(string sResRef, string sTag, location locWhere, int nRespawnTime, int nMaxSpawns, int nCurrent, int bAnimation)
{
    object oNPC;
    oNPC = CreateObject(OBJECT_TYPE_CREATURE, sResRef, locWhere, bAnimation, sTag);

    nCurrent++;
    SetLocalInt(oNPC, "respawn_time", nRespawnTime);
    SetLocalInt(oNPC, "respawn_max", nMaxSpawns);
    SetLocalInt(oNPC, "respawn_current", nCurrent);
    SetLocalInt(oNPC, "respawn_animation", bAnimation);

    //SendMessageToPC(GetFirstPC(), "doSpawn("+ sResRef +", "+ sTag +")");
}


Далее ставим на карту требуемого NPC, в скрипте OnDeath или UserDefined на событие 1007 (главное чтобы во время смерти срабатывало) в самом начале вставляем:
Neverwinter Script Source
#include "название созданного выше скрипта"


И где-нибудь ближе к концу скрипта смерти вставляем:
Neverwinter Script Source
cycleSpawn(OBJECT_SELF);


Настраивается это всё просто. Заходим в Variables созданного NPC и добавляем переменные (все типа int):
respawn_time - Количество секунд, через которое появится новый NPC.
respawn_max - Необязательный параметр. Максимальное количество респаунов NPC.
respawn_animation - Необязательный параметр. Проигрывать ли анимацию во время создания NPC [0/1].

Можно настраивать Variables прямо в синьке NPC, на эффект это не влияет.

Место где появится новый NPC определяется путём выставления вэйпоинтов с названием типа "WPR_"+ тэг_умершего_NPC. Если в начале тэга NPC стоит "NPC_", то эти четыре символа отрежутся.

Всё.

При желании можно можно сохранять любые параметры умирающего NPC, даже случайный лут скопировать с трупа и загрузить в слудеющий респаун такой же. В общем всё что угодно.

Надеюсь кому-нибудь пригодится. wink.gif

P.S. Забыл о вэйпоинтах написать... Исправлено.

Автор: Аваддон Oct 9 2004, 18:51

Этот скрипт можно ставить на факел, фонарь, или луч света. Например факелы и фонари можно расставить по городу. А лучи света или магические брызги - к фонтанам. И когда в городе наступит ночь - зажгуться факелы и будут освещать территорию, а у фонтанов заработает подсветка. Скрипт ставит OnHB плейса. Не забудьте снять галочку Static.

Neverwinter Script Source
void main()
{
   object oSelf = OBJECT_SELF;
   if (GetIsDay()==FALSE && GetLocalInt(OBJECT_SELF,"on")!=1)
   {
   SetLocalInt(OBJECT_SELF,"on",1);
   PlayAnimation(ANIMATION_PLACEABLE_ACTIVATE);
   effect eLight = EffectVisualEffect(VFX_DUR_LIGHT_YELLOW_10);
   ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLight, oSelf);
   }

   if (GetIsDay()==TRUE && GetLocalInt(OBJECT_SELF,"on")==1)
   {
   SetLocalInt(OBJECT_SELF,"on",0);
   PlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE);
   effect eEffect = GetFirstEffect(oSelf);
   while (GetIsEffectValid(eEffect) == TRUE)
       {
       if (GetEffectType(eEffect) == EFFECT_TYPE_VISUALEFFECT)
          RemoveEffect(oSelf, eEffect);
          eEffect = GetNextEffect(oSelf);
       }
   }

}

Автор: Аваддон Oct 12 2004, 20:53

Скрипт получения уровня по алайменту написал [MoF]Darth_Nick. Там он использовал визуальные эффекты для разных алайментов. Я лишь добавил немного своего в этот скрипт. И так, получение лвла по алайменту а-ля горец biggrin.gif

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

if(GetAlignmentGoodEvil(oPC) == ALIGNMENT_EVIL)
{
SetCutsceneMode(oPC, TRUE);
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_FNF_SCREEN_SHAKE), GetLocation(oPC), 8.0);
AssignCommand(oPC, PlayAnimation(ANIMATION_LOOPING_SPASM,1.0,5.0));
DelayCommand(1.0,AssignCommand(oPC,PlayVoiceChat(VOICE_CHAT_LAUGH)));
DelayCommand(3.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SUMMON_EPIC_UNDEAD), oPC));
DelayCommand(3.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_HARM), oPC));
DelayCommand(4.0,AssignCommand(oPC, PlayAnimation(ANIMATION_LOOPING_DEAD_FRONT,1.0,10.0)));
DelayCommand(3.8,AssignCommand(oPC,PlayVoiceChat(VOICE_CHAT_DEATH)));
DelayCommand(5.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_SLEEP), oPC));
DelayCommand(10.0,SetCutsceneMode(oPC, FALSE));
}
else if(GetAlignmentGoodEvil(oPC) == ALIGNMENT_GOOD)
{
SetCutsceneMode(oPC, TRUE);
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_FNF_SCREEN_SHAKE), GetLocation(oPC), 8.0);
AssignCommand(oPC, PlayAnimation(ANIMATION_LOOPING_SPASM,1.0,5.0));
DelayCommand(1.0,AssignCommand(oPC,PlayVoiceChat(VOICE_CHAT_NEARDEATH)));
DelayCommand(3.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_HOLY_AID), oPC));
DelayCommand(3.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SUNBEAM), oPC));
DelayCommand(4.0,AssignCommand(oPC, PlayAnimation(ANIMATION_LOOPING_DEAD_FRONT,1.0,10.0)));
DelayCommand(3.8,AssignCommand(oPC,PlayVoiceChat(VOICE_CHAT_DEATH)));
DelayCommand(5.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_SLEEP), oPC));
DelayCommand(10.0,SetCutsceneMode(oPC, FALSE));
}
else if(GetAlignmentGoodEvil(oPC) == ALIGNMENT_NEUTRAL)
{
SetCutsceneMode(oPC, TRUE);
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_FNF_SCREEN_SHAKE), GetLocation(oPC), 8.0);
AssignCommand(oPC, PlayAnimation(ANIMATION_LOOPING_SPASM,1.0,5.0));
DelayCommand(1.0,AssignCommand(oPC,PlayVoiceChat(VOICE_CHAT_NEARDEATH)));
DelayCommand(3.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SOUND_BURST), oPC));
DelayCommand(3.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_HEALING_X), oPC));
DelayCommand(4.0,AssignCommand(oPC, PlayAnimation(ANIMATION_LOOPING_DEAD_FRONT,1.0,10.0)));
DelayCommand(3.8,AssignCommand(oPC,PlayVoiceChat(VOICE_CHAT_DEATH)));
DelayCommand(5.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_SLEEP), oPC));
DelayCommand(10.0,SetCutsceneMode(oPC, FALSE));
}
}

Автор: Аваддон Oct 13 2004, 00:05

Ой, чето зачастил я со скриптамиsmile.gif Но надеюсь пригодится dntknw.gif
Этот скрипт на отдых. Для начала разберемся с условиями отдыха:

1. У игрока должна быть кроватка(подстилка) aka бэдролл
2. Так же должна быть в наличие еда.
3. Расстояние от разведенного костра должно быть не более 3х метров.
4. Если игрок спит в тяжелых доспехах (более 20 lbs) то у него есть риск заболеть, вредно ведь для здоровьица геройского. Но спасы рулятwink.gif А если не рулят то придется переодеваться в пижамку (гы-гы biggrin.gif )

Чтобы развести костер надо:
1. Найти дрова (сами запихнете их в какое нить дупло и т.п.)
2. Разложить дрова на земле.
3. Пожечь факелом.
4. Костер горит 180 сек (можете сами регулировать)
5. Если вы используете выложенные дрвоа без факела - игрок их поднимает, если с факелом - разводит костер.

Теперь с предметами:

Item'ы:
Подстилка - тэг [bedroll]
Еда - тэг [food]
Дрова - тэг [wood]

Placeable'ы:
Костер - синька [camp]
Подстилка (внешне выглядит как раскатаная из рулона ткань) - синька [place_bedroll]
Дрова (внешне выглядит как куча дров aka woodpile biggrin.gif) - синька [place_wood] .

P.S. Синька это Blueprint ResRef

Со всех плейсов снимите галочку Static! А плейс Дрова должен быть Используемый.

Поехали...

Скрипт ставится на OnPlayerRest

Neverwinter Script Source
//////////////////////////////////////////////////
////////////Avaddon's Rest System//////////
////////// Script On Player Rest ////////////
////////// Date: 12.10.2004 ///////////////
//////// Created by: Avaddon ////////////
/////////////////////////////////////////////

#include "nw_i0_tool"
void main()
{
object oPC = GetLastPCRested();
object oCamp = GetNearestObjectByTag("camp",oPC);
object oBedroll = GetNearestObjectByTag("place_bedroll",oPC);
effect eSleep = EffectVisualEffect(VFX_IMP_SLEEP);
effect eBlind = EffectBlindness();
effect eDisease = EffectDisease(DISEASE_SOLDIER_SHAKES);

    if (GetLastRestEventType() == REST_EVENTTYPE_REST_STARTED) //отдых начат
    {
        if(GetIsObjectValid(oCamp)!=TRUE) //проверка расстоЯниЯ до костра
        {
         FloatingTextStringOnCreature("Здесь слишком холодно",oPC,FALSE);
         AssignCommand(oPC,ClearAllActions()); //отмена отдыха
        }
       else
       {
       if(GetDistanceBetween(oPC,oCamp)>3.0)
       {
       FloatingTextStringOnCreature("Здесь слишком холодно",oPC,FALSE);
       AssignCommand(oPC,ClearAllActions()); //отмена отдыха
       }
       else
         {
        if (HasItem(oPC,"bedroll")==TRUE) //проверка на наличие подстилки
        {
            if (HasItem(oPC,"food")==TRUE) //проверка на наличие еды
            {
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSleep,oPC,30.0); // Эффект Z-z-z
            FadeToBlack(oPC, FADE_SPEED_SLOW); //тушим свет
            CreateObject(OBJECT_TYPE_PLACEABLE,"place_bedroll",GetLocation(oPC)); // Расстилаем подстилку
            DestroyObject(GetItemPossessedBy(oPC,"food")); //съедаем еду
            DestroyObject(GetItemPossessedBy(oPC,"bedroll")); //забираем у игрока подстилку из инвентори (реализм, блин)
            SetLocalInt(oPC,"slept",1); //сон удачен
            }
            else
            {
            FloatingTextStringOnCreature("Не боитесь помереть во сне от голода?!",oPC,FALSE);
            AssignCommand(oPC,ClearAllActions());
            }
        }
        else
        {
        FloatingTextStringOnCreature("Вам не на чем спать",oPC,FALSE);
        AssignCommand(oPC,ClearAllActions());
        }
       }
       }
    }
   if (GetLastRestEventType() == REST_EVENTTYPE_REST_FINISHED) //отдых закончен
   {
   FadeFromBlack(oPC, FADE_SPEED_SLOW); //продираем глазки
   DestroyObject(oBedroll); //убираем подстилку
   SetLocalInt(oPC,"slept",0); //отдых удачно окончен
   CreateItemOnObject("bedroll", oPC,1); // отдаем игроку в инвентори его подстилку
   if (GetWeight(GetItemInSlot(INVENTORY_SLOT_CHEST,oPC))>20) // проверка на вес брони
   {
   ApplyEffectToObject(DURATION_TYPE_INSTANT,eDisease,oPC); //игрок заболел
   }

   }

   if (GetLastRestEventType() == REST_EVENTTYPE_REST_CANCELLED) //отдых прерван
   {
   if(GetLocalInt(oPC,"slept")==1) //если отдых был прерван после того как он был успешно начат
   {
   FadeFromBlack(oPC, FADE_SPEED_FAST); //быстро продираем глазки
   DestroyObject(oBedroll); //убираем подстилку
   FloatingTextStringOnCreature("Вы проснулись от сильного шума, но глаза еще не привыкли к свету.",oPC,FALSE);
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSleep,oPC,10.0); //сонный игрок
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eBlind,oPC,10.0); //еще не проснулсЯ
   SetLocalInt(oPC,"slept",0); //успешный отдых прерван
   CreateItemOnObject("bedroll", oPC,1); // возвращаем в инвентори подстилку
   }
   }

}


Скрипт ставится на UnAcquireItem
Neverwinter Script Source
/////////////////////////////////////////
    //////////Avaddon's Rest System//////////
   ////// Script On UnAcquireItem //////////
  //////// Date: 12.10.2004 ///////////////
  //////// Created by: Avaddon ////////////
/////////////////////////////////////////
void main()
{
object oLost = GetModuleItemLost();
object oPC = GetModuleItemLostBy();
if (GetTag(oLost)=="wood")
{
CreateObject(OBJECT_TYPE_PLACEABLE,"place_wood",GetLocation(oPC)); //выкладываем плейс дров
DestroyObject(oLost); //уничтожаем выложенны мешочек с итемом дров
}
}


Скрипт ставится на On Used плейса дров
Neverwinter Script Source
/////////////////////////////////////////
    //////////Avaddon's Rest System//////////
   ////// Script On Used Woodpile //////////
  //////// Date: 12.10.2004 ///////////////
  //////// Created by: Avaddon ////////////
/////////////////////////////////////////
#include "nw_i0_tool"
void main()
{
object oPC = GetLastUsedBy();

    if (GetIsPC(oPC)==TRUE)
    {
    if (GetTag(GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC))=="NW_IT_TORCH001") //проверка - есть ли факел в руке
    {
    AssignCommand(oPC,PlayAnimation(ANIMATION_LOOPING_GET_LOW,1.0,2.0));
    CreateObject(OBJECT_TYPE_PLACEABLE,"camp",GetLocation(OBJECT_SELF),TRUE);// если есть - поджигаем костер
    DestroyObject(OBJECT_SELF); //убираем дрова
    }
    else
    {
    DestroyObject(OBJECT_SELF);
    CreateItemOnObject("wood",oPC,1); //если нет - игрок поднимает дрова
    }
}
}


Скрипт ставится на On Heartbeat костра
Neverwinter Script Source
/////////////////////////////////////////
    //////////Avaddon's Rest System//////////
   ////// Script On Heartbeat Campfire /////
  //////// Date: 12.10.2004 ///////////////
  //////// Created by: Avaddon ////////////
/////////////////////////////////////////

void main()
{
int iFire = GetLocalInt(OBJECT_SELF,"fire");

if (iFire<1)
{
SetLocalInt(OBJECT_SELF,"fire",6);
}
else
{
SetLocalInt(OBJECT_SELF,"fire",iFire+6);
}

if (iFire>180) //проверка - прошло ли более 180 секунд
{
DeleteLocalInt(OBJECT_SELF,"fire");
DestroyObject(OBJECT_SELF);
}
}


Эээ вроде ничего не напутал. Если что не получается - скажите, я поправлю.

Автор: Lex Nov 5 2004, 22:10

Источник: Валут.
Нашел: Авадон.

Neverwinter Script Source
// Make a large SoU bench usable by 3 creatures simultaneously
void main()
{
    // Set some variable for a beter understanding
    object oPlayer = GetLastUsedBy();
    object oBench = OBJECT_SELF;

    // Get a hold on the 3 pillows
    object oPillow1 = GetLocalObject( OBJECT_SELF, "Pillow 1" );
    object oPillow2 = GetLocalObject( OBJECT_SELF, "Pillow 2" );
    object oPillow3 = GetLocalObject( OBJECT_SELF, "Pillow 3" );

    // If "pillow 1" do not exist, create 3 of them and attach them to the bench
    if( !GetIsObjectValid( oPillow1 ) )
    {
        // Set up some variable for understanding
        object oArea = GetArea( oBench );
        vector locBench = GetPosition( oBench );
        float fOrient = GetFacing( oBench );

        // You can change the space between pillows changing this value
        float fSpace = 1.0f;

        // Calculate location of the 3 pillows
        location locPillow1 = Location( oArea, locBench + AngleToVector( fOrient + 90.0f ) * fSpace, fOrient );
        location locPillow2 = Location( oArea, locBench + AngleToVector( fOrient - 90.0f ) * fSpace, fOrient );
        location locPillow3 = Location( oArea, locBench, fOrient );

        // Create the 3 pillows
        oPillow1 = CreateObject( OBJECT_TYPE_PLACEABLE, "plc_invisobj", locPillow1 );
        oPillow2 = CreateObject( OBJECT_TYPE_PLACEABLE, "plc_invisobj", locPillow2 );
        oPillow3 = CreateObject( OBJECT_TYPE_PLACEABLE, "plc_invisobj", locPillow3 );
   
        // "attach" the pillows to the bench
        SetLocalObject( OBJECT_SELF, "Pillow 1", oPillow1 );
        SetLocalObject( OBJECT_SELF, "Pillow 2", oPillow2 );
        SetLocalObject( OBJECT_SELF, "Pillow 3", oPillow3 );
    }
   
    // Get a hold on the nearest invisible object, (maybe a pillow)
    int iDistance = 1;
    object oPillow = GetNearestObjectByTag( "InvisibleObject", oPlayer, iDistance );
   
    // while we find invisible object and that we did not check the 3 linked pillows
    int iCount = 0;
    while( GetIsObjectValid( oPillow ) || iCount < 3 )
    {
        // if it is one of the three pillow linked the the bench
        if( oPillow == oPillow1 || oPillow == oPillow2 || oPillow == oPillow3 )
        {
            iCount = iCount + 1 ;
            // If available
            if( !GetIsObjectValid( GetSittingCreature( oPillow ) ) )
            {
                // Sit and quit the script
                AssignCommand( oPlayer, ActionSit( oPillow ) );
                return;
            }
        }
        // Get the next nearest invisible object
        iDistance = iDistance + 1;
        oPillow = GetNearestObjectByTag( "InvisibleObject", oPlayer, iDistance );
    }
}


Автор: Аваддон Nov 17 2004, 22:29

Я тут написал пару скриптиков. Они для сервера использующего APS/NWNX 2 + MySQL.
Естественно писал для своих нужд, но может кому и пригодится.
Главная его цель - информативность.
Если вы умеете работатьс MySQL то польза от него будет большая. Он регистрирует персонажей. Потом просмтривая БД вы можете узнать сколько:
-Игроков зарегистрированно
-ДМов зарегистрированно
-Персонажей на одном аккаунте
-Персонажей на одном IP
-Персонажей на одном CD-Key
-Аккаунтов на одном IP
-Аккаунтов на одном CD-Key
-Сколько персонажей определенной расы на шарде
-Сколько персонажей определенной под-расы на шарде
-Сколько персонажей поклоняются определнному одинаковому божеству, и поклоняются ли вообще
-Сколько персонажей мужских, а сколько женских.
-Дату создания персонажа.
-ну и еще что-нибудь если забыл.
Да, если кто нибудь напишет PHP форму для статистики читающую из этой БД - это будет замечательно - тогда срочно свяжитесь со мнойsmile.gif

Скрипты:

Скрипт aps_include поставляется в erf архиве вместе с APS/NWNX 2.

Скрипт на OnModuleLoad:

Neverwinter Script Source
#include "aps_include"
void main()
{
SQLInit();
string sSQL="CREATE TABLE `reg_data` ("+
"  `status` varchar(64) NOT NULL default '',"+
"  `login` varchar(64) NOT NULL default '',"+
"  `name` varchar(64) NOT NULL default '',"+
"  `gender` char(1) NOT NULL default '',"+
"  `race` varchar(100) NOT NULL default '',"+
"  `sub_race` varchar(100) NOT NULL default '',"+
"  `deity` varchar(100) NOT NULL default '',"+
"  `cd_key` varchar(64) NOT NULL default '',"+
"  `ip` varchar(25) NOT NULL default '',"+
"  `creation_date` datetime NOT NULL default '0000-00-00 00:00:00',"+
") TYPE=MyISAM;";


  SQLExecDirect("DESCRIBE reg_data");
  //Если таблицы нет - создаем ее
  if (SQLFetch()!= SQL_SUCCESS)
  {
    SQLExecDirect(sSQL);
  }
}


Скрипт на OnClientEnter:
Neverwinter Script Source
#include "aps_include"
void main()
{
object oPC=GetEnteringObject();
string sName=SQLEncodeSpecialChars(GetName(oPC));//ИМЯ персонажа
string sLogin=SQLEncodeSpecialChars(GetPCPlayerName(oPC)); // Логин игрока
string sGender="М"; if(GetGender(oPC)==GENDER_FEMALE)sGender="Ж";//Пол
string sKey=GetPCPublicCDKey(oPC); //CD-key игрока
string sIp=GetPCIPAddress(oPC); //Ip игрока
string sDeity=GetDeity(oPC); //Божество игрока
string sStatus = "PC";////ДМ или Игрок
if (GetIsDM(oPC)==TRUE)sStatus = "DM";
string sRace = "Неизвестно"; //Расы заносимые при регистрации в БД
if(GetRacialType(oPC)==RACIAL_TYPE_DWARF)sRace = "Дворф";
if(GetRacialType(oPC)==RACIAL_TYPE_ELF)sRace = "Эльф";
if(GetRacialType(oPC)==RACIAL_TYPE_GNOME)sRace = "Гном";
if(GetRacialType(oPC)==RACIAL_TYPE_HALFELF)sRace = "Полуэльф";
if(GetRacialType(oPC)==RACIAL_TYPE_HALFLING)sRace = "Полурослик";
if(GetRacialType(oPC)==RACIAL_TYPE_HALFORC)sRace = "Полуорк";
if(GetRacialType(oPC)==RACIAL_TYPE_HUMAN)sRace = "Человек";
string sSubrace=GetStringLeft(GetSubRace(oPC), 99);


//Выполним запрос SQL - выбираем строчку со статусом где логин и чар-нейм = логин и ИМЯ персонажа вошедшего игрока
string sSelect = "SELECT cd_key FROM `reg_data` WHERE login='"+GetPCPlayerName(oPC)+
"' AND name='" +GetName(oPC)+ "' AND status='"+sStatus+"'";

//Регистрируем игрока статус - регистред, логин, чар-нейм, пол, раса, подраса, сд-кей, ip, и дата регистрации
string sReg="INSERT INTO reg_data (status, login, name, gender,"+
       "race,sub_race, deity,cd_key,ip,creation_date) "+
       "VALUES('"+sStatus+
      "','"+sLogin+
      "','"+sName+
      "','"+sGender+
      "','"+sRace+
      "','"+sSubrace+
      "','"+sDeity+
      "','"+sKey+
      "','"+sIp+
      "',NOW())";

//Проверка на статус игрока (зарегистрирован или нет)
SQLExecDirect(sSelect);
if (SQLFirstRow() == SQL_SUCCESS)
    {
    SendMessageToPC(oPC,"Рады вас видеть снова!");

    }
    else
    {
        SQLExecDirect(sReg);
        SendMessageToPC(oPC,"Приветствуем Вас! Вас персонаж был автоматически зарегистрирован!");
    }
}

Автор: [MoF]Darth_Nick Nov 18 2004, 05:38

Neverwinter Script Source
//::///////////////////////////////////////////////
//:: Name: Наитупейшая Ловушка
//:://////////////////////////////////////////////
/*
Скрипт ставится на OnEnter тригера(Generic)...
Описание - Из названия всё понятно smile.gif
*/

//:://////////////////////////////////////////////
//:: Created By: [MoF]Darth_Nick
//:://////////////////////////////////////////////

void main()
{
object oPC = GetEnteringObject();
effect eBall = EffectVisualEffect(VFX_FNF_FIREBALL);

if (GetIsPC(oPC) && GetCurrentHitPoints(oPC) <= 70)
{
DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBall, oPC));
DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oPC));
}
else if (GetIsPC(oPC) && GetCurrentHitPoints(oPC) > 70)
{
FloatingTextStringOnCreature("Heh...This trick is not for me!", oPC);
}
}


дык...

Автор: Лито Nov 22 2004, 10:49

у меня вот такий скрипт на OnPlayerDeath

CODE
void main()
{
object oPlayer = GetLastPlayerDied();
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_DEATH), GetLocation(oPlayer));

DelayCommand(6.0,AssignCommand(oPlayer,ClearAllActions()));
DelayCommand(2.5, PopUpGUIPanel(oPlayer,GUI_PANEL_PLAYER_DEATH));
}


Чтобы всплывало окошко нужна например такая строка
CODE
DelayCommand(2.5, PopUpGUIPanel(oPlayer,GUI_PANEL_PLAYER_DEATH));


А для снятия экспы можно использовать этот стандартный скрипт yes.gif
CODE
#include "nw_i0_plot"
void ApplyPenalty(object oDead)
{
   int nXP = GetXP(oDead);
   int nPenalty = 100 * GetHitDice(oDead);
   int nHD = GetHitDice(oDead);
   // * You can not lose a level with this respawning
   int nMin = ((nHD * (nHD - 1)) / 2) * 1000;

   int nNewXP = nXP - nPenalty;
   if (nNewXP < nMin)
      nNewXP = nMin;
   SetXP(oDead, nNewXP);
   int nGoldToTake =    FloatToInt(0.10 * GetGold(oDead));
   // * a cap of 10 000gp taken from you
   if (nGoldToTake > 10000)
   {
       nGoldToTake = 10000;
   }
   AssignCommand(oDead, TakeGoldFromCreature(nGoldToTake, oDead, TRUE));
   DelayCommand(4.0, FloatingTextStrRefOnCreature(58299, oDead, FALSE));
   DelayCommand(4.8, FloatingTextStrRefOnCreature(58300, oDead, FALSE));

}
void main()
{
   object oRespawner = GetLastRespawnButtonPresser();
   AssignCommand(oRespawner,JumpToLocation(GetLocation(GetObjectByTag("WP_RAISE"))));
   ApplyPenalty(oRespawner);
   ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectResurrection(),oRespawner);
   ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectHeal(GetMaxHitPoints(oRespawner)), oRespawner);
   RemoveEffects(oRespawner);
}

Я его немножко изменил...не знаю насколько хорошо, но все пашет good.gif

Автор: [MoF]Darth_Nick Nov 24 2004, 04:57

Я смерть плеера в БД записываю smile.gif

Neverwinter Script Source
#include "aps_include"
void main()
{
object oPC = GetLastPlayerDied();
string sDeath = "UPDATE `reg_data` SET death=1 WHERE name='" + GetName(oPC) + "'";
string sDHelp = "Вы умерли, но можете воскреснуть!";
PopUpDeathGUIPanel(oPC, TRUE, TRUE, 1, sDHelp);
SQLExecDirect(sDeath);
}

Чуть изменил скрипты Аваддона...

Аваддон ты мог отредактировать скрипт и записывать еще лвлы туды smile.gif
Вопрос 1: как можно изменить хелсы ПС на те которые я хочу сам, через скрипты?
Добавлено в [mergetime]1101261601[/mergetime]
П.С. у мя снятие экспы на OnRespawn ставится smile.gif и золото не отбираю, ибо не жадный lol.gif lol.gif

Автор: Ilharess Nov 24 2004, 12:40

Спаунер/анспаунер для гвардов (Утром открывается дверь и появляется гвард идет на свой пост или свои вэйпы, несет службу весь день или ночь, когда приходит время идет обратно к двери если у него есть ключ то открывает ее, если нет то стучит и ему открывают, можно использовать и для спауна и обычных нпсов, если не много изменить biggrin.gif ).
В вараблах двери создаем переменные
DAYTIMEGUARD string “resref npc”, если гвард не нужен то ""
NIGHTTIMEGUARD string “resref npc”, если гвард не нужен то ""
GATESGUARD string “resref npc”, если гвард не нужен то ""
На onhb двери вешаем :

Neverwinter Script Source
/*
  door_guardspaw_5
  Spawner for guards.
*/

//#include "kv_tools"
void main()
{
//--
string sDaytimeGuard = "MOB_DAYTIMEGUARD" + GetSubString(GetTag(OBJECT_SELF), 4, GetStringLength(GetTag(OBJECT_SELF)));
object oDaytimeGuard = GetObjectByTag(sDaytimeGuard);
//--
string sNighttimeGuard = "MOB_NIGHTTIME" + GetSubString(GetTag(OBJECT_SELF), 4, GetStringLength(GetTag(OBJECT_SELF)));
object oNighttimeGuard = GetObjectByTag(sNighttimeGuard);
//--
string sGatesGuard = "MOB_GATESGUARD" + GetSubString(GetTag(OBJECT_SELF), 4, GetStringLength(GetTag(OBJECT_SELF)));
object oGatesGuard = GetObjectByTag(sGatesGuard);
//--Spawn day guard--//
if ( GetIsDay() && !GetIsObjectValid(oDaytimeGuard) && GetLocalString(OBJECT_SELF, "DAYTIMEGUARD") != "")

   {
     ActionOpenDoor(OBJECT_SELF);
     object oNewGuard = CreateObject(OBJECT_TYPE_CREATURE, GetLocalString(OBJECT_SELF, "DAYTIMEGUARD"), GetLocation(OBJECT_SELF), 0, sDaytimeGuard);

      /* if (GetIsObjectValid(oNewGuard))
         {
          DebugMessage(GetTag(OBJECT_SELF) + ": Guard " + sDaytimeGuard + " spawned sucsesfull");
         }*/

//--Spawn Night Guard--//
   }  else if ( GetIsNight() && !GetIsObjectValid(oNighttimeGuard) && GetLocalString(OBJECT_SELF, "NIGHTTIMEGUARD") != "")
             {
               ActionOpenDoor(OBJECT_SELF);
               object oNewGuard = CreateObject(OBJECT_TYPE_CREATURE, GetLocalString(OBJECT_SELF, "NIGHTTIMEGUARD"), GetLocation(OBJECT_SELF), 0, sNighttimeGuard);

              /*   if (GetIsObjectValid(oNewGuard))
                   {
                    DebugMessage(GetTag(OBJECT_SELF) + ": Guard " + sNighttimeGuard + " spawned sucsesfull");
                   }*/

//--Spawn Gate Guard--//
             } else if ( GetIsDusk() && !GetIsObjectValid(oGatesGuard) && GetLocalString(OBJECT_SELF, "GATESGUARD") != "")
                     {
                      ActionOpenDoor(OBJECT_SELF);
                      object oNewGuard = CreateObject(OBJECT_TYPE_CREATURE, GetLocalString(OBJECT_SELF, "GATESGUARD"), GetLocation(OBJECT_SELF), 0, sGatesGuard);
                   /*if (GetIsObjectValid(oNewGuard))
                       {
                        DebugMessage(GetTag(OBJECT_SELF) + ": Guard " + sGatesGuard + " spawned sucsesfull");
                       }*/

                     }
//--
if (GetIsNight() && GetIsObjectValid(oDaytimeGuard))
{
   SignalEvent(oDaytimeGuard,  EventUserDefined(111));//TIME TO GO HOME:)
   SetLocalObject(GetArea(OBJECT_SELF), "THE_DOOR", OBJECT_SELF);
}
else if (GetIsDay() && GetIsObjectValid(oNighttimeGuard))
       {
        SignalEvent(oNighttimeGuard,  EventUserDefined(111));//TIME TO GO HOME:)
        SetLocalObject(GetArea(OBJECT_SELF), "THE_DOOR", OBJECT_SELF);
       }
       else if (GetIsDawn() && GetIsObjectValid(oGatesGuard))
             {
              SignalEvent(oGatesGuard,  EventUserDefined(111));//TIME TO GO HOME:)
              SetLocalObject(GetArea(OBJECT_SELF), "THE_DOOR", OBJECT_SELF);
             }
}


На onopen
Neverwinter Script Source
/*
door_guardspaw_8
Spawner for guards.
*/


void main()
{

DelayCommand(5.0, ActionCloseDoor(OBJECT_SELF));
SetLocked(OBJECT_SELF, TRUE);
//--
object oClicker = GetLastOpenedBy();
if ( GetIsPC(oClicker)) return;
//--
string sDaytimeGuard = "MOB_DAYTIMEGUARD" + GetSubString(GetTag(OBJECT_SELF), 4, GetStringLength(GetTag(OBJECT_SELF)));
//--
string sNighttimeGuard = "MOB_NIGHTTIME" + GetSubString(GetTag(OBJECT_SELF), 4, GetStringLength(GetTag(OBJECT_SELF)));
//--
string sGatesGuard = "MOB_GATESGUARD" + GetSubString(GetTag(OBJECT_SELF), 4, GetStringLength(GetTag(OBJECT_SELF)));
//--
if (GetTag(oClicker) == sDaytimeGuard || GetTag(oClicker) == sNighttimeGuard || GetTag(oClicker) == sGatesGuard)
   {
     DelayCommand(1.0, DestroyObject(oClicker));
   }

}



На onfailtoopen
Neverwinter Script Source
/*
door_guardspaw_4
Spawner for guards.
*/


void main()
{
//--
object oClicker = GetClickingObject();
if (GetIsPC(oClicker)) return;
//--
string sDaytimeGuard = "MOB_DAYTIMEGUARD" + GetSubString(GetTag(OBJECT_SELF), 4, GetStringLength(GetTag(OBJECT_SELF)));
//--
string sNighttimeGuard = "MOB_NIGHTTIME" + GetSubString(GetTag(OBJECT_SELF), 4, GetStringLength(GetTag(OBJECT_SELF)));
//--
string sGatesGuard = "MOB_GATESGUARD" + GetSubString(GetTag(OBJECT_SELF), 4, GetStringLength(GetTag(OBJECT_SELF)));
//--
if (GetTag(oClicker) == sDaytimeGuard || GetTag(oClicker) == sNighttimeGuard || GetTag(oClicker) == sGatesGuard)
   {

     AssignCommand(oClicker, SpeakString("*Ñòó÷èò â äâåðü*"));
     DelayCommand(1.0, ActionOpenDoor(OBJECT_SELF));
     DelayCommand(1.5, DestroyObject(oClicker));

   }

}


В userdef нпса добавлете:
Neverwinter Script Source
//--стандартный ondef код--//
............................................
else if (nUser == 111//TIME TO GO HOME:)
    {

      if ( !GetIsInCombat() || GetCurrentAction() != ACTION_DIALOGOBJECT)
        {
          ClearAllActions();
          ActionMoveToObject(GetLocalObject(GetArea(OBJECT_SELF), "THE_DOOR"));
          ActionOpenDoor(GetLocalObject(GetArea(OBJECT_SELF), "THE_DOOR"));
        }
    }


ЗЫ мой первый нвн скрипт так что если это тупо не смейтесьsmile.gif
Чуть не забылsmile.gif Дверь должна иметь тэг DOOR_7 символов (индификатор спаунера)

Автор: Аваддон Nov 27 2004, 12:29

долго отсутствовал, с интернетом опять неприятности были....

QUOTE (baskan @ Nov 20 2004, 17:26)
Вопрос насчет скрипта смерти Аваддона, на 1странице
Вопрос: Что нужно дописать, чтобы PC не сразу попадал в фугу, а перед этим всплывало окошко, и что дописать, что экспа снималась? А так ваще скрипт супер!

Вот, Лито меня выручил. И так все объяснилsmile.gif

QUOTE ([MoF)
Darth_Nick, Nov 24 2004, 04:57]
Вопрос 1: как можно изменить хелсы ПС на те которые я хочу сам, через скрипты?

Хэлсы всмысле возможность максимальных хэлсов или вообще просто там сделать что у перса стало 2- хэлсов?
Тогда это надо сделать так:

int iMax = Берешь Максимальные Хит-Поинты перса;
int iValue = 20 ;//сколько хочешь хит-поинтов сделать персу
int iDiff=iMax-iSet; //разница между максимальными хит-поинтами и теми которые ты хочешь установить
int iSet = iMax-iDiff;

А затем просто выполняешь команду Магическое Повреждение (iSet) на PC
В это случае у игрока станет 20 хит поинтов.

QUOTE ([MoF)
Darth_Nick, Nov 24 2004, 04:57]
Я смерть плеера в БД записываю
Чуть изменил скрипты Аваддона...
Аваддон ты мог отредактировать скрипт и записывать еще лвлы туды


Няя...а зачем? Я этот скрипт делал как Регистрационный. А ты вероятно хочешь статистику сервера сделать? Тогда погоди немного... Я тут пишу одну системку, чтобы игроку надо было своего персонажа регистрировать через Web интерфейсsmile.gif Во первых это поможет отследить чтобы игроки не создавали себе кучу игроков, а во вторых, незарегистрированных лично на сайте шарда - пускать на сервер не будет.

Автор: Аваддон Nov 29 2004, 09:35

На ваульте полно Сервер-статус-чекеров, но они берут инфу когда снифят трафик от сервака к серверу Bioware. В нашем НВН сервере есть такая галочка "Post game to Inernet", которую самому поставить нельзя, а если интернет у сервера не доступен (например, в локальной сети) то, это галочка убирается, траффик от сервера не передается, и следовательно все PHP скрипты для статуса, не работают.
Но у меня появилась идея сделать статус сервера с помощью APS/NWNX2 и базы данных MySQL. [MoF]Darth_Nick написал еще для нее PHP скрипт который будет брать данные из MySQL.

Статус позволяет видеть:

- Количество игроков на сервере
- Их имена (зачем MoF]Darth_Nick'у нужны аккаунты - понятия не имею, но я чуть модифицировал его скрипт - если вам нужны аккаунты см. в теме "Статус Сервера через PHP страницу"
Итак, для начала мои скрипты:
- Пол
- Раса и Подраса
- Уровень
- Классы и уровень каждого класса
- PC или DM

Теперь скрипты:

OnModuleLoad

Neverwinter Script Source
/*
////////////////////////////////
//////Created By: Avaddon//////
//////Date: 28. 11. 2004//////
/////////////////////////////
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\MYSQL SERVER STATUS\\\\\\\
\\\\\\Put this script:\\\\\\\\\
\\\\\\\"OnModuleLoad"\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
*/

#include "aps_include"
void main()
{
//СтандартаЯ команда в "aps_onload"
SQLInit();

//Команда MySQL "Создать таблицу REG_DATA"
string sSQL="CREATE TABLE `reg_data` ("+
"  `pc_dm` varchar(64) NOT NULL default '',"+
"  `login` varchar(64) NOT NULL default '',"+
"  `name` varchar(64) NOT NULL default '',"+
"  `gender` varchar(10) NOT NULL default '',"+
"  `race` varchar(64) NOT NULL default '',"+
"  `sub_race` varchar(100) NOT NULL default '',"+
"  `levels` varchar(3) NOT NULL default '',"+
"  `class_1` varchar(64) NOT NULL default '',"+
"  `class_2` varchar(64) NOT NULL default '',"+
"  `class_3` varchar(64) NOT NULL default '',"+
"  `deity` varchar(100) NOT NULL default '',"+
"  `cd_key` varchar(64) NOT NULL default '',"+
"  `ip` varchar(25) NOT NULL default '',"+
"  `line_status`  varchar(4) NOT NULL default '',"+
"  `creation_date` datetime NOT NULL default '0000-00-00 00:00:00',"+
") TYPE=MyISAM;";

/*Команда MySQL "Выставить line_status" на "off", везде где он = "on".
ИспользуетсЯ при загрузке модулЯ длЯ обновлениЯ статистики после краша
или выключениЯ сервера. */

string sOffline = "UPDATE `reg_data` SET line_status = 'off' WHERE line_status='on'";

  //ПроверЯем есть ли таблица REG_DATA
  SQLExecDirect("DESCRIBE reg_data");

  //Если таблицы нет - создаем ее
  if (SQLFetch()!= SQL_SUCCESS)
  {
    SQLExecDirect(sSQL);
  }
  //При загрузке модулЯ всем выставлЯем статус "Offline"
  SQLExecDirect(sOffline);
}



OnClientEnter

Neverwinter Script Source
/*
////////////////////////////////
//////Created By: Avaddon//////
//////Date: 28. 11. 2004//////
/////////////////////////////
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\MYSQL SERVER STATUS\\\\\\\
\\\\\\Put this script:\\\\\\\\\
\\\\\\\"OnClentEnter"\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
*/

#include "aps_include"
void main()
{
object oPC=GetEnteringObject();
string sName=SQLEncodeSpecialChars(GetName(oPC));//ИМЯ персонажа
string sLogin=SQLEncodeSpecialChars(GetPCPlayerName(oPC)); // Логин игрока
string sGender="Мужской"; if(GetGender(oPC)==GENDER_FEMALE)sGender="Женский";//Пол
string sKey=GetPCPublicCDKey(oPC); //CD-key игрока
string sIp=GetPCIPAddress(oPC); //Ip игрока
string sDeity=GetDeity(oPC); //Божество игрока
string sPC_DM = "PC"; if (GetIsDM(oPC)==TRUE)sPC_DM = "DM";////ДМ или Игрок
string sSubrace=GetStringLeft(GetSubRace(oPC), 99);//Подраса игрока
string sAllLevels = IntToString(GetHitDice(oPC));
//Расы заносимые при регистрации в БД////////////////////////
string sRace;                                              //
int iRace = GetRacialType(oPC);                            //
switch (iRace)                                            //
    {                                                      //
    case RACIAL_TYPE_DWARF:                                //
    sRace = "Дворф";                                      //
    break;                                                //
                                                          //
    case RACIAL_TYPE_ELF:                                  //
    sRace = "Эльф";                                        //
    break;                                                //
                                                          //
    case RACIAL_TYPE_GNOME:                                //
    sRace = "Гном";                                        //
    break;                                                //
                                                          //
    case RACIAL_TYPE_HALFELF:                              //
    sRace = "Полуэльф";                                    //
    break;                                                //
                                                          //
    case RACIAL_TYPE_HALFLING:                            //
    sRace = "Полурослик";                                  //
    break;                                                //
                                                          //
    case RACIAL_TYPE_HALFORC:                              //
    sRace = "Полуорк";                                    //
    break;                                                //
                                                          //
    case RACIAL_TYPE_HUMAN:                                //
    sRace = "Человек";                                    //
    break;                                                //
    }                                                      //
/////////////////////////////////////////////////////////////


//Классы игрока///////////////////////////////////////////
int iNum;                                  //
for (iNum=0; iNum<4; iNum++)
{
string sClass;                                          //
int iClass = GetClassByPosition(iNum,oPC);              //
switch (iClass)                                        //
    {                                                  //
    case CLASS_TYPE_ARCANE_ARCHER:                      //
    sClass = "Тайный Стрелок";                          //
    break;                                              //
                                                        //
    case CLASS_TYPE_ASSASSIN:                          //
    sClass = "Убийца";                                  //
    break;                                              //
                                                        //
    case CLASS_TYPE_BARBARIAN:                          //
    sClass = "Варвар";                                  //
    break;                                              //
                                                        //
    case CLASS_TYPE_BARD:                              //
    sClass = "Бард";                                    //
    break;                                              //
                                                        //
    case CLASS_TYPE_BLACKGUARD:                        //
    sClass = "Страж Тьмы";                              //
    break;                                              //
                                                        //
    case CLASS_TYPE_CLERIC:                            //
    sClass = "Клирик";                                  //
    break;                                              //
                                                        //
    case CLASS_TYPE_DIVINECHAMPION:                    //
    sClass = "Чемпион Торма";                          //
    break;                                              //
                                                        //
    case CLASS_TYPE_DRAGONDISCIPLE:                    //
    sClass = "Ученик Дракона";                          //
    break;                                              //
                                                        //
    case CLASS_TYPE_DRUID:                              //
    sClass = "Друид";                                  //
    break;                                              //
                                                        //
    case CLASS_TYPE_DWARVENDEFENDER:                    //
    sClass = "Защитник Дворфов";                        //
    break;                                              //
                                                        //
    case CLASS_TYPE_FIGHTER:                            //
    sClass = "Воин";                                    //
    break;                                              //
                                                        //
    case CLASS_TYPE_HARPER:                            //
    sClass = "Разведчик Арфистов";                      //
    break;                                              //
                                                        //
    case CLASS_TYPE_INVALID:                            //
    sClass = " - ";                      //
    break;                                              //
                                                        //
    case CLASS_TYPE_MONK:                              //
    sClass = "Монах";                                  //
    break;                                              //
                                                        //
    case CLASS_TYPE_PALADIN:                            //
    sClass = "Паладин";                                //
    break;                                              //
                                                        //
    case CLASS_TYPE_PALEMASTER:                        //
    sClass = "Бледный Мастер";                          //
    break;                                              //
                                                        //
    case CLASS_TYPE_RANGER:                            //
    sClass = "Следопыт";                                //
    break;                                              //
                                                        //
    case CLASS_TYPE_ROGUE:                              //
    sClass = "Плут";                                    //
    break;                                              //
                                                        //
    case CLASS_TYPE_SHADOWDANCER:                      //
    sClass = "Танцор Тени";                            //
    break;                                              //
                                                        //
    case CLASS_TYPE_SHIFTER:                            //
    sClass = "Оборотень";                              //
    break;                                              //
                                                        //
    case CLASS_TYPE_SORCERER:                          //
    sClass = "Волшебник";                              //
    break;                                              //
                                                        //
    case CLASS_TYPE_WEAPON_MASTER:                      //
    sClass = "Мастер Оружий";                          //
    break;                                              //
                                                        //
    case CLASS_TYPE_WIZARD:                            //
    sClass = "Маг";                                    //
    break;                                              //
    }                                                  //
//////////////////////////////////////////////////////////

//Берем класс данной позиции и заносим его в локальную строку
SetLocalString(oPC,"Class"+IntToString(iNum),sClass);//
//Берем уровень данного класса и заносим его в локальную строку
SetLocalString(oPC,"Level"+IntToString(iNum),IntToString(GetLevelByPosition(iNum,oPC)));//;
}
//Читаем уровни 1,2, и 3  класса
string sLevel1 = GetLocalString(oPC,"Level1");
string sLevel2 = GetLocalString(oPC,"Level2");
string sLevel3 = GetLocalString(oPC,"Level3");

//Читаем 1,2, и 3  класс
string sClass_1 = GetLocalString(oPC,"Class1")+" ("+sLevel1+")";
string sClass_2 = GetLocalString(oPC,"Class2")+" ("+sLevel2+")";
string sClass_3 = GetLocalString(oPC,"Class3")+" ("+sLevel3+")";


//Выполним запрос SQL - выбираем строчку где логин и чар-нейм = логин и ИМЯ персонажа вошедшего игрока
string sSelect = "SELECT * FROM `reg_data` WHERE login='"+GetPCPlayerName(oPC)+
"' AND name='" +GetName(oPC)+ "' AND pc_dm='"+sPC_DM+"'";

//Команда MySQL "Выставить вощдшему игроку статус OnLine"
string sLine_Status = "UPDATE `reg_data` SET line_status = 'on' WHERE login='"+GetPCPlayerName(oPC)+
"' AND name='" +GetName(oPC)+ "' AND pc_dm='"+sPC_DM+"'";

//Регистрируем игрока статус - регистред, логин, чар-нейм, пол, раса, классы (1,2,3), подраса, сд-кей, ip, и дата регистрации
string sReg="INSERT INTO reg_data (pc_dm, login, name, gender,"+
      "race, sub_race,levels, class_1,class_2,class_3, deity,cd_key,ip,line_status,creation_date) "+
      "VALUES('"+sPC_DM+
      "','"+sLogin+
      "','"+sName+
      "','"+sGender+
      "','"+sRace+
      "','"+sSubrace+
      "','"+sAllLevels+
      "','"+sClass_1+
      "','"+sClass_2+
      "','"+sClass_3+
      "','"+sDeity+
      "','"+sKey+
      "','"+sIp+
      "','on',NOW())";

//Проверка на статус игрока (зарегистрирован или нет)
SQLExecDirect(sSelect);
if (SQLFirstRow() == SQL_SUCCESS)
    {
    SendMessageToPC(oPC,"Статус изменен на [On Line]");
    //Если да - просто изменЯем статус на OnLine
    SQLExecDirect(sLine_Status);
    }
    else
    {
    //Если нет - регистрируем, и выставлЯем статус OnLine
        SQLExecDirect(sReg);
        SendMessageToPC(oPC,"Приветствуем Вас! Вас персонаж был автоматически зарегистрирован!");
        SendMessageToPC(oPC,"Статус изменен на [On Line]");
    }

//Задаем локальные строки игроку с его логином и именем
SetLocalString(oPC,"Login",GetPCPlayerName(oPC));
SetLocalString(oPC,"Name",GetName(oPC));
}



OnClientLeave

Neverwinter Script Source
/*
////////////////////////////////
//////Created By: Avaddon//////
//////Date: 28. 11. 2004//////
/////////////////////////////
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\MYSQL SERVER STATUS\\\\\\\
\\\\\\Put this script:\\\\\\\\\
\\\\\\\"OnClentLeave"\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
*/

#include "aps_include"
void main()
{
object oPC=GetExitingObject();

// Считываем имЯ игрока с его локальной строчки заданной при входе на сервер
string sName=SQLEncodeSpecialChars(GetLocalString(oPC,"Name"));

// Считываем логин игрока с его локальной строчки заданной при входе на сервер
string sLogin=SQLEncodeSpecialChars(GetLocalString(oPC,"Login"));
string sPC_DM = "PC"; if (GetIsDM(oPC)==TRUE)sPC_DM = "DM";////ДМ или Игрок
//
//Выполним запрос SQL - выбираем строчку где логин и чар-нейм = логин и ИМЯ персонажа ушедшего игрока
string sSelect = "SELECT * FROM `reg_data` WHERE login='"+sLogin+
"' AND name='" +sName+ "' AND pc_dm='"+sPC_DM+"'";

//Команда MySQL "Изменить "line_status" на "off", где логин и имЯ = логину и имени ушедшего игрока.
string sLine_Status = "UPDATE `reg_data` SET line_status = 'off' WHERE login='"+sLogin+
"' AND name='" +sName+ "' AND pc_dm='"+sPC_DM+"'";

SQLExecDirect(sSelect);
if (SQLFirstRow() == SQL_SUCCESS)
    {
    SendMessageToPC(oPC,"Статус изменен на [Off Line]");
    SQLExecDirect(sLine_Status);
    }
}


Автор: Аваддон Nov 29 2004, 10:11

продолжение

OnPlayerLevelUp

Neverwinter Script Source
/*
////////////////////////////////
//////Created By: Avaddon//////
//////Date: 28. 11. 2004//////
/////////////////////////////
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\MYSQL SERVER STATUS\\\\\\\
\\\\\\Put this script:\\\\\\\\\
\\\\\\\"OnPlayerLevelUp"\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
*/


#include "aps_include"
void main()
{
object oPC = GetPCLevellingUp();
string sAllLevels = IntToString(GetHitDice(oPC));
//Классы игрока///////////////////////////////////////////
int iNum;                                   //
for (iNum=0; iNum<4; iNum++)
{
string sClass;                                          //
int iClass = GetClassByPosition(iNum,oPC);              //
switch (iClass)                                         //
    {                                                   //
    case CLASS_TYPE_ARCANE_ARCHER:                      //
    sClass = "Тайный Стрелок";                          //
    break;                                              //
                                                        //
    case CLASS_TYPE_ASSASSIN:                           //
    sClass = "Убийца";                                  //
    break;                                              //
                                                        //
    case CLASS_TYPE_BARBARIAN:                          //
    sClass = "Варвар";                                  //
    break;                                              //
                                                        //
    case CLASS_TYPE_BARD:                               //
    sClass = "Бард";                                    //
    break;                                              //
                                                        //
    case CLASS_TYPE_BLACKGUARD:                         //
    sClass = "Страж Тьмы";                              //
    break;                                              //
                                                        //
    case CLASS_TYPE_CLERIC:                             //
    sClass = "Клирик";                                  //
    break;                                              //
                                                        //
    case CLASS_TYPE_DIVINECHAMPION:                     //
    sClass = "Чемпион Торма";                           //
    break;                                              //
                                                        //
    case CLASS_TYPE_DRAGONDISCIPLE:                     //
    sClass = "Ученик Дракона";                          //
    break;                                              //
                                                        //
    case CLASS_TYPE_DRUID:                              //
    sClass = "Друид";                                   //
    break;                                              //
                                                        //
    case CLASS_TYPE_DWARVENDEFENDER:                    //
    sClass = "Защитник Дворфов";                        //
    break;                                              //
                                                        //
    case CLASS_TYPE_FIGHTER:                            //
    sClass = "Воин";                                    //
    break;                                              //
                                                        //
    case CLASS_TYPE_HARPER:                             //
    sClass = "Разведчик Арфистов";                      //
    break;                                              //
                                                        //
    case CLASS_TYPE_INVALID:                            //
    sClass = " - ";                                     //
    break;                                              //
                                                        //
    case CLASS_TYPE_MONK:                               //
    sClass = "Монах";                                   //
    break;                                              //
                                                        //
    case CLASS_TYPE_PALADIN:                            //
    sClass = "Паладин";                                 //
    break;                                              //
                                                        //
    case CLASS_TYPE_PALEMASTER:                         //
    sClass = "Бледный Мастер";                          //
    break;                                              //
                                                        //
    case CLASS_TYPE_RANGER:                             //
    sClass = "Следопыт";                                //
    break;                                              //
                                                        //
    case CLASS_TYPE_ROGUE:                              //
    sClass = "Плут";                                    //
    break;                                              //
                                                        //
    case CLASS_TYPE_SHADOWDANCER:                       //
    sClass = "Танцор Тени";                             //
    break;                                              //
                                                        //
    case CLASS_TYPE_SHIFTER:                            //
    sClass = "Оборотень";                               //
    break;                                              //
                                                        //
    case CLASS_TYPE_SORCERER:                           //
    sClass = "Волшебник";                               //
    break;                                              //
                                                        //
    case CLASS_TYPE_WEAPON_MASTER:                      //
    sClass = "Мастер Оружий";                           //
    break;                                              //
                                                        //
    case CLASS_TYPE_WIZARD:                             //
    sClass = "Маг";                                     //
    break;                                              //
    }                                                   //
    SetLocalString(oPC,"Class"+IntToString(iNum),sClass);
    SetLocalString(oPC,"Level"+IntToString(iNum),IntToString(GetLevelByPosition(iNum,oPC)));//;
//////////////////////////////////////////////////////////
}
string sName=SQLEncodeSpecialChars(GetName(oPC));
string sLogin=SQLEncodeSpecialChars(GetPCPlayerName(oPC));
//Читаем уровни 1,2, и 3  класса
string sLevel1 = GetLocalString(oPC,"Level1");
string sLevel2 = GetLocalString(oPC,"Level2");
string sLevel3 = GetLocalString(oPC,"Level3");

//Читаем 1,2, и 3  класс
string sClass_1 = GetLocalString(oPC,"Class1")+" ("+sLevel1+")";
string sClass_2 = GetLocalString(oPC,"Class2")+" ("+sLevel2+")";
string sClass_3 = GetLocalString(oPC,"Class3")+" ("+sLevel3+")";

//Команда MySQL "Обновить уровни игрока"
string sLevel = "UPDATE `reg_data` SET levels = '"+sAllLevels+
"', class_1 = '"+sClass_1+
"', class_2 = '"+sClass_2+
"', class_3 = '"+sClass_3+
"' WHERE login = '"+sLogin+"' AND name = '"+sName+"'";

SQLExecDirect(sLevel);
}


PHP-скрипт by [MoF]Darth_Nick
Я его немного модифицировал под классы, а так же чтобы сервер говорил об отсутствии игроков на сервере

УДАЛЕНО. Айваном.

Автор: Аваддон Dec 4 2004, 23:45

В одном из моих постов, в Базе Скриптов я опубликовал скрипт на отдых в дикой местности.
Теперь, я бы хотел уделить внимаение отдыху в гостинице.
И так, что нам надо для того чтобы организовать отдых в гостиничной комнате?

1. Нам нужен http://cgi.nwvault.ign.com/dtracker.cgi?file=HAKPACKS_1041513631913&url=http://vnfiles.ign.com/nwn/hakpacks/Adam_Miller1041513631913bed%2Ezip, который заменяет в тайлах простые кровати, на такие же по виду кровати, но на которые игрок может забраться.

2. Нам надо сделать гостиничную комнату. Тэг локации должен начинаться с "free". Например, free_inn_rooms.
Я делал одну локацию в которой много гостиничных комнат, никаким образом не соединенных между собой. В каждой комнате перед кроватью стоит ВэйПоинт с тэгом "BED" и на кровати стоит ВэйПоинт с тэгом "SLEEP".

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

На события модуля OnPlayerRest ставим нижеследующий скрипт.

Neverwinter Script Source
/*
////////////////////////////////
//////Created By: Avaddon//////
//////Date: 04. 12. 2004//////
/////////////////////////////
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\INN ROOM FREE REST\\\\\\\
\\\\\\Put this script:\\\\\\\\\
\\\\\\\"OnPlayerRest"\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
*/

void main()
{
//Эффекты сна
effect eBlack = EffectVisualEffect(VFX_DUR_BLACKOUT);
effect eZzz =  EffectVisualEffect(VFX_IMP_SLEEP);
effect eSlow = EffectSlow();

object oPC = GetLastPCRested();

//Вейпоинт с тэгом "BED" должен находитсЯ перед кроватью на полу
object oBed = GetNearestObjectByTag("BED",oPC);

/*Вейпоинт с тегом "SLEEP" должен находитсЯ на самой кровати
(Я надеюсь вы скачали хак с фиксом кровати на nwvault.ign.com)*/

object oSleep = GetNearestObjectByTag("SLEEP",oPC);

//Берем предметы в слотах
object oArmor =GetItemInSlot(INVENTORY_SLOT_CHEST,oPC);
object oRightHand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
object oLeftHand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
object oBoots = GetItemInSlot(INVENTORY_SLOT_BOOTS,oPC);
object oHelmet = GetItemInSlot(INVENTORY_SLOT_HEAD,oPC);
object oBelt = GetItemInSlot(INVENTORY_SLOT_BELT,oPC);
object oCloak = GetItemInSlot(INVENTORY_SLOT_CLOAK,oPC);
object oArms = GetItemInSlot(INVENTORY_SLOT_ARMS,oPC);

//В качестве тэгов предметов читаем переменные с игрока
string sFree = GetTag(GetArea(oPC));
string sArmor = GetLocalString(oPC,"armor");
string sRightHand = GetLocalString(oPC,"right");
string sLeftHand = GetLocalString(oPC,"left");
string sHelmet = GetLocalString(oPC,"helmet");
string sBoots = GetLocalString(oPC,"boots");
string sBelt = GetLocalString(oPC,"belt");
string sCloak = GetLocalString(oPC,"cloak");
string sArms = GetLocalString(oPC,"arms");

    /*Проверка арены в которой находитсЯ игрок решивший отдохнуть.
    Если тег арены начинаетсЯ с "free" (например "free_inn_rooms"),
    то наш скрипт начинает работу*/

    if(GetStringLeft(sFree,4)=="free")
    {
    //Если игрок еще не на кровати то...
        if(GetLocalInt(GetLastPCRested(),"on_bed")!=1)
        {
        //Записываем на игрока переменные с тегами одетых на него вещей
        SetLocalString(oPC,"armor",GetTag(oArmor));
        SetLocalString(oPC,"right",GetTag(oRightHand));
        SetLocalString(oPC,"left",GetTag(oLeftHand));
        SetLocalString(oPC,"helmet",GetTag(oHelmet));
        SetLocalString(oPC,"boots",GetTag(oBoots));
        SetLocalString(oPC,"belt",GetTag(oBelt));
        SetLocalString(oPC,"cloak",GetTag(oCloak));
        SetLocalString(oPC,"arms",GetTag(oArms));

        /*За 2 секунды он уже должен быть у кровати(расчитано на маленькую
        комнату с кроватью. Раздеваем игрока. Снимаем все кроме колец,
        боеприпасов, и амулета.*/

        DelayCommand(2.0,AssignCommand(oPC,ActionUnequipItem(oArmor)));
        DelayCommand(2.0,AssignCommand(oPC,ActionUnequipItem(oRightHand)));
        DelayCommand(2.0,AssignCommand(oPC,ActionUnequipItem(oLeftHand)));
        DelayCommand(2.0,AssignCommand(oPC,ActionUnequipItem(oHelmet)));
        DelayCommand(2.0,AssignCommand(oPC,ActionUnequipItem(oBoots)));
        DelayCommand(2.0,AssignCommand(oPC,ActionUnequipItem(oBelt)));
        DelayCommand(2.0,AssignCommand(oPC,ActionUnequipItem(oCloak)));
        DelayCommand(2.0,AssignCommand(oPC,ActionUnequipItem(oArms)));

            //При событии отдых начат (в гостинице соответственно)...
            if (GetLastRestEventType()==REST_EVENTTYPE_REST_STARTED)
            {
            //ОтменЯем отдых и выполнЯем следущие действиЯ
            AssignCommand(oPC,ClearAllActions());

            //Подходим к кровати(как он подойдет - тут же разденетсЯ)
            AssignCommand(oPC,ActionMoveToObject(oBed));

            //Когда разденетсЯ - забираемсЯ на кровать
            DelayCommand(2.0,AssignCommand(oPC,ActionJumpToObject(oSleep)));

            //ВыставлЯем переменную "Игрок уже на кровати"
            DelayCommand(2.5,SetLocalInt(oPC,"on_bed",1));

            //Начинаем отдых
            DelayCommand(3.0,AssignCommand(oPC,ActionRest()));

            //Накладываем эффекты сна
            DelayCommand(3.5,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eZzz,oPC,10.0));
            DelayCommand(4.0,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eBlack,oPC,60.0));
            }//Заканчиваем условие "Если Отдых Начат"
        }//Заканчиваем условие "Если игрок не на кровати"
    }//Заканчиваем условие "Если тег арены начинаетсЯ с 'free' "
    else
    {
    /*Здесь - действие которое происходит если тег арены в которой игрок
    находитсЯ не начинаетсЯ с "free".
    Тут "AssignCommand(oPC,ClearAllActions()" - отменЯет отдых. Вы же,
    можете вставить любой другой скрипт, или команды длЯ другого типа отдыха,
    например на природе.*/

    AssignCommand(oPC,ClearAllActions());
    }

  //////////////////////////////////////////////////////////////////////
  /*Если Отдых Окончен или Прерван в арене с тегом начинающимсЯ с "free"
  и игрок находитсЯ на кровати.*/
/////////////////////////////////////

    if(GetStringLeft(sFree,4)=="free" && GetLocalInt(oPC,"on_bed")==1)
    {
        //Если Отдых Завершен
        if (GetLastRestEventType()==REST_EVENTTYPE_REST_FINISHED)
        {
        //Одеваем игрока обратно (теги предметов бывших на нем одетыми читаем из локалок игрока)
        DelayCommand(2.0,AssignCommand(oPC, ActionEquipItem(GetItemPossessedBy(oPC,sArmor), INVENTORY_SLOT_CHEST)));
        DelayCommand(2.0,AssignCommand(oPC, ActionEquipItem(GetItemPossessedBy(oPC,sRightHand), INVENTORY_SLOT_RIGHTHAND)));
        DelayCommand(2.0,AssignCommand(oPC, ActionEquipItem(GetItemPossessedBy(oPC,sLeftHand), INVENTORY_SLOT_LEFTHAND)));
        DelayCommand(2.0,AssignCommand(oPC, ActionEquipItem(GetItemPossessedBy(oPC,sBoots), INVENTORY_SLOT_BOOTS)));
        DelayCommand(2.0,AssignCommand(oPC, ActionEquipItem(GetItemPossessedBy(oPC,sHelmet), INVENTORY_SLOT_HEAD)));
        DelayCommand(2.0,AssignCommand(oPC, ActionEquipItem(GetItemPossessedBy(oPC,sBelt), INVENTORY_SLOT_BELT)));
        DelayCommand(2.0,AssignCommand(oPC, ActionEquipItem(GetItemPossessedBy(oPC,sCloak), INVENTORY_SLOT_CLOAK)));
        DelayCommand(2.0,AssignCommand(oPC, ActionEquipItem(GetItemPossessedBy(oPC,sArms), INVENTORY_SLOT_ARMS)));

        //Встаем с кровати
        AssignCommand(oPC,ActionJumpToObject(oBed));

        //Стираем с игрока все локалки предметов и того что он был на кровати.
        DeleteLocalInt(oPC,"on_bed");
        DeleteLocalString(oPC,"armor");
        DeleteLocalString(oPC,"right");
        DeleteLocalString(oPC,"left");
        DeleteLocalString(oPC,"helmet");
        DeleteLocalString(oPC,"boots");
        DeleteLocalString(oPC,"belt");
        DeleteLocalString(oPC,"cloak");
        DeleteLocalString(oPC,"arms");

        //Убираем эффекты сна
        RemoveEffect(oPC,eBlack);
        }//Заканчиваем условие "Если Отдых Завершен

        /*Если Отдых Прерван То одевать игрока не будем (он проснулсЯ с перепугу,
        или разбудили там.. Не дали спокойно собратьсЯ вобщем.*/

        if (GetLastRestEventType()==REST_EVENTTYPE_REST_CANCELLED)
        {
        //Встаем с кровати
        AssignCommand(oPC,ActionJumpToObject(oBed));

        //Стираем с игрока все локалки предметов и того что он был на кровати.
        DeleteLocalInt(oPC,"on_bed");
        DeleteLocalString(oPC,"armor");
        DeleteLocalString(oPC,"right");
        DeleteLocalString(oPC,"left");
        DeleteLocalString(oPC,"helmet");
        DeleteLocalString(oPC,"boots");
        DeleteLocalString(oPC,"belt");
        DeleteLocalString(oPC,"cloak");
        DeleteLocalString(oPC,"arms");

        /*Эффекты сна не снимаем
        И накладываем Blackout и эффект замедлениЯ,
        чтобы игрок 30 секунд приходилв себЯ.*/


        ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSlow,oPC,30.0);
        //Периодически игрок полусонный подхрапывает
        ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eZzz,oPC,10.0);
        DelayCommand(10.0,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eZzz,oPC,10.0));
        DelayCommand(20.0,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eZzz,oPC,10.0));
        }
    }
}

Автор: Twin Dec 7 2004, 11:38


Пара функций для сохранения и восстановления всех свойств предмета. Дают возможность конвертировать все перманентные (и только перманентные) свойства предмета в строку, которую можно сохранить куда хотите. И также восстановить все свойства (кроме On Monster Hit) из этой строки на предмет. Также сохраняются заряды палочек.
Не сохраняется:
Кастомный вид брони и оружия.
Additional Price отличная от ResRef'овской.
Свойство On Monster Hit (его можно ставить только на Creature Weapon) сохраняется нормально, но при восстановлении работает некорректно. Вернее два из подствойств (SubType) этого свойства не получается восстановить. Карочи, а оно вам ваще нужно? ;)
Количество использований свойства X uses/day. То есть при восстановлении данного свойства из строки возможно, что количество использований обновится как будто после отдыха - не проверял.
Наверняка что-то еще не сохраняется, но мне в голову ничего не приходит.

Neverwinter Script Source
/*
** Конвертациz свойств предмета в строку.
*/

string GetProperties(object oItem)
{
    string sProperties = IntToString(GetItemCharges(oItem));
    int nTemp;
    itemproperty ipTemp = GetFirstItemProperty(oItem);

    while (GetIsItemPropertyValid(ipTemp))
    {
        if (GetItemPropertyDurationType(ipTemp) == 2)
        {
            sProperties += "@"+
                IntToString(GetItemPropertyType(ipTemp)) +":";

            nTemp = GetItemPropertyParam1Value(ipTemp);
            if (nTemp == 255 || nTemp == -1)
                sProperties += "-1:";
            else
                sProperties += IntToString(nTemp - 1) +":";

            sProperties +=
                IntToString(GetItemPropertyCostTable(ipTemp)) +":";

            nTemp = GetItemPropertyCostTableValue(ipTemp);
            if (nTemp == -1)
                sProperties += "-1:";
            else
                sProperties += IntToString(nTemp - 1) +":";

            nTemp = GetItemPropertySubType(ipTemp);
            if (nTemp == -1) sProperties += "0";
            else            sProperties += IntToString(nTemp);
        }

        ipTemp = GetNextItemProperty(oItem);
    }

    return sProperties;
}

/*
** Установка свойств предмета из строки.
*/

void SetProperties(object oItem, string sProperties)
{
    //SendMessageToPC(GetFirstPC(), "SetProperties :: sProperties == "+ sProperties);

    itemproperty ipTemp = GetFirstItemProperty(oItem);
    while (GetIsItemPropertyValid(ipTemp))
    {
        RemoveItemProperty(oItem, ipTemp);
        ipTemp = GetNextItemProperty(oItem);
    }

    int i = 1;
    int pos, nCharges;
    string sTemp;

    nCharges = StringToInt(GetStringLeft(sProperties, FindSubString(sProperties, "@")));
    if (nCharges > 0)
        SetItemCharges(oItem, nCharges);

    while ((pos = FindSubString(sProperties, "@")) != -1)
    {
        sProperties = GetStringRight(sProperties, GetStringLength(sProperties) - pos - 1);

        pos = FindSubString(sProperties, "@");
        if (pos == -1)
            pos = GetStringLength(sProperties);

        sTemp = GetStringLeft(sProperties, pos);

        //SendMessageToPC(GetFirstPC(), "sTemp["+ IntToString(i) +"] == "+ sTemp);
        SetProperty(oItem, sTemp);

        i++;
    }
}

void SetProperty(object oItem, string sProperty)
{
    int pos = FindSubString(sProperty, ":");
    int nType = StringToInt(GetSubString(sProperty, 0, pos));

    sProperty = GetSubString(sProperty, pos + 1, GetStringLength(sProperty));
    pos = FindSubString(sProperty, ":");
    int nParam1Value = StringToInt(GetSubString(sProperty, 0, pos));
    nParam1Value++;

    sProperty = GetSubString(sProperty, pos + 1, GetStringLength(sProperty));
    pos = FindSubString(sProperty, ":");
    int nCostTable = StringToInt(GetSubString(sProperty, 0, pos));

    sProperty = GetSubString(sProperty, pos + 1, GetStringLength(sProperty));
    pos = FindSubString(sProperty, ":");
    int nCostTableValue = StringToInt(GetSubString(sProperty, 0, pos));
    nCostTableValue++;

    sProperty = GetSubString(sProperty, pos + 1, GetStringLength(sProperty));
    int nSubType = StringToInt(sProperty);

    itemproperty ipTemp;

    switch (nType)
    {
/*OK*/  case ITEM_PROPERTY_ABILITY_BONUS:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ABILITY_BONUS _OK_");
            ipTemp = ItemPropertyAbilityBonus(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_AC_BONUS:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_AC_BONUS _OK_");
            ipTemp = ItemPropertyACBonus(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_AC_BONUS_VS_ALIGNMENT_GROUP:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_AC_BONUS_VS_ALIGNMENT_GROUP _OK_");
            ipTemp = ItemPropertyACBonusVsAlign(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_AC_BONUS_VS_DAMAGE_TYPE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_AC_BONUS_VS_DAMAGE_TYPE _OK_");
            ipTemp = ItemPropertyACBonusVsDmgType(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_AC_BONUS_VS_RACIAL_GROUP:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_AC_BONUS_VS_RACIAL_GROUP _OK_");
            ipTemp = ItemPropertyACBonusVsRace(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_AC_BONUS_VS_SPECIFIC_ALIGNMENT:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_AC_BONUS_VS_SPECIFIC_ALIGNMENT _OK_");
            ipTemp = ItemPropertyACBonusVsSAlign(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_ARCANE_SPELL_FAILURE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ARCANE_SPELL_FAILURE _OK_");
            ipTemp = ItemPropertyArcaneSpellFailure(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_ATTACK_BONUS:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ATTACK_BONUS _OK_");
            ipTemp = ItemPropertyAttackBonus(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_ATTACK_BONUS_VS_ALIGNMENT_GROUP:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ATTACK_BONUS_VS_ALIGNMENT_GROUP _OK_");
            ipTemp = ItemPropertyAttackBonusVsAlign(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_ATTACK_BONUS_VS_RACIAL_GROUP:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ATTACK_BONUS_VS_RACIAL_GROUP _OK_");
            ipTemp = ItemPropertyAttackBonusVsRace(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_ATTACK_BONUS_VS_SPECIFIC_ALIGNMENT:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ATTACK_BONUS_VS_SPECIFIC_ALIGNMENT _OK_");
            ipTemp = ItemPropertyAttackBonusVsSAlign(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_BASE_ITEM_WEIGHT_REDUCTION:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_BASE_ITEM_WEIGHT_REDUCTION _OK_");
            ipTemp = ItemPropertyWeightReduction(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_BONUS_FEAT:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_BONUS_FEAT _OK_");
            ipTemp = ItemPropertyBonusFeat(nSubType);
            break;
/*OK*/  case ITEM_PROPERTY_BONUS_SPELL_SLOT_OF_LEVEL_N:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_BONUS_SPELL_SLOT_OF_LEVEL_N _OK_");
            ipTemp = ItemPropertyBonusLevelSpell(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_CAST_SPELL:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_CAST_SPELL _OK_");
            ipTemp = ItemPropertyCastSpell(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DAMAGE_BONUS:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DAMAGE_BONUS _OK_");
            ipTemp = ItemPropertyDamageBonus(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP _OK_");
            ipTemp = ItemPropertyDamageBonusVsAlign(nSubType, nParam1Value, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP _OK_");
            ipTemp = ItemPropertyDamageBonusVsRace(nSubType, nParam1Value, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DAMAGE_BONUS_VS_SPECIFIC_ALIGNMENT:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DAMAGE_BONUS_VS_SPECIFIC_ALIGNMENT _OK_");
            ipTemp = ItemPropertyDamageBonusVsSAlign(nSubType, nParam1Value, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DAMAGE_REDUCTION:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DAMAGE_REDUCTION _OK_");
            ipTemp = ItemPropertyDamageReduction(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DAMAGE_RESISTANCE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DAMAGE_RESISTANCE _OK_");
            ipTemp = ItemPropertyDamageResistance(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DAMAGE_VULNERABILITY:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DAMAGE_VULNERABILITY _OK_");
            ipTemp = ItemPropertyDamageVulnerability(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DARKVISION:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DARKVISION _OK_");
            ipTemp = ItemPropertyDarkvision();
            break;
/*OK*/  case ITEM_PROPERTY_DECREASED_ABILITY_SCORE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DECREASED_ABILITY_SCORE _OK_");
            ipTemp = ItemPropertyDecreaseAbility(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DECREASED_AC:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DECREASED_AC _OK_");
            ipTemp = ItemPropertyDecreaseAC(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER _OK_");
            ipTemp = ItemPropertyAttackPenalty(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DECREASED_DAMAGE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DECREASED_DAMAGE _OK_");
            ipTemp = ItemPropertyDamagePenalty(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DECREASED_ENHANCEMENT_MODIFIER:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DECREASED_ENHANCEMENT_MODIFIER _OK_");
            ipTemp = ItemPropertyEnhancementPenalty(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DECREASED_SAVING_THROWS:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DECREASED_SAVING_THROWS _OK_");
            ipTemp = ItemPropertyReducedSavingThrowVsX(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DECREASED_SAVING_THROWS_SPECIFIC:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DECREASED_SAVING_THROWS_SPECIFIC _OK_");
            ipTemp = ItemPropertyReducedSavingThrow(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_DECREASED_SKILL_MODIFIER:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_DECREASED_SKILL_MODIFIER _OK_");
            ipTemp = ItemPropertyDecreaseSkill(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_ENHANCED_CONTAINER_REDUCED_WEIGHT:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ENHANCED_CONTAINER_REDUCED_WEIGHT _OK_");
            ipTemp = ItemPropertyContainerReducedWeight(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_ENHANCEMENT_BONUS:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ENHANCEMENT_BONUS _OK_");
            ipTemp = ItemPropertyEnhancementBonus(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_ALIGNMENT_GROUP:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_ALIGNMENT_GROUP _OK_");
            ipTemp = ItemPropertyEnhancementBonusVsAlign(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_RACIAL_GROUP:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_RACIAL_GROUP _OK_");
            ipTemp = ItemPropertyEnhancementBonusVsRace(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_SPECIFIC_ALIGNEMENT:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_SPECIFIC_ALIGNEMENT ?_OK_");
            ipTemp = ItemPropertyEnhancementBonusVsSAlign(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_EXTRA_MELEE_DAMAGE_TYPE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_EXTRA_MELEE_DAMAGE_TYPE _OK_");
            ipTemp = ItemPropertyExtraMeleeDamageType(nSubType);
            break;
/*OK*/  case ITEM_PROPERTY_EXTRA_RANGED_DAMAGE_TYPE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_EXTRA_RANGED_DAMAGE_TYPE _OK_");
            ipTemp = ItemPropertyExtraRangeDamageType(nSubType);
            break;
/*OK*/  case ITEM_PROPERTY_FREEDOM_OF_MOVEMENT:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_FREEDOM_OF_MOVEMENT _OK_");
            ipTemp = ItemPropertyFreeAction();
            break;
/*OK*/  case ITEM_PROPERTY_HASTE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_HASTE _OK_");
            ipTemp = ItemPropertyHaste();
            break;
/*OK*/  case ITEM_PROPERTY_HEALERS_KIT:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_HEALERS_KIT _OK_");
            ipTemp = ItemPropertyHealersKit(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_HOLY_AVENGER:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_HOLY_AVENGER _OK_");
            ipTemp = ItemPropertyHolyAvenger();
            break;
/*OK*/  case ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE _OK_");
            ipTemp = ItemPropertyDamageImmunity(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_IMMUNITY_MISCELLANEOUS:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_IMMUNITY_MISCELLANEOUS _OK_");
            ipTemp = ItemPropertyImmunityMisc(nSubType);
            break;
/*OK*/  case ITEM_PROPERTY_IMMUNITY_SPECIFIC_SPELL:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_IMMUNITY_SPECIFIC_SPELL _OK_");
            ipTemp = ItemPropertySpellImmunitySpecific(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_IMMUNITY_SPELL_SCHOOL:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_IMMUNITY_SPELL_SCHOOL _OK_");
            ipTemp = ItemPropertySpellImmunitySchool(nSubType);
            break;
/*OK*/  case ITEM_PROPERTY_IMMUNITY_SPELLS_BY_LEVEL:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_IMMUNITY_SPELLS_BY_LEVEL _OK_");
            ipTemp = ItemPropertyImmunityToSpellLevel(nCostTableValue+1);
            break;
/*OK*/  case ITEM_PROPERTY_IMPROVED_EVASION:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_IMPROVED_EVASION _OK_");
            ipTemp = ItemPropertyImprovedEvasion();
            break;
/*OK*/  case ITEM_PROPERTY_KEEN:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_KEEN _OK_");
            ipTemp = ItemPropertyKeen();
            break;
/*OK*/  case ITEM_PROPERTY_LIGHT:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_LIGHT _OK_");
            ipTemp = ItemPropertyLight(nCostTableValue, nParam1Value);
            break;
/*OK*/  case ITEM_PROPERTY_MASSIVE_CRITICALS:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_MASSIVE_CRITICALS _OK_");
            ipTemp = ItemPropertyMassiveCritical(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_MIGHTY:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_MIGHTY _OK_");
            ipTemp = ItemPropertyMaxRangeStrengthMod(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_MIND_BLANK:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_MIND_BLANK");
            break;
/*OK*/  case ITEM_PROPERTY_MONSTER_DAMAGE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_MONSTER_DAMAGE ?OK?");
            ipTemp = ItemPropertyMonsterDamage(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_NO_DAMAGE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_NO_DAMAGE _OK_");
            ipTemp = ItemPropertyNoDamage();
            break;
/*OK*/  case ITEM_PROPERTY_ON_HIT_PROPERTIES:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ON_HIT_PROPERTIES _OK_");
            ipTemp = ItemPropertyOnHitProps(nSubType, nCostTableValue, nParam1Value);
            break;
/*FAIL*/case ITEM_PROPERTY_ON_MONSTER_HIT:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ON_MONSTER_HIT _PARTIAL_ "+ IntToString(nSubType) +"!"+ IntToString(nParam1Value));
            ipTemp = ItemPropertyOnMonsterHitProperties(nSubType, nParam1Value);
            break;
/*OK*/  case ITEM_PROPERTY_ONHITCASTSPELL:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_ONHITCASTSPELL _OK_");
            ipTemp = ItemPropertyOnHitCastSpell(nSubType, nCostTableValue+1);
            break;
/*OK*/  case ITEM_PROPERTY_POISON:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_POISON");
            break;
/*OK*/  case ITEM_PROPERTY_REGENERATION:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_REGENERATION _OK_");
            ipTemp = ItemPropertyRegeneration(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_REGENERATION_VAMPIRIC:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_REGENERATION_VAMPIRIC _OK_");
            ipTemp = ItemPropertyVampiricRegeneration(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_SAVING_THROW_BONUS:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_SAVING_THROW_BONUS _OK_");
            ipTemp = ItemPropertyBonusSavingThrowVsX(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC _OK_");
            ipTemp = ItemPropertyBonusSavingThrow(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_SKILL_BONUS:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_SKILL_BONUS _OK_");
            ipTemp = ItemPropertySkillBonus(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_SPECIAL_WALK:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_SPECIAL_WALK ?OK?");
            ipTemp = ItemPropertySpecialWalk(nSubType);
            break;
/*OK*/  case ITEM_PROPERTY_SPELL_RESISTANCE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_SPELL_RESISTANCE _OK_");
            ipTemp = ItemPropertyBonusSpellResistance(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_THIEVES_TOOLS:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_THIEVES_TOOLS _OK_");
            ipTemp = ItemPropertyThievesTools(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_TRAP:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_TRAP _OK_");
            ipTemp = ItemPropertyTrap(nSubType, nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_TRUE_SEEING:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_TRUE_SEEING _OK_");
            ipTemp = ItemPropertyTrueSeeing();
            break;
/*OK*/  case ITEM_PROPERTY_TURN_RESISTANCE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_TURN_RESISTANCE _OK_");
            ipTemp = ItemPropertyTurnResistance(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_UNLIMITED_AMMUNITION:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_UNLIMITED_AMMUNITION _OK_");
            ipTemp = ItemPropertyUnlimitedAmmo(nCostTableValue);
            break;
/*OK*/  case ITEM_PROPERTY_USE_LIMITATION_ALIGNMENT_GROUP:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_USE_LIMITATION_ALIGNMENT_GROUP _OK_");
            ipTemp = ItemPropertyLimitUseByAlign(nSubType);
            break;
/*OK*/  case ITEM_PROPERTY_USE_LIMITATION_CLASS:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_USE_LIMITATION_CLASS _OK_");
            ipTemp = ItemPropertyLimitUseByClass(nSubType);
            break;
/*OK*/  case ITEM_PROPERTY_USE_LIMITATION_RACIAL_TYPE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_USE_LIMITATION_RACIAL_TYPE _OK_");
            ipTemp = ItemPropertyLimitUseByRace(nSubType);
            break;
/*OK*/  case ITEM_PROPERTY_USE_LIMITATION_SPECIFIC_ALIGNMENT:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_USE_LIMITATION_SPECIFIC_ALIGNMENT _OK_");
            ipTemp = ItemPropertyLimitUseBySAlign(nSubType);
            break;
/*OK*/  case ITEM_PROPERTY_USE_LIMITATION_TILESET:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_USE_LIMITATION_TILESET");
            break;
/*OK*/  case ITEM_PROPERTY_VISUALEFFECT:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_VISUALEFFECT _OK_");
            ipTemp = ItemPropertyVisualEffect(nSubType);
            break;
/*OK*/  case ITEM_PROPERTY_WEIGHT_INCREASE:
            //SendMessageToPC(GetFirstPC(), "const ITEM_PROPERTY_WEIGHT_INCREASE _OK_");
            ipTemp = ItemPropertyWeightIncrease(nParam1Value);
            break;
        default:
            //SendMessageToPC(GetFirstPC(), "const default");
            break;
    }

    if (GetIsItemPropertyValid(ipTemp)) {
        AddItemProperty(DURATION_TYPE_PERMANENT, ipTemp, oItem);
    }
}

Данный скрипт можно исползовать для создания банка вещей. Так как проблема сохранения вещей с динамическими теперь отпадает.

Автор: Tarre Talliorne Jan 5 2005, 13:19

http://rage-t.boom.ru/creative.html
На эой страничке нашего сайта висят пару библиотек. ИМХО довольно полезных.

Автор: Лито Jan 27 2005, 21:00

Многие начинающие не могут нормально соединить несколько отдельных скриптов в один целый, например часто надо вписывать в скрипт OnClientEnter дополнительные...хм...вещи. Специально для них я сделал систему захода игрока на сервер. она соединяет два скрипта _kaa_ и baal в одно целое, кроме того в системе реализованна выдача начального пакета по класу. Все что надо изменить это вбить РесРефы вещей которые вы хотите дать игроку.
Проверка на первый заход производится с помощью проверки на наличие определенного предмета в инвенторе, то есть если этот предмет есть то скрипт останавливается на точке выдачи стартового пакета, если же этого предмета нет, то скрипт выдает игроку этот предметsmile.gif и стартовый пакет. В моем случае этот предмет oBook, создаете предмет, копируете его ресреф и заменяете
object oBook=GetItemPossessedBy(oPC, "item004"); на свой

Вот сама система:

Neverwinter Script Source
//::///////////////////////////////////////////////
//:: module_enter
//:://////////////////////////////////////////////
/*   system OnClientEnter
*/

//:://////////////////////////////////////////////
//:: Created By: _kaa_ , Baal , Ëèòî
//:: Created On: Jan 27, 2005
//:://////////////////////////////////////////////
#include "nw_o0_itemmaker"
void main()
{
object oPC = GetEnteringObject();
object oStore = GetModule();
string sStoreName = GetName(oPC)+GetPCPlayerName(oPC); // =[PC name] + [login name]
SetLocalString(oPC,"HP_MyIdString",sStoreName); // Çàãðóçêà õèò ïîèíòîâ è ñïåëëîâ
int iSavedHP = GetLocalInt(oStore,sStoreName);
if (iSavedHP != 0)
{
effect efDamage = EffectDamage(GetMaxHitPoints(oPC)-iSavedHP,DAMAGE_TYPE_MAGICAL,DAMAGE_POWER_ENERGY);
ApplyEffectToObject(DURATION_TYPE_INSTANT,efDamage,oPC);
}

int k,j,nSpells;
for (k=1; k < 510; k++)
{
nSpells = GetLocalArrayInt(oStore,sStoreName+"_spells",k);
if (nSpells)
  for (j=0; j <= GetHasSpell(k,oPC)-nSpells; j++) DecrementRemainingSpellUses(oPC, k);
if(GetIsDM(oPC)) //Åñëè DM, òî íå âûäàâàòü ñòàðòîâûé ïàêåò
        return;
object oBook=GetItemPossessedBy(oPC, "item004");
if(!GetIsObjectValid(oBook))  //Åñëè äîñòóïåí ïðåäìåò ñ ResRef*îì "item004",
                              //íå âûäàâàòü ñòàðòîâûé ïàêåò, åñëè íå äîñòóïåí, òî óíè÷òîæèòü âñå âåùè â èíâåíòàðå
{
  object oItem = GetFirstItemInInventory (oPC);
  while(GetIsObjectValid(oItem))
    {
    DestroyObject(oItem);
    oItem = GetNextItemInInventory (oPC);
    }
  int i=0;
  while(i<14)
    {
    DestroyObject(GetItemInSlot(i, oPC));
    i++;
    }
if(GetLevelByClass(CLASS_TYPE_FIGHTER, oPC)) //Âûäà÷à íà÷àëüíîãî ïàêåòà ïî êëàññó
    {
  GiveGoldToCreature(oPC, 500);
  CreateItemOnObject("item004", oPC); //Âûäà÷à âåùåé ïî ResRef*àì
  CreateItemOnObject("Item", oPC);
   CreateItemOnObject("Item", oPC);
    CreateItemOnObject("Item", oPC);
  CreateItemOnObject("item001", oPC);
  CreateItemOnObject("item003", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  }
  else if(GetLevelByClass(CLASS_TYPE_BARBARIAN, oPC))
  {
    GiveGoldToCreature(oPC, 500);
  CreateItemOnObject("item004", oPC);
  CreateItemOnObject("Item", oPC);
   CreateItemOnObject("Item", oPC);
    CreateItemOnObject("Item", oPC);
  CreateItemOnObject("item001", oPC);
  CreateItemOnObject("item003", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  }
  else if(GetLevelByClass(CLASS_TYPE_MONK, oPC))
  {
      GiveGoldToCreature(oPC, 500);
  CreateItemOnObject("item004", oPC);
  CreateItemOnObject("Item", oPC);
   CreateItemOnObject("Item", oPC);
    CreateItemOnObject("Item", oPC);
  CreateItemOnObject("item001", oPC);
  CreateItemOnObject("item003", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  }
  else if(GetLevelByClass(CLASS_TYPE_RANGER, oPC))
  {
    CreateItemOnObject("item004", oPC);
  CreateItemOnObject("Item", oPC);
   CreateItemOnObject("Item", oPC);
    CreateItemOnObject("Item", oPC);
  CreateItemOnObject("item001", oPC);
  CreateItemOnObject("item003", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  }
  else if(GetLevelByClass(CLASS_TYPE_WIZARD, oPC))
  {
      CreateItemOnObject("item004", oPC);
  CreateItemOnObject("Item", oPC);
   CreateItemOnObject("Item", oPC);
    CreateItemOnObject("Item", oPC);
  CreateItemOnObject("item001", oPC);
  CreateItemOnObject("item003", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  }
  else if(GetLevelByClass(CLASS_TYPE_SORCERER, oPC))
  {
  CreateItemOnObject("item004", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("item001", oPC);
  CreateItemOnObject("item003", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  }
  else if(GetLevelByClass(CLASS_TYPE_BARD, oPC))
  {
    CreateItemOnObject("item004", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("item001", oPC);
  CreateItemOnObject("item003", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  }
  else if(GetLevelByClass(CLASS_TYPE_DRUID, oPC))
  {
      CreateItemOnObject("item004", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("item001", oPC);
  CreateItemOnObject("item003", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  }
  else if(GetLevelByClass(CLASS_TYPE_BARD, oPC))
  {
  CreateItemOnObject("item004", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("item001", oPC);
  CreateItemOnObject("item003", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  }
  else if(GetLevelByClass(CLASS_TYPE_CLERIC, oPC))
  {
  CreateItemOnObject("item004", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("item001", oPC);
  CreateItemOnObject("item003", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  }
  else if(GetLevelByClass(CLASS_TYPE_PALADIN, oPC))
  {
  CreateItemOnObject("item004", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("item001", oPC);
  CreateItemOnObject("item003", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  }
  else if(GetLevelByClass(CLASS_TYPE_ROGUE, oPC))
  {
  CreateItemOnObject("item004", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("Item", oPC);
  CreateItemOnObject("item001", oPC);
  CreateItemOnObject("item003", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  CreateItemOnObject("it_mpotion004", oPC);
  }
  }
  }
}


Кроме того чтобы скрипт нормально работал надо поставить еще один(_kaa_) на OnClientLeave
Вот и он
Neverwinter Script Source
#include "nw_o0_itemmaker"
void main()
{
object oPC = GetExitingObject();
object oStore = GetModule();
string sStoreName = GetLocalString(oPC,"HP_MyIdString");
SetLocalInt(oStore, sStoreName, GetCurrentHitPoints(oPC));
int k,nSpells;
for (k=1;k<510;k++)
{
nSpells = GetHasSpell(k,oPC);
if (nSpells)
  SetLocalArrayInt(oStore,sStoreName+"_spells",k,nSpells);
}
}

Автор: Lex Jan 27 2005, 22:14

Скрипт на смерть НПС. НПС исчезает, а на его месте появляется труп на который переносятся все вещи покойного. Сам труп исчезает через 250 секунд.

"low_plc_loot" - резреф трупа в палитре.

Neverwinter Script Source
//::Created by      Лито
//::Modificated by  Lex
void Clear(object oBag = OBJECT_SELF)
{
object oItem = GetFirstItemInInventory(oBag);
while (GetIsObjectValid(oItem))
  {
  DestroyObject(oItem);
  oItem = GetNextItemInInventory(oBag);
  }
DestroyObject(oBag,1.0);
}
void main()
{
string sTemplate = "low_plc_loot";
string sTag = GetTag(OBJECT_SELF);
location lLoc = GetLocation(OBJECT_SELF);
object oloot = CreateObject(OBJECT_TYPE_PLACEABLE, sTemplate, lLoc, TRUE, sTag);
int i = 0;
object oItem = GetFirstItemInInventory(OBJECT_SELF);
while (GetIsObjectValid(oItem))
    {
    if (GetDroppableFlag(oItem))
       CopyObject(oItem,lLoc,oloot);
    DestoyObject(oItem);
    oItem = GetNextItemInInventory(OBJECT_SELF);
    }
oItem = GetItemInSlot(i,OBJECT_SELF);
while (i<14)
    {
    if (GetDroppableFlag(oItem))
       CopyObject(oItem,lLoc,oloot);
    DestoyObject(oItem);
    i++;
    oItem = GetItemInSlot(i,OBJECT_SELF);
    }
AssignCommand(oloot,DelayCommand(250.0,Clear(oloot)));
}

Автор: Aiwan Mar 13 2005, 20:25

СКРИПТ ВЕДУЩИЙ ИГРОКА ЗА НПС ПО ТОЧКАМ.
Вейпов должно быть столько сколько я нарисовал, но либо меньше 10 ли бо больше чем у меня. Почему? Не знаю, неделю гонял Стинки по вейпам и он гад прыгал на некоторые из них при количестве 10, а так нет. Идет как миленький.
и расчитай скорость так, что бы НПС НЕ ЗАСТРЯЛ и не опаздал на 15 сек до точки. Иначе вы просто прыгнете на следующий вейп и диалог прервется. А так он остановится и продолжите диалог.

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Copyright © 2004 WRG!  www.wrg.ru
//:: am_pc_stinki_go2
//:://////////////////////////////////////////////
/*
  ПЕРЕДВИЖЕНИЕ оРС ЗА НПС, СКРИПТ СТАВИТСЯ
    НА СТРОКУ В ДИАЛОГЕ oPC (!)

*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan    Aiwan@e-mail.ru
//:: Created On: 20.03.2004
//:://////////////////////////////////////////////
void main()
{
    object oPC = GetPCSpeaker();
    object oStinki = GetObjectByTag("MM_STINKI");
    object oWp01 = GetObjectByTag("WP_STINKI_01");
    object oWp02 = GetObjectByTag("WP_STINKI_02");
    object oWp03 = GetObjectByTag("WP_STINKI_03");
    object oWp04 = GetObjectByTag("WP_STINKI_04");
    object oWp05 = GetObjectByTag("WP_STINKI_05");
    object oWp06 = GetObjectByTag("WP_STINKI_06");
    object oWp07 = GetObjectByTag("WP_STINKI_07");
    object oWp08 = GetObjectByTag("WP_STINKI_08");
    object oWp09 = GetObjectByTag("WP_STINKI_09");
    object oWp10 = GetObjectByTag("WP_STINKI_10");
    object oWp11 = GetObjectByTag("WP_STINKI_11");
    object oDoor = GetObjectByTag("AM_DOOR_FLEG_NO");
    effect eHaste = EffectHaste(); // ЧТО БЫ ИГРОК НЕ ОТСТАВАЛ!

    SetLocalInt(oPC, "STINKI", 3);
    AssignCommand(oStinki, ActionPauseConversation());
    AssignCommand(oPC, ActionForceFollowObject(oStinki, 4.0f));
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eHaste, oPC, 9999.0);
    AssignCommand(oStinki, ActionDoCommand(SetCommandable(FALSE, oPC)));
    AssignCommand(oStinki, ActionForceMoveToObject(oWp02, TRUE, 4.0));
    AssignCommand(oStinki, ActionDoCommand(SetFacingPoint(GetPosition(oPC))));
    AssignCommand(oStinki, ActionDoCommand(SpeakString("Не отставай!")));
    AssignCommand(oStinki, ActionWait(1.0));
    AssignCommand(oStinki, ActionForceMoveToObject(oWp03, TRUE, 4.0));
    AssignCommand(oStinki, ActionWait(2.0));
    AssignCommand(oStinki, ActionForceMoveToObject(oWp04, TRUE, 4.0));
    AssignCommand(oStinki, ActionDoCommand(SetFacingPoint(GetPosition(oPC))));
    AssignCommand(oStinki, ActionDoCommand(SpeakString("Не сильно быстро?")));
    AssignCommand(oStinki, ActionWait(2.0));
    AssignCommand(oStinki, ActionForceMoveToObject(oWp05, TRUE, 4.0));
    AssignCommand(oStinki, ActionWait(2.0));
    AssignCommand(oStinki, ActionForceMoveToObject(oDoor, TRUE, 4.0));
    AssignCommand(oStinki, ActionDoCommand(SpeakString("Не обращай внимание, нас никто не тронет.")));
    AssignCommand(oStinki, ActionForceMoveToObject(oWp06, TRUE, 4.0));
    AssignCommand(oStinki, ActionWait(2.0));
    AssignCommand(oStinki, ActionForceMoveToObject(oWp07, TRUE, 4.0));
    AssignCommand(oStinki, ActionWait(2.0));
    AssignCommand(oStinki, ActionForceMoveToObject(oWp08, TRUE, 1.0));
    AssignCommand(oStinki, ActionDoCommand(SpeakString("Мы почти пришли!")));
    AssignCommand(oStinki, ActionForceMoveToObject(oWp09, TRUE, 1.0));
    AssignCommand(oStinki, ActionWait(2.0));
    AssignCommand(oStinki, ActionForceMoveToObject(oWp10, TRUE, 1.0));
    AssignCommand(oStinki, ActionWait(2.0));
    AssignCommand(oStinki, ActionForceMoveToObject(oWp11, TRUE, 1.0));
    AssignCommand(oStinki, ActionDoCommand(SetFacingPoint(GetPosition(oPC))));
    AssignCommand(oStinki, ActionDoCommand(RemoveEffect(oPC, eHaste)));
    AssignCommand(oStinki, ActionDoCommand(SetCommandable(TRUE, oPC)));
    AssignCommand(oStinki, ActionResumeConversation());
}

Автор: Lex Mar 17 2005, 11:51

СЕРИЯ "СКРИПТЫ ПРОКЛЯТИЯ ЛЕВОРА"
ЦИКЛ "СКРИПТЫ ДЯДЮШКИ LEX'А"


Цель:
сделать 2 (можно и более) НПС которые как будто между собой разговаривают.
(те, кто играл ПЛ в Тсурлаголе видели такие примеры. Особенно в тавернах.)
Реализация:
ставим 2х НПС, даем соотв. тэги и ставим между ними нивидимый объект, в ХБ которого вносим этот скрипт.

"+" - эффект диалога. Так как фразы стыкуются (вы сами их пишите так, что на вопрос дается ответ и прочее.) так как они все парные.
"-" - на каждую уникальную группу свой скрипт. Текст разговора пишется в скрипте.

Neverwinter Script Source
//::///////////////////////////////////////////////
//:: Name lm_2speakers
//:: Copyright © 2004 -=WRG!=-
//:://////////////////////////////////////////////
/*
скрипт разговора 2-х НПС. Шаблон.
*/

//:://////////////////////////////////////////////
//:: Created By: Lex
//:: Created On: Agust 2004
//:://////////////////////////////////////////////

void ANIMATION(object oD)
/// Рандомная анимация во время разговора. настраивайте сами.
    {
    int A=0;
    float T,S;
    switch (Random(8)+1)
       {
       case 2: A=ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD;T=3.0;S=1.0;break;
       case 3: A=ANIMATION_FIREFORGET_TAUNT;T=3.0;S=1.0;break;
       case 4: A=ANIMATION_FIREFORGET_PAUSE_BORED;S=1.0;break;
       case 5: A=ANIMATION_LOOPING_LISTEN;T=5.0;S=1.0;break;
       case 6: A=ANIMATION_LOOPING_LISTEN;T=5.0;S=1.0;break;
       }
    if (A==0) return;
    AssignCommand(oD,PlayAnimation(A,S,T));
    }

void DIALOG(object oD1,object oD2)
    {
    string s1="",s2="";
    string ya = GetName(GetObjectByTag("ya")); // "+ya+"
    switch (Random(30))
         {
         case 0: s1="Как дела, друг?";s2="Да идут по маленьку..";break;
         case 1: s1="И как она? Симпатична"+ya+"?";s2="А как же! Ты мен"+ya+" обижаешь!";break;
         /// и так далее 20 фраз типа вопрос-выссказывание и ответ на это дело
         }
    AssignCommand(oD1,SpeakString(s1)); /// первый НПС говорит фразу
    AssignCommand(oD2,DelayCommand(5.0,SpeakString(s2))); /// второй отвечает
    }

void main()
{
object oPC = GetFirstPC();
if (GetArea(oPC)!=GetArea(OBJECT_SELF)) return; // если нет игрока, то молчим
object oD1 = GetNearestObjectByTag("SPEAKING_NPC_1"); // первый НПС
object oD2 = GetNearestObjectByTag("SPEAKING_NPC_1"); // второй НПС
if (GetIsInCombat(oD1)) return; // если первый НПС дерется то молчим
if (GetIsInCombat(oD2)) return; // если второй НПС дерется то молчим
if ( (IsInConversation(oD1)) || (IsInConversation(oD2)) ) return; /// если один из НПС разговаривает с игроком
if (GetDistanceToObject(oPC)>10.0) return; // если игрок далеко (больше 10 футов) то он как будто ничего не слышит.
AssignCommand(oD1,SetFacingPoint(GetPosition(oD2))); // повернуться навтречу друг другу
AssignCommand(oD2,SetFacingPoint(GetPosition(oD1)));
DIALOG(oD1,oD2);
ANIMATION(oD1);
ANIMATION(oD2);
}



================================================================================

Небольшой простенький скрипт на слот onDamage плэйсебла. (ТЭГ плэйса "DANGER")

Плэйс взрывается, если его повредить. Если у вас есть Проклятие Левора, то в пещере почти все бочки это объекты с таким скриптом. Сила взрыва растет, если рядом есть такие же объекты.
ВНИМАНИЕ: больше таких 5 рядом не ставить. Тормозит....скрипт не оптимален.
Делалася под СоУ, поэтому использованны не локалки, а поле
KeyTag. Скрипт старый и давно мной не улучшавшийся. Это вам просто для работы.
(как юзать в таком варианте KeyTaG:
ставим флаг Закрыто и Требуется ключ. Поле открывается. Теперь пишем туда что надо и снимаем флаг Закрыто.
ограничение: скрипт лучше не ставить на закрытые объекты, так как поле KeyTaG нужно для работы.)
в поле KeyTag радиус и сила взрыва: X_Y
X - сила по нижепреведенной шкале. По умолчанию 2
1 - слабый
2 - средний
3 - сильный
Y - радиус в футах. (не более 9). По умолчанию 5 футов.
подрыв объекта происходит при повреждении более чем на 30%.
Neverwinter Script Source
//::///////////////////////////////////////////////
//:: Name ******
//:: FileName lm_damage_danger
//:: Copyright © 2003 -=WRG!=-.
//:://////////////////////////////////////////////
/*
THIS SCRIPT CHECKS IF ANYBODY DAMAGED DANGER OBJECT MORE THEN 30%
THEN THE OBJECT EXPLOSE
EXPLOSION DEPENDS ON STRONG EXPLOSION RADIUS.
EXPLOSION RADIUS & STRONG ARE IN TrapKeyTag of object
*/

//:://////////////////////////////////////////////
//:: Created By: Lex
//:: Created On: October 2003
//:: Special thanks to:
//::    Baal (WRG) for advice about calculation power
//:://////////////////////////////////////////////

void DamageObject(float ExplosionRadius, int Strong, object oDamager, location lCenter)
   {
   float modifier=1.0;
   effect eAddition;
   int DamagePower=DAMAGE_POWER_PLUS_ONE;
   float fDistance = GetDistanceBetweenLocations(GetLocation(oDamager),lCenter);
   switch(Strong)
      {
      case 1: modifier=0.5;
              DamagePower=DAMAGE_POWER_NORMAL;
              eAddition = EffectFrightened();
              break;
      case 2: modifier=1.0;
              DamagePower=DAMAGE_POWER_PLUS_ONE;
              eAddition = EffectFrightened();
              break;
      case 3: modifier=1.5;
              DamagePower=DAMAGE_POWER_PLUS_TWO;
              eAddition = EffectParalyze();
              break;
      default:modifier=2.0;
              DamagePower=DAMAGE_POWER_PLUS_THREE;
              eAddition = EffectParalyze();
              break;
      }
   int iDamage = FloatToInt((ExplosionRadius*ExplosionRadius/2 - fDistance*fDistance/2)*modifier+modifier*5);
   effect eDamage = EffectDamage(iDamage,DAMAGE_TYPE_FIRE,DamagePower);
   AssignCommand(oDamager,ClearAllActions());
   AssignCommand(oDamager,DelayCommand(0.2,SetCommandable(FALSE,oDamager)));
   if (GetObjectType(oDamager)==OBJECT_TYPE_CREATURE)
       if (Random(2)==1)
           AssignCommand(oDamager,PlayAnimation(ANIMATION_LOOPING_DEAD_FRONT,0.6,2.0));
       else AssignCommand(oDamager,PlayAnimation(ANIMATION_LOOPING_DEAD_BACK,0.6,2.0));
   AssignCommand(oDamager,DelayCommand(0.8,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectVisualEffect(VFX_COM_HIT_FIRE),oDamager,1.0)));
   if (fDistance<=ExplosionRadius/3)
     {
     float time = modifier*ExplosionRadius/fDistance;
     AssignCommand(oDamager,DelayCommand(0.8,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eAddition,oDamager,time)));
     }
   AssignCommand(oDamager,DelayCommand(0.3,ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oDamager)));
   AssignCommand(oDamager,DelayCommand(2.5,SetCommandable(TRUE,oDamager)));
   }
void main()
{
//========================================================
int iDamage;
float ExplosionRadius;
int Strong;
location lCenter;
int Next=TRUE;
int Filter;
int Explosion;
object oDamager;
string STR;
int Critical=0;
Filter = OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE;
lCenter = GetLocation(OBJECT_SELF);
if (GetTrapKeyTag(OBJECT_SELF)!="**")
   {
   ExplosionRadius=5.0;
   Strong=2;
   }
else if (GetTag(OBJECT_SELF)!="ITM_FIREMINE")
   {
    iDamage = GetMaxHitPoints()-GetCurrentHitPoints();
    STR = GetStringRight(GetTrapKeyTag(OBJECT_SELF),1);
    if (STR!="") ExplosionRadius = StringToFloat(STR);
    STR = GetStringLeft(GetTrapKeyTag(OBJECT_SELF),1);
    if (STR!="") Strong = StringToInt(STR);
    if ((Strong>3)||(Strong==0)) Strong=2;
    if ((ExplosionRadius>10.0)||(ExplosionRadius==0.0)) ExplosionRadius=5.0;
    if (iDamage*10 < GetMaxHitPoints()*3) return;
   }
else
   {
   ExplosionRadius = 6.5;
   Strong = 2;
   SendMessageToPC(GetFirstPC(),"MINE");
   }
Strong = GetLocalInt(OBJECT_SELF,"ADD_STRONG")+Strong;
if (Strong<3) Explosion = VFX_FNF_GAS_EXPLOSION_FIRE;
else Explosion = VFX_FNF_FIREBALL;
if ((iDamage<GetMaxHitPoints()/3)&&(GetDamageDealtByType(DAMAGE_TYPE_FIRE)==0)) return;
if (GetLocalInt(OBJECT_SELF,"ALREADY")) return;
SetLocalInt(OBJECT_SELF,"ALREADY",TRUE);
oDamager = GetFirstObjectInShape(SHAPE_SPHERE,ExplosionRadius,lCenter,TRUE,Filter);
object oPC = GetFirstPC();
DestroyObject(OBJECT_SELF);
if ((GetLocalInt(GetObjectByTag("TS_LOCALS"),"FIRECAMP_DESTROED"))&&(GetTag(GetArea(OBJECT_SELF))=="TSUR_SUB_EASTFOREST_BOMBCAVE"))
     return;
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY,EffectVisualEffect(VFX_IMP_PULSE_FIRE),lCenter,1.5);
ApplyEffectAtLocation(DURATION_TYPE_PERMANENT,EffectVisualEffect(Explosion),lCenter);
   while (GetIsObjectValid(oDamager))
     {
     if ((GetTag(oDamager)=="DANGER")&&(!GetLocalInt(oDamager,"ALREADY"))&&(GetDistanceToObject(oDamager)<=ExplosionRadius/2))
        {
        if (Next) SetLocalInt(oDamager,"ADD_STRONG",1);
        ExplosionRadius = ExplosionRadius + 2.0;
        Critical++;
        }
     if (Critical==3)
         {
         Next=TRUE;
         }
     if (Critical==5)
         {
         Strong++;
         Critical=0;
         }
     AssignCommand(oDamager,DamageObject(ExplosionRadius,Strong,oDamager,lCenter));
     oDamager = GetNextObjectInShape(SHAPE_SPHERE,ExplosionRadius,lCenter,TRUE,Filter);
     }
}

Автор: Aiwan Mar 17 2005, 16:18

СЕРИЯ "СКРИПТЫ ПРОКЛЯТИЯ ЛЕВОРА"
ЦИКЛ "СКРИПТЫ ДЯДЮШКИ AIWAN'А"


Скрипт который позволяет при наличии надетой брони с определенным ТЕГом ходить во вражественном лагере smile.gif Ну или где там вам надо...

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Created By: WRG! Aiwan aiwan@e-mail.ru
//:: Created On: 14.01.2004
//:://////////////////////////////////////////////
//:: Скрипт проверки брони "Железного Трона"
//::  у РС на фрегате "Отшельник"
//:://////////////////////////////////////////////
#include "NW_I0_GENERIC"

void main()
{
if (GetArea(OBJECT_SELF) != GetArea(GetFirstPC()))
       return; // Если РС нет в локации то возврат
   int nEvent = GetUserDefinedEventNumber();
   if (nEvent == 1002) // Стандартный эвент на юзердеф
   {
    object oPC = GetLastPerceived();
    object oNPC = OBJECT_SELF;
    object oArm = GetItemInSlot(INVENTORY_SLOT_CHEST, oPC); // Предмет в слоте РС "броня"
      if (GetLastPerceptionSeen() && GetIsPC(oPC))
         {
          if (GetTag(oArm) != "AM_ITM_IRONTRON" && GetLocalInt(oPC,"TRONE_ALARM") != 1)
          // Если Таг надетой брони не равен AM_ITM_IRONTRON и нет локалки тревоги
            {
             SetLocalInt(oPC, "TRONE_ALARM", 1); // Вы обнаружены и поднята тревога
             SetFacingPoint(GetPosition(oPC));
             SpeakString("А ну стой, ты что тут вынюхиваешь?!");
             AdjustReputation(oPC, oNPC, -100);
             DetermineCombatRound(oPC);
             }
            if (GetLocalInt(oNPC, "LOOK") != 1 && GetTag(oArm) == "AM_ITM_IRONTRON" &&
                GetLocalInt(oPC,"TRONE_ALARM") != 1)
             {
             SetLocalInt(oNPC, "LOOK", 1); // Ставим локалку что бы часто не болтали
             AssignCommand(oNPC, ClearAllActions());
             AssignCommand(oNPC, ActionDoCommand(SetFacingPoint(GetPosition(oPC))));
             DelayCommand(16.0f, SetLocalInt(oNPC, "LOOK", 0));
             int iRand = Random(10);
              switch (iRand)
              {
                    case 0:
                    {
                         SpeakString("Займись делом, солдат!"); break;
                    }
                    case 1:
                    {
                         SpeakString("Привет, ты новенький?"); break;
                    }
                    case 2:
                    {
                        SpeakString("Смотри, скоро прибудут боссы..."); break;
                    }
                    case 3:
                    {
                        SpeakString("Ты откуда выполз?"); break;
                    }
                    case 4:
                    {
                        SpeakString("Ты чего тут делаешь?"); break;
                    case 5:
                    {
                        SpeakString("Слушай, твои доспехи тебе не жмут?"); break;
                    case 6:
                    {
                        SpeakString("Иди на пост!"); break;
                    }
                     case 7:
                    {
                        SpeakString("Я твою рожу не помню что-то..."); break;
                    }
                     case 8:
                    {
                        SpeakString("Эй, ты свой ведь? Да?"); break;
                    }
                     AssignCommand(oNPC, ActionDoCommand(WalkWayPoints()));
               }
              }
            }
          }
        }
       }
    return;
}


Дальше, два скрипта для запуска диалога в котором участвует НПС которого вы атакуете и диалог начинается с определенного нр у НПС. Скрипты финального боя с воином в модуле 3.

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Copyright © 2004 WRG!  www.wrg.ru
//:: Name: oud_am_warrord
//:://////////////////////////////////////////////
/*
   UserDefined - СКРИПТ ЗАПУСКА СЦЕНЫ С ДАЛЛИКОМ
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan    Aiwan@e-mail.ru
//:: Created On: 26.02.2004
//:://////////////////////////////////////////////
void main()
{
int nEvent = GetUserDefinedEventNumber();
//======================= DAMAGED EVENT 1006 ===================================
if (nEvent == 1006)
  {
   object oPC = GetFirstPC(); // Опишите своего РС как вам надо.
   object oCat = GetHenchman(oPC);
   object oWord = OBJECT_SELF;
   object oSlave1 = GetObjectByTag("AM_SKELLETON_SLAVE_01"); // Скелет - Раб 1
   object oSlave2 = GetObjectByTag("AM_SKELLETON_SLAVE_02"); // Скелет - Раб 2
   object oWPTrone = GetObjectByTag("WP_TRONE_WARRIOR");
   int iCurHP = GetCurrentHitPoints(OBJECT_SELF);
   int iMaxHP = GetMaxHitPoints(OBJECT_SELF);
   int iD;
//==============================================================================
  if (!GetIsPC(oPC) || !GetLocalInt(oPC, "DALLIK_HELP"))
    {return;}
    int Class = GetClassByPosition(1, oPC); // При разных классах надо нанести разное повреждение
    switch (Class)
      {
      case CLASS_TYPE_BARBARIAN:{iD = 200; break;}
      case CLASS_TYPE_BARD:{iD = 300; break;}
      case CLASS_TYPE_CLERIC:{iD = 250; break;}
      case CLASS_TYPE_DRUID:{iD = 300; break;}
      case CLASS_TYPE_FIGHTER:{iD = 200; break;}
      case CLASS_TYPE_MONK:{iD = 150; break;}
      case CLASS_TYPE_PALADIN:{iD = 200; break;}
      case CLASS_TYPE_RANGER:{iD = 250; break;}
      case CLASS_TYPE_ROGUE:{iD = 300; break;}
      case CLASS_TYPE_SORCERER:{iD = 300; break;}
      case CLASS_TYPE_WIZARD:{iD = 300; break;}
      }

  if (GetIsPC(oPC) && ((iMaxHP - iD) >= iCurHP) && !GetLocalInt(oWord, "DALLIK_JAMP"))
   {
   SetLocalInt(oWord, "DALLIK_JAMP", TRUE);
   AssignCommand(oPC, ClearAllActions());
   AssignCommand(oCat, ClearAllActions());
   AssignCommand(OBJECT_SELF, ClearAllActions());
   AssignCommand(oSlave1, ClearAllActions());
   AssignCommand(oSlave2, ClearAllActions());
   ExecuteScript("am_chang_fr_warr", OBJECT_SELF); // Скрипт меняет репутацию у участников боя
// DelayCommand(0.5, ExecuteScript("am_scen_warr_03", oPC));
   }
  }
}


Вот сам скрипт смены репутации:
Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Copyright © 2004 WRG!  www.wrg.ru
//:: name: am_chang_fr_warr
//:://////////////////////////////////////////////
/*
     ИЗМЕНЕНИЕ ФРАКЦИИ И ПЕРСОНАЛНЫХ ОТНОШЕНИЙ
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan    Aiwan@e-mail.ru
//:: Created On: 23.03.2004
//:://////////////////////////////////////////////
void main()
{
   object oPC = GetFirstPC();
   object oHen = GetHenchman(oPC);
   object oWord = GetObjectByTag("AM_WARRIOR_HORDE"); // Воин Орды
   object oSlave1 = GetObjectByTag("AM_SKELLETON_SLAVE_01"); // Скелет - Раб 1
   object oSlave2 = GetObjectByTag("AM_SKELLETON_SLAVE_02"); // Скелет - Раб 2
   location lClose = GetLocation(GetObjectByTag("AIWAN_CLOSE_ARENA")); //Скрыт.арена Aiwan'a
   object oNeutral = GetObjectByTag("AM_TRUE_NEUTRAL"); // Нейтральный НПС с фракцией ПОФИГИСТОВ
   ChangeFaction(oWord, oNeutral);
   ChangeFaction(oSlave1, oNeutral);
   ChangeFaction(oSlave2, oNeutral);
//--------------------------------------
   ClearPersonalReputation(oSlave1, oPC);
   ClearPersonalReputation(oPC, oSlave1);
   ClearPersonalReputation(oSlave1, oHen);
   ClearPersonalReputation(oHen, oSlave1);
//--------------------------------------
   ClearPersonalReputation(oSlave2, oPC);
   ClearPersonalReputation(oPC, oSlave2);
   ClearPersonalReputation(oSlave2, oHen);
   ClearPersonalReputation(oHen, oSlave2);
//--------------------------------------
   ClearPersonalReputation(oWord, oPC);
   ClearPersonalReputation(oPC, oWord);
   ClearPersonalReputation(oWord, oHen);
   ClearPersonalReputation(oHen, oWord);
}



СКРИПТ ЗАПРЕЩАЮЩИЙ МОНСТРАМ ВЫХОДИТЬ
ИЗ ЛОКАЦИИ ВСЛЕД ЗА ИГРОКОМ
Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Copyright © 2004 WRG
//:: a0_onareaexit
//:://////////////////////////////////////////////
/*
    СКРИПТ ЗАПРЕЩАЮЩИЙ МОНСТРАМ ВЫХОДИТЬ
        ИЗ ЛОКАЦИИ ВСЛЕД ЗА ИГРОКОМ
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan    Aiwan@e-mail.ru
//:: Created On: 21.04.2004
//:://////////////////////////////////////////////
void main()
{
  object oPC = GetEnteringObject();
  object oAnimal = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oPC);
  object oDominated = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oPC);
  object oFamiliar = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oPC);
  object oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC);
  object oSummoned = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC);
  object oJamp = GetTransitionTarget(OBJECT_SELF);
  //Чисто для моих земель, чтобы фамилиары не разгуливали где попало, пока их владельцы задумчиво стоят в области
  if (GetIsPC(oPC) && !GetIsPosessedFamiliar(oPC))
  {
  AssignCommand(oPC, JumpToObject(oJamp));
  AssignCommand(oAnimal, JumpToObject(oJamp));
  AssignCommand(oDominated, JumpToObject(oJamp));
  AssignCommand(oFamiliar, JumpToObject(oJamp));
  AssignCommand(oHenchman, JumpToObject(oJamp));
  AssignCommand(oSummoned, JumpToObject(oJamp));
  }
  else
  {
  //Иначе наши монстрyaшки будут задумчиво покачиваться у двери, совершенно беззащитные
  AssignCommand(oPC, ClearAllActions());
  }
}

Автор: Lex Mar 18 2005, 22:42

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ ДЯДЮШКИ MILEZ'А"

Автор:::::::::::::::::Milez::::::::::::::::::::::::::::::
May 22 2003
Cкрипт для смерти.
Вешать на OnPlayerDying модуля.
+ скрипта в том, что он не использует хартбит.
Это бета-версия скрипта предложена as is, автор не несет ответственности за материальный и моральные ущерб, который этот скрипт может кому-то принести!

Neverwinter Script Source
void DyingTicker(object oPC)
{
   int iHP=GetCurrentHitPoints(oPC);
   if (iHP>0) {
       RemoveEffect(oPC,EffectBlindness());
       DeleteLocalInt(oPC,"DyingDC");
       DeleteLocalInt(oPC,"STvsDeathSucceed");
       return;
   }
   int iDC;
   int iDam;
   int iSuc;
   if (iHP<-9) { ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDeath(TRUE,TRUE),oPC); }
   else {
       iDam=d4();
       iDC=GetLocalInt(oPC,"DyingDC");
       if (FortitudeSave(oPC,iDC)>0) {
           iDam=iDam/2;
           iSuc=GetLocalInt(oPC,"STvsDeathSucceed")+1;
           SetLocalInt(oPC,"STvsDeathSucceed",iSuc);
           if (iSuc>2) {
               FloatingTextStringOnCreature("Кровотечение прекратилось",oPC,FALSE);
               return;
           }
       }
       AssignCommand(oPC,DelayCommand(6.0,DyingTicker(oPC)));
       ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(iDam), oPC);
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectBlindness(),oPC,6.0);
       SetLocalInt(oPC,"DyingDC",iDC+1);
   }
}

void main()
{
   object oPC=GetLastPlayerDying();
   if (!GetIsPC(oPC)) return;
   SetLocalInt(oPC,"DyingDC",15);
   SetLocalInt(oPC,"STvsDeathSucceed",0);
   FloatingTextStringOnCreature("У менz открылось кровотечение",oPC,FALSE);
   DyingTicker(oPC);
}

Смысл в том, что каждый раунд (6 сек) игрок кидает спасбросок стойкости для половинного дамаджа от 1d4, при этом DC, который надо побить, увеличивается с каждым раундом на 1 (начальное значение 15). При удачном спасбраске 2 раза подряд кровотечение прекращается.
от 0 до -9 - игрок без сознание. От -10 и меньше - смерть без спасброска.

************************************************************************************

Автор:::::::::::::::::Milez::::::::::::::::::::::::::::::
May 24 2003

Вот температурный скрипт, полностью в соответсвии с D&D 3ed согласно разделам HEAT и COLD в DMG. Писан мной, любые совпадения в реализации с другими подобными скриптами являются чисто случайными. За общую идею создать нечто подобное спасибо ДБколлу. Подробнее об общем алгоритме работы см DMG (Температура, в отличие от DMG, приведена не в иноземных Фаренгейтах, а в старых добрых Цельсиях).
Всяческое использование, модификация, дебаггинг приветствуются! Никакой ответственности за причиненный моральный/материальный ущерб в результате работы скрипта автор не несет!

Вешать на OnEnter местности.
Neverwinter Script Source
void DealTemperatureDamage(object oPC)

{
   // Игрок без сознания
   if (GetCurrentHitPoints(oPC)<1) return;
   // Где находится игрок?
   object oArea=GetArea(oPC);
   // И какая там температура?
   int iT=GetLocalInt(oArea,"Temperature");
   // Температура комфортабельна или не установлена
   // (значение 0 рассматривается как неустановленная температура. Вместо 0 ставьте -1)
   if (((iT<=32) && (iT>=4)) || (iT==0)) return;
   // Определяем переменные
   int iDamType;
   int iDamAmount;
   int iSaveType;
   float iInterval;

   object oFire;
   int iFatigue=FALSE;
   int iFortSave;
   int i;
   effect eDam;
   // Носим тяжелую броню и/или плащ?
   int iCloth=(GetItemACValue(GetItemInSlot(INVENTORY_SLOT_CHEST,oPC))>5)
               ||GetIsObjectValid((GetItemInSlot(INVENTORY_SLOT_CLOAK,oPC)));
   // Сколько раз мы уже "стучали" по игроку?
   int iTimes=GetLocalInt(oPC,"TemperatureDamageTimer");
   int iDC=15+iTimes; // Подсчет DC
   if (iT>32) { // Жарко!
       FloatingTextStringOnCreature("Мне жарко!",oPC);
       iDamType=DAMAGE_TYPE_FIRE;
       iSaveType=SAVING_THROW_TYPE_FIRE;
       iDamAmount=d4();
       if (iCloth) iDC+=4; // -4 пенальти к спасброску аналогично +4 к DC (так как спасбросок делается встроенной функцией). При желание спасбросок можно делать вручную, но встроенная функция уж больно красиво пишет о спасброске в логах smile.gif
       if (iT>60) { // Адская жарища!
       // 1d6 дамадж каждые 2 реальные секунды без спасброска
           eDam=EffectDamage(d6(),iDamType);
           ApplyEffectToObject(DURATION_TYPE_INSTANT,eDam,oPC);
           for (i=2;i<10;i+=2)
               AssignCommand(oPC,DelayCommand(IntToFloat(i),
               ApplyEffectToObject(DURATION_TYPE_INSTANT,eDam,oPC)));
           iFatigue=TRUE;
           iInterval=10.0;
       } else if (iT>43) { // Очччень жарко!
           iInterval=20.0;
           iFatigue=TRUE;
       } else { // Просто жарко
           iInterval=120.0;
       }
   } else if (iT<4) { // Холодно!
       // ищем костер
       oFire=GetNearestObjectByTag("ku_campfire",oPC);
       // Если рядом костер, но мы согреемся
       if ((GetIsObjectValid(oFire)) &&
           (GetDistanceBetween(oFire,oPC)<5.0)) {
           iDC=0;
           RemoveEffect(oPC,EffectSlow());
           iInterval=120.0;
       } else {
           iDamType=DAMAGE_TYPE_COLD;
           iSaveType=SAVING_THROW_TYPE_COLD;
           iDamAmount=d6();
           FloatingTextStringOnCreature("Мне холодно!",oPC);
           if (iT<-18) { // Жуткий мороз
               if (iCloth) iInterval=120.0; else iInterval=20.0;
               iFatigue=TRUE;
           } else { // Very cold
               if (iCloth) iDC=0; // Мы хорошо одеты и легкий морозец нам не страшен
               iInterval=120.0;
           }
       }
   }
   if (iDC>0){
       iFortSave=FortitudeSave(oPC,iDC,iSaveType);
       if (iFortSave==0) {
           ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDamage(iDamAmount,iDamType),oPC);
           if (iFatigue) ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectSlow(),oPC,iInterval);
       }
   }
   SetLocalInt(oPC,"TemperatureDamageTimer",iTimes+1);
   AssignCommand(oPC,DelayCommand(iInterval,DealTemperatureDamage(oPC)));
}


void main()
{
   object oPC=GetEnteringObject();
   if (GetIsObjectValid(oPC)) {
       DeleteLocalInt(oPC,"TemperatureDamageTimer");
       AssignCommand(oPC,DealTemperatureDamage(oPC));
   }
}

где
ku_campfire - "синька" костра

************************************************************************************

Автор:::::::::::::::::Milez::::::::::::::::::::::::::::::
May 24 2003

Скрипт для "тягловых" животных. Легко переделывается для банка. Писано мной, любые совпадения с чьей-либо реализацией как в деталях так и в общем алгоритме чисто случайны. Всяческие изменения, доработки, дебаггинг приветствуются. За моральный/материальный ущерб в результате работы скрипта автор ответственности не несет!
На "тягловом" НПЦ (я использовал окса, но это может быть и хенчман, и фамильяр) в диалоге ставиться строчка наподобие "Перебрать поклажу". В Action Taken ставиться следующий скрипт:
Neverwinter Script Source
void main()
{
   object oPC=GetPCSpeaker();
   object oPackAnimal=OBJECT_SELF;
   location lLoc=GetLocation(oPC);
   object oContainer=CreateObject(OBJECT_TYPE_PLACEABLE,"inviscont",lLoc);
   object oEnum=GetFirstItemInInventory(oPackAnimal);
   SetLocalObject(oContainer,"LinkedPackAnimal",oPackAnimal);
   while (GetIsObjectValid(oEnum)) {
       CopyObject(oEnum,lLoc,oContainer);
       DestroyObject(oEnum);
       oEnum=GetNextItemInInventory(oPackAnimal);
   }
   AssignCommand(oPC,ClearAllActions());
   AssignCommand(oPC,ActionInteractObject(oContainer));
}

Создается "синька" врменного контейнера (я использовал за образец Invisible Object), на "синьке" ставяться аттрибуты Usable, Plot, Has Inventory. Имя синьки в данном случае "inviscont". В обработчик "синьки" OnClose ставиться следующий скрипт:
Neverwinter Script Source
void main()
{
   object oMaster=GetLocalObject(OBJECT_SELF,"LinkedPackAnimal");
   location lLoc=GetLocation(OBJECT_SELF);
   object oEnum=GetFirstItemInInventory();
   while (GetIsObjectValid(oEnum)) {
       CopyObject(oEnum,lLoc,oMaster);
       DestroyObject(oEnum);
       oEnum=GetNextItemInInventory();
   }
   DelayCommand(1.0,DestroyObject(OBJECT_SELF));
}


************************************************************************************

Автор:::::::::::::::::Milez::::::::::::::::::::::::::::::
May 27 2003
Гильдия Убийц.
(с) Оригинальная идея ONYX'а.
(с) Реализация Milez'а.
Система маленько запутанна, в модуле все взаимосвязано, здесь только основные скрипты, без диалогов и прочего.
Итак, есть айтем Контракт, в св-вах добавлено Cast: Unique Power Unlim Times/Day. Имя синьки contract.
Есть айтем Голова "клиента", в св-вах Cast: Unique Power Self Only Unlim Times/Day. Имя синьки headofclient.
В OnActivateItem модуля следующая бяка:
Neverwinter Script Source
location RandomLocationFrom(location lOrigin)
{
   vector vOrigin=GetPositionFromLocation(lOrigin);
   vOrigin.x+=(Random(11)-5);
   vOrigin.y+=(Random(11)-5);
   return Location(GetAreaFromLocation(lOrigin),vOrigin,GetFacingFromLocation(lOrigin));
}

void SummonKiller(object oClient,object oMaster)
{
   location lClient=RandomLocationFrom(GetLocation(oClient));
   ApplyEffectAtLocation(DURATION_TYPE_INSTANT,
       EffectVisualEffect(VFX_FNF_SMOKE_PUFF),lClient);
   object oKiller=CreateObject(OBJECT_TYPE_CREATURE,"gypsy007",lClient);
   SetLocalObject(oKiller,"MyClient",oClient);
   SetLocalString(oKiller,"MyClientName",GetName(oClient));
   SetLocalString(oKiller,"MyClientTag",GetTag(oClient));
   SetLocalObject(oKiller,"MyMaster",oMaster);
  & nbsp;DelayCommand(IntToFloat(Random(51)+50),AssignCommand(oKiller,ActionAttack(o
Client)));
}

void SummonKillers(object oClient,object oMaster,int iNumKillers)
{
   int i;
   for (i=1;i<=iNumKillers;i++) {
       SummonKiller(oClient,oMaster);
   }
}

void main()
{
   object oOwner=GetItemActivator();
   if (!GetIsPC(oOwner)) return;
   object oSource=GetItemActivated();
   object oTarget=GetItemActivatedTarget();
   string sSourTag=GetTag(oSource);
   if (sSourTag=="contract") {
       int iNumOfKillers=GetLocalInt(oSource,"NumberOfKillers");
       if (iNumOfKillers<1) {
           DestroyObject(oSource);
       } else
       if ((GetObjectType(oTarget)==OBJECT_TYPE_CREATURE) && (!GetIsDM(oTarget)) && (!GetPlotFlag(oTarget)))
      {
           FloatingTextStringOnCreature("The murder have been assigned!",oOwner,FALSE);
           DelayCommand(IntToFloat(Random(51)+50),
               SummonKillers(oTarget,oOwner,iNumOfKillers));
           DestroyObject(oSource);
       } else {
           FloatingTextStringOnCreature("The murder can't be assigned to an item, DM or plot character!",oOwner,FALSE);
       }
   } else if (sSourTag=="headofclient") {
       FloatingTextStringOnCreature("This is the head of "+
           GetLocalString(oSource,"Client"),oOwner,FALSE);

   }
}

Персонажи:
Наемник (типа главарь). В его диалоге уставливается кол-во убийц для задания, забираются деньги у игрока,
дается контракт (CreateItemOnObject("contract",oPC)).
Кол-во убийц-исполнителей должно писаться на контракте (SetLocalInt(oContract,"NumberOfKillers",xxx))
Убийца. Собственно исполнитель. Имя синьки "gypsy007". В OnHeartbeat убийцы такая бяка:
Neverwinter Script Source
void main()
{
   object oClient=GetLocalObject(OBJECT_SELF,"MyClient");
   object oMaster=GetLocalObject(OBJECT_SELF,"MyMaster");
   object oMessenger;
   string sNotifyVar;
   if ((!GetIsObjectValid(oClient)) || GetIsDead(oClient)) {
       if (GetIsObjectValid(oMaster)) {
           sNotifyVar="Notified"+GetLocalString(OBJECT_SELF,"MyClientTag");
           if (GetLocalInt(oMaster,sNotifyVar)!=TRUE) {
               oMessenger=CreateObject(OBJECT_TYPE_CREATURE,"halfmerc002",
                   GetLocation(oMaster),TRUE);
               SetLocalObject(oMessenger,"MyMaster",oMaster);
               SetLocalString(oMessenger,"MyClient",GetLocalString(OBJECT_SELF,"MyClientName"));
               SetLocalString(oMessenger,"NotifyVar",sNotifyVar);
               SetLocalInt(oMaster,sNotifyVar,TRUE);
           }
       }
       DestroyObject(OBJECT_SELF);
   }
}

Вестник Гильдии Убийц. После исполнения задания доставляет заказчику голову жертвы. Имя синьки "halfmerc002".
Диалог длинный, хитрый и может быть любым. Основной скрипт который должен быть для отдавания головы жертвы следующий:
Neverwinter Script Source
void main()
{
   object oPC=GetPCSpeaker();
   object oHead=CreateItemOnObject("headofclient",oPC);
   SetLocalString(oHead,"Client",GetLocalString(OBJECT_SELF,"MyClient"));
   SetLocalObject(oHead,"Master",oPC);
   DeleteLocalInt(oPC,GetLocalString(OBJECT_SELF,"NotifyVar"));
}

Работа скрипта: игрок говорит с Наемником и просит его убрать какого-либо игрока/неписю.
Наемник спрашивает сколько посылать убийц и в зависимости от их кол-ва устанавливает цену,
если игрок согласен и у него хватает денег, то игроку дается контракт и забираются деньги.
Потом контракт используется на том неписе/игроке которого надо "убрать", после чего через 50-100 секунд
(DelayCommand(IntToFloat(Random(51)+50),... Впрочем это можно регулировать) около "клиента" материализуется энное кол-во убийц. Они атакуют жертву (убийцы у меня в спец. фракции Killer, которая нейтральна ко всем, так что атакуют они только намеченную жертву, но это можно менять) и если жертва успешно убивается, то к заказчику направляется гонец (если жертва выживает, то значит убийцы умирают и посылать гонца некому) и убийцы бесследно смываются с места преступления. Игрок говорит с посыльным и получает голову "клиента". Если использовать эту голову, то игроку-заказчику напишет чья это голова.
Вот и все.

************************************************************************************

Автор:::::::::::::::::Milez::::::::::::::::::::::::::::::
May 14 2003
Это система отдыха в моем модуле (модуль пока еще не вышел из стадии первичной разработки поэтому о нем пока ни гу-гу).
Навеяно системой отдыха из Axistown'а но полностью писано мной

kel_rest
Neverwinter Script Source
void DestroyFirecamp(object oCampFire=OBJECT_SELF)
{
// Создаем обгорелое пятно на месте костра и гасим костер
   object oLandMark=CreateObject(OBJECT_TYPE_PLACEABLE,"plc_weathmark",GetLocation(oCampFire));
// Пятно исчезает через 120 секунд (2 реальных минуты, 1 игровой час). Менять по вкусу
   AssignCommand(oLandMark,DelayCommand(120.0,DestroyObject(oLandMark)));
   DestroyObject(oCampFire);
}

void ApplyRestEffect(object oTarget=OBJECT_SELF)
{
// Создаем эффекты сна. Функцию править по вкусу.
   effect eSleep=EffectBlindness();

   if (GetRacialType(oTarget)==RACIAL_TYPE_ELF)
   {
// Эльфы не спят, а впадают в транс (см. описание эльфов в D&D 3ed)
       if (GetGender(oTarget)==GENDER_FEMALE)
           FloatingTextStringOnCreature("Я вошла в транс",oTarget,FALSE);
       else
           FloatingTextStringOnCreature("Я вошел в транс",oTarget,FALSE);
   } else

       eSleep=EffectLinkEffects(eSleep,EffectVisualEffect(VFX_IMP_SLEEP));
// Эффект сна на 30 секунд. Менять по желанию.
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSleep,oTarget,30.0);
}

object FindFood(object oTarget=OBJECT_SELF)
{
   object oEnum=GetFirstItemInInventory(oTarget);
   while (GetIsObjectValid(oEnum) && (GetTag(oEnum)!="KEL_FOOD"))
       oEnum=GetNextItemInInventory(oTarget);
   return oEnum;
}


ku_makecamp (вешать на OnUsed дров)
Neverwinter Script Source
#include "kel_rest"

void main()
{
   object oPC=GetLastUsedBy();
   if (!GetIsPC(oPC)) return;
   object oTorch=GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
   if (GetIsObjectValid(oTorch) &&
          (GetTag(oTorch) == "NW_IT_TORCH001") &&
// Флаг, висящий на области (например в таверне) и позволяющий отдыхать бесплатно
          (GetLocalInt(GetArea(oPC),"NoCampArea") != TRUE)) {
       object oFire=CreateObject(OBJECT_TYPE_PLACEABLE,"ku_campfire",GetLocation(OBJECT_SELF));
       DestroyObject(OBJECT_SELF);
// Огонь гаснет через 900 секунд (15 реальных минут или 7,5 игровых часов)
// Менять по желаю
       AssignCommand(oFire,DelayCommand(900.0,DestroyFirecamp(oFire)));
   } else {
       CreateItemOnObject("kel_wood",oPC);
       DestroyObject(OBJECT_SELF);
   }
}


kua_dropwood (вешать OnUnAquiredItem модуля)
Neverwinter Script Source
void main()
{
   object oPC=GetModuleItemLostBy();
   if (!GetIsPC(oPC)) return;
   object oItem=GetModuleItemLost();
   if (!GetIsObjectValid(oItem)) return;
   string sResRef=GetTag(oItem);
   if (sResRef=="KEL_WOOD")
   {
// Пропатчено by Milez on 14/05/2003, по намекам некоего Guest
       if (GetIsObjectValid(GetAreaFromLocation(GetLocation(oItem)))) {
           CreateObject(OBJECT_TYPE_PLACEABLE,"ku_woodpile",GetLocation(oItem));
           DestroyObject(oItem);
       }
   }
}


kr_resteffect (вешать на OnRested модуля)
Neverwinter Script Source
#include "kel_rest"
void main()
{
   object oPC=GetLastPCRested();
   if (GetCurrentAction(oPC)!=ACTION_REST) return;
   int iFreeRest=GetLocalInt(GetArea(oPC),"FreeRestArea");
   if (iFreeRest) ApplyRestEffect(oPC);
   else {
       object oCampFire=GetNearestObjectByTag("ku_campfire",oPC);
// нельзя отдыхать дальше 3 метров от костра (расстояние менять по вкусу)
       if (GetIsObjectValid(oCampFire) && (GetDistanceBetween(oPC,oCampFire)<=3.0)) {
           object oFood=FindFood(oPC);
           if (GetIsObjectValid(oFood)) {
               DestroyObject(oFood);
               ApplyRestEffect(oPC);
           } else {
               FloatingTextStringOnCreature("Мне надо перекусить",oPC,FALSE);
               AssignCommand(oPC,ClearAllActions());
           }
       } else {
           FloatingTextStringOnCreature("Я не могу отдыхать далеко от костра",oPC,FALSE);
           AssignCommand(oPC,ClearAllActions());
       }
   }
}


khb_cfire_sfx (на OnHeartbeat костра, исключительно для красоты, можно не использовать в целях повышения скорости работы кода)
Neverwinter Script Source
void main()
{
   PlaySound("al_cv_firecamp1");
}



Используемые "синьки":
KEL_WOOD - дрова как айтем в инвентаре
ku_woodpile - горка дров как плэйсабл айтем на земле
ku_campfire - сам костер
KEL_FOOD - еда

************************************************************************************


Автор:::::::::::::::::Milez::::::::::::::::::::::::::::::
May 29 2003
"Приведем НВН в соответствие с АДиД". На повестке дня скрипт для ветра. Ниже базовый инклуд. Основная функция - ApplyWindEffect.
Параметры:
int iWindForce - сила ветра: 0 - Light wind; 1 - Moderate wind; 2 - Strong wind; 3 - Severe wind; 4 - Windstorm; 5 - Hurricane force wind; 6 - Tornado.
Neverwinter Script Source
float fWindDirection
- направление ветра, угол.
Neverwinter Script Source
object oTarget
- на кого "подуть"
Рекомендуется использовать в Heartbeat'е, перебирая всех игроков, так как по АДиД эти проверки должны проходить каждый раунд. Реально в хартбите использовать можно например так:
Neverwinter Script Source
void main()
{
   object oPC=GetFirstPC();
   while (GetIsObjectValid(oPC)) {
       ApplyWindEffect(4,45.0,oPC);
       oPC=GetNextPC();
   }
}

Работает в соответствии с соответствующим разделом DMG.
Ниже собственно сам инклуд.
Neverwinter Script Source
vector BlowAwayTo(vector vOrigin,float fAngle,float fRange)
{
   float dx=fRange*cos(fAngle);
   float dy=fRange*sin(fAngle);
   return Vector(vOrigin.x+dx,vOrigin.y+dy,vOrigin.z);
}

// "Сдувание". Сбивание с ног + отбрасывание на 1d4*10 футов с 1d4 дамаджа на каждые 10 футов.
void ApplyBlowAwayEffect(float fWindDirection,object oTarget=OBJECT_SELF)
{
   int iRange=d4();
   int iDam=d4(iRange);
   iRange *= 10;
   float fRange=FeetToMeters(IntToFloat(iRange));
   vector vNewPos=BlowAwayTo(GetPosition(oTarget),fWindDirection,fRange);
   AssignCommand(oTarget,ClearAllActions(TRUE));
   AssignCommand(oTarget,JumpToLocation(Location(GetArea(oTarget),vNewPos,GetFacin
g(oTarget))));
   AssignCommand(oTarget,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectKnockdown(),oTarget,6.0));
   ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDamage(iDam),oTarget);
   PrintVector(vNewPos,TRUE);
}

void ApplyWindEffect(int iWindForce,float fWindDirection,object oTarget=OBJECT_SELF)
{
if (iWindForce<1) return;
object oTorch=GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oTarget);

if (GetBaseItemType(oTorch)==BASE_ITEM_TORCH) {
   if (iWindForce==1) { // Moderate wind имеет 50% шанс погасить незащищенный огонь (факел)
       if (d2()==1) ActionUnequipItem(oTorch);
       return;
   } else { ActionUnequipItem(oTorch); } // Stronger winds extinguish fire at 100%
} else if (iWindForce==1) return; // If there's no lit torch moderate wind doesn't do any effect

int iCreatureSize=GetCreatureSize(oTarget);
// Так как мы будем накладывать пенальти на удаленные атаки, мы вызнаем, держит ли чар метательное/стреляющее оружие
int iWpnType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oTarget));
int iFeet;
vector vVec;
int bRangeWpn=FALSE;

if (iWpnType!=BASE_ITEM_INVALID) {
   bRangeWpn=(iWpnType==BASE_ITEM_DART)||
             (iWpnType==BASE_ITEM_HEAVYCROSSBOW)||
             (iWpnType==BASE_ITEM_LIGHTCROSSBOW)||
             (iWpnType==BASE_ITEM_LONGBOW)||
             (iWpnType==BASE_ITEM_SHORTBOW)||
             (iWpnType==BASE_ITEM_SHURIKEN)||
             (iWpnType==BASE_ITEM_SLING)||
             (iWpnType==BASE_ITEM_THROWINGAXE);
}

switch (iWindForce) {
case 2: // Strong wind
   if (bRangeWpn)
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectAttackDecrease(2),oTarget,6.0);
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectSkillDecrease(SKILL_LISTEN,2),oTarget,6.0);

   if (iCreatureSize==1) // оч. маленькое существо (Tiny)
       if (FortitudeSave(oTarget,10)==0)
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectKnockdown(),oTarget,3.0);
break;
case 3: // Severe wind
   if (bRangeWpn)
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectAttackDecrease(4),oTarget,6.0);
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectSkillDecrease(SKILL_LISTEN,4),oTarget,6.0);

   if (iCreatureSize<4)
   if (FortitudeSave(oTarget,15)==0)
   switch (iCreatureSize) {
   case 3: // Среднее существо (Medium).
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectEntangle(),oTarget,6.0);
   break;
   case 2: // Маленькое сущ-во (Small)
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectKnockdown(),oTarget,6.0);
   break;
   case 1:
       ApplyBlowAwayEffect(fWindDirection,oTarget);
   }
break;
case 4: // Windstorm
   if (bRangeWpn)
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectAttackDecrease(50),oTarget,6.0);
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectSkillDecrease(SKILL_LISTEN,8),oTarget,6.0);

   if (iCreatureSize<6)
   if (FortitudeSave(oTarget,18)==0)
   switch (iCreatureSize) {
   case 3:
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectKnockdown(),oTarget,6.0);
   break;
   case 4: // Большое (Large)
   case 5: // или огромное сущ-во (Huge)
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectEntangle(),oTarget,6.0);
   break;
   case 2:
   case 1:
       ApplyBlowAwayEffect(fWindDirection,oTarget);
   break;
   }
break;
case 5: // Hurricane force wind
   if (bRangeWpn)
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectAttackDecrease(50),oTarget,6.0);
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectSkillDecrease(SKILL_LISTEN,50),oTarget,6.0);

   if (iCreatureSize<6)
   if (FortitudeSave(oTarget,20)==0)
   switch (iCreatureSize) {
   case 3:
   case 2:
   case 1:
       ApplyBlowAwayEffect(fWindDirection,oTarget);
   break;
   case 4:
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectKnockdown(),oTarget,6.0);
   break;
   case 5:
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectEntangle(),oTarget,6.0);
   break;
   }
break;
case 6: // Tornado (WOW!)
   if (bRangeWpn)
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectAttackDecrease(50),oTarget,6.0);
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectSkillDecrease(SKILL_LISTEN,50),oTarget,6.0);
   if ((iCreatureSize==5) && (FortitudeSave(oTarget,30)==0))
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectKnockdown(),oTarget,6.0);
   else { // Торнадо особый случай. Он не сбивает с ног, а засасывает на 1d10 раундов, давая 6d6 дамаджа за раунд
       iFeet=GetLocalInt(oTarget,"IsInTornado");
       if (iFeet<1)
           if (FortitudeSave(oTarget,30)==0) iFeet=d10();
       if (iFeet>0) {
           iFeet-=1;
// По АДиД жерло торнадо движется с линейной скоростью 30 миль в час.
// В пересчете на реальные для НВН значения получаются астрономические цифры, кроме того летание
// в НВН нормально не сделаешь, поэтому я предположил что торнадо каждый раунд кидает чара в случайное
// место в радиусе 10 метров от текущего местоположения. Садисты это значение могут увеличить
           vVec=GetPosition(oTarget);
           vVec.x+=Random(21)-10;
           vVec.y+=Random(21)-10;
           AssignCommand(oTarget,ClearAllActions(TRUE));
           AssignCommand(oTarget,JumpToLocation(Location(GetArea(oTarget),vVec,GetFacing(o
Target))));
           AssignCommand(oTarget,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
               EffectKnockdown(),oTarget,6.0));
           ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDamage(d6(6)),oTarget);
       }
       SetLocalInt(oTarget,"IsInTornado",iFeet);
   }
break;
}
}

Кроме того сила ветра 3 (Severe wind) соответствует спеллу Gust of Wind, так что кому не в терпеж ждать этого спелла в SoU можете заюзать этот скрипт для создание этого спелла вручную
Смотреть spells.2da, там прописаны данные по спеллам, включая скрипты, эти спеллы реализующие.

************************************************************************************


Автор:::::::::::::::::Milez::::::::::::::::::::::::::::::
Jun 8 2003
Как и обещал, скрипт для осадков. Прошу прощения за такую задержку: только начались экзамены, просто не было времени. Писано как всегда мной, теперь уже по готовому шаблону (см. ветер, кстати, этот шаблон очень удобно использовать во многих случаях, может кому пригодиться). Ниже только функция, использовать можно так же, как скрипт на ветер.
Все сделано по DMG AD&D 3ed.
Neverwinter Script Source
int PRECIPITATION_RAIN=1;
int PRECIPITATION_SNOW=2;
int PRECIPITATION_SLEET=3;
int PRECIPITATION_HAIL=4;

void ApplyPrecipitationEffect(int iPrecType,object oTarget=OBJECT_SELF)
{
object oTorch=GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oTarget);
if (GetBaseItemType(oTorch)==BASE_ITEM_TORCH) ActionUnequipItem(oTorch);
int iWpnType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oTarget));
int bRangeWpn=FALSE;

if (iWpnType!=BASE_ITEM_INVALID) {
   bRangeWpn=(iWpnType==BASE_ITEM_DART)||
             (iWpnType==BASE_ITEM_HEAVYCROSSBOW)||
             (iWpnType==BASE_ITEM_LIGHTCROSSBOW)||
             (iWpnType==BASE_ITEM_LONGBOW)||
             (iWpnType==BASE_ITEM_SHORTBOW)||
             (iWpnType==BASE_ITEM_SHURIKEN)||
             (iWpnType==BASE_ITEM_SLING)||
             (iWpnType==BASE_ITEM_THROWINGAXE);
}

switch(iPrecType) {
case 3: //PRECIPITATION_SLEET - морось
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectMovementSpeedDecrease(50),oTarget,7.0);
case 1: //PRECIPITATION_RAIN - дождь
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectSkillDecrease(SKILL_SPOT,4),oTarget,7.0);

   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectSkillDecrease(SKILL_SEARCH,4),oTarget,7.0);

   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectSkillDecrease(SKILL_LISTEN,4),oTarget,7.0);

   if (bRangeWpn)
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectAttackDecrease(4),oTarget,7.0);
break;
case 2: //PRECIPITATION_SNOW - снег
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectMovementSpeedDecrease(50),oTarget,7.0);

   if (bRangeWpn)
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
       EffectAttackDecrease(4),oTarget,7.0);

   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectSkillDecrease(SKILL_SPOT,4),oTarget,7.0);

   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectSkillDecrease(SKILL_SEARCH,4),oTarget,7.0);
break;
case 4: //PRECIPITATION_HAIL - град
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectMovementSpeedDecrease(50),oTarget,7.0);

   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
   EffectSkillDecrease(SKILL_LISTEN,4),oTarget,7.0);

   if (d100()<=5) {
       ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDamage(1,DAMAGE_TYPE_BLUDGEONIN
G),oTarget);
       SendMessageToPC(oTarget,"Здороваz градина внезапно стукнула тебz по голове.");
   }
break;
}
}

Это предпоследний скрипт из цикла скриптов, реализующих окружающую среду по АДиД. Последним будет скрипт для штормов, но там уже в принципе все просто: это в основном смесь осадков и ветра.

************************************************************************************

Автор: Lex Mar 18 2005, 23:50

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ ДЯДЮШКИ MILEZ'А"

Автор:::::::::::::::::Milez::::::::::::::::::::::::::::::
Jun 29 2003
Еще один спавн. Фишка в том, что респавн существ основан на вероятностом законе, а не на времени, через которое спавн должен происходить. Может кому пригодиться.
Основной скрипт на Heartbeat плейсабла, играющего роль спавна:

Neverwinter Script Source
void main()
{
   object oSelf=OBJECT_SELF;
   object oPC=GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC);
   if (!GetIsObjectValid(oPC)) return;
   float fActDist=IntToFloat(GetMaxHitPoints()); // расстоЯние, на к-ом должен поЯвитьсЯ игрок от спавна, чтобы тот заработал
   if (GetDistanceBetween(oPC,oSelf)>fActDist) return;
   int iSpawnDist=GetReflexSavingThrow(oSelf); // макс. расст-ие, на к-ом будут поЯвлЯться сущ-ва
   int iSpawnChance=GetWillSavingThrow(oSelf); // вероЯтность поЯвлениЯ существа, %
   int iMaxSpawn=GetFortitudeSavingThrow(oSelf); // макс. кол-во сущ-в, поддерживаемых спавном
   int iSpawned=GetLocalInt(oSelf,"SpawnedCreatures");
   object oMonster;
   string sMonster;
   float fSpawnAngle;
   float fSpawnDist;
   vector vSpawnPlace;
   location lSpawnLoc;
   if (iSpawned<iMaxSpawn) {
       if (d100()<=iSpawnChance) {
           iSpawned++;
           fSpawnDist=IntToFloat(Random(iSpawnDist)+1);
           fSpawnAngle=IntToFloat(Random(360));
           vSpawnPlace=GetPosition(oSelf);
           vSpawnPlace.x+=fSpawnDist*cos(fSpawnAngle);
           vSpawnPlace.y+=fSpawnDist*sin(fSpawnAngle);
           lSpawnLoc=Location(GetArea(oSelf),vSpawnPlace,IntToFloat(Random(360)));
// Здесь вставьте подобным образом список сущ-в, которые будут спавнитьсЯ
           switch (Random(2)) {
           case 0:
               sMonster="nw_skeleton";
           break;
           case 1:
               sMonster="nw_zombie01";
           break;
           }
           oMonster=CreateObject(OBJECT_TYPE_CREATURE,sMonster,lSpawnLoc);
           SetLocalObject(oMonster,"MySpawner",oSelf);
           SetLocalObject(oSelf,"LastMonsterSpawned",oMonster);
       }
   }
   SetLocalInt(oSelf,"SpawnedCreatures",iSpawned);
}


В OnUserDefined стандартного скрипта nw_c2_defaultd добавим обработчик на событие 1007 (смерть), для регистрации смерти существа на мастер-спавне:
Neverwinter Script Source
...
object oSpawnPoint;
switch(iEvent) {
...
case 1007:
       oSpawnPoint=GetLocalObject(OBJECT_SELF,"MySpawner");
       if (GetIsObjectValid(oSpawnPoint)) {
           SetLocalInt(oSpawnPoint,"SpawnedCreatures",GetLocalInt(oSpawnPoint,"SpawnedCreatures")-1);
       }
   break;
...
}


Модификации возможны самые разные. Можно добавить флаг на макс. спавн, чтобы спавн работал только 1 раз, можно внести ограничения по времени. Короче, делайте что хотите
Настраивается спавн до обидног просто:
с св-вах плейсабла-спавна (я использовал невидимый объект) ставите:
Max Hit Points - расстояние, на котором должен появиться игрок, чтобы спавн заработал.
Reflex Save - макс. расст-ие от спавна, на котором будут создаваться сущ-ва.
Fortitude Save - макс. кол-во существ, к-ое будет поддерживаться спавном.
Will Save - вероятность того, что существо будет создано при каждом данном вызове скрипта, в процентах (100 - существа будут спавниться всегда, 0 - спавн отключен. 100 используйте очень осторожно: спавн будет постоянно поддерживать популяцию монстров, игрок просто может не успеть всех прибить!)

************************************************************************************

Автор:::::::::::::::::Milez::::::::::::::::::::::::::::::
Feb 24 2004
Ээээх, давно я тут не писал. Времени скриптовать не было. И вот жизнь подладилась, вышла ХотУ и... Сбылась мечта идиота! Я наконец-то смог сделать нормального призрака!
Вот функция:
Neverwinter Script Source
void SetGhostState(object oPC)
{
   // polymorph, so we can't equip/use things, cast spells etc.
   effect eGhost = EffectPolymorph(POLYMORPH_TYPE_SPECTRE,TRUE);
   // this way we can pass thru other mobs
   eGhost = EffectLinkEffects(EffectCutsceneGhost(),eGhost);
   // ghosts are invisible, you know
   eGhost = EffectLinkEffects(EffectInvisibility(INVISIBILITY_TYPE_DARKNESS),eGhost);
   // ghosts can't attack as well
   eGhost = EffectLinkEffects(EffectDazed(),eGhost);
   // others can't detect ghosts, no way!
   eGhost = EffectLinkEffects(EffectEthereal(),eGhost);
   // these effects can't be dispelled, as well as they can't be removed by rest
   eGhost = SupernaturalEffect(eGhost);

   ApplyEffectToObject(DURATION_TYPE_PERMANENT,eGhost,oPC);
   SetPlotFlag(oPC,TRUE); // ghosts are invincible
   SetLocalInt(oPC,"IAmAGhost",1);
}

Ставим ее на OnDeath, а скрипт ресурректа правим так, чтобы, будучи скастованным на чара, проверял соотв-ую лок. переменную и, если надо, "оживлял" чара, скидывая эффкты.

КОНЕЦ ЦИКЛА "СКРИПТЫ ДЯДЮШКИ MILEZ'А" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 01:06

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ ДЯДЮШКИ _kaa_"

Автор:::::::::::::::::_kaa_::::::::::::::::::::::::::::::
Feb 24 2004
По поводу защиты чаров от хака. Вот простая реализация, привязывает конкретный аккаунт и имя персонажа к СД-КЕЮ. Есть возможность ДМ-ом отключить защиту на некоторое время (например сменили СД-КЕЙ и не могут попасть на шард)
Все ключи хранятся в базе данных на сервере.

Neverwinter Script Source
void main()
{
object oPC = GetEnteringObject();
string sCDKEY = GetPCPublicCDKey(oPC);
string sName = GetName(oPC);
string sPCName = GetPCPlayerName(oPC);
//Зачем нужны скобки (или вообще любые символы) - думайте сами.
string sID = "("+sPCName+")"+sName;
int SecurityDisabled = GetLocalInt(GetModule(),"SecurityDisable");
//if (GetIsDM(oPC)) return;
WriteTimestampedLogEntry("Security: "+sName+" :["+sPCName+"]: with key ="+sCDKEY);
string sReadID = GetCampaignString("Security",sID);
// ЕСЛИ НОВЫЙ ИЛИ ПРОВЕРКА ОТКЛЮЧЕНА - ПЕРЕЗАПИСЫВАТЬ КЛЮЧИ
if (sReadID =="" || SecurityDisabled)
   SetCampaignString("Security",sID,sCDKEY);
if (sReadID != sCDKEY && sReadID !="" && !SecurityDisabled)
   {
    BootPC(oPC);
    SendMessageToAllDMs("Security: Error! "+sName+" :["+sPCName+"]: with key ="+sCDKEY+ " != "+sReadID);
    WriteTimestampedLogEntry("Security: Error! "+sName+" :["+sPCName+"]: with key ="+sCDKEY+ " != "+sReadID);
   }
else
   WriteTimestampedLogEntry("Security: Check ok.");
}

Чтобы отключить на время защиту - из ДМ-клиента в консоли набираете:
dm_setmodulevarint SecurityDisable 1
включить обратно :
dm_setmodulevarint SecurityDisable 0

************************************************************************************

Автор:::::::::::::::::_kaa_::::::::::::::::::::::::::::::
Oct 3 2003
Скрипт для магазинов. Проверяет наличие такого товара в магазине, если уже есть - то после продажи удаляет. Нужен на шардах, где мазагины со временем забиваются ловушками, камнями и т.п. - при наличии более 10 страниц ассортимента в магазине начинаются заметные торможения сервера, проверенно.
Только одно требования к самим магазинам. В теге должно содержаться слово "_SHOP" (//Иначе нельзя узнать, магазин это или нет). - Вру ведь и никто не видит wacko.gif
Есть функция узнать тип объекта GetObjectType();
Вызывать из события модуля OnUnAcquireItem
Проще всего добавить в уже существующий обработчки строку:
ExecuteScript("at_check_dupe",OBJECT_SELF);

Сам скрипт:
at_check_dupe
Neverwinter Script Source
void main()
{
object oLostItem = GetModuleItemLost();
object oLostBy = GetModuleItemLostBy();
object oNewPosessor = GetItemPossessor(oLostItem);

if (FindSubString(GetStringUpperCase(GetTag(oNewPosessor)),"_SHOP"))
   {
    int n = 0;
    object oItem = GetFirstItemInInventory(oNewPosessor);
    while (GetIsObjectValid(oItem))
        {
          if (GetTag(oLostItem) == GetTag(oItem)) n++;
          if (n>1)
               {
                 DestroyObject(oLostItem);
                 break;
               }
          oItem = GetNextItemInInventory(oNewPosessor);
        }
   }
}


************************************************************************************

Автор:::::::::::::::::_kaa_::::::::::::::::::::::::::::::
Jan 30 2004
Из нового.
Реализация кольца духа - при надевании игрок становится полупрозрачным и может проходить сквозь других игроков. При снятии - эффект пропадает.
При желании можно добавить и неузвимость (не стал делать, ибо нефиг).
Для эффекта рекомендую добавить DayToNight() при надевании и наоборот.
на событие модуля onPlayerEquipItem()
Neverwinter Script Source
void main()
{
object oPC = GetPCItemLastEquippedBy();
object oItem = GetPCItemLastEquipped();
if (GetTag(oItem) == "mg_it_ringghost")
   {
   effect E = EffectCutsceneGhost();
   E = EffectLinkEffects(EffectEthereal(),E);
   ApplyEffectToObject(DURATION_TYPE_PERMANENT,E,oPC);
   }
}
[/nss

на onPlayerUnEquipItem()
[nss] 
void FindAndRemoveGhostEffect(object O)
{
effect e = GetFirstEffect(O);
while (GetIsEffectValid(e))
   {
   if (GetEffectType(e) == EFFECT_TYPE_CUTSCENEGHOST)
       RemoveEffect(O,e);
   if (GetEffectType(e) == EFFECT_TYPE_ETHEREAL)
       RemoveEffect(O,e);
   e = GetNextEffect(O);
   }
void main()
{
object oPC = GetPCItemLastUnequippedBy();
object oItem = GetPCItemLastUnequipped();
// кольцо духа
if (GetTag(oItem) == "mg_it_ringghost")
   {
   FindAndRemoveGhostEffect(oPC);
   }

где mg_it_ringghost - тег кольца.
написанно вчера для Мидгарда.

************************************************************************************

Автор:::::::::::::::::_kaa_::::::::::::::::::::::::::::::
Mar 25 2004
Расцветка сообщений, выводимых SendMessageToPC()
Работает все примерно так: есть тег <cRGB> и парный ему </c>
RGB - это три символа, ascii код каждого - это значение соответствующей цветовой компоненты.
Посколько многие символы нельзя использовать в скиптах, я взял " " (пробел) (32) и букву "ю" (254) как минимум и максимум.
После использования тега раскраски - закрывайте тег в помощью s_end()
Мне было достаточно 4 цветов, вот самый простейший код:
Neverwinter Script Source
string s_green() 
{     
return "<c ю >"
}   
string s_blue()
{     
return "<c  ю>"
}   
string s_red() 
{     
return "<cю  >"
}   
string s_white() 
{     
return "<cююю>"

string s_end() 
{     
return "</c>"
}


Вроде можно и в диалогах через SetCustomToken

************************************************************************************

Автор:::::::::::::::::_kaa_::::::::::::::::::::::::::::::
Mar 26 204
Простейшая реализация двумерного массива (очень полезен при кэширование .2da таблиц).
Ограничение - размерность, поставил 0..999

Neverwinter Script Source
//Add string S to array O[X,Y]
void _arr_SetStringXY(object O, int X,int Y,string S,string Prefix="_arr");
//Get string S from array O[X,Y]
string _arr_GetStringXY(object O, int X,int Y,string Prefix="_arr");
string _arr_AddNull(int I)
{
   string result = "";
   if (I<10) result+="0";
   if (I<100) result+="0";
   result += IntToString(I);
   return result;
}

void _arr_SetStringXY(object O, int X,int Y,string S,string Prefix="_arr")
{
   SetLocalString(O,Prefix+_arr_AddNull(X)+_arr_AddNull(Y),S);
}

string _arr_GetStringXY(object O, int X,int Y,string Prefix="_arr")
{
   return GetLocalString(O,Prefix+_arr_AddNull(X)+_arr_AddNull(Y));
}


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

************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ ДЯДЮШКИ _kaa_" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 13:56

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ ДЯДЮШКИ DBCOLL'A"

автор::::::::::::DBColl::::::::::::::::::::
May 7 2003
скрипт на первое использование рычага отпирает и открывает дверь, на второе закрывает и захлопывает ее и тд.
На "OnUsed" рычага

Neverwinter Script Source
void main()
{
object oDoor=GetNearestObjectByTag("ТЭГ_ДВЕРИ");
if(GetIsOpen(oDoor)) // если она открыта
   {
    AssignCommand(OBJECT_SELF,ActionCloseDoor(oDoor));
    // захлопнуть дверь. действие привязанно к рычагу.
    SetLocked(oDoor,TRUE); // запереть дверь
    ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE);
    // рычаг переходит в другое положение
    }
else if(!GetIsOpen(oDoor)) //иначе, если дверь не открыта
    {
    SetLocked(oDoor,FALSE);// отпереть дверь
    AssignCommand(OBJECT_SELF,ActionOpenDoor(oDoor));
    // открыть дверь.
    ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE);
    // перевод рычага в другое положение
    }
}


************************************************************************************

Автор:::::::::::::::::DBColl::::::::::::::::::::::::::::::
May 8 2003
данный скрипт каждые 18 секунд убавляет хиты, если игрок более, чем на 15 футов от костра.
(эмуляция действия холода)
Neverwinter Script Source
void main()
{
object oPC = GetFirstPC();
object oFlame = GetObjectByTag("тэг пламени");
int nSpeedOfDec = 3
// 3 раунда (за 18 секунд здоровье уменьшиться на 1 единицу)
int nSpeed = GetLocalInt(oPC, "DecHealthSpeed");
// первый раз даже если такая переменная не заведена, значение будет == 0
if (nSpeed == nSpeedOfDec && GetDistanceBetween(oPC, oFlame) > 15.0)
  // проверяем сколько раундов прошло с последнего уменьшения Health
  // и расстояние до костра (15 метров)
  {
  effect eDamage = EffectDamage( 1, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_NORMAL);
  /// определяется кол-во повреждений и тип
  ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oPC);
  /// нанесение урона
  AssignCommand(oPC, ActionSpeakString("Блин, холодно однако..."));
  SetLocalInt(oPC, "DecHealthSpeed", 0);
  return;
  }
else if (GetDistanceBetween(oPC, oFlame) < 15.0
        && GetCurrentHitPoints(oPC) <= GetMaxHitPoints(oPC))
  /// если дистанция 15 метров или меньше, то лечить 2 хитпоинта за раунд
  {
  effect eHeal = EffectHeal(2);
  ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oPC);
  return;
  }
SetLocalInt(oPC, "DecHealthSpeed", nSpeed+1);
}


************************************************************************************

Автор:::::::::::::::::DBColl::::::::::::::::::::::::::::::
May 28 2003
Это скрипт командира охраны. Ему все солдаты (его фракции) отдают честь. ставится в UserDefined
Neverwinter Script Source
#include nw_i0_generic
void main()
{
int nEvent = GetUserDefinedEventNumber();
if (nEvent == 1002)
   {
   object oNPC = GetLastPerceived();
   if (GetFactionEqual(oNPC, OBJECT_SELF))
      {
      if (GetLastPerceptionSeen() && GetDistanceToObject(oNPC) < 6.0f &&
      GetLocalInt(oNPC, "GREATED") != 1)
          {
          SetLocalInt(oNPC, "GREATED", 1);
          AssignCommand(oNPC, ClearAllActions());
          AssignCommand(oNPC, ActionDoCommand(SetFacingPoint(GetPosition(OBJECT_SELF))));
          AssignCommand(oNPC, ActionSpeakString("ЗдравиЯ желаю!"));
          AssignCommand(oNPC, ActionPlayAnimation(ANIMATION_FIREFORGET_SALUTE, 0.5f, 1.0f));
          AssignCommand(oNPC, ActionDoCommand(WalkWayPoints()));
          DelayCommand(15.0f, SetLocalInt(oNPC, "GREATED", 0));
          }
      }
   return;
   }
}


************************************************************************************

Автор:::::::::::::::::DBColl::::::::::::::::::::::::::::::
Feb 20 2004
Я вот смотрю-смотрю, жду, но что-то так никто и не догадался, как просто можно сделать всплывающую строку на триггере... Вот мой вариант:
1. Создать триггер в палитре. В ОнЭнтер нужен всего один универсальный скрипт! Этот юзаем мы в Проклятии.
Neverwinter Script Source
//::///////////////////////////////////////////////
//:: Name
//:: Copyright © 2003 WRG!
//:://////////////////////////////////////////////
//:: Created By: DBColl
//:: Created On: 7.09.2003
//:://////////////////////////////////////////////
void main()
{
   object oPC = GetEnteringObject();
   if (!GetIsPC(oPC) || GetLocalInt(OBJECT_SELF, "triggered") > 0)
       return;
   string sStr = GetName(OBJECT_SELF);
   AssignCommand(oPC, SpeakString(sStr));
   if (GetLockKeyTag(OBJECT_SELF) == "")
       SetLocalInt(OBJECT_SELF, "triggered", 1);
}

2. Создаем этот триггер в модуле, заходим в его свойства и в поле Name пишем текст, который должен всплыть над игроком при наступании на него!!!
3. В KeyTag вносим что-то (любое число!) и получаем постоянно всплывающий текст над всеми PC, кто войдет на него.

************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ ДЯДЮШКИ DBCOLL'A" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"


Автор: Lex Mar 19 2005, 15:03

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ ДЯДЮШКИ LAZY RAMN'Ы"

автор::::::::::::Lazy Ramna::::::::::::::::::::
Oct 14 2003
LEX: ИСТОРИЧЕСКИЙ СКРИПТ LAZY. ОКТЯБРЬ 2003 ГОДА!! ВЕСЬ РУНЕТ ПОЛЬЗОВАЛСЯ ЭТОЙ ИДЕЕЙ ДО ВЫХОДА ПАТЧА DUMBO
Скрипт, позволяющий использовать букву "я" в скриптах
В константных строках буковка "я" запрещена, однако в переменных ее никто не запрещал. Посему создаем любой плэсейбл с тэгом ax_letter_ya и именем "я". Потом просто через ya() получаем нашу буковку, либо заменяем в строке все "йа" на "я". pardon.gif

Neverwinter Script Source
string ya(string sMessage = "йа")
   {
    string sYa = GetName(GetObjectByTag("ax_letter_ya"));
    string sResult = "";
    string sSub;
    int i = 0;
    while ((sSub = GetSubString(sMessage, i, 2)) != "")
           {
           if (sSub == "йа")
              {
              sResult += sYa;
              i += 2;
              }
           else
              {
              sResult += GetStringLeft(sSub, 1);
              i++;
              }
           }
    return sResult;
  }


Использование:
1) string sMessage = "Мо"+ya()+" сто"+ya()+"ть как стена";
2) string sMessage = ya("Мойа стойать как стена");
В обоих случаях в sMessage будет "Моя стоять как стена"

************************************************************************************

автор::::::::::::Lazy Ramna::::::::::::::::::::
Mar 15 2004
Не знаю, было или нет (я сюда не сильно заглядываю ), вот элементарнейший скрипт "автоперехода". Телепортирует наступившую на триггер кричу к объекту, тэг которого прописан в KeyTag. Вешается на OnEnter.
Neverwinter Script Source
void main()
{
object oPC = GetEnteringObject();
object oTarget = GetObjectByTag(GetTrapKeyTag(OBJECT_SELF));
if (GetIsObjectValid(oPC) && GetIsObjectValid(oTarget)) {
     AssignCommand(oPC, ClearAllActions());
     AssignCommand(oPC, JumpToObject(oTarget));
}
}

Я его ставлю после городских ворот, или ворот на мосту. Если PC не захочет "входить" в ворота, а решит пройтись чуть дальше к краю локации, то его насильно кинут куда надо.
Добавлено 18:57
Простенький инклюд. Позволяет получать кол-во лет/месяцев/дней/часов/минут/секунд, которое прошло с момента старта модуля. (в стиле UNIX_TIMESTAMP ) AX_LIB_START_YEAR - стартовый год.
Neverwinter Script Source
//© 2003 by Alexander Ponyatikh, aka Lazy Ranma

const int AX_LIB_START_YEAR = 0;

int GetCurrentYear()
{
   return GetCalendarYear() - AX_LIB_START_YEAR;
}

int GetCurrentMonth()
{
   return GetCurrentYear()*12 + GetCalendarMonth();
}

int GetCurrentDay()
{
   return (GetCurrentMonth() - 1)*28 + GetCalendarDay();
}

int GetCurrentHour()
{
   return (GetCurrentDay() - 1)*24 + GetTimeHour();
}

int GetCurrentMinute()
{
   return GetCurrentHour()*FloatToInt(HoursToSeconds(1))/60 + GetTimeMinute();
}

int GetCurrentSecond()
{
   return GetCurrentMinute()*60 + GetTimeSecond();
}


************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ ДЯДЮШКИ LAZY RAMN'Ы" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 16:06

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ ДЯДЮШКИ BAAL'A"

автор::::::::::::Baal::::::::::::::::::::
May 7 2003
данный скрипт забирает у игрока (или любого другого объекта) все вещи и дестроит их.

Neverwinter Script Source
void main()
{
  object oPC = GetFirstPC();
  /// выбирает игрока ( если хотите другой объект то GetObjectByTag("тэг объекта")
  object oInv = GetFirstItemInInventory(oPC);
    /// брать первый предмет из инвентаря игрока
  while(GetIsObjectValid(oInv)) /// пока в инвентаре есть предмет
      {
      DestroyObject(oInv); /// удаляет его
      oInv = GetNextItemInInventory(oPC);
      /// брать следующий предмет из инвентаря игрока
      }
    int i=0;
    while(i<14
      {
      DestroyObject(GetItemInSlot(i, oPC)); /// удаление вещей из слотов
      i++;
      }
}


************************************************************************************

автор::::::::::::Baal::::::::::::::::::::
Aug 18 2003
Вот конечный, работающий скрипт часов, для тех кому интересно. Спасибо ДБу за то, что помог с минутами.
Neverwinter Script Source
void main()
{
int iHour=GetTimeHour();
int iGameHourRealMinutes = 2; // число реальных минут равное 1 игровому часу (в настройках модулЯ)
float fMinute = IntToFloat(GetTimeMinute());
float fSecond = IntToFloat(GetTimeSecond());
float fGameMinute = fMinute*(60/iGameHourRealMinutes)+(fSecond/iGameHourRealMinutes);
int iMinute=FloatToInt(fGameMinute);
string sHour;
string sMinute;
if(iHour>0||iHour==21)
sHour=" Час ";
if(iHour>1||iHour>21)
sHour=" Часа ";
if(iHour>4&&iHour<21)
sHour=" часов ";
if(iHour==0)
sHour=" часов ";
sHour=IntToString(iHour)+sHour;

int iVR=StringToInt(GetStringRight(IntToString(iMinute),1));
if(iVR==0)
sMinute=IntToString(iMinute)+" минут.";
if(iVR>0)
sMinute=IntToString(iMinute)+" минута.";
if(iVR>1)
sMinute=IntToString(iMinute)+" минуты.";
if(iVR>4||(iMinute>10&&iMinute<21))
sMinute=IntToString(iMinute)+" минут.";
if(iMinute<10)
sMinute="0"+sMinute;

AssignCommand(GetFirstPC(),SpeakString("Московское времЯ: "+sHour+sMinute));
PlaySound("as_an_rooster1");//звук можно убрать :-)
}


************************************************************************************

автор::::::::::::Baal::::::::::::::::::::
Этот скрипт подсчитовает сколько у цели предметов с выбранным тегом. oInventory - чей инвентарь. sItemTag - Тег
Neverwinter Script Source
int ItemsAmount(string sItemTag, object oCreature = OBJECT_SELF)
{
int N=0;
object oItem = GetFirstItemInInventory(oCreature);
while (GetIsObjectValid(oItem))
  {
  if(GetTag(oItem) == sItemTag)
      {
      N = N + GetNumStackedItems(oItem);
      }
  oItem = GetNextItemInInventory(oCreature);
  }
return N;
}


************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ ДЯДЮШКИ BAAL'A" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 16:21

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ SMITH'A"

автор::::::::::::Smith::::::::::::::::::::
Sep 24 2003
Мне иногда приходилось сталкиваться с задачей создания случайной локации на заданном растоянии от какого-то объекта. Среди стандартных функций тулсета я такой вещи не нашел (хотя может быть плохо искал ), так, что пришлось написать самому. Может кому и пригодиться:

Neverwinter Script Source
location RandomLocation(object oTarget, float fRadius, int iLine = TRUE)
{
if(!iLine)
fRadius=IntToFloat(Random(FloatToInt(fRadius)));

float iXO=VectorMagnitude(GetPosition(oTarget))*cos(VectorToAngle(GetPosition(oTarget)
));
float iYO=VectorMagnitude(GetPosition(oTarget))*sin(VectorToAngle(GetPosition(oTarget)
));
float fRndomAngle=IntToFloat(Random(360));
location lNewLoc=Location(GetArea(oTarget),Vector(iXO+fRadius*cos(fRndomAngle),iYO+fRadiu
s*sin(fRndomAngle)),360.0);
return lNewLoc;
}

Скрипт создает случайную локацию на растоянии fRadius метров от объекта oTarget, причем, если задать iLine = FALSE, то локация может быть создана внутри круга на произвольном растоянии от объекта, не превышающем, однако, fRadius.

************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ SMITH'A" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 16:22

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ SELLARY"

автор::::::::::::sellary::::::::::::::::::::
Oct 20 2003
Функция определяет, можно ли надеть указанный армор.
в функцию передаем:
oArmor - объект армора,
oCreature - объект создания, на которое этот армор пытаемся одеть
возвращает TRUE, если одеть можно, FALSE - в обратном случае.
Проверка идет без учета класса создания (возможно, в дальнейшем модифицирую "по просьбам радиослушателей").
Отдельное спасибо Lazy Ranma за идею и spurlos - за мотивацию, DBColl за подсказку с уровнем.

Neverwinter Script Source
int GetIsValidArmor(object oArmor, object oCreature)
{
       // считаем базовую цену армора
       int nPrice = GetGoldPieceValue(oArmor);

       // определяем уровень создания
       int nClass = GetHitDice(oCreature);

       // определяем, может ли создание класса nClass
       // одевать броню стоимостью nPrice
       // (используется таблица #13 из приложения;
       // считаем, что создание более, чем 20 уровня
       // может одеть любой армор)
       int bResult = TRUE;
       switch (nClass) {
               case 1: bResult = (nPrice<=1000);
                       break;
               case 2: bResult = (nPrice<=1500);
                       break;
               case 3: bResult = (nPrice<=2500);
                       break;
               case 4: bResult = (nPrice<=3500);
                       break;
               case 5: bResult = (nPrice<=5000);
                       break;
               case 6: bResult = (nPrice<=6500);
                       break;
               case 7: bResult = (nPrice<=9000);
                       break;
               case 8: bResult = (nPrice<=12000);
                       break;
               case 9: bResult = (nPrice<=15000);
                       break;
               case 10: bResult = (nPrice<=19500);
                       break;
               case 11: bResult = (nPrice<=25000);
                       break;
               case 12: bResult = (nPrice<=30000);
                       break;
               case 13: bResult = (nPrice<=35000);
                       break;
               case 14: bResult = (nPrice<=40000);
                       break;
               case 15: bResult = (nPrice<=50000);
                       break;
               case 16: bResult = (nPrice<=65000);
                       break;
               case 17: bResult = (nPrice<=75000);
                       break;
               case 18: bResult = (nPrice<=90000);
                       break;
               case 19: bResult = (nPrice<=110000);
                       break;
               case 20: bResult = (nPrice<=130000);
                       break;
               default: bResult = (nClass>20);
                       break;
       };

       // возвращаем результат
       return bResult;
}


************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ SELLARY" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 16:23

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ GREEDO BEEFY"

автор::::::::::::Greedo Beefy::::::::::::::::::::
Jan 10 2004
Может кому то пригодится...
Если хотите что бы на вашем сервере, имеются ввиду шарды с PW, время и дата не сбрасывались с рестартом то можно сделать следующее.
Такой вот скриптик вешаем на любой предмет в модуле, лучше в защищенной локе, в слот OnHeartBeat

Neverwinter Script Source
void SaveCurTime (int minutes)
{
  int current = GetLocalInt(GetModule(), "cyclestill");
  if (current < ((minutes * 60) / 6))
  SetLocalInt(GetModule(), "cyclestill", current + 1);
  else
  {
        object oMod = GetModule();
        int iMonth = GetCalendarMonth();
        int iDay = GetCalendarDay();
        int iYear = GetCalendarYear();
        int iHour = GetTimeHour();
        SetCampaignInt("server_time", "CUR_YEAR", iYear, oMod);
        SetCampaignInt("server_time", "CUR_DAY", iDay, oMod);
        SetCampaignInt("server_time", "CUR_MONTH", iMonth, oMod);
        SetCampaignInt("server_time", "CUR_HOUR", iHour, oMod);
        SetLocalInt(GetModule(), "cyclestill", 0);
        WriteTimestampedLogEntry("Save Current Time completed");
  }
return;
}
void main ()
{
SaveCurTime(10);
}

Раз в десять минут (можно поставить любое значение) будет сохранятся текущая дата и время на сервере , игровое конечно же.
А на OnModuleLoad ставим это:
Neverwinter Script Source
void main()
{
object oMod = GetModule();
int iMonthNew = GetCampaignInt("server_time", "CUR_MONTH", oMod);
int iDayNew = GetCampaignInt("server_time", "CUR_DAY", oMod);
int iYearNew = GetCampaignInt("server_time", "CUR_YEAR", oMod);
int iHourNew = GetCampaignInt("server_time", "CUR_HOUR", oMod);
SetCalendar (iYearNew, iMonthNew, iDayNew);
SetTime (iHourNew, 0, 0, 0);
}

Написать скрипт вынудило желание ввести в банковскую систему проценты по вкладам и кредиты с процентами, которые зависят от времени. Ну как в жизни
С уважением Александр Дишке

************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ GREEDO BEEFY" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 16:24

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ DOCFEERT'A"

автор::::::::::::DocFeert::::::::::::::::::::
Feb 10 2004
Вот скрипт для уборщика:
Cтавится на OnHeartBeat уборщика
Как только уборщик увидит валяющийся на земле предмет, он его сразу поднимет.

Neverwinter Script Source
void main()
{
object oItem = GetFirstObjectInArea(GetArea(OBJECT_SELF));
while (GetIsObjectValid(oItem) == TRUE)
ClearAllActions();
{
if (GetObjectType(oItem) == OBJECT_TYPE_ITEM)
{
ActionPickUpItem(oItem);
}
oItem = GetNextObjectInArea(GetArea(OBJECT_SELF));
}
}


************************************************************************************

автор::::::::::::DocFeert::::::::::::::::::::
Feb 24 2004
Скрипт определяет кол-во жизней цели в процентах. oObject - чьи жизни, Возвращает кол-во жизней oObject.
Neverwinter Script Source
int Percent(object oObject)
{
int iCur = GetCurrentHitPoints(oObject);
int iMax = GetMaxHitPoints(oObject);
int iSt = iCur * 100;
int iPercent = iSt / iMax;
return iPercent;
}


************************************************************************************

автор::::::::::::DocFeert::::::::::::::::::::
Feb 24 2004
Скрипт на автооткрывание дверей. Делаем триггер и вешаем на него 2 скрипта. Это на OnEnter Триггера:
Neverwinter Script Source
void main()
{
object oDoor = GetFirstObjectInShape(SHAPE_SPHERE, 3.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_DOOR);
if (GetLocked(OBJECT_SELF) == FALSE)
{
ActionOpenDoor(oDoor);
}
}

А это на OnExit Триггера:
Neverwinter Script Source
void main()
{
if (GetLocked(OBJECT_SELF) == FALSE)
{
object oDoor = GetFirstObjectInShape(SHAPE_SPHERE, 3.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_DOOR);
ActionCloseDoor(oDoor);
}
}

Триггер просто растягивается под открываемой дверью.

************************************************************************************

автор::::::::::::DocFeert::::::::::::::::::::
Mar 10 2004
А этот код позволяет создать "случайную локацию", как например в БГ или Фаллоут, когда идешь, идешь... И натыкаешься на каких-нибудь рейдеров. Для этого в oArea записываем локацию, в которой будут создоваться обьекты, в Х записываем количество тайлов этой локации по оси Х, в Y записываем количество тайлов этой локации по оси Y, в sObjByResRef пишем тег по ресрефу обьекта, в iObjType пишем тип обьекта (OBJECT_TYPE_*) а в iMaxObjects пишем максимальное количество этих обьектов.
Neverwinter Script Source
void RandomObjectsAtRandomLocation(object oArea, int X, int Y, string sObjByResRef, int iObjType, int iMaxObjects)
{
int iMax = 0;
float fX = IntToFloat(Random(X * 10));
float fY = IntToFloat(Random(Y * 10));
float fZ = 0.0;
float fF = IntToFloat(Random(360));
location lLoc = Location(oArea, Vector(fX, fY, fZ), fF);
while (iMax != iMaxObjects)
{
iMax = iMax + 1;
float fX = IntToFloat(Random(X * 10));
float fY = IntToFloat(Random(Y * 10));
float fZ = 0.0;
float fF = IntToFloat(Random(360));
location lLoc = Location(oArea, Vector(fX, fY, fZ), fF);
if (d2(1) == 2)
{
CreateObject(iObjType, sObjByResRef, lLoc, FALSE);
}
}
}


************************************************************************************

автор::::::::::::DocFeert::::::::::::::::::::
Mar 10 2004
А этот скрипт для переноса всех обьектов (крич, плейсов, итемов) из одной локации в другую. В oAreaFrom записываем локацию ИЗ которой переносим обьекты, в oAreaTo пишим ту локацию В которую переносим обьекты, если iDestroy = TRUE, все обьекты в локации oAreaFrom уничтожаются. Если в локации игрок, то он тоже переностится.
Neverwinter Script Source
void MoveArea(object oAreaFrom, object oAreaTo, int iDestroy=TRUE)
{
object oObject = GetFirstObjectInArea(oAreaFrom);
while (GetIsObjectValid(oObject) == TRUE)
{
location lLoc = Location(oAreaTo, GetPosition(oObject), GetFacing(oObject));
if (GetObjectType(oObject) == OBJECT_TYPE_ITEM)
{
CopyObject(oObject, lLoc, OBJECT_INVALID, GetTag(oObject));
if (iDestroy == TRUE)
{
DestroyObject(oObject);
}
}
if ((GetObjectType(oObject) == OBJECT_TYPE_PLACEABLE))
{
string sTag = GetResRef(oObject);
CreateObject(OBJECT_TYPE_PLACEABLE, sTag, lLoc);
if (iDestroy == TRUE)
{
DestroyObject(oObject);
}
}
if (GetObjectType(oObject) == OBJECT_TYPE_CREATURE)
{
AssignCommand(oObject, JumpToLocation(lLoc));
}
oObject = GetNextObjectInArea(oAreaFrom);
}
}


************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ DOCFEERT'A" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 16:26

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ MALKOR'A"

автор::::::::::::MalkoR::::::::::::::::::::
Sep 13 2003
Идея скрипта такая. Стоит обелиск, вокруг стоят 4 шарика силы. В обелиске по порядку стоят 10 невидимых объекта, мелких. Шарики накладывают на onHeartbeat эффект луча в рэндом из этих 10 невидимых объекта. Получаеться эффект питания обелиска энергией этими шариками.
скрипт ставиться в onHeartbeat шариков

Neverwinter Script Source
void main()
{
object wp_k4 = GetObjectByTag("TWp_KEEPER4"); //WayPoint стояший на месте шарика, это на тот случай, если шарик атакуя кого то отойдет.
AssignCommand(OBJECT_SELF, ActionJumpToObject(wp_k4)); //перемешаеться на свое место
object os = OBJECT_SELF;
effect eff = EffectBeam(VFX_BEAM_LIGHTNING,os,BODY_NODE_CHEST,FALSE); //какой эффект накладывать на обелиск (тут была идея сделать ещё один скрипт, чтоб луч был рэндом, но с первого разане вышло, продолжать не стал из- за своей запарки  )

object c1 = GetObjectByTag("TP_CORPOSE_001"); //определяет невидимый объект в обелиске
object c2 = GetObjectByTag("TP_CORPOSE_002");
object c3 = GetObjectByTag("TP_CORPOSE_003");
object c4 = GetObjectByTag("TP_CORPOSE_004");
object c5 = GetObjectByTag("TP_CORPOSE_005");
object c6 = GetObjectByTag("TP_CORPOSE_006");
object c7 = GetObjectByTag("TP_CORPOSE_007");
object c8 = GetObjectByTag("TP_CORPOSE_008");
object c9 = GetObjectByTag("TP_CORPOSE_009");
object c10 = GetObjectByTag("TP_CORPOSE_010");

int a = d10();

if (a == 1)
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eff,c1,6.0f);
return;
}
if (a == 2)
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eff,c2,6.0f);
return;
}
if (a == 3)
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eff,c3,6.0f);
return;
}
///. . . . . . (а == 4, а ==5 и т.д. до 9) . . . . . . .

if (a == 10)
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eff,c10,6.0f);
return;
}
}


************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ MALKOR'A" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 16:28

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ ДЯДЮШКИ VALLEO"

автор::::::::::::Valleo::::::::::::::::::::
Mar 19 2004
Маленький скриптик для реализации болота:

Neverwinter Script Source
void StartBog()
{
object oBog = OBJECT_SELF;
object oArea = GetArea(oBog);
location lLocation = GetLocation(oBog);
location lLoc;
location lLocat;
object oObject = GetFirstObjectInShape(SHAPE_SPHERE,100.0,lLocation,FALSE,OBJECT_TYPE_CREATURE);
while(GetIsObjectValid(oObject))
{
lLoc = GetLocation(oObject);
lLocat = GetLocalLocation(oObject,"BOGLOC");
if(GetIsObjectValid(GetAreaFromLocation(lLocat)))
  {
  float fDist = GetDistanceBetweenLocations(lLoc,lLocat);
  if(fDist < 5.0)
   {
   effect eSlow = EffectMovementSpeedDecrease(75);
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSlow,oObject,70.0);
   FloatingTextStringOnCreature("Вас засасывает в бололто...",oObject,FALSE);
   }
  }
SetLocalLocation(oObject,"BOGLOC",lLoc);
oObject = GetNextObjectInShape(SHAPE_SPHERE,100.0,lLocation,FALSE,OBJECT_TYPE_CREATURE);
}
}
void main()
{
object oBog = OBJECT_SELF;
int iTimer = GetLocalInt(oBog,"TIMER");
if(iTimer <= 9)
{
iTimer = iTimer + 1;
SetLocalInt(oBog,"TIMER",iTimer);
return;
}
SetLocalInt(oBog,"TIMER",0);
StartBog();
}

Ставится на хербит любого объекта на локации болота (главное чтобы объект был плотовый )...

************************************************************************************

автор::::::::::::Valleo::::::::::::::::::::
Mar 19 2004
Мой личный код на проверку скилла Persuade. Используется харизма и ее модификатор, а так же кубики для болей реалестичности...
Использовать:
NPC: Привет!
1) И тебе привет! У тебя же есть работа?
NPC (1) [Проверка удачна] Да, конечно! <-- сюда вставить скрипт проверки Persuade
NPC (2) [Проверка неудачна] С чего ты взял?
2) Извини, обознался...
Neverwinter Script Source
int StartingConditional()
{
object oPC = GetPCSpeaker();
object oNPC = OBJECT_SELF;
object oWinner;
int iCharisma = GetAbilityScore(oPC,ABILITY_CHARISMA);
if(iCharisma < 7)
{
SendMessageToPC(oPC,"У вас харизма ниже 7, вы не можете нормально разговаривать с "+GetName(oNPC));
return FALSE;
}
int iPCPersuade, iNPCPersuade;
int iAddPC, iAddNPC;
int iPCCharModif, iNPCCharModif;
if(GetHasSkill(SKILL_PERSUADE,oPC)) iPCPersuade = GetSkillRank(SKILL_PERSUADE,oPC);
if(GetHasSkill(SKILL_PERSUADE,oNPC)) iNPCPersuade = GetSkillRank(SKILL_PERSUADE,oNPC);
iPCCharModif = GetAbilityModifier(ABILITY_CHARISMA,oPC);
iNPCCharModif = GetAbilityModifier(ABILITY_CHARISMA,oNPC);
iAddPC = d12();
iAddNPC = d12();
SendMessageToPC(oPC,"Проверка на скилл Persuade:");
SendMessageToPC(oPC,"Ваш сккилл равен = "+IntToString(iPCPersuade)+" + "+IntToString(iAddPC)+" (d12) + "+IntToString(iPCCharModif)+" (модификатор харизмы) = " +IntToString(iPCPersuade+iAddPC+iPCCharModif));
SendMessageToPC(oPC,"Скилл вашего оппонента равен = "+IntToString(iNPCPersuade)+" + "+IntToString(iAddNPC)+" (d12)  + "+IntToString(iNPCCharModif)+" (модификатор харизмы) = " +IntToString(iNPCPersuade+iAddNPC+iNPCCharModif));
iPCPersuade = iPCPersuade + iAddPC + iPCCharModif;
iNPCPersuade = iNPCPersuade + iAddNPC + iNPCCharModif;
if(iPCPersuade > iNPCPersuade)
{
SendMessageToPC(oPC,"Вы удачно провели проверку скилла.");
return TRUE;
}
SendMessageToPC(oPC,"Вы провалили проверку.");
return FALSE;
}


************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ ДЯДЮШКИ VALLEO" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 16:30

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ ТЕМНОГО ЛОРДА"

автор::::::::::::Темный лорд::::::::::::::::::::
May 17 2003
Скрипт на то. Чтобы после смерти объекты воскрешали. Я делал его для себя. Подскажу как его еще можно использовать.
Я взял обычных людей. Поставив им тег h01. И вставил в onDeath этот скрипт. В результате получилось, что если убить этого человека.
Он превратится в зомби. Главное не забыть поставить на карте объект Nekrolog01.

Neverwinter Script Source
void Raise()
{
effect eVisDead = EffectVisualEffect(VFX_IMP_HEAD_ACID);///Эффект с которым объект будет воскресать. В данном случае это кислота!
object oNew = CreateObject(OBJECT_TYPE_CREATURE,"ZombieWeak07", GetLocation(OBJECT_SELF)) ;///Тег объекта который будет воскресать.
ApplyEffectAtLocation(DURATION_TYPE_PERMANENT, eVisDead, GetLocation(oNew));

}
void main()
{
object oCleric = GetNearestObjectByTag("Nekrolog01");/// Тег объекта который будет оживлять. И которого надо убить чтобы остальные больше не оживали.

if (GetIsObjectValid(oCleric) == TRUE && GetIsDead(oCleric) == FALSE)
{
AssignCommand(oCleric, ClearAllActions());
AssignCommand(oCleric, ActionPlayAnimation(ANIMATION_LOOPING_WORSHIP, 1.0, 3.0));///Действия которые выполняет "оживитель" как только умирает один из объектов. В данном случае становится на колени.
effect eVisCleric = EffectVisualEffect(VFX_IMP_AURA_NEGATIVE_ENERGY);/// Эффект с которым клирик воскрешает. В данном случае появляется красного цвета аура. Но эффекты можно менять!
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVisCleric, oCleric);
DelayCommand(3.0, Raise());
DelayCommand(0.2,AssignCommand(oCleric, SpeakOneLinerConversation())) ;
}
}

Самое необходимое я выделил.

************************************************************************************

автор::::::::::::Темный лорд::::::::::::::::::::
May 17 2003
Скрипт моего друга. Он если зайдет то даст его описание. Вообще скрипт на то чтобы после смерти находится в бессознательном состоянии 10 едениц. 1 вставляется в OnHeartbeat. Второй в OnPlayerDying. /// Без пояснений.
Neverwinter Script Source
void loadBehaviors()
{
SetLocalInt(OBJECT_SELF, "DEATH_TARGET", -10);
SetLocalInt(OBJECT_SELF, "PLAYER_ONLY_GRUNTS_WHILE_DYING", FALSE);
}
void bleedCheck(object pc)
{
if (!GetIsPC(pc))
return;
int DEATH_TARGET = GetLocalInt(OBJECT_SELF, "DEATH_TARGET");
int PLAYER_ONLY_GRUNTS_WHILE_DYING = GetLocalInt(OBJECT_SELF, "PLAYER_ONLY_GRUNTS_WHILE_DYING");
int hp = GetCurrentHitPoints(pc);
if ((hp <= 0) && (hp > DEATH_TARGET))
    {
    effect dmg = EffectDamage(1);
    ApplyEffectToObject(DURATION_TYPE_INSTANT, dmg, pc);
    int which = Random(6)+1;
    if (PLAYER_ONLY_GRUNTS_WHILE_DYING)
    switch (which)
        {
        case 1:
              PlayVoiceChat(VOICE_CHAT_PAIN1, pc);
              break;
        case 2:
              PlayVoiceChat(VOICE_CHAT_PAIN2, pc);
              break;
        case 3:
              PlayVoiceChat(VOICE_CHAT_PAIN3, pc);
              break;
        case 4:
              PlayVoiceChat(VOICE_CHAT_HEALME, pc);
              break;
        case 5:
              PlayVoiceChat(VOICE_CHAT_NEARDEATH, pc);
              break;
        case 6:
              PlayVoiceChat(VOICE_CHAT_HELP, pc);
              break;
       }
    }
else if (hp <= DEATH_TARGET)
   {
   effect death = EffectDeath(FALSE, FALSE);
   ApplyEffectToObject(DURATION_TYPE_INSTANT, death, pc);
   }
}

void main()
{
loadBehaviors();
object pc = GetFirstPC();
while (GetIsObjectValid(pc))
   {
   bleedCheck(pc);
   pc = GetNextPC();
   }
}



Neverwinter Script Source
void main()
{
// load up desired behaviors for all OnHeartbeat scripts
loadBehaviors();

// enumerate all PCs, calling bleedCheck on each
// if you want to add more / other scripts that act on all players
// every heartbeat, this is the place to do it ... just put a call
// to them after (or before) bleedCheck, within the while loop.
object pc = GetFirstPC();

while (GetIsObjectValid(pc))
  {
  bleedCheck(pc);
  pc = GetNextPC();
  }
}


************************************************************************************

автор::::::::::::Темный лорд::::::::::::::::::::
Jun 3 2003
Вот еще скрипт из моего модуля. Ставится как правило. На OnUsed
предмета. Что телепортирует игрока на заданный вэйпоинт.
Neverwinter Script Source
void main()
{
object oPC = GetLastUsedBy();
object oTarget = GetObjectByTag("Waypoint"); /// тэг Waypoint-та, на который попадёт игрок.
effect eVis = EffectVisualEffect(VFX_IMP_HEALING_X); /// эффект с которым игрок будет попадать.
location lPC = GetLocation(oPC);
ApplyEffectAtLocation(DURATION_TYPE_PERMANENT, eVis, lPC);
AssignCommand(oPC,JumpToObject(oTarget));
}


************************************************************************************

автор::::::::::::Темный лорд::::::::::::::::::::
Jun 3 2003
На превращение НПC в предмет. Вставляется в Heartbeat!!
(Скрипт взят из гаргульи.)
Neverwinter Script Source
void main()
  {
  object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
  if ((GetIsObjectValid(oPC) != TRUE) || (GetIsDead(oPC) == TRUE) || GetDistanceToObject(oPC) >= 10.0)
    {
    location l = GetLocation(OBJECT_SELF);
    location lNew = Location( GetAreaFromLocation(l), GetPositionFromLocation(l), GetFacingFromLocation(l) + 180);
    // CreateObject( OBJECT_TYPE_PLACEABLE, "plc_statue3", lNew );
    CreateObject(OBJECT_TYPE_PLACEABLE, "StatueStone", lNew); /// предмет в который НПК будет превращатся.
    DestroyObject(OBJECT_SELF, 0.5);
    }
  }


************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ ТЕМНОГО ЛОРДА" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 16:31

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ NEUROSHOOTA"

автор::::::::::::neuroshoot::::::::::::::::::::
Jun 19 2003
Скрипт смены погоды (таких наверное дофига уже сделали, но ине лень было искать, вот и написал).
Скрипт кладете на хертбит зоны:

Neverwinter Script Source
void main()
{
object oArea = OBJECT_SELF;
int nRain = WEATHER_RAIN;
int nClear = WEATHER_CLEAR;
int nDef = WEATHER_USE_AREA_SETTINGS;
int nHour = GetTimeHour();
if(nHour == 20|| nHour == 21|| nHour == 22|| nHour == 23||
nHour == 24|| nHour == 0 || nHour == 1 || nHour == 2 ||
nHour == 3 || nHour == 4 || nHour == 5 || nHour == 6 &&
!GetLocalInt(oArea, "IsDef") == 1)
{
SetWeather(oArea, nDef);
SetLocalInt(oArea, "IsRaining", 0);
SetLocalInt(oArea, "IsClear", 0);
SetLocalInt(oArea, "IsDef", 1);
}

if(nHour == 7 || nHour == 8 || nHour == 9 || nHour == 10||
nHour == 11|| nHour == 12&&
!GetLocalInt(oArea, "IsClear") == 1)
{
SetWeather(oArea, nClear);
SetLocalInt(oArea, "IsRaining", 0);
SetLocalInt(oArea, "IsClear", 1);
SetLocalInt(oArea, "IsDef", 0);
}

if(nHour == 13|| nHour == 14|| nHour == 15|| nHour == 16||
nHour == 17|| nHour == 18|| nHour == 19&&
!GetLocalInt(oArea, "IsRaining") == 1)
{
SetWeather(oArea, nRain);
SetLocalInt(oArea, "IsRaining", 1);
SetLocalInt(oArea, "IsClear", 0);
SetLocalInt(oArea, "IsDef", 0);
}
}

Вроде все работает. Если хотите, чтобы погода менялась чаще, поменяйте измените время срабатывания. Для полноты картины разместите на карте различные звуки, которые будут появляться в определенное время (например звук грозы и т.д.).

************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ ТЕМНОГО ЛОРДА" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 16:33

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ ДЯДЮШКИ AIWAN'A"

автор::::::::::::Aiwan::::::::::::::::::::
Jan 19 2004
Скрипт лута для класса в после выполнения квеста.

Neverwinter Script Source
//::///////////////////////////////////////////////////////////
//:: Created By: WRG! Aiwan aiwanwrg.ru
//:: Created On: 19.01.2004
//:://////////////////////////////////////////////////////////
/*
Скрипт на OnOpen сундука. Здесь приведены только
два класса, но проверить можно любой, достаточно
скопировать строки кода и кликнув на классе в скрипте
F-2, выбрать нужный класс. Если класс не попал в
проверку, то получаем самую нижнюю вещь.
*/

//:://////////////////////////////////////////////////////////
void main()
{
  object oPC = GetLastOpenedBy();

  if (!GetIsPC(oPC) || GetLocalInt(OBJECT_SELF, "DO_IT") ||
       !GetLocalInt(oPC, "ПЕРЕМЕННАЯ_КВЕСТА"))
      {return;}
     SetLocalInt(OBJECT_SELF, "DO_IT", TRUE);

     if(GetLevelByClass(CLASS_TYPE_CLERIC, oPC) >= 1) // КЛЕРИК выше 1 уров.
       {
       CreateItemOnObject("res-ref предмета", OBJECT_SELF, 1);
         return;
       }
     if(GetLevelByClass(CLASS_TYPE_WIZARD,oPC) >= 1) // МАГ выше 1 уров. итд
       {
       CreateItemOnObject("res-ref предмета ", OBJECT_SELF, 1);
         return;
       }
       CreateItemOnObject("res-ref предмета ", OBJECT_SELF, 1); // все остальные
         return;
}


************************************************************************************

автор::::::::::::Aiwan::::::::::::::::::::
Mar 5 2004
Вот простенький скрипт, ставится на OnOpen сундука, саркофаги и т.д. При проверке скилла поиск, создает в инвентаре объект в зависимости от алигмента. Код не идеален, но работает
Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Created By: WRG! Aiwan aiwane-mail.ru
//:: Created On: 06.12.2003
//:://////////////////////////////////////////////
/*  Скрипт на OnOpen сундука или саркофага.
     у каждого, алигмента свой приз.
    Если поиск прошел, получаем плюшку.
*/

//:://////////////////////////////////////////////
#include "nw_i0_tool"
void main()
{
  object oPC = GetLastOpenedBy();

  if (GetIsPC(oPC) && GetLocalInt(OBJECT_SELF, "DO_IT") != 1 &&
     (AutoDC(DC_HARD, SKILL_SEARCH, oPC))) // ПРОВЕРКА СКИЛЛА ПОИСК
    {
    AssignCommand(oPC, SpeakString("Bам удалось обнаружить предмет."));
    if (GetAlignmentGoodEvil(oPC) == ALIGNMENT_GOOD) // ПЛЮШКА ДЛЯ ГУДА
       {
       CreateItemOnObject("ResRef ОБЪЕКТА", OBJECT_SELF, 1);
       }
       if (GetAlignmentGoodEvil(oPC) == ALIGNMENT_EVIL) // ПЛЮШКА ДЛЯ ЕВИЛА
           {
           CreateItemOnObject("ResRef ОБЪЕКТА", OBJECT_SELF, 1);
           }
    RewardPartyXP(1500, oPC);
    SetLocalInt(OBJECT_SELF, "DO_IT", 1);
    }
  if (GetIsPC(oPC) && GetLocalInt(OBJECT_SELF, "DO_IT") != 1)
  {
  AssignCommand(oPC, SpeakString("Вам не удалось обнаружить ничего."));
  RewardPartyXP(500, oPC);
  SetLocalInt(OBJECT_SELF, "DO_IT", 1);
  }
}


************************************************************************************

автор::::::::::::Aiwan::::::::::::::::::::
Mar 5 2004
Вот еще один скрипт. Короче, создаете в палитре НПС и делаете его с нужными свойствами, что бы он рандомно бродил или еще что. Дальше, в локации где он должен спавниться, на любой объект вешаете скрипт на хербит. И усе, ночью будет приведение, днем все спокойно

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Copyright © 2004 WRG!
//:://////////////////////////////////////////////
/*
СТАВИМ НЕВИДИМЫЙ ОБЪЕКТ В ЛОКЕ И НА OnHeartBeat
КИДАЕМ СКРИПТ. НОЧЬЮ ПОЯВЛЯЕТСЯ ДУХ ИЗ ПАЛИТРЫ
С НАСТУПЛЕНИЕМ УТРА ДЕСТРОИТЬСЯ. КТО ХОЧЕТ МОЖЕТ
      ДОБАВИТЬ ТОЧНОЕ ВРЕМЯ ДЛЯ СПАВНА
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 03.02.2004
//:://////////////////////////////////////////////

void main()
{
    object oItm = OBJECT_SELF;
    object oTarget = GetObjectByTag("WP_NIMPHA_GOST"); //ТОЧКА ПОЯВЛЕНИЯ ДУХА
    object oGost = GetObjectByTag("ANDR_GOST");
//=====================  ДЕНЬ  ====================
    if (GetIsDay() && GetLocalInt(OBJECT_SELF, "NIGHT") == 1)
    {
      ApplyEffectAtLocation(DURATION_TYPE_INSTANT,
      EffectVisualEffect(VFX_FNF_SOUND_BURST), GetLocation(oGost));
      ActionWait(1.0);
      ActionDoCommand(DestroyObject(oGost));
      SetLocalInt(OBJECT_SELF, "NIGHT", 0);
    }
    if (!GetIsNight() && GetLocalInt(OBJECT_SELF, "NIGHT") == 0)
    return;
//=====================  НОЧЬ =====================
    {
    if (!GetIsNight() || GetLocalInt(OBJECT_SELF, "NIGHT") == 1)
    return;

      oGost = CreateObject(OBJECT_TYPE_CREATURE, "ResRef_ДУХА", GetLocation(oTarget));
      ApplyEffectAtLocation(DURATION_TYPE_INSTANT,
      EffectVisualEffect(VFX_IMP_DEATH_WARD), GetLocation(oTarget));
      AssignCommand(oGost, ClearAllActions());
      SetLocalInt(OBJECT_SELF, "NIGHT", 1);
     }
}


Перед спавном вашего Духа поставьте строчку, я не проверял. но должно пахать:
Neverwinter Script Source
if (GetTimeHour()==23) // ТУТ УКАЖЕТЕ ВРЕМЯ


************************************************************************************

автор::::::::::::Aiwan::::::::::::::::::::
Mar 8 2004
У меня много дверей в модуле, которые произносят фразу, типа: "Запечатано магией. Открыть нельзя" Ну и в том же духе. Так вот, скриптов-стрингов развелось уже довольно много Сел я тут и написал парачку ну очень простеньких скриптиков для этих нужд. Если вам пригодятся, буду только рад.
Первый, просто скрипт. Если вам не в лом его править под каждую дверь, то ставьте его.
Второй проще для установки, но немного с побочным эффектом в виде вейпоинта. Какой нравится, тот и берите.
Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Copyright © 2004 WRG!
//:: OnFailToOpen
//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 10.01.2004
//:://////////////////////////////////////////////
void main()
{
string oDoor = GetTag(OBJECT_SELF);
string sMesseg = "ОШИБКА! TAG двери НЕПРАВИЛЬНЫЙ!"; // ЕСЛИ ВЫ ОШИБЛИСЬ С ТЭГОМ
{
   if (oDoor == "TAG_ДВЕРИ_01" || oDoor == "TAG_ДВЕРИ_02") // ОДИНАКОВЫЕ ФРАЗЫ ДЛЯ РАЗНЫХ ДВЕРЕЙ
      {sMesseg = "Дверь заперта, ключ украден.";}
   if (oDoor == "TAG_ДВЕРИ_03")
      {sMesseg = "Дверь заперта.";}
SpeakString(sMesseg);
}
}


Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Copyright © 2004 WRG!
//:: OnFailToOpen
//:://////////////////////////////////////////////
/*
  WP_DOOR_TXT - вейп с именем нашего текста.
    Ставим его сразу перед нужной дверью.
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 10.01.2004
//:://////////////////////////////////////////////
void main()
{
object oWp = GetNearestObjectByTag("WP_DOOR_TXT"); // БЕРЕМ БЛИЖАЙШИЙ
string sDoor = GetName(oWp);

   if (GetIsObjectValid(oWp) && GetDistanceBetween(oWp, OBJECT_SELF) <= 10.0f)
       //  ЕСЛИ ЕСТЬ ТАКОЙ WP И ОН НЕ ДАЛЬШЕ 10 МЕТРОВ
       {
       SpeakString(sDoor); // ПРОИЗНОСИМ ЕГО ИМЯ
        return;
       }
       else
          {
          SpeakString("Ошибка! Не могу найти WP_DOOR_TXT!");// ЕСЛИ МЫ ЗАБЫЛИ ПОСТАВИТЬ
          return;
          }
}


************************************************************************************

автор::::::::::::Aiwan::::::::::::::::::::
Mar 14 2004
Воот ну очень простой скриптик. Рандомный лут в КВЕСТОВЫЙ сундук, плюшка к плотовому предмету или еще куда.
Мне необходимо дать игроку разные вещи но +4, +5 и т.д. Править лут общий из-за пары сундуков не охота
Чем проще тем надежнее Вспомнил как мне нужен был такой скрипт год назад
Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Copyright © 2004 WRG!  www.wrg.ru
//:: OnOpen OBJECT
//:://////////////////////////////////////////////
/*
           РАНДОМНЫЙ ЛУТ ДЛЯ СУНДУКА
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan    Aiwane-mail.ru
//:: Created On: 14.03.2004
//:://////////////////////////////////////////////
void main()
{
  object oPC = GetLastOpenedBy();
  string sResRef;
if (!GetIsPC(oPC) || GetLocalInt(OBJECT_SELF, "DO_IT"))
      {return;}
{
  SetLocalInt(OBJECT_SELF, "DO_IT", TRUE);
  int iPrize = Random(10);
             switch (iPrize)
             {
                   case 0:
                   {
                        sResRef = "sResRef_itm"; break;
                   }
                   case 1:
                   {
                        sResRef = "sResRef_itm"; break;
                   }
                   case 2:
                   {
                        sResRef = "sResRef_itm"; break;
                   }
                   case 3:
                   {
                        sResRef = "sResRef_itm"; break;
                   }
                   case 4:
                   {
                        sResRef = "sResRef_itm"; break;
                   }
                   case 5:
                   {
                        sResRef = "sResRef_itm"; break;
                   }
                   case 6:
                   {
                        sResRef = "sResRef_itm"; break;
                   }
                   case 7:
                   {
                        sResRef = "sResRef_itm"; break;
                   }
                   case 8:
                   {
                        sResRef = "sResRef_itm"; break;
                   }
                   case 9:
                   {
                        sResRef = "sResRef_itm"; break;
                   }
             }
     CreateItemOnObject(sResRef, OBJECT_SELF, 1); // ЭТО РАНДОМНЫЙ ЛУТ
     CreateItemOnObject("sResRef_itm_2", OBJECT_SELF, 1); // ЭТО ПОСТОЯННЫЙ, т.е. В ЛЮБОМ СЛУЧАЕ ВЕЩЬ №2
   }
}


************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ ДЯДЮШКИ AIWAN'A" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 16:34

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ EXICUTIONER'A"

автор::::::::::::NightElf-Sniper aka Executioner::::::::::::::::::::
Заняляс я тут немного скриптованием и вот что из этого получилось:

Neverwinter Script Source
//:: Dlg_Open_Store :: Executioner :://

void main()
{
string sNPSTag = GetTag(OBJECT_SELF);
object oStore = GetNearestObjectByTag(sNPSTag+"_store");

if(GetObjectType(oStore) == OBJECT_TYPE_STORE)
OpenStore(oStore, GetPCSpeaker());

else
ActionSpeakStringByStrRef(53090, TALKVOLUME_TALK);
}

Универсальный скрипт открытия магазинов, что бы все работало делаете так:
создаете непися с тегом m_weapons, после чего создаете рядом с ним магазин и даете ему тег m_weapons_store, после чего скрипт ставится на нужную ветвь диалога...
И вот это:
Neverwinter Script Source
/******************************
Name: _On_Pl_Death
Autor: Executioner
*******************************/


void main()
{
object oDied = GetLastPlayerDied();
object oHenchman = GetHenchman(oDied);
object oKiller = GetLastAttacker(oDied);
object oMod = GetModule();

string sName = GetName(oDied);
string sID = GetName(oDied)+GetPCPublicCDKey(oDied); //ID умершего, ибо скрипт писался для мультика...

int iGold = GetGold(oDied);

location lDiedHere = GetLocation(oDied);

object oDeathCorpse=CreateObject(OBJECT_TYPE_PLACEABLE,"mod_deathcorpse",lDiedHere,FALSE,"DeathCorpse"+sID);
object oBag = CreateItemOnObject("mod_bagofgold",oDeathCorpse);


//убираем хенчу
if (GetIsObjectValid(oHenchman))
RemoveHenchman(oDied, oHenchman);


//Воскрешаем
ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectResurrection(),oDied);
ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectHeal(GetMaxHitPoints(oDied)), oDied);
AssignCommand(oDied, ActionJumpToObject(GetObjectByTag("wp_death"))); &#092;&#092; Туда, куда должен прыгать чар после смерти(храм&#092;фуга)


//Снимаем 10% экспы
int iDeadXP = 10;
int iXP = GetXP(oDied);
int iNewXP = iXP-iXP*iDeadXP/100;

SetXP(oDied, iNewXP);

//Отнимаем деньги и вещи и кидаем их в лут
SetLocalString(oDeathCorpse,"oDiedName",sName);
SetLocalInt(oBag,"Gold",iGold);

int i;
for(i=0;i<15;i++)
AssignCommand(oDeathCorpse, ActionTakeItem(GetItemInSlot(i, oDied), oDied));

AssignCommand(oDeathCorpse, TakeGoldFromCreature(iGold,oDied,TRUE));
}
[nss]

[nss]
//:: OnOpen_DthCorpse :: Executioner :://
void main()
{
SpeakString("Corpse of "+GetLocalString(OBJECT_SELF,"oDiedName"),TALKVOLUME_TALK);
}


Neverwinter Script Source
//:: OnClse_DthCorpse :: Executioner :://
void main()
{
if(GetIsObjectValid(GetFirstItemInInventory(OBJECT_SELF))==FALSE)
DelayCommand(3.0,DestroyObject(OBJECT_SELF));
}

Для полной работоспособности надо создать еще 1 плейсейбл и 1 итем и поставить вейпойн куда надо бросать после смерти(фуга\храм)

плейсейбл:
tag: Mod_DeathCorpse
resref: mod_deathcorpse
ставим галку напротив Usable и Has Inventory
так же на OnClose ставим скрипт OnClse_DthCorpse, а на OnOpen соответственно OnOpen_DthCorpse
итем:
tag: Mod_BagOfGold
resref: mod_bagofgold

Что мы получаем в итоге: после смерти убирается хенча, снимается 10% экспы. Все вещи которые были на нем и деньги отбираются и бросаются в лут, который появляется на месте смерти. После бросаем нашего чара туда, куда надо ) там можете с ним делать все. что захотите
А зачем вешать на лут скрипты - а затем, что бы нам говорили кто умер, и после что бы не валялись они по всему модулю...

************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ EXICUTIONER'A" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 16:37

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ (MOF)DARTH_NICK'A"

автор::::::::::::[MoF]Darth_Nick::::::::::::::::::::
Jul 3 2004
получение лвла по алайменту

Neverwinter Script Source
/*
Created By: [MoF]Darth_Nick
Data Of Creating: 02.07.2004 11:03
Discription: So, this script is do following - when you have a level up, after up
script founding your alignment(GOOD, EVIL, NEUTRAL) and doing something visual effects
for you. Also effects maybe change if you change Constans...Sample:
VFX_FNF_SUMMON_EPIC_UNDEAD - this is first constant of evil leveling, delete that and
enter something yours in the list of constants, an example - VFX_FNF_IMPLOSION.
*/


void main()
{
object oPC = GetPCLevellingUp();

if(GetAlignmentGoodEvil(oPC) == ALIGNMENT_EVIL)
{
DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SUMMON_EPIC_UNDEAD), oPC));
DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_HARM), oPC));
}
else if(GetAlignmentGoodEvil(oPC) == ALIGNMENT_GOOD)
{
DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_HOLY_AID), oPC));
DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SUNBEAM), oPC));
}
else if(GetAlignmentGoodEvil(oPC) == ALIGNMENT_NEUTRAL)
{
DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SOUND_BURST), oPC));
DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_HEALING_X), oPC));
}
}


************************************************************************************

автор::::::::::::[MoF]Darth_Nick::::::::::::::::::::
Jul 3 2004
веселая ловушка
Neverwinter Script Source
/*
Created By: [MoF]Darth_Nick
Data Of Creating: 11:37
Discription: Script is stand on a OnEnter of Generic Triger, you also can use it in the
trap, but unexpectandlly is be very other!
*/


void main()
{
object oPC = GetEnteringObject();
effect eBall = EffectVisualEffect(VFX_FNF_FIREBALL);

if (GetIsPC(oPC) == GetCurrentHitPoints(oPC) < 70)
{
DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBall, oPC));
DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oPC));
}
else if (GetIsPC(oPC) == GetCurrentHitPoints(oPC) > 70)
{
FloatingTextStringOnCreature("Heh...This trick is not for me!", oPC);
}
}


************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ (MOF)DARTH_NICK'A" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 19 2005, 16:39

СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ"
ЦИКЛ "СКРИПТЫ RED DEVIL'A"

автор::::::::::::Red Devil::::::::::::::::::::
Jul 31 2004
Значит так крафтинг. Крафт осущетсвляется при разговоре с неписем.
Крафт брони +1 к АС.

Neverwinter Script Source
#include "x2_inc_itemprop"
void main()
{
int iBonus;
object oPC=GetPCSpeaker();
object oArmor=GetItemInSlot(INVENTORY_SLOT_CHEST,oPC);
itemproperty ipHasAC=GetFirstItemProperty(oArmor);
GetItemPropertyType(ipHasAC)==ITEM_PROPERTY_AC_BONUS;
if (!GetIsObjectValid(oArmor)) return;
if (GetBaseItemType(oArmor)!=BASE_ITEM_ARMOR) return;
   {
   iBonus=GetItemPropertyCostTableValue(ipHasAC);
   if (iBonus<0) iBonus=0;
   iBonus++;
   itemproperty ipAddAC=ItemPropertyACBonus(iBonus);
   IPSafeAddItemProperty(oArmor,ipAddAC);
   }
}


************************************************************************************

автор::::::::::::Red Devil::::::::::::::::::::
Jul 31 2004
Крафт оружия +1энчант бонус, либо елси это лук или арбалет +1 атак бонус.
Neverwinter Script Source
#include "x2_inc_itemprop"
void main()
{
object oPC=GetPCSpeaker();
object oWeap=GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
int iBonus;
int bType=GetBaseItemType(oWeap);
if (!GetIsObjectValid(oWeap)) return;
if ((bType == BASE_ITEM_BASTARDSWORD) ||
(bType == BASE_ITEM_BATTLEAXE) ||
(bType == BASE_ITEM_CLUB) ||
(bType == BASE_ITEM_DAGGER) ||
(bType == BASE_ITEM_DIREMACE) ||
(bType == BASE_ITEM_DOUBLEAXE) ||
(bType == BASE_ITEM_DWARVENWARAXE) ||
(bType == BASE_ITEM_GREATAXE) ||
(bType == BASE_ITEM_GREATSWORD) ||
(bType == BASE_ITEM_HALBERD) ||
(bType == BASE_ITEM_HANDAXE) ||
(bType == BASE_ITEM_HEAVYFLAIL) ||
(bType == BASE_ITEM_KAMA) ||
(bType == BASE_ITEM_KATANA) ||
(bType == BASE_ITEM_KUKRI) ||
(bType == BASE_ITEM_LIGHTFLAIL) ||
(bType == BASE_ITEM_LIGHTHAMMER) ||
(bType == BASE_ITEM_LIGHTMACE) ||
(bType == BASE_ITEM_LONGSWORD) ||
(bType == BASE_ITEM_MORNINGSTAR) ||
(bType == BASE_ITEM_QUARTERSTAFF) ||
(bType == BASE_ITEM_RAPIER) ||
(bType == BASE_ITEM_SCIMITAR) ||
(bType == BASE_ITEM_SCYTHE) ||
(bType == BASE_ITEM_SHORTSPEAR) ||
(bType == BASE_ITEM_SHORTSWORD) ||
(bType == BASE_ITEM_SICKLE) ||
(bType == BASE_ITEM_TWOBLADEDSWORD) ||
(bType == BASE_ITEM_WARHAMMER) ||
(bType == BASE_ITEM_WHIP) ||
(bType == BASE_ITEM_SHURIKEN) ||
(bType == BASE_ITEM_WHIP))
{
iBonus=IPGetWeaponEnhancementBonus(oWeap);
iBonus++;
itemproperty ipAdd=ItemPropertyEnhancementBonus(iBonus);
IPSafeAddItemProperty(oWeap,ipAdd);
}
else
if ((bType == BASE_ITEM_SLING)||
(bType == BASE_ITEM_SHORTBOW)||
(bType == BASE_ITEM_LONGBOW)||
(bType == BASE_ITEM_LIGHTCROSSBOW)||
(bType == BASE_ITEM_HEAVYCROSSBOW))
{
itemproperty ipHasAttack=GetFirstItemProperty(oWeap);
GetItemPropertyType(ipHasAttack)==ITEM_PROPERTY_ATTACK_BONUS;
iBonus=GetItemPropertyCostTableValue(ipHasAttack);
if (iBonus<0) iBonus=0;
iBonus++;
itemproperty ipAddAttack=ItemPropertyAttackBonus(iBonus);
IPSafeAddItemProperty(oWeap,ipAddAttack);
}
}


************************************************************************************

КОНЕЦ ЦИКЛА "СКРИПТЫ RED DEVIL'A" СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"


КОНЕЦ СЕРИИ "СКРИПТЫ СТАРОЙ БАЗЫ"

Автор: Lex Mar 24 2005, 11:10

СЕРИЯ "СКРИПТЫ ПРОКЛЯТИЯ ЛЕВОРА"
ЦИКЛ "СКРИПТЫ ДЯДЮШКИ BAAL'A"

Скриптовая система из "Проклятия Левора", предназначенная для переноса вещей хенчмана в следующий модуль. Работает только с одним хенчманом! Скрипт bm_inv_transit1 запускаеться перед переходом в новый модуль. Скрипт bm_inv_transit3 запускаеться в новом модуле, уже после того как присоединен хенчман(хенч должен быть с пустыми слотами и инвентарем).

На закрытой локе должны находиться 2 монстра с пустым инвентарем и с тагами SECOND_PC и SECOND_HENCH
в палитре должны быть 3 сумки с одинаковым тагом и ресрефом transit_cont1, transit_cont2 и transit_cont3

Neverwinter Script Source
//::///////////////////////////////////////////////
//:: FileName  bm_inv_transit1
//:: © 2005 WRG!
//:://////////////////////////////////////////////
/*
   Первый скрипт копирует все вещи из инвентарЯ РС и
      хенча в ивентари монстров на закрытой локе,
        уничтожаЯ оригиналы. "плотовые" вещи
         обрабатываютьсЯ в первую очередь
*/

//:://////////////////////////////////////////////
//:: Created By: BaaL
//:: Created On:
//:://////////////////////////////////////////////

int GetHasObject (object oCreature, object oItem)
{
object oItm = GetFirstItemInInventory(oCreature);
while(GetIsObjectValid(oItm))
  {
  if (oItm == oItem) return TRUE;
  oItm = GetNextItemInInventory(oCreature);
  }
return FALSE;
}

void main()
{
object oPC = GetFirstPC();
object oHench = GetHenchman(oPC);
object oSecPC = GetObjectByTag("SECOND_PC");
object oSecHench = GetObjectByTag("SECOND_HENCH");
object oCopy;
object oItem;
string sContainerTag;
object oContainer;
// Если нет хенча то скрипт не запускаетьсЯ.
if(!GetIsObjectValid(oHench)) return;
// plot PC
sContainerTag = "transit_cont1";
oContainer = CreateItemOnObject(sContainerTag, oSecPC);
oItem = GetFirstItemInInventory(oPC);
while(GetIsObjectValid(oItem))
  {
  if(GetPlotFlag(oItem))
    {
    if(GetBaseItemType(oItem) != BASE_ITEM_LARGEBOX)
      {
      oCopy = CopyItem(oItem, oContainer, TRUE);
      if(!GetHasObject(oContainer, oCopy))
        {
        DestroyObject(oCopy);
        oContainer = CreateItemOnObject(sContainerTag, oSecPC);
        oCopy = CopyItem(oItem, oContainer, TRUE);
        }
      DestroyObject(oItem);
      }
    }
  oItem = GetNextItemInInventory(oPC);
  }

// plot Hench
sContainerTag = "transit_cont2";
oContainer = CreateItemOnObject(sContainerTag, oSecHench);
oItem = GetFirstItemInInventory(oHench);
while(GetIsObjectValid(oItem))
  {
  if(GetPlotFlag(oItem))
    {
    if(GetBaseItemType(oItem) != BASE_ITEM_LARGEBOX)
      {
      oCopy = CopyItem(oItem, oContainer, TRUE);
      if(!GetHasObject(oContainer, oCopy))
        {
        DestroyObject(oCopy);
        oContainer = CreateItemOnObject(sContainerTag, oSecHench);
        oCopy = CopyItem(oItem, oContainer, TRUE);
        }
      DestroyObject(oItem);
      }
    }
  oItem = GetNextItemInInventory(oHench);
  }
// not plot PC
sContainerTag = "transit_cont1";
oContainer = CreateItemOnObject(sContainerTag, oSecPC);
oItem = GetFirstItemInInventory(oPC);
while(GetIsObjectValid(oItem))
  {
  if(!GetPlotFlag(oItem))
    {
    if(GetBaseItemType(oItem) != BASE_ITEM_LARGEBOX)
      {
      oCopy = CopyItem(oItem, oContainer, TRUE);
      if(!GetHasObject(oContainer, oCopy))
        {
        DestroyObject(oCopy);
        oContainer = CreateItemOnObject(sContainerTag, oSecPC);
        oCopy = CopyItem(oItem, oContainer, TRUE);
        }
      DestroyObject(oItem);
      }
    }
  oItem = GetNextItemInInventory(oPC);
  }
// not plot Hench
sContainerTag = "transit_cont2";
oContainer = CreateItemOnObject(sContainerTag, oSecHench);
oItem = GetFirstItemInInventory(oHench);
while(GetIsObjectValid(oItem))
  {
  if(!GetPlotFlag(oItem))
    {
    if(GetBaseItemType(oItem) != BASE_ITEM_LARGEBOX)
      {
      oCopy = CopyItem(oItem, oContainer, TRUE);
      if(!GetHasObject(oContainer, oCopy))
        {
        DestroyObject(oCopy);
        oContainer = CreateItemOnObject(sContainerTag, oSecHench);
        oCopy = CopyItem(oItem, oContainer, TRUE);
        }
      DestroyObject(oItem);
      }
    }
  oItem = GetNextItemInInventory(oHench);
  }
// Автоматически запускаем второй скрипт:
DelayCommand(0.5, ExecuteScript("bm_inv_transit2", OBJECT_SELF));
}

Neverwinter Script Source
//::///////////////////////////////////////////////
//:: FileName  bm_inv_transit2
//:: © 2005 WRG!
//:://////////////////////////////////////////////
/*
   Второй скрипт возвращает все вещи в инвентарь РС,
  раскладываЯ их по сумкам. По возможности заполнЯет
         уже имеющиесЯ у РС сумки (NEW!)
*/

//:://////////////////////////////////////////////
//:: Created By: BaaL
//:: Created On:
//:://////////////////////////////////////////////

void FindContainers(object oCreature)
{
int NN=0;
object oItm = GetFirstItemInInventory(oCreature);
while(GetIsObjectValid(oItm))
  {
  if(GetBaseItemType(oItm) == BASE_ITEM_LARGEBOX)
    {
    SetIdentified(oItm, TRUE);
    NN++;
    SetLocalInt(oCreature, "CONT_NUMBER", NN);
    SetLocalObject(oCreature, "CONTAINER"+IntToString(NN), oItm);
    }
  oItm = GetNextItemInInventory(oCreature);
  }
return;
}

int Ncont(object oCreature)
{
return GetLocalInt(oCreature, "CONT_NUMBER");
}

object GiveContainer(object oCreature, int NN)
{
return GetLocalObject(oCreature, "CONTAINER"+IntToString(NN));
}

void DeleteLocals(object oCreature)
{
int NN = Ncont(oCreature);
int NN1 = 1;
while (NN >= NN1)
  {
  DeleteLocalObject(oCreature, "CONTAINER"+IntToString(NN1));
  NN1++;
  }
DeleteLocalInt(oCreature, "CONT_NUMBER");
return;
}

int GetHasObject (object oCreature, object oItem)
{
object oItm = GetFirstItemInInventory(oCreature);
while(GetIsObjectValid(oItm))
  {
  if (oItm == oItem) return TRUE;
  oItm = GetNextItemInInventory(oCreature);
  }
return FALSE;
}

void main()
{
object oPC = GetFirstPC();
object oHench = GetHenchman(oPC);
object oSecPC = GetObjectByTag("SECOND_PC");
object oSecHench = GetObjectByTag("SECOND_HENCH");
object oCopy;
string sContainerTag;
int iContNumber = 1;
object oContainer;
object oItem = GetFirstItemInInventory(oHench);
while(GetIsObjectValid(oItem))
  {
  if(GetBaseItemType(oItem) == BASE_ITEM_LARGEBOX)
    {
    oCopy = CopyItem(oItem, oPC);
    DestroyObject(oItem);
    }
  oItem = GetNextItemInInventory(oHench);
  }
FindContainers(oPC);
///---///---
sContainerTag = "transit_cont1";
// oContainer = CreateItemOnObject(sContainerTag, oPC);
oContainer=(iContNumber>Ncont(oPC))?CreateItemOnObject(sContainerTag,oPC):GiveContainer(oPC,iContNumber);
oItem = GetFirstItemInInventory(oSecPC);
while(GetIsObjectValid(oItem))
  {
    if(GetBaseItemType(oItem) != BASE_ITEM_LARGEBOX && GetTag(oItem) != sContainerTag)
      {
      oCopy = CopyItem(oItem, oContainer, TRUE);
      // esli item v sumku ne vlez  - sozdaem novuyu
      if(!GetHasObject(oContainer, oCopy))
        {
        DestroyObject(oCopy);
        // oContainer = CreateItemOnObject(sContainerTag, oPC);
        iContNumber++;
        oContainer=(iContNumber>Ncont(oPC))?CreateItemOnObject(sContainerTag,oPC):GiveContainer(oPC,iContNumber);
        oCopy = CopyItem(oItem, oContainer, TRUE);
        }
      // uni4tojaem original
      DestroyObject(oItem);
      }
  oItem = GetNextItemInInventory(oSecPC);
  }

///---///---
sContainerTag = "transit_cont2";
// oContainer = CreateItemOnObject(sContainerTag, oPC);
iContNumber++;
oContainer=(iContNumber>Ncont(oPC))?CreateItemOnObject(sContainerTag,oPC):GiveContainer(oPC,iContNumber);
oItem = GetFirstItemInInventory(oSecHench);
while(GetIsObjectValid(oItem))
  {
    if(GetBaseItemType(oItem) != BASE_ITEM_LARGEBOX && GetTag(oItem) != sContainerTag)
      {
      oCopy = CopyItem(oItem, oContainer, TRUE);
      // esli item v sumku ne vlez  - sozdaem novuyu
      if(!GetHasObject(oContainer, oCopy))
        {
        DestroyObject(oCopy);
        // oContainer = CreateItemOnObject(sContainerTag, oPC);
        iContNumber++;
        oContainer=(iContNumber>Ncont(oPC))?CreateItemOnObject(sContainerTag,oPC):GiveContainer(oPC,iContNumber);
        oCopy = CopyItem(oItem, oContainer, TRUE);
        }
      // uni4tojaem original
      DestroyObject(oItem);
      }
  oItem = GetNextItemInInventory(oSecHench);
  }

///---///---
sContainerTag = "transit_cont3";
oContainer = CreateItemOnObject(sContainerTag, oPC);
int iSlot = 0;
oItem = GetItemInSlot(iSlot, oHench);
while (iSlot < 14)
  {
  if(GetIsObjectValid(oItem))
    {
    oCopy = CopyItem(oItem, oContainer, TRUE);
    // esli item v sumku ne vlez  - sozdaem novuyu
    if(!GetHasObject(oContainer, oCopy))
      {
      DestroyObject(oCopy);
      oContainer = CreateItemOnObject(sContainerTag, oPC);
      oCopy = CopyItem(oItem, oContainer, TRUE);
      }
    // uni4tojaem original
    DestroyObject(oItem);
    }
  iSlot ++;
  oItem = GetItemInSlot(iSlot, oHench);
  }
DeleteLocals(oPC);

oItem = GetFirstItemInInventory(oSecPC);
while(GetIsObjectValid(oItem))
  {
  DestroyObject(oItem);
  oItem = GetNextItemInInventory(oSecPC);
  }
oItem = GetFirstItemInInventory(oSecHench);
while(GetIsObjectValid(oItem))
  {
  DestroyObject(oItem);
  oItem = GetNextItemInInventory(oSecHench);
  }
}

Neverwinter Script Source
//::///////////////////////////////////////////////
//:: FileName  bm_inv_transit3
//:: © 2005 WRG!
//:://////////////////////////////////////////////
/*
   Третий скрипт запускаетьсЯ уже в новом модуле
      после того как присоеденен хенч. Скрипт
   раскладывает вещи в инвентаре хенча и копирует
     вещи РС монстру, попутно уничтожаЯ Ящики.
*/

//:://////////////////////////////////////////////
//:: Created By: BaaL
//:: Created On:
//:://////////////////////////////////////////////
int GetSuitableSlot(object oItem)
{
int iSlot;
switch  (GetBaseItemType(oItem))
  {
  case BASE_ITEM_AMULET:         iSlot = INVENTORY_SLOT_NECK;      break;
  case BASE_ITEM_ARMOR:          iSlot = INVENTORY_SLOT_CHEST;     break;
  case BASE_ITEM_ARROW:          iSlot = INVENTORY_SLOT_ARROWS;    break;
  case BASE_ITEM_BASTARDSWORD:   iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_BATTLEAXE:      iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_BELT:           iSlot = INVENTORY_SLOT_BELT;      break;
  case BASE_ITEM_BOLT:           iSlot = INVENTORY_SLOT_BOLTS;     break;
  case BASE_ITEM_BOOTS:          iSlot = INVENTORY_SLOT_BOOTS;     break;
  case BASE_ITEM_BRACER:         iSlot = INVENTORY_SLOT_ARMS;      break;
  case BASE_ITEM_BULLET:         iSlot = INVENTORY_SLOT_BULLETS;   break;
  case BASE_ITEM_CLOAK:          iSlot = INVENTORY_SLOT_CLOAK;     break;
  case BASE_ITEM_CLUB:           iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_DAGGER:         iSlot = INVENTORY_SLOT_LEFTHAND;  break;
  case BASE_ITEM_DART:           iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_DIREMACE:       iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_DOUBLEAXE:      iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_DWARVENWARAXE:  iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_GLOVES:         iSlot = INVENTORY_SLOT_ARMS;      break;
  case BASE_ITEM_HALBERD:        iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_HANDAXE:        iSlot = INVENTORY_SLOT_LEFTHAND;  break;
  case BASE_ITEM_HEAVYCROSSBOW:  iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_HEAVYFLAIL:     iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_HELMET:         iSlot = INVENTORY_SLOT_HEAD;      break;
  case BASE_ITEM_KAMA:           iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_KATANA:         iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_KUKRI:          iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_LARGESHIELD:    iSlot = INVENTORY_SLOT_LEFTHAND;  break;
  case BASE_ITEM_LIGHTCROSSBOW:  iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_LIGHTFLAIL:     iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_LIGHTHAMMER:    iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_LIGHTMACE:      iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_LONGBOW:        iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_LONGSWORD:      iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_MAGICSTAFF:     iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_MORNINGSTAR:    iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_QUARTERSTAFF:   iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_RAPIER:         iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_RING:           iSlot = INVENTORY_SLOT_RIGHTRING; break;
  case BASE_ITEM_SCIMITAR:       iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_SCYTHE:         iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_SHORTBOW:       iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_SHORTSPEAR:     iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_SHORTSWORD:     iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_SHURIKEN:       iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_SLING:          iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_SMALLSHIELD:    iSlot = INVENTORY_SLOT_LEFTHAND;  break;
  case BASE_ITEM_THROWINGAXE:    iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_TORCH:          iSlot = INVENTORY_SLOT_LEFTHAND;  break;
  case BASE_ITEM_TOWERSHIELD:    iSlot = INVENTORY_SLOT_LEFTHAND;  break;
  case BASE_ITEM_TWOBLADEDSWORD: iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  case BASE_ITEM_WARHAMMER:      iSlot = INVENTORY_SLOT_RIGHTHAND; break;
  }
return iSlot;
}

void main()
{
object oPC = GetFirstPC();
object oHench = GetHenchman(oPC);
object oSecPC = GetObjectByTag("SECOND_PC");
object oCopy;
object oContainer;
object oItem2;
object oItem = GetFirstItemInInventory(oPC);
// Если нет чемодана "transit_cont3" (это значит скрипты 1 и 2 не запускались,
// т.е. хенч в новый модуль не перешел), то удалЯем хенча в новом модуле
// и останавливаем скрипт
if(!GetIsObjectValid(GetItemPossessedBy(oPC, "transit_cont3")))
  {
  DestroyObject(oHench);
  return;
  }
AssignCommand(oHench, ClearAllActions());
while (GetIsObjectValid(oItem))
  {
  ///+++
  if(GetTag(oItem) == "transit_cont1")
    {
    oContainer = oItem;
    oItem2 = GetFirstItemInInventory(oContainer);
    while (GetIsObjectValid(oItem2))
      {
      oCopy = CopyItem(oItem2, oSecPC, TRUE);
      DestroyObject(oItem2);
      oItem2 = GetNextItemInInventory(oContainer);
      }
    DestroyObject(oContainer);
    }
  ///---
  ///+++
  if(GetTag(oItem) == "transit_cont2")
    {
    oContainer = oItem;
    oItem2 = GetFirstItemInInventory(oContainer);
    while (GetIsObjectValid(oItem2))
      {
      oCopy = CopyItem(oItem2, oHench, TRUE);
      DestroyObject(oItem2);
      oItem2 = GetNextItemInInventory(oContainer);
      }
    DestroyObject(oContainer);
    }
  ///---
  ///+++
  if(GetTag(oItem) == "transit_cont3")
    {
    oContainer = oItem;
    oItem2 = GetFirstItemInInventory(oContainer);
    while (GetIsObjectValid(oItem2))
      {
      oCopy = CopyItem(oItem2, oHench, TRUE);
      SetIdentified(oCopy, TRUE);
      AssignCommand(oHench, ActionEquipItem(oCopy, GetSuitableSlot(oCopy)));
      DestroyObject(oItem2);
      oItem2 = GetNextItemInInventory(oContainer);
      }
    DestroyObject(oContainer);
    }
  ///---
  oItem = GetNextItemInInventory(oPC);
  }
// Автоматически запускаем четвертый скрипт:
DelayCommand(0.5, ExecuteScript("bm_inv_transit4", OBJECT_SELF));
}

Neverwinter Script Source
//::///////////////////////////////////////////////
//:: FileName  bm_inv_transit4
//:: © 2005 WRG!
//:://////////////////////////////////////////////
/*
      Четвертый скрипт возвращает вещи РС
*/

//:://////////////////////////////////////////////
//:: Created By: BaaL
//:: Created On:
//:://////////////////////////////////////////////
void main()
{
object oPC = GetFirstPC();
object oSecPC = GetObjectByTag("SECOND_PC");
object oCopy;
object oItem = GetFirstItemInInventory(oSecPC);
while (GetIsObjectValid(oItem))
  {
  oCopy = CopyItem(oItem, oPC, TRUE);
  DestroyObject(oItem);
  oItem = GetNextItemInInventory(oSecPC);
  }
}

Автор: ][umepa Mar 27 2005, 09:32

скрипт чтобы NPC шел за игроком. Будет идти даже после окончания боя.
1создаёте диалог. на вкладке ACTION TAKEN пишите команду

Neverwinter Script Source
void main()
{
object oPC = GetPCSpeaker();
ActionForceFollowObject(oPC, 1.0);
SetLocalObject(OBJECT_SELF, "PC_TO_FOLLOW", oPC);
}


cтавьте на ветку диалога.
2теперь в скрипте OnSpawn надо раскомментировать строчку SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT);
раскомментировать значит убрать вот такой знак // т.е просто стираете эти слэши.У меня в скрипте подобной комадны сразу не было я вставил сразу ту о которой говорил выше
3 теперь в скрипте OnUserDefined пишите
Neverwinter Script Source
void main()
{
int nEvent = GetUserDefinedEventNumber();
if (nEvent == EVENT_HEARTBEAT)
  {
  object oPC = GetLocalObject(OBJECT_SELF, "PC_TO_FOLLOW");
  // если ПС не определен ИЛИ идет бой -> прервать сценарий
  if(!GetIsObjectValid(oPC) || GetIsInCombat() ) return;
  ActionForceFollowObject(oPC, 1.0);
  }
}


не забудьте сохранить стандартный скрипт OnUserDefined,а новый скрипт под другим именем
вот вроде и всё.

Автор: RiPPeR Apr 27 2005, 10:13


СЕРИЯ "СКРИПТЫ ДЛЯ ШАРДА"
ЦИКЛ "СКРИПТЫ RIPPER'a"


Я написал пару простых, но очень полезный скриптов для шардов, на них "нанизываются" все остальные примочки.

Что я сделал:

  • Индексацию игроков
  • Защита их аккаунтов от взлома
  • Сохранение локации и координат игрока после рестарта сервера
  • ДМ палка для управления игроками
Все скрипты взаимосвязанны.

pl_onlogon.nss (поставить в OnClientEnter модуля)
Neverwinter Script Source
//  ===========================================
//  pl_on_logon.nss             12.12.04                                            
//    © RiPPeR                                                                            
//                  glebkk@xaker.ru                                                     
//  ===========================================  

#include "main_spirit"

void main()
{
object oPlayer = GetEnteringObject();
object oSpirit = GetPlayerSpirit(oPlayer);
string ID = IntToString(GetLocalInt(oSpirit, "ID"));
string sAccount = GetPCPlayerName(oPlayer);

string sDB_CDKEY = GetCampaignString("db",sAccount+"_CDKEY");
string sPC_CDKEY = GetPCPublicCDKey(oPlayer);

if (GetStringLength(sDB_CDKEY) <= 1) //Нет записи в базе данных
  SetCampaignString("db",sAccount+"_CDKEY",sPC_CDKEY);
else
if (sDB_CDKEY != sPC_CDKEY)
  BootPC(oPlayer);

if (oSpirit == OBJECT_INVALID) //Новый персонаж
  {
  oSpirit = CreateItemOnObject("spirit", GetEnteringObject(), 1);

  int nCounter = GetCampaignInt("db","pl_Counter") + 1;

  SetLocalInt(oSpirit,"ID",nCounter);
  SetCampaignInt("db","pl_Counter",nCounter);

  ID = IntToString(nCounter);
  }
else //Старый
  {
  }

SetLocalInt(oSpirit,"bFlaged",1);
SetLocalInt(oSpirit,"bConnected",1);
}


pl_on_logoff.nss (поставить в OnClientLeave модуля)

Neverwinter Script Source
//  ===========================================
//  pl_on_logoff.nss             12.12.04                                            
//    © RiPPeR                                                                            
//                  glebkk@xaker.ru                                                     
//  ===========================================  

#include "main_spirit"

void main()
{
object oPlayer = GetExitingObject();
object oSpirit = GetPlayerSpirit(oPlayer);

string ID = IntToString(GetLocalInt(oSpirit,"ID"));

SetLocalInt(oSpirit,"bConnected",0);
}


default.nss
Neverwinter Script Source
//  ===========================================
//  default.nss             12.12.04                                            
//    © RiPPeR                                                                            
//                  glebkk@xaker.ru                                                     
//  ===========================================  

#include "main_spirit"

void main()
{
object oPlayer = OBJECT_SELF;
object oSpirit = GetPlayerSpirit(oPlayer);

vector vPos = GetPosition(oPlayer);

if (GetLocalInt(oSpirit,"bFlaged") == 0)
  {
  SetLocalFloat(oSpirit,"pos_x",vPos.x);
  SetLocalFloat(oSpirit,"pos_y",vPos.y);
  SetLocalFloat(oSpirit,"pos_z",vPos.z);
  SetLocalFloat(oSpirit,"pos_angle",VectorToAngle(vPos));
  }
else
  SetLocalInt(oSpirit,"bFlaged",0);
}

main_spirit.nss (просто инклуд)
Neverwinter Script Source
//  ===========================================
//  main_spirit.nss             12.12.04                                            
//    © RiPPeR                                                                            
//                  glebkk@xaker.ru                                                     
//  ===========================================  

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;
}


main_active_item.nss
Neverwinter Script Source
//  ===========================================
//  main_active_item.nss             12.12.04                                            
//    © RiPPeR                                                                            
//                  glebkk@xaker.ru                                                     
//  ===========================================  

#include "main_spirit"

void main()
{
object oPlayer = GetItemActivator();
object oItem = GetItemActivated();
object oTarget = GetItemActivatedTarget();

string sResRef = GetResRef(oItem);
string sTag = GetTag(oItem);

if (sResRef == "dm_wand")
//if (GetIsDM(oPlayer)) //Раскомментировать, если ДМ-палку может использовать только ДМ
  {
  AssignCommand(oPlayer,ActionStartConversation(oPlayer,"dm_wand_pl_list",TRUE,FALSE));
  ExecuteScript("dm_ban_info",oPlayer);
  SpeakString("DM_WAND ACT",TALKVOLUME_SHOUT);
  }
}


m_def_loc_enter.nss (ставить на OnEnter _всех_ локаций, _кроме_ стартовой)
Neverwinter Script Source
//  ===========================================
//  m_def_loc_enter.nss             12.12.04                                            
//    © RiPPeR                                                                            
//                  glebkk@xaker.ru                                                     
//  ===========================================  

#include "main_spirit"

void main()
{
object oArea = OBJECT_SELF;
object oPlayer = GetEnteringObject();
object oSpirit = GetPlayerSpirit(oPlayer);

string sTag = GetTag(oArea);
string sResRef = GetResRef(oArea);

SetLocalString(oSpirit, "pos_area", sTag);
ExecuteScript(sResRef,oArea); //Раскомментироваться для запуска OnEnter локи скрипта с именем - рес-реф'ом локи
}

m_loc_saver.nss
Сделать локацию 2х2.
Туда поставить таким образом триггеры:
CODE

====
=**=
=**=
====

= - Тригеры для перехода
* - Тригер с этим скриптом

В центре тригера со скриптом поставить стартовый вэйпоинт.

Neverwinter Script Source
//  ===========================================
//  m_loc_saver.nss             12.12.04                                            
//    © RiPPeR                                                                            
//                  glebkk@xaker.ru                                                     
//  ===========================================  

#include "main_spirit"

void main()
{
  object oPlayer = GetEnteringObject();
  object oSpirit = GetPlayerSpirit(oPlayer);

  vector vPlayer;
  location lPlayer;
  object oArea;

  float x = GetLocalFloat(oSpirit,"pos_x");
  float y = GetLocalFloat(oSpirit,"pos_y");
  float z = GetLocalFloat(oSpirit,"pos_z");
  float angle = GetLocalFloat(oSpirit,"pos_angle");

  string sArea = GetLocalString(oSpirit,"pos_area");

  vPlayer = Vector(x,y,z);
  oArea = GetObjectByTag(sArea);

  lPlayer = Location(oArea,vPlayer,angle);

  SetLocalInt(oSpirit,"bConnected",1);
  AssignCommand(oPlayer,ActionJumpToLocation(lPlayer));
}

dm_ban_boot.nss
Neverwinter Script Source
//  ===========================================
//  dm_ban_boot.nss             12.12.04                                            
//    © RiPPeR                                                                            
//                  glebkk@xaker.ru                                                     
//  ===========================================  

#include "main_spirit"

void main()
{
int nID = GetLocalInt(OBJECT_SELF,"DM_WAND_ID");

object oPlayer = GetFirstPC();
object oSpirit;

while (oPlayer != OBJECT_INVALID)
  {
  oSpirit = GetPlayerSpirit(oPlayer);

  if (GetLocalInt(oSpirit,"ID") == nID)
    {
    BootPC(oPlayer);
    break;
    }
  }
}


dm_ban_info.nss
Neverwinter Script Source
//  ===========================================
//  dm_ban_info.nss             12.12.04                                            
//    © RiPPeR                                                                            
//                  glebkk@xaker.ru                                                     
//  ===========================================  

#include "main_spirit"

string PlayerList(object oPC);
object GetPCByPlaceNum(int num);
int GetPCAmount();

string GetGoodEvil(object oPC);
string GetLawChaotic(object oPC);

void main()
{
int num = GetLocalInt(OBJECT_SELF,"DM_WAND_NUM");
int player_amount = GetPCAmount();

if (num == 0)
  num = player_amount;

if (num > player_amount)
  num = 1;

object oPC = GetPCByPlaceNum(num);
int ID = GetLocalInt(GetPlayerSpirit(oPC),"ID");

SetLocalInt(OBJECT_SELF,"DM_WAND_NUM",num);
SetLocalInt(OBJECT_SELF,"DM_WAND_ID",ID);

string sPlayerList = PlayerList(oPC);

SetCustomToken(1999, sPlayerList);
}

string PlayerList(object oPC)
{
//object oPC = GetFirstPC();
string Text = "  Информация о персонаже  \n";

string Account = GetPCPlayerName(oPC);
string Name = GetName(oPC);
string ID = IntToString(GetLocalInt(GetPlayerSpirit(oPC),"ID"));
string CD_KEY = GetPCPublicCDKey(oPC);
string IP = GetPCIPAddress(oPC);

string Level = IntToString(GetLevelByPosition(1, oPC) + GetLevelByPosition(2, oPC) + GetLevelByPosition(3, oPC));
string BadGood = GetGoodEvil(oPC);
string ChaoticLaw = GetLawChaotic(oPC);
string ThisHP = IntToString(GetCurrentHitPoints(oPC));
string MaxHP = IntToString(GetMaxHitPoints(oPC));
string AC = IntToString(GetAC(oPC));

string Area = GetName(GetArea(oPC));

Text += "<cццц>"+"-----------------------------\n";
Text += "<cццц>"+"Аккаунт: "+"<cк>"+Account+"\n";
Text += "<cццц>"+"Имя персонажа: "+"<cк>"+Name+"\n";
Text += "<cццц>"+"ID: "+"<cк>"+ID+"\n";
Text += "<cццц>"+"PUBLIC CD KEY: "+"<cк>"+CD_KEY+"\n";
Text += "<cццц>"+"IP: "+"<cк>"+IP+"\n";
Text += "<cццц>"+"\n";
Text += "<cццц>"+"Уровень: "+"<cк>"+Level+"\n";
Text += "<cццц>"+"Хороший/Злой: "+"<cк>"+BadGood+"\n";
Text += "<cццц>"+"Хаотичный/Порядочный: "+"<cк>"+ChaoticLaw+"\n";
Text += "<cццц>"+"HP: "+"<cк>"+ThisHP+"/"+"<cк>"+MaxHP+"\n";
Text += "<cццц>"+"AC: "+"<cк>"+AC+"\n";
Text += "<cццц>"+"Локация: "+"<cк>"+Area+"\n";

return Text;
}

object GetPCByPlaceNum(int num)
{
object oPC = GetFirstPC();
int num2 = 0;

for (num2 = 0; num2 < num - 1; num2++)
  oPC = GetNextPC();

return oPC;
}

int GetPCAmount()
{
object oPC = GetFirstPC();
int num = 0;

while (oPC != OBJECT_INVALID)
  {
  num++;
  oPC = GetNextPC();
  }

return num;
}

string GetGoodEvil(object oPC)
{
int ret = GetAlignmentGoodEvil(oPC);

if (ret == ALIGNMENT_GOOD)
  return "GOOD";

if (ret == ALIGNMENT_EVIL)
  return "EVIL";

if (ret == ALIGNMENT_NEUTRAL)
  return "NEUTRAL";

return "OBJECT_INVALID";
}

string GetLawChaotic(object oPC)
{
int ret = GetAlignmentLawChaos(oPC);

if (ret == ALIGNMENT_LAWFUL)
  return "LAWFUL";

if (ret == ALIGNMENT_CHAOTIC)
  return "CHAOTIC";

if (ret == ALIGNMENT_NEUTRAL)
  return "NEUTRAL";

return "OBJECT_INVALID";
}

dm_ban_minus.nss
Neverwinter Script Source
//  ===========================================
//  dm_ban_minus.nss             12.12.04                                            
//    © RiPPeR                                                                            
//                  glebkk@xaker.ru                                                     
//  ===========================================  

void main()
{
SetLocalInt(OBJECT_SELF,"DM_WAND_NUM",GetLocalInt(OBJECT_SELF,"DM_WAND_NUM") - 1);
ExecuteScript("dm_ban_info",OBJECT_SELF);
ExecuteScript("dm_w_return",OBJECT_SELF);
}

dm_ban_plus.nss
Neverwinter Script Source
//  ===========================================
//  dm_ban_plus.nss             12.12.04                                            
//    © RiPPeR                                                                            
//                  glebkk@xaker.ru                                                     
//  ===========================================  

void main()
{
SetLocalInt(OBJECT_SELF,"DM_WAND_NUM",GetLocalInt(OBJECT_SELF,"DM_WAND_NUM") + 1);
ExecuteScript("dm_ban_info",OBJECT_SELF);
ExecuteScript("dm_w_return",OBJECT_SELF);
}

dm_w_return.nss
Neverwinter Script Source
//  ===========================================
//  dm_w_return.nss             12.12.04                                            
//    © RiPPeR                                                                            
//                  glebkk@xaker.ru                                                     
//  ===========================================  

void main()
{
ExecuteScript("dm_ban_info",OBJECT_SELF);
AssignCommand(OBJECT_SELF,ActionStartConversation(OBJECT_SELF,"dm_wand_pl_list",TRUE,FALSE));
}


Для работы скриптов ДМ-посоха нужно:
Создать любой итем с рес-реф'ом "dm_wand" и Уник Повером.
Создать диалог dm_wand_pl_list

Структура диалога:
CODE

[OWNER] - <CUSTOM1999>
       |
Запутить (ActionTaken - dm_ban_boot)
Следующий игрок (ActionTaken - dm_ban_plus)
Предыдущий игрок (ActionTaken - dm_ban_minus)
Выход


Это чисто пример по созданию посоха, можно легко модернизировать во что-то оч. хорошее smile.gif. Дерзайте

Кроме того обязательно нужно создать в палитре новый итем с тагом "Spirit", ResRef'ом "spirit", Undropable

p.s. у кого проблемы с установкой пишите в приват.

МОДУЛЬ МОЖНО СКАЧАТЬ http://glebkk.xaker.ru/Basic.zip

Автор: Aiwan Jun 9 2005, 09:39

Тут мне понадобились факела включаемые. Помнится кто-то из молодежи спрашивал как сделать. Вот скрипт и демка в виде файла.

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: OnEnter  am_ten_torch_on
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
    ВКЛЮЧАЕМ ОГОНЬ ФАКЕЛОВ И ЗВУК К НИМ НОЧЬЮ.

Таг факела = "AM_PLS_TORCH_ON". Он должен быть с
активированной анимацией и отключена опция Static.
Звуковой объект ставим рядом с факелом, помните его таг
ДОЛЖЕН БЫТЬ УНИКАЛЬНЫМ ВО ВСЕМ МОДУЛЕ. Иначе не
сработает. К примеру таг моего звука, равен тагу
триггера плюс порядковый номер, начиная с еденицы:
AM_SOUND_TORTCH_(порядковый номер = i). Расставляйте
на локации факела и звуки рядом. Все готово!

*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 08.06.2005
//:://///////////////////////////////////////////
#include "am_inc_debug"
void main()
{
  int i=1; // Первый порядковый номер тага звука
  float f=0.5; // Задержка включения
  float r=f+0.2; // Задержка пересчета освещения
  object oPC = GetEnteringObject();
  string sSound = GetTag(OBJECT_SELF); // Приравнял таг триггера к звуовому
  object oTorch = GetFirstObjectInArea(OBJECT_SELF);
  object oSound = GetObjectByTag(sSound+IntToString(i)); // Звуковой объект
  if (!GetIsPC(oPC)) {return;}
//---------------------------------- ДЕНЬ --------------------------------------
  if (GetIsDay() && !GetLocalInt(OBJECT_SELF, "DEACTIVATED"))
     // Если день но факела горят
  {
  while (GetIsObjectValid(oTorch))
      {
       if (GetTag(oTorch) == "AM_PLS_TORCH_ON" && !GetLocalInt(oTorch, "LIGHT_OFF"))
         /* Проверяем все объекты на локации, берем с нужным тегом и без
             локальной переменной, что с объектом уже выключен. */

          {
          SetLocalInt(oTorch, "LIGHT_OFF", TRUE);
          AssignCommand(oTorch, PlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE));
          DelayCommand(f, SetPlaceableIllumination(oTorch, FALSE));
          DelayCommand(r, RecomputeStaticLighting(GetArea(oTorch)));
          Debug(FloatToString(f));
          Debug(FloatToString®);
          f=f+0.4; // Сделай паузу!
          r=f+0.2; // Глотни-ка тоже, фанты.
        /* Каджый факел заставим съесть Твикс. И прересчитаем свет позже. Не
           должно быть рывков, но если они все же появились, увеличьте немного, на 0.2,
           к примеру. Если и потом не пропали, то выкиньте ваш компьютер в окно,
           Это надо было сделать года два назад.                                  */

          }
          if (GetIsObjectValid(oSound))
             {
             SoundObjectStop(oSound); // Выключаем звук
             i++;  // Присвоим объекту звука таг на единицу больше
             }
       oSound = GetObjectByTag("AM_SOUND_TORCH_"+IntToString(i));
       oTorch = GetNextObjectInArea(OBJECT_SELF);
      }
   SetLocalInt(OBJECT_SELF, "DEACTIVATED", TRUE);
   }
//----------------------------- НОЧЬ -------------------------------------------
  if (GetIsNight() && GetLocalInt(OBJECT_SELF, "DEACTIVATED"))
     // Если ночь но мы затушили факела
  {
  while (GetIsObjectValid(oTorch))
      {
       if (GetTag(oTorch) == "AM_PLS_TORCH_ON" && GetLocalInt(oTorch, "LIGHT_OFF"))
           {
          SetLocalInt(oTorch, "LIGHT_OFF", FALSE);
          AssignCommand(oTorch, PlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
          DelayCommand(f, SetPlaceableIllumination(oTorch, TRUE));
          DelayCommand(r, RecomputeStaticLighting(GetArea(oTorch)));
          Debug(FloatToString(f));
          Debug(FloatToString®);
          f=f+0.4;
          r=f+0.2;
          }
          if (GetIsObjectValid(oSound))
             {
             SoundObjectPlay(oSound); // Включаем звук
             i++; // Присвоим объекту звука таг на единицу больше
             }
       oSound = GetObjectByTag("AM_SOUND_TORCH_"+IntToString(i));
       oTorch = GetNextObjectInArea(OBJECT_SELF);
      }
   SetLocalInt(OBJECT_SELF, "DEACTIVATED", FALSE); // ЧТо бы один раз сработало
   return;
   }
}

Добавлено в [mergetime]1118299586[/mergetime]
CODE
Блин, парсется (r) на ®, заккоментрируйте строку в скрипте или исправьте Debug(FloatToString®);

Добавлено в [mergetime]1118299909[/mergetime]
Neverwinter Script Source
//::///////////////////////////////////////////////
//:: Name: am_inc_common
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
          БИБЛИОТЕКА ДЛЯ ОТЛАДКИ СКРИПТОВ
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan      Aiwan@e-mail.ru
//:: Created On: 30.05.2005
//:://////////////////////////////////////////////

// СООБЩЕНИЯ ДЛЯ ПРОВЕРКИ (ИСПОЛЬЗУЮТСЯ В СЛУЖЕБНЫХ ЦЕЛЯХ ДЛЯ ОТЛАДКИ КОДА СКРИПТОВ)
// А ТАК ЖЕ ДЛЯ ДМ-ов
// LocalInt - "DEBAG_PC" на модуле, отключит дебаг игрокам
// LocalInt - "DEBAG_DM" на модуле, отключит дебаг DM-ам
void Debug(string message);
// Выводит в Debug: TAG, ResRef и Name объекта.
void DebugObject(object oObject);

//------------------------------------------------------------------------------
void Debug(string message)
{
    object oPC = GetFirstPC();
    if (!GetLocalInt(GetModule(), "DEBAG_PC"))
    {
      SendMessageToPC(oPC, "Debag message: "+message);
    }
    if (!GetLocalInt(GetModule(), "DEBAG_DM"))
          {
            SendMessageToAllDMs("Debag message to DMs: "+message);
          }
}
void DebugObject(object oObject)
{
    string sTag = GetTag(oObject);
    string sResRef = GetResRef(oObject);
    string sName = GetName(oObject);
    Debug ("TAG = "+sTag+", ResRef = "+sResRef+",  Name = "+sName+".");
}
/*
void main(){}


 demo_mod.rar ( 9.63 килобайт ) : 76
 

Автор: Buldog Jun 23 2005, 20:21

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

И вылилась идейка вот в такой скрипт:

Neverwinter Script Source
//////////////////////////////////////
//////////////////////////////////////
//////For Area Transmition Trigers////
//////////////////////////////////////
//////////OnClick Script//////////////
//////////////////////////////////////
////////////Created By Buldog/////////
////////////////23.06.05//////////////
//////////////////////////////////////
//////////////////////////////////////

void main()
{
    object oPC = GetClickingObject();
    object oTarget = GetTransitionTarget(OBJECT_SELF);
    object oTArea = GetArea(oTarget);

    location lTarget;

    vector vPC = GetPosition(oPC);
    vector vTarget = GetPosition(oTarget);
    vector vTLoc = Vector();

    vTLoc.z = vPC.z;

    if(vPC.x < 10.0 || vPC.x > vTarget.x * 2 - 10) vTLoc.x = vTarget.x * 2 - vPC.x;
    else vTLoc.x = vPC.x;

    if(vPC.y < 10.0 || vPC.y > vTarget.y * 2 - 10) vTLoc.y = vTarget.y * 2 - vPC.y;
    else vTLoc.y = vPC.y;

    float fFace = GetFacing(oPC);

    lTarget = Location(oTArea, vTLoc, fFace);

    AssignCommand(oPC, ClearAllActions());
    AssignCommand(oPC, ActionJumpToLocation(lTarget));
}


Подготовка местности:

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

Ограничения:

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

Автор: Aiwan Jun 24 2005, 21:22

Функция для библиотеки. Выдает любому уровню процент ХР заданный вами. К примеру у вас квестов 10. Зашел РС 30 левелом или 5 -м, всеравно выполнив 10 квестов он наберет 1 левел...

Neverwinter Script Source
//::///////////////////////////////////////////////
//:: Name: am_inc_dialog
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
          БИБЛИОТЕКА ДЛЯ ДИАЛОГОВ
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan      Aiwan@e-mail.ru
//:: Created On: 22.06.2005
//:://////////////////////////////////////////////
#include "am_inc_debug"

// ФУНКЦИЯ РАЗДЕЛЕНИЯ ХР В ЗАВИСИМОСТИ ОТ УРОВНЯ
// iPercent - Проценты от уровня. По умолчанию 10%
void GiveXPScale(object oPC, int iPercent=10);

//------------------------------------------------------------------------------
void GiveXPScale(object oPC, int iPercent=10)
{
    object oCreature;
    int iHit = GetHitDice(oPC); // Берем уровень объекта
    int iXP; // Это искомое число ХР для квеста
    int i = iHit*1000; // Это ХР на один уровень больше чем у объекта
    iXP= i/iPercent;
    Debug("Уровень ХР на один больше нашего - "+IntToString(i));
    Debug("Процент добавляемого ХР от уровня - "+IntToString(iPercent));
    Debug("Искомая сумма ХР - "+IntToString(iXP));
    /*
    Нужное количество ХР равно ХР на уровень больше, деленное на число
    int iP, которое определяет процент от уровня. По умолчанию это 10%.
    */

    GiveXPToCreature(oPC,iXP);
}
/*
void main(){}

Автор: Friedrich Aug 10 2005, 22:15

Вот маленький инклюд с функцией makeTrace изображает дымную трассу (типа как от ракеты) между двумя точками, с помощью виз. эффектов (н.п. VFX_FNF_SMOKE_PUFF).
Что-то похожее было в первом модуле СоУ в подземелье с плохой эльфой.

Neverwinter Script Source
// ********************************* //
// * fh_inc_trace                  * //
// * (с) Friedrich W. Heik, 2005.  * //
// * darkowl@inbox.ru              * //
// ********************************* //

//** Interface **

// Преобразует декартовы координаты в сферические
// Возвращаемый вектор имеет формат:
// x - ro:  расстояние от начала координат до точки
// y - fi:  угол поворота, вокруг вертикальной оси (от оси X против ч.с.)
// z - psi: угол наклона от горизонтальной плоскости
vector sph(vector vDsc);

// Преобразует сферические координаты в декартовы
// Формат вектора vSph:
// x - ro:  расстояние от начала координат до точки
// y - fi:  угол поворота, вокруг вертикальной оси (от оси X против ч.с.)
// z - psi: угол наклона от горизонтальной плоскости
vector dsc(vector vSph);

// Изменяет абс. величину вектора
// Возвр. вектор длиною fMagnitude, сонаправленный с vVector.
vector setMagnitude(vector vVector, float fMagnitude);

// Рисует дымную трассу между двумя точками
// lSource:  Начало трассы
// lTarget:  Цель
// fJump:    Дистанция шага между эффектами, м.
// fSpeed:    Скорость "снаряда", м/с
// nTraceVFX: эффект дыма, которым рисуется трасса
// nBurstVFX: эффект взрыва в конце трассы (исп. -1 (VFX_NONE), если взрыв не требуется) 
void makeTrace(location lSource, location lTarget, float fJump = 0.25f, float fSpeed = 10.0f, int nTraceVFX = VFX_FNF_SMOKE_PUFF, int nBurstVFX = VFX_FNF_FIREBALL);


//** Implementation **

// Преобразует декартовы координаты в сферические
// Возвращаемый вектор имеет формат:
// x - ro:  расстояние от начала координат до точки
// y - fi:  угол поворота, вокруг вертикальной оси (от оси X против ч.с.)
// z - psi: угол наклона от горизонтальной плоскости
vector sph(vector vDsc)
{
  float ro = VectorMagnitude(vDsc);
  float fi = atan(vDsc.y/vDsc.x); // I четверть
  float psi = asin(vDsc.z/ro);

  if (vDsc.x < 0.0) fi += 180.0;      // II, III: +Pi
  else if (vDsc.y < 0.0) fi += 360.0; // IV: +2Pi, чтобы угол был положительным smile.gif
  return Vector(ro, fi, psi);
}

// Преобразует сферические координаты в декартовы
vector dsc(vector vSph)
{
  float x = vSph.x*cos(vSph.z)*cos(vSph.y); // ro*cos(psi)*cos(fi)
  float y = vSph.x*cos(vSph.z)*sin(vSph.y); // ro*cos(psi)*sin(fi)
  float z = vSph.x*sin(vSph.z); // ro*sin(psi)
  return Vector(x, y, z);
}

vector setMagnitude(vector vVector, float fMagnitude)
{
  vector vSph = sph(vVector);
  vSph.x = fMagnitude;
  return dsc(vSph);
}

void makeTrace(
  location lSource,    // Начало трассы
  location lTarget,    // Цель
  float fJump = 0.25f// Дистанция шага между эффектами, м.
  float fSpeed = 10.0f, // Скорость "снаряда", м/с
  int nTraceVFX = VFX_FNF_SMOKE_PUFF,
  int nBurstVFX = VFX_FNF_FIREBALL) 
{
  float fInterval = fJump/fSpeed;
  effect eVis = EffectVisualEffect(nTraceVFX);

  vector vOA = GetPositionFromLocation(lSource); // вектор (OA)
  vector vOB = GetPositionFromLocation(lTarget); // вектор (OB)
  vector vAB = vOB - vOA; // вектор (AB) = (OB)-(OA)
 
  //vector vNorm = VectorNormalize(vAB); // единичный вектор, коллинеарный AB
  vector vJump = setMagnitude(vAB, fJump);
 
  vector vCurrent = vOA;
  object oArea = GetAreaFromLocation(lTarget);
  int n = FloatToInt( VectorMagnitude(vAB)/fJump );
  int i;
  float fDelay = 0.0;
  for (i=0; i < n; i++)
  {
    vCurrent += vJump;
    location lCurrent = Location(oArea, vCurrent, 0.0);
    fDelay += fInterval;
    DelayCommand(fDelay, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lCurrent));
  }
  // Fireball VFX on target:
  if (nBurstVFX != VFX_NONE)
  {
    fDelay += fInterval;
    effect eBurst = EffectVisualEffect(nBurstVFX);
    DelayCommand(fDelay, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eBurst, lTarget));
  }
}
//void main(){}


Функции, устанавливают заданное числовое значение аляймента:
Neverwinter Script Source
void setGoodEvilValue(object oCreature, int nValue)
{
  if(!GetIsObjectValid(oCreature)||
    (GetObjectType(oCreature) != OBJECT_TYPE_CREATURE))
    return;
 
  if (nValue < 0) nValue = 0;
  else if (nValue > 100) nValue = 100;
 
  int nCurGE = GetGoodEvilValue(oCreature);
  int nShift = abs(nCurGE - nValue);
  if (nShift == 0) return;
  int nDir = (nValue > nCurGE) ? ALIGNMENT_GOOD : ALIGNMENT_EVIL;
  AdjustAlignment(oCreature, nDir, nShift);
  if (GetGoodEvilValue(oCreature) != nValue)
    setGoodEvilValue(oCreature, nValue);
}

void setLawChaosValue(object oCreature, int nValue)
{
  if(!GetIsObjectValid(oCreature)||
    (GetObjectType(oCreature) != OBJECT_TYPE_CREATURE))
    return;
 
  if (nValue < 0) nValue = 0;
  else if (nValue > 100) nValue = 100;
 
  int nCurLC = GetLawChaosValue(oCreature);
  int nShift = abs(nCurLC - nValue);
  if (nShift == 0) return;
  int nDir = (nValue > nCurLC) ? ALIGNMENT_LAWFUL : ALIGNMENT_CHAOTIC;
  AdjustAlignment(oCreature, nDir, nShift);
  if (GetLawChaosValue(oCreature) != nValue)
    setLawChaosValue(oCreature, nValue);
}
//void main(){}

Вдруг кому-нибудь пригодится.

Автор: DraX Aug 12 2005, 11:16

Нет проблем. Итак, вот он, скрипт:

Neverwinter Script Source
if(GetLocalInt(OBJECT_SELF, "DO_ONCE") != 1)
{
string sTag = "OBJECT"// Тэг нужного нам объекта
num nNum = 1// Начинаем считать объекты с номера 1 по нужный нам

for(nNum = 1; nNum <= 4; nNum++)  // Номер 4 - кол-во объектов
{
  int nNum2 = nNum++;

  if(nNum2 > 4)
    nNum2 = 1;

  object oStart = GetObjectByTag(sTag + "_" + nNum);
  object oEnd = GetObjectByTag(sTag + "_" + Num2);

  ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectBeam(VFX_BEAM_FIRE, oEnd, BODY_NODE_CHEST), oStart);
}

SetLocalInt(OBJECT_SELF, "DO_ONCE", 1);
}


Спасибо, Aiwan. Этот скрипт и вправду лучше - не загружает систему и более обширней в применении. Ставить на OnHeartbeat локации или триггера.

ЗЫ: Сорри за опечатки

Автор: 2_advanced Aug 30 2005, 15:11

альтернатива стандартному отдыху с возможностью ставить свою анимацию, выставлять время реста, проверки до/после/во время реста и т.п.

Neverwinter Script Source
void RestEnd()
{
    object oPC = OBJECT_SELF;

    int nRez = GetLocalInt(oPC, "LastEventRest"); // спим?

    DeleteLocalInt(oPC, "LastEventRest");
    DeleteLocalLocation(oPC, "RestLocation");

    if(!nRez) // не спим
        return;

    FadeFromBlack(oPC, FADE_SPEED_SLOWEST); //

    object oBedroll = GetLocalObject(oPC, "bedroll");
    if(GetIsObjectValid(oBedroll))
    {
        DestroyObject(oBedroll, 3.5f);
        CreateItemOnObject(BEDROLL_IT_RES, oPC);
        DeleteLocalObject(oPC, "bedroll");
    }
}

void RestFinish()
{
    object oPC = OBJECT_SELF;

    if(!GetLocalInt(oPC, "LastEventRest"))
        return;

    DeleteLocalInt(oPC, "NextRest");

    ActionMoveToLocation(GetLocation(oPC)); // stand up tongue.gif

//todo:сохр нужного - хп. и т.п.
    ForceRest(oPC);
//todo:восстановление

    SendMessageToPC(oPC, "<cооо>Отдых закончен..</c>");

    if(!GetLocalInt(oPC, "REST_DONT_SLEEP"))
        ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD);

    RestEnd();
}

void RestFailCheck() // check chance to rest // c:RestBegin: random(restduration)
{
    object oPC = OBJECT_SELF;
    object oArea = GetArea(oPC);

    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_SLEEP), oPC);

    if(!GetLocalInt(oPC, "LastEventRest"))
        return;

    if(!GetIsObjectValid(oArea))
        return;

    object oPC2 = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC); // спокойный рест если рядом кто-то есть
    if(oPC2 != OBJECT_INVALID && !GetIsEnemy(oPC, oPC2) && GetDistanceBetween(oPC, oPC2) < 10.0)
        return;

    object oChance = GetNearestObjectByTag(REST_CHANCE_PL_TAG);
    if(oChance == OBJECT_INVALID)
        return;

    int nChance = GetLocalInt(oChance, "REST_CHANCE");

    if(!nChance || (nChance >= d100()))
        return;

    RestEnd();
}

void RestThread() // cancel rest checks tongue.gif // c:RestBegin
{
    object oPC = OBJECT_SELF;

    if(!GetLocalInt(oPC, "LastEventRest")) // уже не спим
        return;

// враждебная крича или перемещения игрока
    object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
    if( GetLocation(oPC) != GetLocalLocation(oPC, "RestLocation") ||
        (GetIsObjectValid(oEnemy) && GetDistanceBetween(oEnemy, oPC) < 15.0)   )
    {
        SendMessageToPC(oPC, "<cооо>Отдых сорван.</c>");
        RestEnd();
        return;
    }

    if(GetLocalInt(oPC, "REST_DONT_SLEEP"))
        ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE, 1.0, 3.0);
    else
        ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT, 1.0, 3.0);

    AssignCommand(oPC, DelayCommand(3.0f, RestThread())); // повтор
}

void NextRestTimer() // proc. 4 min. for failed rest // c:RestBegin
{
    object oPC = OBJECT_SELF;

    int nCurr = GetLocalInt(oPC, "NextRest");

    if(nCurr)
    {
        if(!GetLocalInt(oPC, "LastEventRest"))
            SetLocalInt(oPC, "NextRest", nCurr - 1);

        AssignCommand(oPC, DelayCommand(30.0, NextRestTimer())); // временной промежуток между рестами(при неудаче): 8 * 30 сек = 4 мин
    }
}

void RestBegin(float fSeconds)
{
    object oPC = OBJECT_SELF;

    ClearAllActions();

    SetLocalInt(oPC, "NextRest", 8); // временной промежуток между рестами
    SetLocalInt(oPC, "LastEventRest", 1); // рест?!
    SetLocalLocation(oPC, "RestLocation", GetLocation(oPC));

    AssignCommand(oPC, DelayCommand(30.0f, NextRestTimer()));
    AssignCommand(oPC, DelayCommand(3.0f + fSeconds, RestFinish())); // финиш
    AssignCommand(oPC, DelayCommand(3.0f, RestThread())); // проверки

    DelayCommand(3.5f, FadeToBlack(oPC, FADE_SPEED_MEDIUM));
}

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

    if(GetIsDM(oPC) || GetIsDMPossessed(oPC))
    {
        ForceRest(oPC);
        return;
    }

    object oMod = GetModule();

    if(GetLocalInt(oPC, "LastEventRest")) // рест уже запущен. игрок пытается перезапустить
    {
        AssignCommand(oPC, ClearAllActions());
       
        if(GetLocalInt(oPC, "REST_DONT_SLEEP"))
            DelayCommand(0.1f, ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE, 1.0, 3.0));
        else
            DelayCommand(0.1f, ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT, 1.0, 3.0));
       
        return;
    }


    int nNextRest = GetLocalInt(oPC, "NextRest");
    if(nNextRest)
    {
        AssignCommand(oPC, ClearAllActions());
        SendMessageToPC(oPC, "<cооо>Отдых возможен в течение " + IntToString(nNextRest/2) + " минут</c>");
        return;
    }


    object oChance = GetNearestObjectByTag(REST_CHANCE_PL_TAG); // неспокойность места smile.gif
    if(oChance != OBJECT_INVALID)
    {
        int nChance = GetLocalInt(oChance, "REST_CHANCE");
        if(!nChance)
        {
            AssignCommand(oPC, ClearAllActions());
            SendMessageToPC(oPC, "<cо0о>Вы не можете отдыхать тут.</c>");
            return;
        }
    }

    switch(GetLastRestEventType())
    {
        case REST_EVENTTYPE_REST_STARTED:
            int nDelay = REST_DELAY;
            int nLastRest = GetActionLastTime(oPC, "REST");

            if(nLastRest < nDelay)
            {
                FloatingTextStringOnCreature("<cооо>Вы не устали.</c>", oPC, 0);
                SendMessageToPC(oPC, "<cо0о>Отдых возможен через " + IntToString(nDelay - nLastRest - 1) + ":" + IntToString(59-GetTimeMinute()) + " час(а) .</c>");
                AssignCommand(oPC, ClearAllActions());
                return;
            }

// проверки на наличие необходимых для отдыха итемов
            oBedroll = GetItemPossessedBy(oPC, BEDROLL_IT_RES);
            if(GetClassByPosition(1, oPC) == CLASS_TYPE_MONK || GetRacialType(oPC) == RACIAL_TYPE_ELF)
            {
                SetLocalInt(oPC, "REST_DONT_SLEEP", 1);
            }
            else
            if(GetIsObjectValid(oBedroll))
            {
                DestroyObject(oBedroll);
                oBedroll = CreateObject(OBJECT_TYPE_PLACEABLE, BEDROLL_PL_RES, GetLocation(oPC));
                SetLocalObject(oPC, "bedroll", oBedroll);
            }
            else
            {
                SendMessageToPC(oPC, "<cооо>Вам не на чем спать.</c>");
                AssignCommand(oPC, ClearAllActions());
                return;
            }

// костёр smile.gif но тут не о нём
            object oCamp = GetNearestObjectByTag(CAMPFIRE_PL_RES, oPC);
            if(GetIsDay() || (GetIsObjectValid(oCamp) && GetDistanceBetween(oCamp, oPC) < 4.5))
                SetLocalInt(oPC, "REST_CAMPFIRE", 1);

// из 2да время отдыха
            int nRestDuration = StringToInt(Get2DAString("restduration", "DURATION", GetHitDice(oPC)));
            if(nRestDuration)
            {
                float fCheckDelay = IntToFloat(nRestDuration)/1000.0f;

                DelayCommand(0.1f, AssignCommand(oPC, ActionUnequipItem(GetItemInSlot(INVENTORY_SLOT_LEFTHAND)))); // убрать все из рук
                DelayCommand(0.2f, AssignCommand(oPC, ActionUnequipItem(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND))));
                DelayCommand(0.4f, AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0, 2.7))); // анимация укладывания лежака
                DelayCommand(0.0f, AssignCommand(oPC, RestBegin(fCheckDelay))); // рест.начало

                DelayCommand(IntToFloat(Random(nRestDuration))/1000.0f, AssignCommand(oPC, RestFailCheck())); // ..проснуться в неспокойном месте tongue.gif
            }

            break;
    }
}

в модульный onEnter:
Neverwinter Script Source
DeleteLocalInt(oPC, "NextRest");
DeleteLocalInt(oPC, "LastEventRest");

Добавлено в 15:18
позволяет получать разницу во времени между действиями..

Neverwinter Script Source
void SetActionLastTime(object oPC, string sAction)
{
    string sPCName = GetPCPlayerName(oPC); // для уникальности.. вообще использую № персонажа

    int nHour = GetTimeHour();
    int nDay  = GetCalendarDay();
    int nMonth = GetCalendarMonth();
    int nYear = GetCalendarYear();

    string sData = IntToString(nHour) + ";" + IntToString(nDay) + ";" + IntToString(nMonth) + ";" + IntToString(nYear) + ";";

    SetLocalString(GetModule(), sAction + sPCName, sData);
}

int GetActionLastTime(object oPC, string sAction)
{
    string sPair;
    string sPCName = GetPCPlayerName(oPC);
    string sData = GetLocalString(GetModule(), sAction + sPCName);

    if(sData == "")
    {
        return 100;
    }

    int nLastMinute;
    int nLastHour;
    int nLastDay;
    int nLastMonth;
    int nLastYear;

    int i;
    for(i=0; i<5; i++)
    {
        int nPos = FindSubString(sData, ";"); // вычленение. почему в НВС нет phpшного explode? biggrin.gif
        if(nPos != -1)
        {
            sPair = GetStringLeft(sData, nPos);
            sData = GetStringRight(sData, GetStringLength(sData) - 1 - nPos);

            switch(i)
            {
                case 0: nLastHour   = StringToInt(sPair); break;
                case 1: nLastDay    = StringToInt(sPair); break;
                case 2: nLastMonth  = StringToInt(sPair); break;
                case 3: nLastYear   = StringToInt(sPair); break;
            }
        }
    }

    int nMinute = GetTimeMinute();
    int nHour = GetTimeHour();
    int nDay  = GetCalendarDay();
    int nYear = GetCalendarYear();
    int nMonth = GetCalendarMonth();

    if(nLastYear != nYear)
        nMonth = nMonth + 12;

    if(nLastMonth != nMonth)
        nDay = nDay + 28 * (nYear - nLastYear);

    if(nDay != nLastDay)
        nHour = nHour + 24 * (nDay - nLastDay);

    return (nHour - nLastHour);
}

Автор: Aiwan Sep 20 2005, 08:57

Скрипт запрещает классы в модуле. Годится для сингла. Для шардов надо придумать как описать РС. Ставится это добро на OnPlayerLevelUp модуля.

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: OnPlayerLevelUp  "am_mod_levelup"
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
  Скрипт запрещающий использование выборочных
  классов в модуле. Спасибо Dumbo за упрощенную
  форумулу, моя была в пять раз больше pardon.gif.
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 20.09.2005
//:://////////////////////////////////////////////
void main()
{
    object oPC = GetFirstPC();
    int iHit = GetHitDice(oPC); // Берем уровень игрока
    int iXP = GetXP(oPC); // Вся ХР игрока
    string sClass; // Для сообщения игроку что он сделал неправильно
    int iClass2 = GetClassByPosition(2, oPC); // Второй класс мультикласса
    int iClass3 = GetClassByPosition(3, oPC); // Третий  класс мультикласса
    int F = CLASS_TYPE_FIGHTER; // Воин
    int R = CLASS_TYPE_ROGUE;  // Вор
    int D = CLASS_TYPE_DRUID;  // Друид
    int P = CLASS_TYPE_PALADIN; // И так далее...

    // Для примера классs: Если Воин, Вор, Друид, Паладин
    if  ((iClass2==F || iClass3==F) || (iClass2==R || iClass3==R)
      || (iClass2==D || iClass3==D) || (iClass2==P || iClass3==P))
      {
          if(iClass2==F || iClass3==F) sClass = "Воин";
          if(iClass2==R ||  iClass3==R) sClass = "Вор";
          if(iClass2==D || iClass3==D) sClass = "Друид";
          if(iClass2==P || iClass3==P) sClass = "Паладин";

        // Присвоим РС в начале ХР на уровень меньше, значит заберем один
        // уровень, что мы запретили из использования. Дальше, мы возвращаем
        // назад всю нашу ХР, ведь ХР может быть намного больше чем мы
        // потратили на поднятие уровня.
        SetXP(oPC, (iHit*(iHit-1)*500)-((iHit-1)*1000));
        DelayCommand(0.5, SetXP(oPC, iXP));

        // Можно так сообщить, можно что-то другое.
        SendMessageToPC(oPC, "Вы использовали запрещенный класс: "+sClass);

        /*
          Тут можно вписать что-нибудь из эффектов, для острастки.
        */

      }
}

Автор: 2_advanced Oct 26 2005, 19:42

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

зы. необходим неразрушимый невидимый объект sittingsurface

Neverwinter Script Source
void main()
{
    object oPC = GetLastUsedBy();
    object oChair = OBJECT_SELF;

    if(GetIsObjectValid(oChair) && GetIsObjectValid(oPC))
    {
        object oSurf = GetLocalObject(oChair, "surf");

        if(GetIsObjectValid(oSurf))
        {
            object oSitter = GetSittingCreature(oSurf);

            if(!GetIsObjectValid(oSitter) || GetArea(oSitter) != GetArea(oChair))
                DestroyObject(oSurf);
            else
                return;
        }

        vector vSurf = GetPosition(oChair);
        vSurf.z = 0.0;

        location lSurf = Location(GetArea(oChair), vSurf, GetFacing(oChair));

        object oNewSurf = CreateObject(OBJECT_TYPE_PLACEABLE, "sittingsurface", lSurf, FALSE);

        SetLocalObject(oChair, "surf", oNewSurf);

        AssignCommand(oPC, ActionSit(oNewSurf));
    }
}
для доработки: выкидывать игрока с *объекта посадки* при уничтожении стула, профиксить баг с высотой посадки для разных расс (было такое на 1.29 о_О), сделать возможным усаживаться нескольким персонажам на 1 большой объект (диван pardon.gif) с автораспределением свободных сидячих мест.
<сделаю позже swoon.gif >

Автор: Aiwan Nov 2 2005, 00:18

Скрипт вешается на строку диалога НПС. Если он загородил нам проход, просим отойти в сторону. Очень актуально для сингла. Когда НПС стоит поперек выхода и нет сил его обойти...

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: ActionTaken  am_at_npc_step
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
  NPC уходит на точку рандомную точку, освобождая
  игроку проход в локации. Использует функцию
  генерирования рандомной локации.
*/

//:://///////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 01.10.2005
//:://///////////////////////////////////////////
//:: CreateRandomLocation Function by Baal
//:://///////////////////////////////////////////
location CreateRandomLocation(object oTarget, float fRadius, int bOnLine = TRUE)
{
if(!bOnLine)
fRadius=IntToFloat(Random(FloatToInt(fRadius)));

float iXO=VectorMagnitude(GetPosition(oTarget))*cos(VectorToAngle(GetPosition(oTarget)));
float iYO=VectorMagnitude(GetPosition(oTarget))*sin(VectorToAngle(GetPosition(oTarget)));
float fRndomAngle=IntToFloat(Random(360));
location lNEW=Location(GetArea(oTarget),Vector(iXO+fRadius*cos(fRndomAngle),iYO+fRadius*sin(fRndomAngle)),360.0);
return lNEW;
}
//:://///////////////////////////////////////////

void main()
{
    object oPC = GetPCSpeaker(); // Игрок
    object oSelf = OBJECT_SELF; // НПС с которым идет диалог
    location lFree = CreateRandomLocation(oSelf, 5.0);
    // Генерим случайную точку в радиусе 5 метров
    int iRun = FALSE; // Параметр определяющий скорость НПС

    if(GetLocalInt(oSelf, "RUN"))
      {
        iRun = TRUE; // Если присвоить локалку "RUN" на НПС, то он побежит.
      }
    AssignCommand(oSelf, ClearAllActions()); // Почистим стек команд
    AssignCommand(oSelf, ActionMoveToLocation(lFree, iRun));
    // Использую ActionMove, что бы НПС не переместился в "мертвую" точку без прохода.
    AssignCommand(oSelf, ActionDoCommand(SetFacingPoint(GetPosition(oPC))));
}

Автор: Aiwan Nov 8 2005, 15:13

Скрипт активирует на локации енкаучеры ночные и дневные. Соответсвенно одни выключает, другие включает. Все работает как часы и оптимизировано Лексом. За шо ему гранд респект. good.gif

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: OnEnter  am_ahb_day_night
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
  Скрипт локаций День/Ночь. Запускает OnUserDefined
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Edit By: Lex
//:: Created On: 24.05.2005
//:://///////////////////////////////////////////
//#include "am_inc_common"
void main()
{
object oPC = GetFirstPC();
if (GetArea(oPC) != OBJECT_SELF) return;

if (GetIsDusk()||GetIsNight())
    {
    if (GetLocalInt(OBJECT_SELF, "Night") != 1)
        {
        SetLocalInt(OBJECT_SELF, "Day", 0);
        SetLocalInt(OBJECT_SELF, "Night", 1);
        SignalEvent(OBJECT_SELF, EventUserDefined(3000));
        return;
        }
    else return;
    }
if (GetIsDawn()||GetIsDay())
    {
    if (GetLocalInt(OBJECT_SELF, "Day") != 1)
        {
        SetLocalInt(OBJECT_SELF, "Night", 0);
        SetLocalInt(OBJECT_SELF, "Day", 1);
        SignalEvent(OBJECT_SELF, EventUserDefined(1000));
        return;
        }
    else return;
    }
}


Neverwinter Script Source
//:://////////////////////////////////////////////
//:: ActionTaken  lm_aud_enc_activ
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
    Активирует енкаучеры. Дневные и ночные.
  LocalInt(oEnc, "ENCOUNTER_SPAWN_NIGHT") - ночные.
  LocalInt(oEnc, "ENCOUNTER_SPAWN_DAY") - дневные.
*/

//:://///////////////////////////////////////////
//:: Created By: Lex
//:: Created On: 08.11.2005
//:://///////////////////////////////////////////

void EncounterController(int ActivateStatus, object oArea = OBJECT_SELF)
{
int nEN = GetLocalInt(oArea,"ENCOUNTERS");
object oEncounter;
while (nEN > 0)
    {
    oEncounter = GetLocalObject(oArea,"ENCOUNTER_"+IntToString(nEN));
    if(GetLocalInt(oEncounter, "ENCOUNTER_SPAWN_NIGHT"))
        SetEncounterActive(!ActivateStatus, oEncounter);
    else  if(GetLocalInt(oEncounter, "ENCOUNTER_SPAWN_DAY"))
        SetEncounterActive(ActivateStatus, oEncounter);
    nEN--;
    }
}

void main()
{
  int nEvent = GetUserDefinedEventNumber();
  int ActivateStatus;
  int nEN = GetLocalInt(OBJECT_SELF,"ENCOUNTERS");
  if (nEN == 0)
      {
      object oEnc = GetFirstObjectInArea(OBJECT_SELF);
      while (GetIsObjectValid(oEnc))
          {
            if(GetObjectType(oEnc) == OBJECT_TYPE_ENCOUNTER)
                {
                nEN++;
                SetLocalObject(OBJECT_SELF,"ENCOUNTER_"+IntToString(nEN),oEnc);
                }
            oEnc = GetNextObjectInArea(OBJECT_SELF);
          }
      if (nEN == 0) nEN = -1;
      SetLocalInt(OBJECT_SELF,"ENCOUNTERS",nEN);
      }
if (nEvent == 1000) // День
  {
  if (nEN == -1) return;
  EncounterController(TRUE);
  return;
  }
if (nEvent == 3000) // Ночь
  {
  if (nEN == -1) return;
  EncounterController(FALSE);
  return;
  }
}

Добавлено в [mergetime]1131452068[/mergetime]
А, забыл! scratch_one-s_head.gif Первый на хертбит арены. Второй на юзерДеф ей же.

Автор: Aiwan Nov 14 2005, 14:45

Выкладываю скрипт+заготовку ERF триггера, что бы вы не мучались с настройкой. Давно я использую на триггерах три своих темповых скрипта, для присвоения каких-нибудь локалок на игрока, для проверки того или иного диалога, строки, действия и прочее. Очень меня задолбало это. Писать каждый раз новый скрипт и я написал триггер для теста. Что он делает? Он присваивает до 5 уникальных локалок на игрока и НПС, может отправить НПС в точку которую вы укажите. Например, НПС в другой локе, вы наступили на триггер, он спавнился рядом и повесили на него три локалки, повесили на РС две локалки и можно быть в середине вашего сюжета. Еще он (скрипт) может запускать другие скрипты на НПС, РС и OBJECT_SEL, соответсвенно.

Как он настраивается:
DEACTIVATED == 1 отключает триггер после первого раза. Например, вы насупили раз, прошли одну ветку диалога. Подошли, наступили второй, прошли заново диалог и т.д. Надо? Ставьте 0 и будет бесконечно приваивать ваши локалки.
LOCAL_NPC_01 - Присваивает переменную на НПС. Пример: ПЕРЕМЕННАЯ_01

Neverwinter Script Source
SetLocalInt(oNPC, "ПЕРЕМЕННАЯ", 1);
SetLocalInt(oNPC, "ДРУГАЯ_ПЕРЕМЕННАЯ", 2);

LOCAL_PC_01 - Присваивает переменную на PС. Пример: ПЕРЕМЕННАЯ_01
Neverwinter Script Source
SetLocalInt(oPC, "ПЕРЕМЕННАЯ", 1);
SetLocalInt(oPC, "ДРУГАЯ_ПЕРЕМЕННАЯ", 5);

RUN_SCRIPT - ИМЯ_СКРИПТА - запускает на OBJECT_SELF
Neverwinter Script Source
ExecuteScript("ИМЯ_СКРИПТА", OBJECT_SELF);

RUN_SCRIPT_ON_NPC - ИМЯ_СКРИПТА - запускает на oNpc
Neverwinter Script Source
ExecuteScript("ИМЯ_СКРИПТА", oNpc);

На игрока понятное дело так же.
TAG_NPC - Таг нашего НПС.
TAG_WP_TO_JUMP - ТАГ нашего вейпоинта. НПС прыгнет на него, если только вы укажете ТАГ точки.
Ну вот и все. Все локалки работают до пяти штук на РС и НПС.

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: OnEnter  am_ten_test
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
    ТЕСТОВЫЙ СКРИПТ ДЛЯ ПРИСВОЕНИЯ ПЕРЕМЕННЫХ
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 11.11.2005
//:://////////////////////////////////////////////
//#include "sz_inc_common"
#include "am_inc_debug"

void main()
{
object oPC = GetEnteringObject(); // PC
object oSelf = OBJECT_SELF;
string sNpc = GetLocalString(oSelf, "TAG_NPC");
string sWp = GetLocalString(oSelf, "TAG_WP_TO_JUMP");
object oNpc = GetObjectByTag(sNpc);
object oWp = GetWaypointByTag(sWp);

if(GetLocalInt(oSelf, "DEACTIVATED")==2)
  return;
/*
//------------------------------------------------------------------------------
  Заккоментированные строки работают с библиотекой SlavaZ-а, на которой
  построены многие квесты наших модулей.

//------------------------------ КВЕСТ #1 --------------------------------------
string sQ1 = GetLocalString(oSelf, "QUEST_01");
string sQuest1 = GetStringLeft(sQ1, GetStringLength(sQ1)-3);
int iQ1 = StringToInt(GetStringRight(sQ1, 2));
//------------------------------ КВЕСТ #2 --------------------------------------
string sQ2 = GetLocalString(oSelf, "QUEST_02");
string sQuest2 = GetStringLeft(sQ2, GetStringLength(sQ2)-3);
int iQ2 = StringToInt(GetStringRight(sQ2, 2));
//------------------------------ КВЕСТ #3 --------------------------------------
string sQ3 = GetLocalString(oSelf, "QUEST_03");
string sQuest3 = GetStringLeft(sQ3, GetStringLength(sQ3)-3);
int iQ3 = StringToInt(GetStringRight(sQ3, 2));
//------------------------------ КВЕСТ #4 --------------------------------------
string sQ4 = GetLocalString(oSelf, "QUEST_04");
string sQuest4 = GetStringLeft(sQ4, GetStringLength(sQ4)-3);
int iQ4 = StringToInt(GetStringRight(sQ4, 2));
//------------------------------ КВЕСТ #5 --------------------------------------
string sQ5 = GetLocalString(oSelf, "QUEST_05");
string sQuest5 = GetStringLeft(sQ5, GetStringLength(sQ5)-3);
int iQ5 = StringToInt(GetStringRight(sQ5, 2));

  if(sQ1!=""){
  SetQuestStatus(sQuest1, iQ1, TRUE);
  Debug("Установим переменную QUEST: "+sQuest1+" == "+IntToString(iQ1));}
  if(sQ2!=""){
  SetQuestStatus(sQuest2, iQ2, TRUE);
  Debug("Установим переменную QUEST: "+sQuest2+" == "+IntToString(iQ2));}
  if(sQ3!=""){
  SetQuestStatus(sQuest3, iQ3, TRUE);
  Debug("Установим переменную QUEST: "+sQuest3+" == "+IntToString(iQ3));}
  if(sQ4!=""){
  SetQuestStatus(sQuest4, iQ4, TRUE);
  Debug("Установим переменную QUEST: "+sQuest4+" == "+IntToString(iQ4));}
  if(sQ5!=""){
  SetQuestStatus(sQuest5, iQ5, TRUE);
  Debug("Установим переменную QUEST: "+sQuest5+" == "+IntToString(iQ5));}
*/

//------------------------------------------------------------------------------
//                  Эти переменные вешаются на игрока
//------------------------------------------------------------------------------

//--------------------------- ПЕРЕМЕННАЯ #1 ------------------------------------
string sL1 = GetLocalString(oSelf, "LOCAL_PC_01");
string sLocal1 = GetStringLeft(sL1, GetStringLength(sL1)-3);
int iL1 = StringToInt(GetStringRight(sL1, 2));
//--------------------------- ПЕРЕМЕННАЯ #2 ------------------------------------
string sL2 = GetLocalString(oSelf, "LOCAL_PC_02");
string sLocal2 = GetStringLeft(sL2, GetStringLength(sL2)-3);
int iL2 = StringToInt(GetStringRight(sL2, 2));
//--------------------------- ПЕРЕМЕННАЯ #3 ------------------------------------
string sL3 = GetLocalString(oSelf, "LOCAL_PC_03");
string sLocal3 = GetStringLeft(sL3, GetStringLength(sL3)-3);
int iL3 = StringToInt(GetStringRight(sL3, 2));
//--------------------------- ПЕРЕМЕННАЯ #4 ------------------------------------
string sL4 = GetLocalString(oSelf, "LOCAL_PC_04");
string sLocal4 = GetStringLeft(sL4, GetStringLength(sL4)-3);
int iL4 = StringToInt(GetStringRight(sL4, 2));
//--------------------------- ПЕРЕМЕННАЯ #5 ------------------------------------
string sL5 = GetLocalString(oSelf, "LOCAL_PC_05");
string sLocal5 = GetStringLeft(sL5, GetStringLength(sL5)-3);
int iL5 = StringToInt(GetStringRight(sL5, 2));

  if(sL1!=""){
  SetLocalInt(oPC, sLocal1, iL1);
  Debug("Установим переменную на РС LocalInt: "+sLocal1+" == "+IntToString(iL1));}
  if(sL2!=""){
  SetLocalInt(oPC, sLocal2, iL2);
  Debug("Установим переменную на РС LocalInt: "+sLocal2+" == "+IntToString(iL2));}
  if(sL3!=""){
  SetLocalInt(oPC, sLocal3, iL3);
  Debug("Установим переменную на РС LocalInt: "+sLocal3+" == "+IntToString(iL3));}
  if(sL4!=""){
  SetLocalInt(oPC, sLocal4, iL4);
  Debug("Установим переменную на РС LocalInt: "+sLocal4+" == "+IntToString(iL4));}
  if(sL5!=""){
  SetLocalInt(oPC, sLocal5, iL5);
  Debug("Установим переменную на РС LocalInt: "+sLocal5+" == "+IntToString(iL5));}

//------------------------------------------------------------------------------
//                  Эти переменные вешаются на НПС
//------------------------------------------------------------------------------

//--------------------------- ПЕРЕМЕННАЯ #1 ------------------------------------
string sLn1 = GetLocalString(oSelf, "LOCAL_NPC_01");
string sLocalN1 = GetStringLeft(sLn1, GetStringLength(sLn1)-3);
int iLn1 = StringToInt(GetStringRight(sLn1, 2));
//--------------------------- ПЕРЕМЕННАЯ #2 ------------------------------------
string sLn2 = GetLocalString(oSelf, "LOCAL_NPC_02");
string sLocalN2 = GetStringLeft(sLn2, GetStringLength(sLn2)-3);
int iLn2 = StringToInt(GetStringRight(sLn2, 2));
//--------------------------- ПЕРЕМЕННАЯ #3 ------------------------------------
string sLn3 = GetLocalString(oSelf, "LOCAL_NPC_03");
string sLocalN3 = GetStringLeft(sLn3, GetStringLength(sLn3)-3);
int iLn3 = StringToInt(GetStringRight(sLn3, 2));
//--------------------------- ПЕРЕМЕННАЯ #4 ------------------------------------
string sLn4 = GetLocalString(oSelf, "LOCAL_NPC_04");
string sLocalN4 = GetStringLeft(sLn4, GetStringLength(sLn4)-3);
int iLn4 = StringToInt(GetStringRight(sLn4, 2));
//--------------------------- ПЕРЕМЕННАЯ #5 ------------------------------------
string sLn5 = GetLocalString(oSelf, "LOCAL_NPC_05");
string sLocalN5 = GetStringLeft(sLn5, GetStringLength(sLn5)-3);
int iLn5 = StringToInt(GetStringRight(sLn5, 2));

  if(sLn1!=""){
  SetLocalInt(oNpc, sLocalN1, iLn1);
  Debug("Установим переменную на "+GetName(oNpc)+" LocalInt: "+sLocalN1+" == "+IntToString(iLn1));}
  if(sLn2!=""){
  SetLocalInt(oNpc, sLocalN2, iLn2);
  Debug("Установим переменную на "+GetName(oNpc)+" LocalInt: "+sLocalN2+" == "+IntToString(iLn2));}
  if(sLn3!=""){
  SetLocalInt(oNpc, sLocalN3, iLn3);
  Debug("Установим переменную на "+GetName(oNpc)+" LocalInt: "+sLocalN3+" == "+IntToString(iLn3));}
  if(sLn4!=""){
  SetLocalInt(oNpc, sLocalN4, iLn4);
  Debug("Установим переменную на "+GetName(oNpc)+" LocalInt: "+sLocalN4+" == "+IntToString(iLn4));}
  if(sLn5!=""){
  SetLocalInt(oNpc, sLocalN5, iLn5);
  Debug("Установим переменную на "+GetName(oNpc)+" LocalInt: "+sLocalN5+" == "+IntToString(iLn5));}
//------------------------------------------------------------------------------
// Тут мы определяем нашего НПС. Отправляем его на вейпоинт, енсли нужно.
//------------------------------------------------------------------------------
  if(sNpc!="" && !GetIsObjectValid(oNpc))
    {
      Debug("ОШИБКА! Вашего НПС не существует!");
    }
  if(sWp!="")
  {
      if(!GetIsObjectValid(oWp))
        {
          Debug("ОШИБКА! Неправильный ТАГ вейпоинта!");
          return;
        }
      AssignCommand(oNpc, ClearAllActions());
      AssignCommand(oNpc, JumpToObject(oWp));
  }
//------------------------------------------------------------------------------
//  Тут мы запускаем нужные скрипты на игрока, НПС или просто на сам триггер.
//------------------------------------------------------------------------------
string sScOnPC = GetLocalString(oSelf, "RUN_SCRIPT_ON_PC");
string sScOnNpc = GetLocalString(oSelf, "RUN_SCRIPT_ON_NPC");
string sScOnSelf = GetLocalString(oSelf, "RUN_SCRIPT");

if(sScOnPC!="")
{
  ExecuteScript(sScOnPC, oPC);
  Debug("Запущен скрипт "+sScOnPC+" на РС");
}
if(sScOnNpc!="")
{
  ExecuteScript(sScOnNpc, oNpc);
  Debug("Запущен скрипт "+sScOnNpc+" на "+GetName(oNpc));
}
if(sScOnSelf!="")
{
  ExecuteScript(sScOnSelf, oSelf);
  Debug("Запущен скрипт "+sScOnSelf+" на OBJECT_SELF");
}
//------------------------------------------------------------------------------
//                Параметры, определяют работу триггера.
//------------------------------------------------------------------------------
if(GetLocalInt(oSelf, "DEACTIVATED")==1)
  SetLocalInt(oSelf, "DEACTIVATED", 2);
}


http://www.wrg.ru/TEMP/Aiwan/am_tr_test.erf.rar


 

Автор: -fenix- Nov 16 2005, 14:10

Вот тут решил написать скрипты, которые может кому, пригодятся, но лично мне они пока не нужны. Зачем написал? Просто так. crazy.gif

Что эти скрипты делают?
Они дают процент экспы за убийство/разрушение объекта равное проценту нанесенного ущерба.
Пример:
Есть бочка, у нее 10 хитов.
За разрушение назначено 100 опыта.
Если вы снимите 100% хитов(10), то получите 100% опыта(100).
Если вы снимете 50% хитов(5), то получите 50% опыта(50). Остальной опыт либо пропадет (если кроме вас объект лупили только НПС), либо поделится между другими ПС лупившими объект, либо поделится между всеми ПС и часть пропадет, от лупивших НПС.
ХМ, надеюсь, идея ясна.
Приступим к скриптам.
Для реализации нам нужно два скрипта: один на OnDamaged объекта, другой на OnDeath объекта. Скрипты универсальные и ограничений по атакующим у них нет. Дома я проверил, как смог, но так как шарда у меня дома нет, то данный аспект проверить не смог. Но по идее все работает нормально, если заметите баг, обязательно сообщите. Еще, на шарде ни когда не играл, поэтому может это и не идеальный код для него, но думаю, что знающим людям поправить будет не сложно. smile.gif
И так, сами скрипты.


На OnDamaged объекта

Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Created By: -fenix-
//:: Created On: 16.11.2005
//:://////////////////////////////////////////////

void main()
{
object oDamager = GetLastDamager();
int iMaxHit = GetMaxHitPoints();
int iCurHit = GetCurrentHitPoints();
string sNamePC = GetName(oDamager);
int i,Z, iDamage;

if(GetIsPC(oDamager))//если атакующий ПС
{
    //индекс, по каторому будут отличаться все переменные нужные
    for(i = 1; i <= GetLocalInt(OBJECT_SELF, "KOLICHESTVO"); i ++)
    {
        //если такое имя уже есть
        if(sNamePC == GetLocalString(OBJECT_SELF, "NAME_PC_" + IntToString(i)))
        {
            //сколько всего было нанесено ущерба(включая только что нанесенный удар)
            if(iCurHit < 0)
            {
                iDamage = iMaxHit;
            }
            else
            {
                iDamage = iMaxHit - iCurHit;
            }
            //запоминаем кол-во нанесенного ущерба данным ПС
            SetLocalInt(OBJECT_SELF, IntToString(i) + "_DamagePC", (iDamage - GetLocalInt(OBJECT_SELF, "DamageAll")) + GetLocalInt(OBJECT_SELF, IntToString(i) + "_DamagePC"));
            //запоминаем общий ущерб
            SetLocalInt(OBJECT_SELF, "DamageAll", GetLocalInt(OBJECT_SELF, "DamageAll") + (iDamage - GetLocalInt(OBJECT_SELF, "DamageAll")));
            //это для проверки. Можете удалить, можете оставить и потестить
            SendMessageToPC(oDamager, GetLocalString(OBJECT_SELF, "NAME_PC_" + IntToString(i)) + "_нанес1_" + IntToString(GetLocalInt(OBJECT_SELF, IntToString(i) + "_DamagePC")));
            //это для проверки. Можете удалить, можете оставить и потестить
            SendMessageToPC(oDamager, "DamageAll1="
            IntToString(GetLocalInt(OBJECT_SELF, "DamageAll")));
            Z = 1;// чтобы знать, был такой ПС или нет
        }
    }
    //новый ПС
    if(Z != 1)
    {
        //сколько всего было нанесено ущерба(включая только что нанесенный удар)
        if(iCurHit < 0)
        {
            iDamage = iMaxHit;
        }
        else
        {
            iDamage = iMaxHit - iCurHit;
        }
        //добавляем его к "старым" ПС
        SetLocalInt(OBJECT_SELF, "KOLICHESTVO", GetLocalInt(OBJECT_SELF, "KOLICHESTVO") + 1);
        //запоминаем его имя
        SetLocalString(OBJECT_SELF, "NAME_PC_" +
IntToString(GetLocalInt(OBJECT_SELF, "KOLICHESTVO")), sNamePC);
        //запоминаем кол-во нанесенного ущерба данным ПС
        SetLocalInt(OBJECT_SELF, IntToString(GetLocalInt(OBJECT_SELF
"KOLICHESTVO")) + "_DamagePC", (iDamage - GetLocalInt(OBJECT_SELF"DamageAll")));
        //запоминаем общий ущерб
        SetLocalInt(OBJECT_SELF, "DamageAll", GetLocalInt(OBJECT_SELF,
"DamageAll") + GetLocalInt(OBJECT_SELF,
      IntToString(GetLocalInt(OBJECT_SELF, "KOLICHESTVO")) + "_DamagePC"));

/*это для проверки. Можете удалить, можете оставить и потестить*/                     
SendMessageToPC(oDamager,GetLocalString(OBJECT_SELF,"NAME_PC_"+IntToString(GetLocalInt(OBJECT_SELF,"KOLICHESTVO")))
+"_нанес2_"+IntToString(GetLocalInt(OBJECT_SELF,IntToString(GetLocalInt(OBJECT_SELF,"KOLICHESTVO"))+"_DamagePC")));
        //это для проверки. Можете удалить, можете оставить и потестить
        SendMessageToPC(oDamager, "DamageAll2=" + IntToString(GetLocalInt(OBJECT_SELF, "DamageAll")));
    }
}
else//если атакующий не ПС
{
    //сколько всего было нанесено ущерба(включая только что нанесенный удар)
    if(iCurHit < 0)
    {
        iDamage = iMaxHit;
    }
    else
    {
        iDamage = iMaxHit - iCurHit;
    }
    //запоминаем общий ущерб
    SetLocalInt(OBJECT_SELF, "DamageAll", (iDamage - GetLocalInt(OBJECT_SELF,       
    "DamageAll")) + GetLocalInt(OBJECT_SELF, "DamageAll"));
    //это для проверки. Можете удалить, можете оставить и потестить
    SendMessageToPC(GetFirstPC(), "Общий ущерб_" +         
    IntToString(GetLocalInt(OBJECT_SELF, "DamageAll")));
}
}


Второй скрипт ставется на OnDeath объекта. Этот скрипт раздает опыт.
Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Created By: -fenix-
//:: Created On: 16.11.2005
//:://////////////////////////////////////////////

void main()
{
int iMaxHit = GetMaxHitPoints();
int iMaxXP = 100;//тут указываем кол-во опыта за уничтожение объекта
int i, S, iXPPC;

//сколько всего ПС атаковало объект
for(i = 1; i <= GetLocalInt(OBJECT_SELF, "KOLICHESTVO"); i ++)
{
    object oPC = GetFirstPC();

    while(S != 100)
    {
        string sNamePC = GetName(oPC);
        //если мя совпадает
        if(sNamePC == GetLocalString(OBJECT_SELF, "NAME_PC_" + IntToString(i)))
        {
          //считаем кол-во опыта
          iXPPC=((100 * GetLocalInt(OBJECT_SELF, IntToString(i) + "_DamagePC") / iMaxHit) * iMaxXP) / 100;
            //если получается меньше одного, то округляем до 1
            if(iXPPC <1)
            {
                iXPPC = 1;
            }
            GiveXPToCreature(oPC, iXPPC);//даем опыт
            S = 100;
        }
        oPC = GetNextPC();
    }
    S = 0;
}
}

Ну и еще их маленький брат - скрипт считающий отдельно урон ПС и урон всех остальных. Иногда бывает очень нужно узнать урон нанесенный объекту ПС. Скрипт для сингла.
Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Created By: -fenix-
//:: Created On: 20.10.2005
//:://////////////////////////////////////////////

void main()
{
object oPC = GetLastDamager();
int iMaxHit = GetMaxHitPoints();
int iCurHit = GetCurrentHitPoints();


if(GetIsPC(oPC))
{
    int i, j;

    for(i = 1; i = j; i ++)
    {
        if(GetName(oPC) == GetLocalString(OBJECT_SELF, IntToString(i)))
        {
            int iDamage = iMaxHit - iCurHit;

            SetLocalInt(OBJECT_SELF, "DamagePC", (iDamage - GetLocalInt(OBJECT_SELF, "DamageOther") - GetLocalInt(OBJECT_SELF, "DamagePC")) + GetLocalInt(OBJECT_SELF, "DamagePC"));
            SendMessageToPC(oPC, IntToString(GetLocalInt(OBJECT_SELF, "DamagePC")));
        }
        else
        {
            SetLocalString(OBJECT_SELF, IntToString(i + 1), GetName(oPC));
            j = j + 1;
        }
    }
}
else
{
    int iDamage = iMaxHit - iCurHit;

    SetLocalInt(OBJECT_SELF, "DamageOther", (iDamage - GetLocalInt(OBJECT_SELF, "DamagePC") - GetLocalInt(OBJECT_SELF, "DamageOther")) + GetLocalInt(OBJECT_SELF, "DamageOther"));
    SendMessageToPC(oPC, IntToString(GetLocalInt(OBJECT_SELF, "DamageOther")));
}
}


З.Ы Сорри, что порвал страницу blush.gif
Aiwan: вообще-то некоторые строки можно делить и переносить. this.gif
-fenix-: просто мне как-то неудобно так ориентироваться wacko.gif
Но впредь, на форуме, буду строки делить и переноситьyes.gif

Автор: Lex Dec 7 2005, 21:11

Neverwinter Script Source
//::============================================================================
//::    L&A Script Systems - TEXT COLORS  (TS)
//::============================================================================
string sASCII = "#####################################$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ЂЃ‚ѓ„…†‡?‰Љ‹ЊЌЋЏђ‘’“”•--?™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬­®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя";

//:: COLOR CONSTANTS
const string TC_DARK_GRAY = "<c°°°>";
const string TC_GRAY = "<c¦¦¦>";
const string TC_DARK_CYAN = "<c ¦¦>";
const string TC_DARK_MAGENTA = "<c¦ ¦>";
const string TC_DARK_YELLOW = "<c¦¦ >";
const string TC_DARK_RED = "<c¦  >";
const string TC_DARK_GREEN = "<c ¦ >";
const string TC_DARK_BLUE = "<c  ¦>";
const string TC_NONE = ""; // Default (no color)
const string TC_END = "</c>"; // (color end TAG)
const string TC_DEFAULT = TXT_COLOR_NONE;
const string TC_WHITE = "<cяяя>"; // White
const string TC_CYAN = "<c яя>"; // Light Cyan
const string TC_MAGENTA = "<cя я>"; // Magenta
const string TC_YELLOW = "<cяя >"; // Yellow
const string TC_RED = "<cя  >"; // Red
const string TC_GREEN = "<c я >"; // Green
const string TC_BLUE = "<c  я>"; // Blue


// Используйте числа более 35 (там системные знаки, они заменены на #)
string TC_GetASCIIChar(int nByte);
// меняет цвет текста на соответствующий 3 параметрам:
// Red   - красный
// Green - зеленый
// Blue  - синий
// цвет стандарта RGB
string TC_ColorTextRGB(string sText, int nRed, int nGreen, int nBlue);
// меняет цвет текста на соответствующий константе
string TC_ColorText(string sText, string sColor);

//::============================================================================
string TC_GetASCIIChar(int nByte)
{
return GetSubString(sASCII, nByte, 1);
}
//::============================================================================
string TC_ColorTextRGB(string sText, int nRed, int nGreen, int nBlue)
{
string sResult = "<c" + TC_GetASCIIChar(nRed) + TC_GetASCIIChar(nGreen) + TC_GetASCIIChar(nBlue) + ">" + sText + TC_END;
return sResult;
}
//::============================================================================
string TC_ColorText(string sText, string sColor)
{
string sResult = sColor + sText + TC_END;
return sResult;
}

Автор: justshurik Feb 4 2006, 00:48

Скрипт мой, все совпадения с другими скриптами случайны.
Скрипт для управления группой NPC в реальном времени, без создания waypoint-ов. Позволяет группировать NPC в любые построения(к примеру в Каре, Свинью, Шеренгу,Полк и т д.и т п на Ваш вкус) и перемещать их в таком построении. Можно использовать при построении масштабных баталий с участием большого количества неписей(причем под управлением игрока)

CODE

location Preobr(vector a, object oArea);
vector Arifm(vector a,vector b,int flag=0);
float ABSVect(vector a);
vector Proizv(vector a, float n);
vector Ort(vector a);
vector Perpend(vector a);
location Loc(float a,float b, object oArea,object oPC,location CastSpell);
void Go(object NPC, location CastSpell,object oPC,object oArea,float a,float b );
////////////////////////////////////////////////////////////////////////////////
void main()
{
object oPC=GetItemActivator();
object oItem =GetItemActivated();
object oArea=GetObjectByTag("arena");
object oNPC1=GetObjectByTag("NPC1");
object oNPC2=GetObjectByTag("NPC2");
object oNPC3=GetObjectByTag("NPC3");
object oNPC4=GetObjectByTag("NPC4");
object oNPC5=GetObjectByTag("NPC5");
object oNPC6=GetObjectByTag("NPC6");
object oNPC7=GetObjectByTag("NPC7");

if("panel"==GetTag(oItem))
{
location lTarget=GetItemActivatedTargetLocation();
AssignCommand(oNPC1,ClearAllActions());
Go(oNPC1,lTarget,oPC,oArea,1.0,1.0);
//                         a     b
AssignCommand(oNPC2,ClearAllActions());
Go(oNPC2,lTarget,oPC,oArea,1.0,-1.0);
//                         a      b
AssignCommand(oNPC3,ClearAllActions());
Go(oNPC3,lTarget,oPC,oArea,5.0,5.0);
//                         a      b
AssignCommand(oNPC4,ClearAllActions());
Go(oNPC4,lTarget,oPC,oArea,5.0,-5.0);
//                         a     b
AssignCommand(oNPC5,ClearAllActions());
Go(oNPC5,lTarget,oPC,oArea,10.0,10.0);
//                         a     b
AssignCommand(oNPC6,ClearAllActions());
Go(oNPC6,lTarget,oPC,oArea,10.0,-10.0);
//                         a      b
AssignCommand(oNPC7,ClearAllActions());
Go(oNPC7,lTarget,oPC,oArea,5.0,0.0);
}; //                      a    b
}


/*******************************************************************************/
//preobrazovanie vector -> location

location Preobr(vector a, object oArea)
{
location Loc1=Location(oArea,a,GetFacing(oArea));
return Loc1;
}

//slogenie i vichitanie vectorov a i b

vector Arifm(vector a,vector b,int flag=0)
{
float ax,ay,az,bx,by,bz;
ax=a.x;
ay=a.y;
az=a.z;
bx=b.x;
by=b.y;
bz=b.z;
if(flag==0)
{
vector Res1=Vector(ax+bx,ay+by,az+bz);
return Res1;
}
else
{
vector Res2=Vector(bx-ax,by-ay,bz-az);
return Res2;
};
}

//ABS vectora
float ABSVect(vector a)
{
float Mod=sqrt((a.x*a.x)+(a.y*a.y)+(a.z*a.z));
return Mod;
}

//umnogenie vectora na skalyar

vector Proizv(vector a, float n)
{
vector Res=Vector(n*a.x,n*a.y,a.z);
return Res;
}

//Ortonormirovka vectora

vector Ort(vector a)
{
float Mod=ABSVect( a);
vector Res=Vector(a.x/Mod,a.y/Mod,a.z/Mod);
return Res;
}

//perpendikulyar k vectoru

vector Perpend(vector a)
{
vector Res=Vector((-1.0)*a.y,a.x,a.z);
return Res;
}

//osnovnaya funkciya

location Loc(float a,float b, object oArea,object oPC,location CastSpell)
{
vector vPC=GetPosition(oPC);

vector vCastSpell=GetPositionFromLocation(CastSpell);

vector vLocal1=Arifm(vPC,vCastSpell,2);

vector vLocal = Ort(vLocal1);

vector Dop=Proizv(vLocal,a);

vector vDop=Arifm(vLocal1,Dop);

vector vGlobalDop=Arifm(vDop,vPC);

vector vPerpendik=Perpend(vDop);

vector vOrt= Ort(vPerpendik);

vector vLocalRes= Proizv(vOrt,b );

vector vGlobalRes=Arifm(vLocalRes,vGlobalDop);

location Result2=Preobr(vGlobalRes,oArea);

return Result2;
}

void Go(object oNPC, location CastSpell,object oPC,object oArea,float a,float b )
{
CastSpell=GetItemActivatedTargetLocation();
location lTarget=Loc(a,b,oArea,oPC,CastSpell);
AssignCommand(oNPC,ActionMoveToLocation(lTarget,TRUE));
}

Построение можно регулировать с помощью двух параметров a и b. a отвечает за то как удален будет NPC от игрока, а b - за смещение NPC вправо или влево.

Для использования необходимо:
1) Создать предмет со свойством "активировать предмет:дальнее расстояние" и тагом "panel"
2)Поставить группу из семи NPC с тагоми:NPC1 , NPC2 , NPC3 , NPC4 , NPC5 , NPC6 , NPC7
При желании количество неписей и их построение можно поменять произвольным образом

Автор: azathoth Apr 8 2006, 19:05

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

NSS
// name: i_string
// type: Библиотека
// desc: Строковые функции
// autor: Nightwalker Sorcerer
// date: 4.01.2006
// modified: 11.01.2006

////////////////////////////////////////////////////////////////////////////////
// INFO ////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

/*

Contains:

int FindFirstOf(string sString, string sPattern, int nFrom = 0, int bSymbols = TRUE);
int FindLastSubString(string sString, string sSubString);
int FindSubStringFrom(string sString, string sSubString, int nCount = 0);
int Match(string sString, string sPattern);

*/


////////////////////////////////////////////////////////////////////////////////
// CONSTANTS ///////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

const string ANY_SYMBOL = "?";
const string ANY_SEQUENCE = "*";
const string P_BEGIN = "["; // открывающая скобка (1 символ)
const string P_END = "]"; // закрывающая скобка (1 символ)
const string P_OR = "|"; // ИЛИ выражение внутри скобок (1 символ)
const string SYMBOL_NOT = "!";

////////////////////////////////////////////////////////////////////////////////
// FUNCTION DEFINITIONS ////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

// Нахождение первого вхождение в строку sString символов из набора sPattern.
// - sString: строка для поиска;
// - sPattern: набор символов;
// - nFrom: позиция символа, с которого начинается поиск;
// - bSymbols: Зарезервировано, используйте умолчание, чтобы в следующих
//             версиях библиотеки функция работала как предполагалось.
// * Возвращает позицию в строке или отрицательное значение, если
//   позиция не найдена.
// --> Например:
//   > FindFirstOf("a", "abc") - возвращает 0;
//   > FindFirstOf("word", "ro") - возвращает 1;
//   > FindFirstOf("word", " _[](),.-") - возвращает отрицательное значение;
//   > FindFirstOf("wоw", "w", 1) - возвращает 2;
//   > FindFirstOf("string", "some", 1) - возвращает отрицательное значение.
int FindFirstOf(string sString, string sPattern, int nFrom = 0, int bSymbols = TRUE);

// Нахождение последнего вхождения строки sSubString в строку sString.
// - sString: строка для поиска;
// - sSubString: искомая подстрока.
// * Возвращает позицию в строке или отрицательное значение, если позиция
//   не найдена.
int FindLastSubString(string sString, string sSubString);

// Нахождение позиции подстроки sSubstring внутри строки sString,
// начиная поиск с позиции nCount.
// - sString: строка, в которой ищем;
// - sSubString: что ищем;
// - nCount: ищем начиная с этой позиции.
// * Возвращает позицию подстроки или отрицательное значение, если подстрока
//   не найдена.
int FindSubStringFrom(string sString, string sSubString, int nCount = 0);

// Провека совпадения сторки sString с шаблоном sPattern:
// '?' считается любым символом;
// '*' cчитается любой последовательностью символов,
//     в том числе пустой (без символов);
// '!' совпадение считается, если остаток строки не подходит к шаблону,
//     испольйте только в начале шаблона или скобочного выражения,
//     иначе за результат не ручаюсь;
// [..|..|..] один из вариантов, допускается вложенность.
// - sString: строка для проверки;
// - sPattern: правильная палитра.
// * Возвращает TRUE, если строки совпадают, и FALSE, если нет.
// --> Например:
//   > "?*" - любая непустая последовательность;
//   > "itm_*" - все строки, начинающиеся с "itm_";
//   > "i_*_gold" - строки вида "i_25_gold", "i_pi_gold", а также "i__gold";
//   > "*a*" - строки, в которых есть хоть одна буква а;
//   > "[X|N]*" - тэги всех стандарнтых вещей NWN и дополнений;
//   > "[|?[|?]]" - пустая строка или 1-2 символа;
//   > "!wrong" - любая строка, кроме "wrong".
int Match(string sString, string sPattern);

////////////////////////////////////////////////////////////////////////////////
// IMPLEMENTATION //////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

int FindFirstOf(string sString, string sPattern, int nFrom = 0, int bSymbols = TRUE)
{
    int nResult = -1;
    int nCounter, nPosition, nLengthPattern = GetStringLength(sPattern);
    for (nCounter = 0; nCounter < nLengthPattern; nCounter++)
    {
        nPosition = FindSubStringFrom(sString, GetSubString(sPattern, nCounter, 1), nFrom);
             if (nResult < 0) nResult = nPosition;
        else if ((nPosition >= 0) && (nResult > nPosition)) nResult = nPosition;
    }

    return nResult;
}

int FindLastSubString(string sString, string sSubString)
{
    int nSubStrLength, nResult, nNext;

    if ((nSubStrLength = GetStringLength(sSubString)) == 0) return -1;
    if ((nNext = (nResult = FindSubString(sString, sSubString))) < 0) return nResult;

    while ((nNext = FindSubString((sString = GetStringRight(sString, GetStringLength(sString) - nNext - nSubStrLength)), sSubString)) >= 0)
    {
        nResult += (nNext + nSubStrLength);
    }

    return nResult;
}

int FindSubStringFrom(string sString, string sSubString, int nCount = 0)
{
    int nResult = FindSubString(GetStringRight(sString, GetStringLength(sString) - nCount) , sSubString);
    if (nResult < 0) return nResult;
    return (nResult + nCount);
}

int Match(string sString, string sPattern)
{
    // DEBUG
    //SendMessageToPC(GetFirstPC(), "Сравнение '"+sString+"' с '"+sPattern+"'.");

    int nS, nPhB, nPhE;
    int nLengthString = GetStringLength(sString);
    int nLengthPattern = GetStringLength(sPattern);

    if (GetStringLeft(sPattern, 1) == SYMBOL_NOT)
    {
        return (!Match(sString, GetStringRight(sPattern, nLengthPattern - 1)));
    }

    if ((nPhE = (nPhB = FindSubString(sPattern, P_BEGIN))) >= 0) // обработка ИЛИ выражений
    {
        int nNest = 1; // текущая вложенность
        while ((nPhE >= 0) && (nNest > 0))
        {
            nPhE = FindFirstOf(sPattern, P_BEGIN + P_END, nPhE + 1);
            if (GetSubString(sPattern, nPhE, 1) == P_BEGIN) nNest++;
            else nNest--;
        }
        if (nNest != 0) return FALSE; // неправильно расставлены скобки

        int nPhS, nPhF = nPhB; // начало и конец подстроки
        string sSymbol = "";
        while ((sSymbol != P_END) && (nPhF >= 0))
        {
            nPhS = nPhF + 1;
            sSymbol = "";
            while ((((sSymbol != P_OR) || (nNest > 0)) && ((sSymbol != P_END) || (nNest >= 0))) && (nPhF >= 0))
            {
                nPhF = FindFirstOf(sPattern, P_BEGIN + P_OR + P_END, nPhF + 1);
                sSymbol = GetSubString(sPattern, nPhF, 1);
                     if (sSymbol == P_BEGIN) nNest++;
                else if (sSymbol == P_END) nNest--;
            }
            if (Match(sString, GetStringLeft(sPattern, nPhB) + GetSubString(sPattern, nPhS, nPhF - nPhS) + GetStringRight(sPattern, nLengthPattern - nPhE - 1))) return TRUE;
        }
        return FALSE;
    }

    if ((nS = FindSubString(sPattern, ANY_SEQUENCE)) > 0) // строки, содержащие ANY_SEQUENCE, но не вначале
    {
        if (!Match(GetStringLeft(sString, nS), GetStringLeft(sPattern, nS))) return FALSE;

        // упрощаем в "*..."
        return Match(GetStringRight(sString, nLengthString - nS), GetStringRight(sPattern, nLengthPattern - nS));
    }

    if (nS == 0) // теперь ANY_SEQUENCE вначале
    {
        string sPattern2 = GetStringRight(sPattern, nLengthPattern - 1);
        if ((nS = (FindLastSubString(sPattern2, ANY_SEQUENCE) + 1)) > 0) // есть второй ANY_SEQUENCE
        {
            // конечные кусочки после последнего ANY_SEQUENCE должны "совпадать"
            string sPatternAfterSeq = GetStringRight(sPattern, GetStringLength(sPattern) - nS - 1);
            int nLengthAfterSeq = GetStringLength(sPatternAfterSeq);
            if (!Match(GetStringRight(sString, nLengthAfterSeq), sPatternAfterSeq)) return FALSE;

            // упрощаем в "*...*"
            nLengthString = GetStringLength(sString = GetStringLeft(sString, nLengthString - nLengthAfterSeq));
            nLengthPattern = GetStringLength(sPattern = GetStringLeft(sPattern, nS + 1));

            // DEBUG:
            //SendMessageToPC(GetFirstPC(), "тупой подбор '"+sString+"' к '"+sPattern+"'");
            int nCounter1, nCounter2;
            for (nCounter1 = 1; (nCounter1 < nLengthString); nCounter1++)
            {
                for (nCounter2 = 1; (nCounter2 < nLengthPattern); nCounter2++)
                {
                    if (Match(GetStringLeft(sString, nCounter1), GetStringLeft(sPattern, nCounter2)))
                    if (Match(GetStringRight(sString, nLengthString - nCounter1), GetStringRight(sPattern, nLengthPattern - nCounter2)))
                    return TRUE;
                }
            }
            return FALSE;
        }

        // только один ANY_SEQUENCE вначале; осталось сравнить конец строки с палитрой
        return Match(GetStringRight(sString, GetStringLength(sPattern2)), sPattern2);
    }

    // теперь строка и палитра должны быть одинакового размера
    if (nLengthString != nLengthPattern) return FALSE;

    if ((nS = FindSubString(sPattern, ANY_SYMBOL)) >= 0) // в палитре присутствует ANY_SYMBOL
    {
        return Match(GetStringLeft(sString, nS), GetStringLeft(sPattern, nS))
        &&     Match(GetStringRight(sString, nLengthString - nS - 1), GetStringRight(sPattern, nLengthPattern - nS - 1));
    }

    return (sString == sPattern);
}

//void main(){}

Библиотека функций для работы с инвентарем, используя предыдущий инклюд. Основные функции: CreateItemList HasItemList и RemoveItemList, остальные функции тоже полезны в тех или иных ситуациях.
NSS
// name: i_inv
// type: Библиотека
// desc: Функции для работы с инвентарем.
// autor: Nightwalker Sorcerer
// date: 11.01.2005
// modified: 13.01.2005

////////////////////////////////////////////////////////////////////////////////
// INFO ////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

/*

Contains:

void CreateItemList(string sList, object oTarget = OBJECT_SELF);
int GetNumItems(object oTarget = OBJECT_SELF, string sTag = "*", int bCreatureSlots = FALSE);
int GetNumItemsInInventory(object oInventory = OBJECT_SELF, string sTag = "*");
int GetNumItemsInSlot(object oTarget, int nSlot, string sTag = "*");
int HasItemList(object oTarget, string sList, int bCreatureSlots = FALSE);
void RemoveItemList(object oTarget, string sList, int bCreatureSlots = FALSE);
int RemoveItemsFromInventory(object oInventory = OBJECT_SELF, string sTag = "*", int nNum = -1);
int RemoveItemsFromSlot(object oTarget, int nSlot, string sTag = "*", int nNum = -1);
int RemoveItemsFromSlots(object oTarget = OBJECT_SELF, string sTag = "*", int nNum = -1, int bCreatureSlots = FALSE)

*/


////////////////////////////////////////////////////////////////////////////////
// INCLUDES ////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

#include "i_string"

////////////////////////////////////////////////////////////////////////////////
// CONSTANTS ///////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

const string SYMBOL_AND = "&";
const string SYMBOL_EQU = "=";

////////////////////////////////////////////////////////////////////////////////
// FUNCTION DEFINITIONS ////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

// Создание вещей из заданого списка в инвентаре oTarget
// - sList: список вещей в виде "вещь1=кол-во1&вещь2=кол-во2&вещь3=кол-во3",
//   при опускании "=колво", количество считается 1;
// - oTarget: в чьем инвентаре создаем?
// --> Например:
//   > CreateItemList("single_item");
//   > CreateItemList("first_item&second_item&one_arrow=99", oTreasure);
// ? Примечание: если символ '&' плохо видно в списке, можно использовать '&&'.
void CreateItemList(string sList, object oTarget = OBJECT_SELF);

// Нахождение количества вещей с тэгом sTag у персонажа oTarget (в инвентаре
// и слотах)
// - oInventory: персонаж, в имуществе которого ищем;
// - sTag: палитра для проверки тэга;
// - bCreatureSlots: искать ли в невидимых слотах?
// * Возвращает количество найденых вещей.
int GetNumItems(object oTarget = OBJECT_SELF, string sTag = "*", int bCreatureSlots = FALSE);

// Нахождение количества вещей с заданым тэгом sTag в инвентаре oInventory,
// предметы в слотах не учитываются.
// - oInventory: целевой инвентарь
// - sTag: палитра для проверки тэга
// * Возвращает количество найденых вещей, тэг которых подходит под палитру
// --> Например:
//   > GetNumItemsInInventory(oChest, "itm_sword*") - количество вещей с тэгом,
//     начинающимся с "itm_sword" у объекта oChest;
//   > GetNumItemsInInventory(oPC, "eda") - количество вещей с тэгом "eda" у oPC.
int GetNumItemsInInventory(object oInventory = OBJECT_SELF, string sTag = "*");

// Нахождение количества вещей с заданым тегом sTag в слоте инвентаря nSlot
// существа oTarget.
// - oTarget: существо, у которого ищем;
// - nSlot: слот инвентаря;
// - sTag: тэг.
// * Возвращает количество найденых вещей.
int GetNumItemsInSlot(object oTarget, int nSlot, string sTag = "*");

// Нахождение количества вещей с заданым тегом sTag в слотах инвентаря
// существа oTarget.
// - oTarget: существо, у которого ищем;
// - sTag: тэг;
// - bCreatureSlots: считать ли вещи в невидимых слотах?
// * Возвращает количество найденых вещей.
int GetNumItemsInSlots(object oTarget = OBJECT_SELF, string sTag = "*", int bCreatureSlots = FALSE);

// Проверка, имеет ли oTarget cписок вещей sList.
// - sList: список вещей в виде "вещь1=кол-во1&вещь2=кол-во2&вещь3=кол-во3",
//   при опускании "=колво", количество считается 1;
// - oTarget: у кого проверяем;
// - bCreatureSlots: проверять ли вещи в невидимых слотах?
// * Возвращеет TRUE, если объект имеет вещи из списка, иначе FALSE.
// --> Например:
//   > НasItemList(oPC, "quest&gem[1|2]=6") - проверка, есть ли у персонажа вещь
//     c тэгом "quest" и шесть вещей с тэгом gem1 или gem2
// ? Примечание: если символ '&' плохо видно, можно использовать '&&'.
int HasItemList(string sList, object oTarget = OBJECT_SELF, int bCreatureSlots = FALSE);

// Удаление у оTarget списка вещей sList.
// - sList: список вещей в виде "вещь1=кол-во1&вещь2=кол-во2&вещь3=кол-во3",
//   при опускании "=колво", количество считается 1;
// - oTarget: у кого удаляем;
// - bCreatureSlots: удалять ли вещи из невидимых ячеек?
// --> Например:
//   > RemoveItemList(oPC, "fragile=-1&extra") - удаление всех вещей с
//     тэгом "fragile" и одной вещи с тэгом "extra".
// ? Примечание: если символ '&' плохо видно, можно использовать '&&'.
void RemoveItemList(string sList, object oTarget = OBJECT_SELF, int bCreatureSlots = FALSE);

// Удаление заданого количества вещей с тэгом sTag у персонажа.
// - oTarget: персонаж;
// - sTag: палитра для проверки тэга;
// - nNum: количество вещей, коророе нужно удалить, при отрицательном
// значении будут удалены все вещи;
// - bCreatureSlots: удалять ли вещи из невидимых ячеек?
// * Возвращает количество вещей, коророе осталось удалить.
// --> Например:
//   > RemoveItems(oTarget) - удалить все вещи у цели;
//   > RemoveItems(oPC, "flower", 2) - удалить у oPC две вещи с тэгом "flower".
int RemoveItems(object oTarget, string sTag = "*", int nNum = -1, int bCreatureSlots = FALSE);

// Удаление вещей из инвентаря с заданым тэгом, вещи в слотах не удаляются
// - oInventory: целевой инвентарь
// - sTag: палитра для проверки тэга
// - nNum: количество удаляемых вещей, при -1 удалятся все вещи,
//   подходящие под палитру
// * Возвращает количество вещей, которые осталось удалить, т.е 0, если удалено
//   столько вещей, сколько указано или большее число, если найдено меньше вещей,
//   c подходящим тэгом. Возвращает -1, если указано удалять все вещи.
//   Количество удаленных вещей можно получить = nNum - RemoveItemsFromInventory(,, nNum)
// --> Например:
//   > int nNoFood = RemoveItemsFromInventory(oPC, "itm_food", 1) - удаляет 1 еду,
//     nNoFood = 1, если у oPC нет еды;
//   > RemoveItemsFromInventory(oPC, "x*") - удаляет из вещмешка oPC вещи из дополнений.
int RemoveItemsFromInventory(object oInventory = OBJECT_SELF, string sTag = "*", int nNum = -1);

// Удалить nNum вещей из слота nSlot существа oTarget,
// если тэг вещи подходит к sTag.
// - oTarget: существо, у которого удаляем вещи;
// - nSlot: ячейка, из которой удаляем;
// - sTag: палитра тэга;
// - nNum: количество вещей, которое нужно удалить, при отрицательном значении
//   удалять все вещи.
// * Возвращает количество вещей, которые осталось удалить, или отрицательное
//   значение, если указано удалять все вещи.
int RemoveItemsFromSlot(object oTarget, int nSlot, string sTag = "*", int nNum = -1);

// Удалить nNum вещей из ячеек инвентаря существа oTarget с заданным тэгом.
// - oTarget: цель;
// - sTag: палитра тэга;
// - nNum: количество вещей, которое нужно удалить, при отрицательном значении
//   удалять все вещи;
// - bCreatureSlots: удалять ли вещи из невидимых ячеек.
// * Возвращает количество вещей, которые осталось удалить, или отрицательное
//   значение, если указано удалять все вещи.
int RemoveItemsFromSlots(object oTarget = OBJECT_SELF, string sTag = "*", int nNum = -1, int bCreatureSlots = FALSE);

////////////////////////////////////////////////////////////////////////////////
// IMPLEMENTATION //////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

void CreateItemList(string sList, object oTarget = OBJECT_SELF)
{
    int nDiv, nNum;
    string sResRef;
    while (sList != "")
    {
        if ((nDiv = FindSubString(sList, SYMBOL_AND)) < 0)
        {
            nDiv = GetStringLength(sList);
        }
        sResRef = GetStringLeft(sList, nDiv);
        sList = GetStringRight(sList, GetStringLength(sList) - nDiv - 1);
        nNum = 1;
        if ((nDiv = FindSubString(sResRef, SYMBOL_EQU)) >= 0)
        {
            nNum = StringToInt(GetStringRight(sResRef, GetStringLength(sResRef) - nDiv - 1));
            sResRef = GetStringLeft(sResRef, nDiv);
        }

        for ( ; nNum > 0; nNum--) CreateItemOnObject(sResRef, oTarget); // лучше ничего не придумал
    }
}

int GetNumItems(object oTarget = OBJECT_SELF, string sTag = "*", int bCreatureSlots = FALSE)
{
    return GetNumItemsInInventory(oTarget, sTag) + GetNumItemsInSlots(oTarget, sTag, bCreatureSlots);
}

int GetNumItemsInInventory(object oInventory = OBJECT_SELF, string sTag = "*")
{
    int nNum = 0;
    object oItem = GetFirstItemInInventory(oInventory);
    while (GetIsObjectValid(oItem))
    {
        if (Match(GetTag(oItem), sTag))
        {
            nNum += GetItemStackSize(oItem);
        }

        oItem = GetNextItemInInventory(oInventory);
    }

    return nNum;
}

int GetNumItemsInSlot(object oTarget, int nSlot, string sTag = "*")
{
    object oItem = GetItemInSlot(nSlot, oTarget);
    if (Match(GetTag(oItem), sTag)) return GetItemStackSize(oItem);
    return 0;
}

int GetNumItemsInSlots(object oTarget = OBJECT_SELF, string sTag = "*", int bCreatureSlots = FALSE)
{
    int nNum = 0;
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_ARMS,      sTag);
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_ARROWS,    sTag);
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_BELT,      sTag);
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_BOLTS,     sTag);
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_BOOTS,     sTag);
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_BULLETS,   sTag);
    //nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CARMOUR,   sTag);
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CHEST,     sTag);
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CLOAK,     sTag);
    //nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CWEAPON_B, sTag);
    //nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CWEAPON_L, sTag);
    //nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CWEAPON_R, sTag);
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_HEAD,      sTag);
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_LEFTHAND,  sTag);
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_LEFTRING,  sTag);
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_NECK,      sTag);
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_RIGHTHAND, sTag);
    nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_RIGHTRING, sTag);
    if (bCreatureSlots)
    {
        nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CARMOUR,   sTag);
        nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CWEAPON_B, sTag);
        nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CWEAPON_L, sTag);
        nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CWEAPON_R, sTag);
    }

    return nNum;
}

int HasItemList(string sList, object oTarget = OBJECT_SELF, int bCreatureSlots = FALSE)
{
    int nDiv, nNum;
    string sTag;
    while (sList != "")
    {
        if ((nDiv = FindSubString(sList, SYMBOL_AND)) < 0)
        {
            nDiv = GetStringLength(sList);
        }
        sTag = GetStringLeft(sList, nDiv);
        sList = GetStringRight(sList, GetStringLength(sList) - nDiv - 1);
        if ((nDiv = FindSubString(sTag, SYMBOL_EQU)) >= 0)
        {
            nNum = StringToInt(GetStringRight(sTag, GetStringLength(sTag) - nDiv - 1));
            sTag = GetStringLeft(sTag, nDiv);
        }
        else
        {
            nNum = 1;
        }

        if (sTag != "")
        if (GetNumItems(oTarget, sTag, bCreatureSlots) < nNum) return FALSE;
    }
    return TRUE;
}

void RemoveItemList(string sList, object oTarget = OBJECT_SELF, int bCreatureSlots = FALSE)
{
    int nDiv, nNum;
    string sTag;
    while (sList != "")
    {
        if ((nDiv = FindSubString(sList, SYMBOL_AND)) < 0)
        {
            nDiv = GetStringLength(sList);
        }
        sTag = GetStringLeft(sList, nDiv);
        sList = GetStringRight(sList, GetStringLength(sList) - nDiv - 1);
        if ((nDiv = FindSubString(sTag, SYMBOL_EQU)) >= 0)
        {
            nNum = StringToInt(GetStringRight(sTag, GetStringLength(sTag) - nDiv - 1));
            sTag = GetStringLeft(sTag, nDiv);
        }
        else
        {
            nNum = 1;
        }

        RemoveItems(oTarget, sTag, nNum, bCreatureSlots);
    }
}

int RemoveItems(object oTarget, string sTag = "*", int nNum = -1, int bCreatureSlots = FALSE)
{
    nNum = RemoveItemsFromInventory(oTarget, sTag, nNum);
    return RemoveItemsFromSlots(oTarget, sTag, nNum, bCreatureSlots);
}

int RemoveItemsFromInventory(object oInventory = OBJECT_SELF, string sTag = "*", int nNum = -1)
{
    int nStack;
    object oItem = GetFirstItemInInventory(oInventory);
    while (GetIsObjectValid(oItem) && (nNum != 0))
    {
        if (Match(GetTag(oItem), sTag))
        {
                 if (nNum < 0) DestroyObject(oItem);
            else if ((nStack = GetItemStackSize(oItem)) > nNum)
            {
                SetItemStackSize(oItem, nStack - nNum);
                return 0;
            }
            else
            {
                DestroyObject(oItem);
                nNum -= nStack;
            }
        }

        oItem = GetNextItemInInventory(oInventory);
    }

    return nNum;
}

int RemoveItemsFromSlot(object oTarget, int nSlot, string sTag = "*", int nNum = -1)
{
    if (nNum == 0) return nNum;

    object oItem = GetItemInSlot(nSlot, oTarget);
    if (GetIsObjectValid(oItem))
    if (Match(GetTag(oItem), sTag))
    {
        int nStack;

             if (nNum < 0) DestroyObject(oItem);
        else if ((nStack = GetItemStackSize(oItem)) > nNum)
        {
            SetItemStackSize(oItem, nStack - nNum);
            return 0;
        }
        else
        {
            DestroyObject(oItem);
            nNum -= nStack;
        }

    }
    return nNum;
}

int RemoveItemsFromSlots(object oTarget = OBJECT_SELF, string sTag = "*", int nNum = -1, int bCreatureSlots = FALSE)
{
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_ARMS,      sTag, nNum);
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_ARROWS,    sTag, nNum);
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_BELT,      sTag, nNum);
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_BOLTS,     sTag, nNum);
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_BOOTS,     sTag, nNum);
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_BULLETS,   sTag, nNum);
    //nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CARMOUR,   sTag, nNum);
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CHEST,     sTag, nNum);
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CLOAK,     sTag, nNum);
    //nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CWEAPON_B, sTag, nNum);
    //nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CWEAPON_L, sTag, nNum);
    //nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CWEAPON_R, sTag, nNum);
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_HEAD,      sTag, nNum);
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_LEFTHAND,  sTag, nNum);
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_LEFTRING,  sTag, nNum);
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_NECK,      sTag, nNum);
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_RIGHTHAND, sTag, nNum);
    nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_RIGHTRING, sTag, nNum);
    if (bCreatureSlots)
    {
        nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CARMOUR,   sTag, nNum);
        nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CWEAPON_B, sTag, nNum);
        nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CWEAPON_L, sTag, nNum);
        nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CWEAPON_R, sTag, nNum);
    }
    return nNum;
}

//void main(){}


Примеры использования (судя по всему маст би):
- Проверка в диалоге на наличие у персонажа игрока необходимого количества (пусть 3) предметов с заданым тэгом (пусть "quest_item")
NSS
#include "i_inv"

int StartingConditional()
{
    object oPC = GetPCSpeaker();
    int n = GetNumItems(oPC, "quest_item");
    return (n >= 3);
}

- Забрать необходимое кол-во предметов у игрока (пусть те же 3 "quest_item")
NSS
#include "i_inv"

void main()
{
    object oPC = GetPCSpeaker();
    RemoveItems(oPC, "quest_item", 3);
}

Автор: Aiwan Apr 23 2006, 16:57

Эта функция копирует инвентарь объекта, если необходимо, то и все надетые вещи на существо.


NSS
//
// КОПИРУЕТ ВЕСЬ ИНВЕНТАРЬ oMaster=OBJECT_SELF В ИНВЕНТАРЬ oNewMaster
// iDel = TRUE - удаляет копируемый объект из инвентаря хозяина, FALSE - нет
// iUnequip = TRUE - раздевает объект, снимая с него все в инвентарь
void CopyInventory(object oNewMaster, object oMaster=OBJECT_SELF, int iDel=TRUE, int iUnequip=FALSE);

void CopyInventory(object oNewMaster, object oMaster=OBJECT_SELF, int iDel=TRUE, int iUnequip=FALSE)
{
      if(iUnequip==TRUE)
      {
        int i=0;
        while(i<14)
        {
          if(GetItemInSlot(i, oMaster)!= OBJECT_INVALID)
          CopyItem(GetItemInSlot(i, oMaster), oNewMaster, TRUE);
          if(iDel==TRUE) DestroyObject(GetItemInSlot(i, oMaster));
          i++;
        }
      }
      object oItem = GetFirstItemInInventory(oMaster);
      while(GetIsObjectValid(oItem))
      {
        if(GetBaseItemType(oItem) == BASE_ITEM_LARGEBOX)
        {
          CreateItemOnObject(GetResRef(oItem), oNewMaster, 1);
          if(iDel==TRUE) DestroyObject(oItem, 0.5);
        }
        else
            {
              CopyItem(oItem, oNewMaster, TRUE);
              if(iDel==TRUE) DestroyObject(oItem);
            }
          oItem = GetNextItemInInventory(oMaster);
      }
}


Тут все просто. Имеем 25 бутылочек, удаляем из них 3 или одну.
NSS
// ВОЗВРАЩАЕТ КОЛИЧЕСТВО ПРЕДМЕТОВ В СТЕКЕ В ИНВЕНТАРЕ ОБЪЕКТА
int GetItemStackNumber(string sTagItem, object oTarget=OBJECT_SELF);

// УДАЛЯЕТ iNum КОЛИЧЕСТВО ПРЕДМЕТОВ В СТЕКЕ В ИНВЕНТАРЕ ОБЪЕКТА
void RemoveItemStackNumber(string sTagItem, int iNum = 1, object oTarget=OBJECT_SELF);

//------------------------------------------------------------------------------
int GetItemStackNumber(string sTagItem, object oTarget=OBJECT_SELF)
{
  object oItem = GetFirstItemInInventory(oTarget);
  int iNum = 0;
  while (GetIsObjectValid(oItem))
  {
      if (GetTag(oItem) == sTagItem)
      {
        iNum = iNum+GetItemStackSize(oItem);
      }
        oItem = GetNextItemInInventory(oTarget);
    }
    return iNum;
}
//------------------------------------------------------------------------------
void RemoveItemStackNumber(string sTagItem, int iNum = 1, object oTarget=OBJECT_SELF)
{
  object oItem = GetFirstItemInInventory(oTarget);
  while (GetIsObjectValid(oItem) && (iNum != 0))
  {
      if (GetTag(oItem) == sTagItem)
        {
          int i = GetItemStackSize(oItem);
          if (i > iNum)
          {
            SetItemStackSize(oItem, GetItemStackSize(oItem)-iNum);
            iNum = 0;
          }
          else
              {
                DestroyObject(oItem);
                iNum = iNum-i;
              }
        }
        oItem = GetNextItemInInventory(oTarget);
    }
}


Определяем лучший класс мультикласса.
NSS
//
// ЛУЧШИЙ КЛАСС МУЛЬТИКЛАССОВОГО СОЗДАНИЯ
int GetCreatureBestClass(object oCr=OBJECT_SELF);

int GetCreatureBestClass(object oCr)
{
    int class1 = GetClassByPosition(1, oCr);
    int class2 = GetClassByPosition(2, oCr);
    int class3 = GetClassByPosition(3, oCr);
    int classlev1, classlev2, classlev3;
    classlev1 = GetLevelByClass(class1, oCr);
    if (class2 != CLASS_TYPE_INVALID)
        classlev2 = GetLevelByClass(class2, oCr);
    if (class3 != CLASS_TYPE_INVALID)
        classlev3 = GetLevelByClass(class3, oCr);
    int BestClass = class1;
    if (classlev1 < classlev2)
        BestClass = class2;
    if (classlev2 < classlev3)
        BestClass = class3;
    return BestClass;
}

Автор: kreon Apr 24 2006, 06:49

Скрипт "резервирования" нескольких мест на сервере под DM'ов
Бывает, что сервер полностью забит и зайти DM'ом не получается.
Теперь несколько мест будут забиты для ДМов
P.S. Возможно где-то уже есть, если так то сорри
onClientEnter

NSS
int nMaxPlayers = 30; // Макс. число игроков в настройке сервера минус число зарезервированных мест
void main() {
object oPC = GetEnteringObject();
object oMod = GetModule();
int nCurrPC = GetLocalInt(oMod, "CurrPC");
if(nCurrPC >= nMaxPlayers && !GetIsDM(oPC)) {
  BootPC(oPC);
  return;
}
SetLocalInt(oMod, "CurrPC", nCurrPC+1);
// нормальный oncliententer
// ...

OnClientExit
NSS
void main() {
object oMod = GetModule();
SetLocalInt(oMod, "CurrPC", GetLocalInt(oMod, "CurrPC")-1);
// нормальный onclientexit
// ...

Автор: Zirrex Apr 24 2006, 13:02

Скрипт резервирования мест для ДМ-ов.

Аналогичный скрипт. Только чуть эффективней и проще. В момент входа игрока, а не ДМ-а, пересчитывается количество игроков, и если их больше указанной цифры, то входящий игрок бутится.

В скрипте, что выше, есть недостатки. Если клиент "отвалится" от сервера, т.е. у него произойдет дисконнект, то скрипт изменения переменной не выполнится. Далее, ДМ-ы занимают места игроков. Это не очень хорошо. Учитывая то, что максимально клиентов может быть только 30. В настройках сервера надо сделать 35 мест, а игроков ограничить 30-ю местами, используя подобный скрипт. Т.е. изменение переменной необходимо включить в условие, которое игнорирует Дм. И соответственно на выходе с модуля тоже ограничить условие игроком.

NSS
void main()
{
    object oMod = GetModule();

//--------------------------------------------------//
// Данные записываются в отдельный скрипт, а потом  //
// считываются во время загрузки модуля через      //
// действие 'OnModuleLoad'.                        //
    int DMRESERVE = 30; // Для примера - 30 человек
    SetLocalInt(oMod, "DMRESERVE", DMRESERVE);
//--------------------------------------------------//

    object oClient = GetEnteringObject();

    if (GetIsDM(oClient) == FALSE)
    {
        int nReserve = GetLocalInt(oMod, "DMRESERVE");

        if (nReserve == TRUE)
        {
            int nPlayer;

            object oPlayer = GetFirstPC();

            while (GetIsObjectValid(oPlayer))
            {
                nPlayer++;
                oPlayer = GetNextPC();
            }

            if (nPlayer > nReserve)
            {
                BootPC(oClient);
                return;
            }
        }
    }
}


З.Ы. kreon, если не сложно, доработай скрипт.

Автор: Fluyka Apr 29 2006, 14:22

Вообщем я хотела вот что,у меня была такая идея...нужно было разделить отдых и процесс подготовки заклинаний кастующем классом. Это все нужно было все, чтобы клерик мог молиться Богу о заклинаниях только в определенные часы времени суток....ну перепало и магу конечно.smile.gif)

NSS
////////////////////////////////////////////////////////////////////////////////
/////Эта функция каждые 3 секунды проверяет подготавливает ли персонаж магию.///
////////////////////////////////////////////////////////////////////////////////
void Examen(object oPC = OBJECT_SELF)
{
if(!GetLocalInt(oPC,"Rest"))
  {
  ForceRest(oPC);//востановление магии
  ActionMoveToLocation(GetLocation(oPC));//встаем
  FloatingTextStringOnCreature( "Вы успешно подготовили магию.",oPC);

  //удаление локалок
  if(GetIsObjectValid(GetLocalObject(oPC,"GodLay")))
    {
    DestroyObject(GetLocalObject(oPC,"GodLay"));
    DeleteLocalObject(oPC,"GodLay");
    }

  DeleteLocalLocation(oPC, "RestLocation");
  return;
  }
if(GetLocation(oPC) != GetLocalLocation(oPC, "RestLocation"))
  {
  ActionMoveToLocation(GetLocation(oPC));
  FloatingTextStringOnCreature("Вам неудалось подготовить магию.",oPC);

  //удаление локалок
  if(GetIsObjectValid(GetLocalObject(oPC,"GodLay")))
    {
    DestroyObject(GetLocalObject(oPC,"GodLay"));
    DeleteLocalObject(oPC,"GodLay");
    }

  DeleteLocalInt(oPC,"Rest");
  DeleteLocalLocation(oPC, "RestLocation");
  return;
  }
else
  {
  AssignCommand(oPC, DelayCommand(3.0f, Examen(oPC)));
  AssignCommand(oPC,ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE,1.0,3.0));
  }
}

////////////////////////////////////////////////////////////////////////////////
///Это начало подготовки заклинаний для божественных заклинателей///////////////
////////////////////////////////////////////////////////////////////////////////
void BeginGodMagic(object oPC =OBJECT_SELF)
{
object oLay;//тут я сделала луч, с неба как бы, впрочем необязательно. Так что можно убратьsmile.gif

//проверка айламента
if(GetAlignmentGoodEvil(oPC)==ALIGNMENT_EVIL)
{oLay = CreateObject(OBJECT_TYPE_PLACEABLE,"plc_solred",GetLocation(oPC));}
else if (GetAlignmentGoodEvil(oPC)==ALIGNMENT_NEUTRAL)
{oLay = CreateObject(OBJECT_TYPE_PLACEABLE,"plc_solblue",GetLocation(oPC));}
else oLay = CreateObject(OBJECT_TYPE_PLACEABLE,"plc_solwhite",GetLocation(oPC));

//вешаем нужные локалки на Чара и плэйсебл
SetLocalLocation(oPC, "RestLocation", GetLocation(oPC));
SetLocalInt(oPC,"Rest",TRUE);
SetLocalObject(oPC,"GodLay",oLay);

AssignCommand(oPC,ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE,1.0,3.0));
AssignCommand(oPC, DelayCommand(3.0, Examen()));

DelayCommand(1.0,FloatingTextStringOnCreature("Подготовка магии.",oPC));
DelayCommand(30.0,DeleteLocalInt(oPC,"Rest"));
}

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

/*void ExsamenGod(object oPC = OBJECT_SELF)
{
object oGodLatander,oGodMysrta;
int nTime = GetTimeHour();

oGodLatander = GetItemPossessedBy(oPC,"i_latander_sign");
oGodMysrta = GetItemPossessedBy(oPC,"i_mystra_sign");

// Latander
if(GetIsObjectValid(oGodLatander))
{
if((nTime>=6)&&(nTime<13)){BeginGodMagic(oPC);return;}
else return;
}
//Mystra
else if(GetIsObjectValid(oGodMysrta))
{
if((nTime>=23)&&(nTime<4)){BeginGodMagic(oPC);return;}
else return;
}
else{FloatingTextStringOnCreature("Вам не кому молитьсЯ относительно заклинаний.",oPC);}
}*/


////////////////////////////////////////////////////////////////////////////////
/// Это начало подготовки заклинаний для арканных заклинателей /////////////////
////////////////////////////////////////////////////////////////////////////////
void BeginArcaneMagic(object oPC =OBJECT_SELF)
{
SetLocalLocation(oPC, "RestLocation", GetLocation(oPC));
SetLocalInt(oPC,"Rest",TRUE);

AssignCommand(oPC,ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE,1.0,3.0));
DelayCommand(3.0,AssignCommand(oPC,ActionPlayAnimation(ANIMATION_FIREFORGET_READ,1.0,10.0)));
AssignCommand(oPC, DelayCommand(3.0, Examen()));
DelayCommand(1.0,FloatingTextStringOnCreature("Подготовка магии.",oPC));
DelayCommand(30.0,DeleteLocalInt(oPC,"Rest"));
}

////////////////////////////////////////////////////////////////////////////////
///// Проверка. Есть ли у персонажа кастующий класс?  //////////////////////////
////////////////////////////////////////////////////////////////////////////////
void ExamenCastClass(object oPC = OBJECT_SELF)
{

int iu = 1,iClass;
while(iu <=3)
  {
    iClass=GetClassByPosition(iu,oPC);
    if(iClass == CLASS_TYPE_CLERIC){BeginGodMagic(oPC);return;}
    else if(iClass == CLASS_TYPE_DRUID){BeginGodMagic(oPC);return;}
    else if(iClass == CLASS_TYPE_PALADIN){BeginGodMagic(oPC);return;}
    else if(iClass == CLASS_TYPE_RANGER){BeginGodMagic(oPC);return;}
    else if(iClass ==  CLASS_TYPE_WIZARD){BeginArcaneMagic(oPC);return;}
    else if(iClass == CLASS_TYPE_SORCERER){BeginArcaneMagic(oPC);return;}
    else if(iClass == CLASS_TYPE_BARD){BeginArcaneMagic(oPC);return;}
    iu++ ;
  }
}

////////////////////////////////////////////////////////////////////////////////
/// Удаление восстановленных при отдыхе заклинаний /////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void SpellDelete(object oPC = OBJECT_SELF)
{

int nSpell, nKSpell;
for (nSpell = 0; nSpell < 1000; nSpell++)
{
        nKSpell = GetHasSpell(nSpell, oPC);
        if (nKSpell)
        {
          while (nKSpell > 0)
          {
            DecrementRemainingSpellUses(oPC, nSpell);
            nKSpell--;
          }
        }
}
}

////////////////////////////////////////////////////////////////////////////////
//////////////////  Отдых  ///////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void main()
{
object oPC = GetLastPCRested();
object oItem,oItem1;
switch(GetLastRestEventType())
    {
      case REST_EVENTTYPE_REST_STARTED:
      {
      //Необходимые эффекты,проверки и тд..
      break;
      }
      case REST_EVENTTYPE_REST_CANCELLED:
      {
      break;
      }
      case REST_EVENTTYPE_REST_FINISHED:
      {

      SpellDelete(oPC);
      DelayCommand(1.5,ExamenCastClass(oPC));
      break;
      }
    }
}

Автор: kreon May 10 2006, 22:15

Не знаю, было или нет... Раскидывание заходящих игроков по точкам (например для автоматического раскидывания игроков по камерам в тюрьме)
jail_include.nss

NSS
int WP_COUNT = 5; // кол-во вейпойнтов
int PC_PER_WP = 1; // скольо игроков в 1н вейпойнт
string WP_SUFFIX = "_jail_wp"; // суффикс для переменной

jail_on_enter.nss
NSS
#include "jail_include"
void main() {
object oPC = GetEnteringObject();
if(!GetIsPC(oPC) || GetIsDM(oPC)) return;
int i, count;
string sWTag;
object oWP;
for(i=0;i<WP_COUNT;i++) {
  oWP = GetObjectByTag("wp_"+IntToString(i)+WP_SUFFIX);
  count = GetLocalInt(oWP, "pc_count");
  if(count < PC_PER_WP) {
   SetLocalInt(oWP, "pc_count", count+1);
   SetLocalObject(oPC, "wp"+WP_SUFFIX, oWP);
   AssignCommand(oPC, ActionJumpToObject(oWP));
  return;
  }
}
oWP = GetObjectByTag("wp_all"+WP_SUFFIX);
AssignCommand(oPC, ActionJumpToObject(oWP));
}

jail_on_exit.nss
NSS
#include "jail_include"
void main() {
object oPC = GetExitingObject();
if(!GetIsPC(oPC) || GetIsDM(oPC)) return;
object oWP = GetLocalObject(oPC, "wp"+WP_SUFFIX);
int count = GetLocalInt(oWP, "pc_count");
SetLocalInt(oWP, "pc_count", count-1);
DeleteLocalObject(oPC, "wp"+WP_SUFFIX);
}

соотв. ставим вейпойнты с тегами "wp_"+id+WP_SUFFIX, и 1н с тегом "wp_all"+WP_SUFFIX
Думаю остальное все ясно smile.gif

Автор: azathoth Jun 11 2006, 02:50

Функция, определяющая лучшее оружие ближнего боя для указаного персонажа. Учитываются не только фокусы, если они есть (им отдается преимущество), но и специализации. Упор на схему щит+меч. Впрочем нисколько не претендую на полноту, тем более нет учета фита "Weapon Finesse" для предпочтения легкого оружия и полной поддержки дистанционного (необходим фокус, чтобы оно появилось). Метательное вообще не стал включать (не лублу его), если нужно -- раскомментируйте первые три строки.
Опробовано и работает, в своем модуле я использовал эту функцию для создания рандомного оружия у спавнов монстров - если НВН беден на модели, то хотя бы разное оружие у противников смотрится куда лучше.
Функция возвращает константу типа BASE_ITEM_*, по которой нужно создавать необходимую экипировку.

NSS
int GetWeaponBestBaseType(object oFor)
{
    //if (GetHasFeat(FEAT_WEAPON_FOCUS_DART, oFor)) return BASE_ITEM_DART;
    //if (GetHasFeat(FEAT_WEAPON_FOCUS_SHURIKEN, oFor)) return = BASE_ITEM_SHURIKEN;
    //if (GetHasFeat(FEAT_WEAPON_FOCUS_THROWING_AXE, oFor)) return THROWINGAXE;

    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oFor))
    {
        if (GetHasFeat(FEAT_WEAPON_FOCUS_BASTARD_SWORD, oFor)) return BASE_ITEM_BASTARDSWORD;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_KATANA, oFor)) return BASE_ITEM_KATANA;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_DWAXE, oFor)) return  BASE_ITEM_DWARVENWARAXE;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_KUKRI, oFor)) return BASE_ITEM_KUKRI;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SCYTHE, oFor)) return BASE_ITEM_SCYTHE;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_TWO_BLADED_SWORD, oFor)) return BASE_ITEM_TWOBLADEDSWORD;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_DIRE_MACE, oFor)) return BASE_ITEM_DIREMACE;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_DOUBLE_AXE, oFor)) return BASE_ITEM_DOUBLEAXE;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_KAMA, oFor)) return BASE_ITEM_KAMA;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_WHIP, oFor)) return BASE_ITEM_WHIP;
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oFor))
    {
        if (GetHasFeat(FEAT_WEAPON_FOCUS_BATTLE_AXE, oFor)) return BASE_ITEM_BATTLEAXE;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_GREAT_AXE, oFor)) return BASE_ITEM_GREATAXE;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_GREAT_SWORD, oFor)) return BASE_ITEM_GREATSWORD;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_HALBERD, oFor)) return BASE_ITEM_HALBERD;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_HAND_AXE, oFor)) return BASE_ITEM_HANDAXE;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_FLAIL, oFor)) return BASE_ITEM_HEAVYFLAIL;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_FLAIL, oFor)) return BASE_ITEM_LIGHTFLAIL;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_HAMMER, oFor)) return BASE_ITEM_LIGHTHAMMER;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_LONG_SWORD, oFor)) return BASE_ITEM_LONGSWORD;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_LONGBOW, oFor)) return BASE_ITEM_LONGBOW;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_RAPIER, oFor)) return BASE_ITEM_RAPIER;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SCIMITAR, oFor)) return BASE_ITEM_SCIMITAR;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SHORT_SWORD, oFor)) return BASE_ITEM_SHORTSWORD;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SHORTBOW, oFor)) return BASE_ITEM_SHORTBOW;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_WAR_HAMMER, oFor)) return BASE_ITEM_WARHAMMER;
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_ELF, oFor))
    {
        if (GetHasFeat(FEAT_WEAPON_FOCUS_LONG_SWORD, oFor)) return BASE_ITEM_LONGSWORD;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_LONGBOW, oFor)) return BASE_ITEM_LONGBOW;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_RAPIER, oFor)) return BASE_ITEM_RAPIER;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SHORTBOW, oFor)) return BASE_ITEM_SHORTBOW;
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oFor))
    {
        if (GetHasFeat(FEAT_WEAPON_FOCUS_CLUB, oFor)) return BASE_ITEM_CLUB;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_DAGGER, oFor)) return BASE_ITEM_DAGGER;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_HAND_AXE, oFor)) return BASE_ITEM_HANDAXE;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW, oFor)) return BASE_ITEM_HEAVYCROSSBOW;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW, oFor)) return BASE_ITEM_LIGHTCROSSBOW;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_MACE, oFor)) return BASE_ITEM_LIGHTMACE;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_MORNING_STAR, oFor)) return BASE_ITEM_MORNINGSTAR;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_RAPIER, oFor)) return BASE_ITEM_RAPIER;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SHORT_SWORD, oFor)) return BASE_ITEM_SHORTSWORD;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SHORTBOW, oFor)) return BASE_ITEM_SHORTBOW;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_STAFF, oFor)) return BASE_ITEM_QUARTERSTAFF;
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oFor))
    {
        if (GetHasFeat(FEAT_WEAPON_FOCUS_CLUB, oFor)) return BASE_ITEM_CLUB;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_DAGGER, oFor)) return BASE_ITEM_DAGGER;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW, oFor)) return BASE_ITEM_HEAVYCROSSBOW;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW, oFor)) return BASE_ITEM_LIGHTCROSSBOW;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_MACE, oFor)) return BASE_ITEM_LIGHTMACE;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_MORNING_STAR, oFor)) return BASE_ITEM_MORNINGSTAR;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SICKLE, oFor)) return BASE_ITEM_SICKLE;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SLING, oFor)) return BASE_ITEM_SLING;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SPEAR, oFor)) return BASE_ITEM_SHORTSPEAR;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_STAFF, oFor)) return BASE_ITEM_QUARTERSTAFF;
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oFor))
    {
        if (GetHasFeat(FEAT_WEAPON_FOCUS_CLUB, oFor)) return BASE_ITEM_CLUB;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_DAGGER, oFor)) return BASE_ITEM_DAGGER;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SCIMITAR, oFor)) return BASE_ITEM_SCIMITAR;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SICKLE, oFor)) return BASE_ITEM_SICKLE;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SLING, oFor)) return BASE_ITEM_SLING;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SPEAR, oFor)) return BASE_ITEM_SHORTSPEAR;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_STAFF, oFor)) return BASE_ITEM_QUARTERSTAFF;
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_MONK, oFor))
    {
        if (GetHasFeat(FEAT_WEAPON_FOCUS_KAMA, oFor)) return BASE_ITEM_KAMA;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_CLUB, oFor)) return BASE_ITEM_CLUB;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_DAGGER, oFor)) return BASE_ITEM_DAGGER;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_HAND_AXE, oFor)) return BASE_ITEM_HANDAXE;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW, oFor)) return BASE_ITEM_HEAVYCROSSBOW;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW, oFor)) return BASE_ITEM_LIGHTCROSSBOW;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_SLING, oFor)) return BASE_ITEM_SLING;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_STAFF, oFor)) return BASE_ITEM_QUARTERSTAFF;
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oFor))
    {
        if (GetHasFeat(FEAT_WEAPON_FOCUS_CLUB, oFor)) return BASE_ITEM_CLUB;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_DAGGER, oFor)) return BASE_ITEM_DAGGER;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW, oFor)) return BASE_ITEM_HEAVYCROSSBOW;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW, oFor)) return BASE_ITEM_LIGHTCROSSBOW;
        if (GetHasFeat(FEAT_WEAPON_FOCUS_STAFF, oFor)) return BASE_ITEM_QUARTERSTAFF;
    }

    int nSize = GetCreatureSize(oFor);

    if (GetHasFeat(FEAT_POINT_BLANK_SHOT, oFor))
    {
        // TODO: range weapons
    }

    if (GetHasFeat(FEAT_WEAPON_FINESSE, oFor))
    {
        // TODO: fine weapons
    }

    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_MONK, oFor))
    {
        return BASE_ITEM_KAMA;
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oFor))
    {
        // double weapons if has two-weapon fighting feats
        if (GetHasFeat(FEAT_AMBIDEXTERITY, oFor) && GetHasFeat(FEAT_IMPROVED_TWO_WEAPON_FIGHTING, oFor) && (nSize >= CREATURE_SIZE_MEDIUM))
        {
            switch (Random(3))
            {
                case 0: return BASE_ITEM_DIREMACE;
                case 1: return BASE_ITEM_DOUBLEAXE;
                case 2: return BASE_ITEM_TWOBLADEDSWORD;
            }
        }
        // two-handed weapon if can't use shield
        if (!GetHasFeat(FEAT_SHIELD_PROFICIENCY, oFor))
        {
            switch(nSize)
            {
            case CREATURE_SIZE_HUGE:
            case CREATURE_SIZE_LARGE:
            case CREATURE_SIZE_MEDIUM: return BASE_ITEM_SCYTHE;
            case CREATURE_SIZE_SMALL: switch (Random(3))
                {
                case 0: return BASE_ITEM_BASTARDSWORD;
                case 1: return BASE_ITEM_KATANA;
                case 2: return BASE_ITEM_DWARVENWARAXE;
                }
            case CREATURE_SIZE_TINY: switch (Random(3))
                {
                case 0: return BASE_ITEM_KAMA;
                case 1: return BASE_ITEM_WHIP;
                case 2: return BASE_ITEM_KUKRI;
                }
            }
        }
        // one-handed weapon
        switch (nSize)
        {
        case CREATURE_SIZE_HUGE:
        case CREATURE_SIZE_LARGE: return BASE_ITEM_SCYTHE;
        case CREATURE_SIZE_MEDIUM: switch (Random(3))
            {
            case 0: return BASE_ITEM_BASTARDSWORD;
            case 1: return BASE_ITEM_KATANA;
            case 2: return BASE_ITEM_DWARVENWARAXE;
            }
        case CREATURE_SIZE_SMALL: switch (Random(3))
            {
            case 0: return BASE_ITEM_KAMA;
            case 1: return BASE_ITEM_KUKRI;
            case 2: return BASE_ITEM_WHIP;
            }
        case CREATURE_SIZE_TINY:
        }
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oFor))
    {
        if (!GetHasFeat(FEAT_SHIELD_PROFICIENCY, oFor))
        {
            // two-handed
            switch (nSize)
            {
            case CREATURE_SIZE_HUGE:
            case CREATURE_SIZE_LARGE:
            case CREATURE_SIZE_MEDIUM: switch (Random(4))
                {
                case 0: return BASE_ITEM_HALBERD;
                case 1: return BASE_ITEM_GREATSWORD;
                case 2: return BASE_ITEM_GREATAXE;
                case 3: return BASE_ITEM_HEAVYFLAIL;
                }
            case CREATURE_SIZE_SMALL: switch (Random(6))
                {
                case 0: return BASE_ITEM_LONGSWORD;
                case 1: return BASE_ITEM_RAPIER;
                case 2: return BASE_ITEM_SCIMITAR;
                case 3: return BASE_ITEM_BATTLEAXE;
                case 4: return BASE_ITEM_LIGHTFLAIL;
                case 5: return BASE_ITEM_WARHAMMER;
                }
            case CREATURE_SIZE_TINY: switch (Random(3))
                {
                case 0: return BASE_ITEM_SHORTSWORD;
                case 1: return BASE_ITEM_HANDAXE;
                case 2: return BASE_ITEM_LIGHTHAMMER;
                }
            }
        }
        // one-handed
        switch (nSize)
        {
        case CREATURE_SIZE_HUGE:
        case CREATURE_SIZE_LARGE: switch (Random(4))
            {
            case 0: return BASE_ITEM_HALBERD;
            case 1: return BASE_ITEM_GREATSWORD;
            case 2: return BASE_ITEM_GREATAXE;
            case 3: return BASE_ITEM_HEAVYFLAIL;
            }
        case CREATURE_SIZE_MEDIUM: switch (Random(6))
            {
            case 0: return BASE_ITEM_LONGSWORD;
            case 1: return BASE_ITEM_RAPIER;
            case 2: return BASE_ITEM_SCIMITAR;
            case 3: return BASE_ITEM_BATTLEAXE;
            case 4: return BASE_ITEM_LIGHTFLAIL;
            case 5: return BASE_ITEM_WARHAMMER;
            }
        case CREATURE_SIZE_SMALL: switch (Random(3))
            {
            case 0: return BASE_ITEM_SHORTSWORD;
            case 1: return BASE_ITEM_HANDAXE;
            case 2: return BASE_ITEM_LIGHTHAMMER;
            }
        case CREATURE_SIZE_TINY:
        }
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_ELF, oFor))
    {
        switch (Random(2))
        {
            case 0: return BASE_ITEM_LONGSWORD;
            case 1: return BASE_ITEM_RAPIER;
        }
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oFor))
    {
        if (!GetHasFeat(FEAT_SHIELD_PROFICIENCY, oFor))
        {
            // two-handed
            switch (nSize)
            {
            case CREATURE_SIZE_HUGE:
            case CREATURE_SIZE_LARGE:
            case CREATURE_SIZE_MEDIUM: return BASE_ITEM_QUARTERSTAFF;
            case CREATURE_SIZE_SMALL: switch (Random(3))
                {
                case 0: return BASE_ITEM_CLUB;
                case 1: return BASE_ITEM_RAPIER;
                case 2: return BASE_ITEM_MORNINGSTAR;
                }
            case CREATURE_SIZE_TINY: switch (Random(3))
                {
                case 0: return BASE_ITEM_HANDAXE;
                case 1: return BASE_ITEM_LIGHTMACE;
                case 2: return BASE_ITEM_SHORTSWORD;
                }
            }
        }
        // one-handed
        switch (nSize)
        {
        case CREATURE_SIZE_HUGE:
        case CREATURE_SIZE_LARGE: return BASE_ITEM_QUARTERSTAFF;
        case CREATURE_SIZE_MEDIUM: switch (Random(3))
            {
            case 0: return BASE_ITEM_CLUB;
            case 1: return BASE_ITEM_RAPIER;
            case 2: return BASE_ITEM_MORNINGSTAR;
            }
        case CREATURE_SIZE_SMALL: switch (Random(2))
            {
            case 0: return BASE_ITEM_HANDAXE;
            case 1: return BASE_ITEM_LIGHTMACE;
            case 2: return BASE_ITEM_SHORTSWORD;
            }
        case CREATURE_SIZE_TINY: return BASE_ITEM_DAGGER;
        }
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oFor))
    {
        if (!GetHasFeat(FEAT_SHIELD_PROFICIENCY, oFor))
        {
            // two-handed
            switch (nSize)
            {
            case CREATURE_SIZE_HUGE:
            case CREATURE_SIZE_LARGE:
            case CREATURE_SIZE_MEDIUM: switch (Random(2))
                {
                case 0: return BASE_ITEM_SHORTSPEAR;
                case 1: return BASE_ITEM_QUARTERSTAFF;
                }
            case CREATURE_SIZE_SMALL: switch (Random(2))
                {
                case 0: return BASE_ITEM_CLUB;
                case 1: return BASE_ITEM_MORNINGSTAR;
                }
            case CREATURE_SIZE_TINY: switch (Random(2))
                {
                case 0: return BASE_ITEM_LIGHTMACE;
                case 1: return BASE_ITEM_SICKLE;
                }
            }
        }
        // one-handed
        switch (nSize)
        {
        case CREATURE_SIZE_HUGE:
        case CREATURE_SIZE_LARGE: switch (Random(2))
            {
            case 0: return BASE_ITEM_SHORTSPEAR;
            case 1: return BASE_ITEM_QUARTERSTAFF;
            }
        case CREATURE_SIZE_MEDIUM: switch (Random(2))
            {
            case 0: return BASE_ITEM_CLUB;
            case 1: return BASE_ITEM_MORNINGSTAR;
            }
        case CREATURE_SIZE_SMALL: switch (Random(2))
            {
            case 0: return BASE_ITEM_LIGHTMACE;
            case 1: return BASE_ITEM_SICKLE;
            }
        case CREATURE_SIZE_TINY: return BASE_ITEM_DAGGER;
        }
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oFor))
    {
        if (!GetHasFeat(FEAT_SHIELD_PROFICIENCY, oFor))
        {
            // two-handed
            switch (nSize)
            {
            case CREATURE_SIZE_HUGE:
            case CREATURE_SIZE_LARGE:
            case CREATURE_SIZE_MEDIUM: switch (Random(2))
                {
                case 0: return BASE_ITEM_SHORTSPEAR;
                case 1: return BASE_ITEM_QUARTERSTAFF;
                }
            case CREATURE_SIZE_SMALL: switch (Random(2))
                {
                case 0: return BASE_ITEM_CLUB;
                case 1: return BASE_ITEM_SCIMITAR;
                }
            case CREATURE_SIZE_TINY: return BASE_ITEM_SICKLE;
            }
        }
        // one-handed
        switch (nSize)
        {
        case CREATURE_SIZE_HUGE:
        case CREATURE_SIZE_LARGE: switch (Random(2))
            {
            case 0: return BASE_ITEM_SHORTSPEAR;
            case 1: return BASE_ITEM_QUARTERSTAFF;
            }
        case CREATURE_SIZE_MEDIUM: switch (Random(2))
            {
            case 0: return BASE_ITEM_CLUB;
            case 1: return BASE_ITEM_SCIMITAR;
            }
        case CREATURE_SIZE_SMALL: return BASE_ITEM_SICKLE;
        case CREATURE_SIZE_TINY: return BASE_ITEM_DAGGER;
        }
    }
    if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oFor))
    {
        if (!GetHasFeat(FEAT_SHIELD_PROFICIENCY, oFor))
        {
            // two-handed
            switch (nSize)
            {
            case CREATURE_SIZE_HUGE:
            case CREATURE_SIZE_LARGE:
            case CREATURE_SIZE_MEDIUM: return BASE_ITEM_QUARTERSTAFF;
            case CREATURE_SIZE_SMALL: return BASE_ITEM_CLUB;
            case CREATURE_SIZE_TINY:
            }
        }
        // one-handed
        switch (nSize)
        {
        case CREATURE_SIZE_HUGE:
        case CREATURE_SIZE_LARGE: return BASE_ITEM_QUARTERSTAFF;
        case CREATURE_SIZE_MEDIUM: return BASE_ITEM_CLUB;
        case CREATURE_SIZE_SMALL:
        case CREATURE_SIZE_TINY: return BASE_ITEM_DAGGER;
        }
    }

    return BASE_ITEM_INVALID;
}

Автор: Waromon Aug 3 2006, 18:02

Не знаю было, нет что то подобное.
Скрипт, после смерти непися создает невидимый объект в который перекладываются все вещи моба, через минуту все уничтожается.

Синьки:
plc_сorpse - невидимый объект,
plc_blood - пятно крови, появляется если на мобе весит локалка - no_blood.

Переменные:
no_blood - отвечает за появление пятна крови, если переменная TRUE - крови не будет.

1. onDeath, NPC:

NSS
void ClearInventory(object oTarget)
{
object oFirstItem = GetFirstItemInInventory(oTarget);
while (GetIsObjectValid(oFirstItem))
    {
      DestroyObject(oFirstItem);
      oFirstItem = GetNextItemInInventory(oTarget);
    }
}

void main()
{
SetIsDestroyable(FALSE, FALSE);

object oCorpse = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_сorpse",GetLocation(OBJECT_SELF));

if (!GetLocalInt(OBJECT_SELF, "no_blood"))
{
object oBlood = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_blood",                                         GetLocation(OBJECT_SELF));
DestroyObject(oBlood, 120.0f);
}

DestroyObject(oCorpse, 60.0f);    
DestroyObject(OBJECT_SELF, 60.0f);
DelayCommand(59.0f, ClearInventory(oCorpse));
DelayCommand(60.0f, SetIsDestroyable(TRUE, FALSE));

object oItem = GetFirstItemInInventory();
while (GetIsObjectValid(oItem))
{
  if(GetBaseItemType(oItem) == BASE_ITEM_LARGEBOX)
  {
   CreateItemOnObject(GetResRef(oItem), oCorpse, 1);
   DestroyObject(oItem, 0.5);
  }
  else
  {
   CopyItem(oItem, oCorpse, TRUE);
   DestroyObject(oItem);
 }
oItem = GetNextItemInInventory();
}

int i;
for (i=0; i<14; i++)
{
CopyItem(GetItemInSlot(i), oCorpse, TRUE);
}
}


2. На оnClose, oCorpse:

NSS
void main()
{
if (!GetIsObjectValid(GetFirstItemInInventory()))
   {
   DestroyObject(OBJECT_SELF, 0.5);
   }
}

Автор: Angelelf Aug 20 2006, 10:41

Это мой скрипт для разных таверн.Официантка ходит по таверне подходит к разнам клиентам ,спрашивает заказ

идет к стойке берерт заказ идет назад к тому же клиенту отдает ему заказ и берет плату.Время от времени

отдыхает и жалуется на жизнь.Реплики впишете сами не хотелось париться.
Что бы скрипты правильно работали следует создать следущие вай поинты:
Bar1-сюда приходят за напитками
Rest1-здесь отдыхает
wt_return1-ставиться возле бара
WP_TavernPatronXX_01-ставится возле клиентов у каждого клиент должен быть свой номер ХХ
Zone1-ставится где нибудь не подалеку от клиентов


Этот скрипт ставится на оnUserDef

NSS
////////////////////////////////////////////////////////////////////////////////
// Written by Angelelf 24.03.06
// Скрипт придаю щий реальную атмосферу таверне
// требуются следующие вай поинты
// WP_WTCommon_Bar      - место где берутся заказы.Бар
// WP_Rest1            - Здесь она будет отдыхать
// ZoneX                - этот вай поинт обозначает зону обслуживания
// X это номер зоны обслуживания начинается с 1
////////////////////////////////////////////////////////////////////////////////
void DrinkOrderKid(); // Заказ ребенка
void DrinkOrder();    // Заказ посетителей
string CountPatrons();  // Счетчик посетителей
void GetQueryString();  //
void TakeBreak();      // перерыв
void GetMyPay();        // получение пллаты

int StartingConditional()
{
    return TRUE;
}

void DrinkOrderKid() //  Заказ ребенка
{
    int nOrder= -1;
    string sOrder;  // реплика официанта
    string sAmount; // Реплика при передаче заказа
    string sBarkeepR;// Реплика бармена
    nOrder= d4();
    switch(nOrder)
    {
        case 1:
            sOrder = "Бармен,стакан молока для ребенка.";
            sAmount = "Вот твое молоко.";
            sBarkeepR = "Один стакан свежего молока готов.";
            break;
        case 2:
            sOrder = "Один стакан воды пожалуйста";
            sAmount = "Вот вода которую вы заказывали";
            sBarkeepR = "Держи.";
            break;
        case 3:
            sOrder = "Можешь себе представить ребенок попросил водки";
            sAmount = "Простите мы не продаем водку лицам моложе 18 лет";
            sBarkeepR = "Когда они поймут что водка это вредно.";
            break;
        case 4:
            sOrder = "________";
            sAmount = "________";
            sBarkeepR = "_______.";
            break;
    }
    SetLocalString(OBJECT_SELF, "WG_ORDER", sOrder);
    SetLocalString(OBJECT_SELF, "WG_AMOUNT", sAmount);
    SetLocalString(OBJECT_SELF, "WG_BARKEEP", sBarkeepR);
}

void DrinkOrder()  // заказы посетителей
{
    int nOrder= -1;
    string sOrder;
    string sAmount;
    string patronOrder;
    string sBarkeepR;
    nOrder= d8();
    switch(nOrder)
    {
        case 1:
            patronOrder = "Принеси мне эля."; // заказ
            sOrder = ""; //реплика официанта
            sAmount = "";    //реплика при передачи заказа
            sBarkeepR = ""//реплика бармена
            break;
        case 2:
            patronOrder = "";
            sOrder = "";
            sAmount = "";
            sBarkeepR = "";
            break;
        case 3:
            patronOrder = "";
            sOrder = "";
            sAmount = "";
            sBarkeepR = "";
            break;
        case 4:
            patronOrder = "";
            sOrder = "";
            sAmount = "";
            sBarkeepR = "";
            break;
        case 5:
            patronOrder = "";
            sOrder = "";
            sAmount = "";
            sBarkeepR = "";
            break;
        case 6:
            patronOrder = "";
            sOrder = "";
            sAmount = "";
            sBarkeepR = "";
            break;
        case 7:
            patronOrder = "";
            sOrder = "";
            sAmount = "";
            sBarkeepR = "";
            break;
        case 8:
            patronOrder = "";
            sOrder = "";
            sBarkeepR = "";
            sAmount = "";
            break;
    }
    SetLocalString(OBJECT_SELF, "PATRON_ORDER", patronOrder);
    SetLocalString(OBJECT_SELF, "WG_ORDER", sOrder);
    SetLocalString(OBJECT_SELF, "WG_AMOUNT", sAmount);
    SetLocalString(OBJECT_SELF, "WG_BARKEEP", sBarkeepR);
}

string CountPatrons()
{
    int i=-1;
    int j=-1;
    int myZone = GetLocalInt(OBJECT_SELF,"MyZone");
    float size;
    switch(myZone)
    {

    // Изменяйте величену size чтоб официант обслуживал разных клиентов за круг это увеличит реальность
        case 1:
            size=15.0;
            break;
        case 2:
            size=15.0;
            break;
        case 3:
            size=21.0;
            break;
        case 4:
            size=7.0;
            break;
    }
    string myTag = "Zone" + IntToString(myZone);
    string patronTag;
    object oJunk = GetFirstObjectInShape(SHAPE_CUBE, size, GetLocation(GetWaypointByTag(myTag)), TRUE,

CREATURE_TYPE_PLAYER_CHAR);
    if ((GetIsPC(oJunk) == TRUE) || (oJunk == OBJECT_SELF))
    {
        oJunk=GetNextObjectInShape(SHAPE_CUBE, size,GetLocation(GetWaypointByTag(myTag)), TRUE,

CREATURE_TYPE_PLAYER_CHAR);
    }
    while (oJunk != OBJECT_INVALID)
    {
        while ((GetIsPC(oJunk) == TRUE) || (oJunk == OBJECT_SELF))
        {
            oJunk=GetNextObjectInShape(SHAPE_CUBE, size,GetLocation(GetWaypointByTag(myTag)), TRUE,

CREATURE_TYPE_PLAYER_CHAR);
        }
        i++;
        oJunk=GetNextObjectInShape(SHAPE_CUBE, size,GetLocation(GetWaypointByTag(myTag)), TRUE,

CREATURE_TYPE_PLAYER_CHAR);
    }
    int bla=Random(i);

    oJunk = GetFirstObjectInShape(SHAPE_CUBE,  size, GetLocation(GetWaypointByTag(myTag)), TRUE,

CREATURE_TYPE_PLAYER_CHAR);
    if ((GetIsPC(oJunk) == TRUE) || (oJunk == OBJECT_SELF))
    {
        oJunk=GetNextObjectInShape(SHAPE_CUBE, size,GetLocation(GetWaypointByTag(myTag)),  TRUE,

CREATURE_TYPE_PLAYER_CHAR);
    }
    while (oJunk != OBJECT_INVALID)
    {
        while ((GetIsPC(oJunk) == TRUE) || (oJunk == OBJECT_SELF))
        {
            oJunk=GetNextObjectInShape(SHAPE_CUBE, size,GetLocation(GetWaypointByTag(myTag)), TRUE,

CREATURE_TYPE_PLAYER_CHAR);
        }
        j++;
        if (j == bla)
        {
            patronTag = GetTag(oJunk);
        }
        oJunk=GetNextObjectInShape(SHAPE_CUBE, size,GetLocation(GetWaypointByTag(myTag)), TRUE,

CREATURE_TYPE_PLAYER_CHAR);
    }
    return patronTag;
}

void GetQueryString() // Спрашивает заказ у PC
{
    switch(Random(4))
    {
        case 0:
            ActionSpeakString ("",TALKVOLUME_TALK);
            break;
        case 1:
            ActionSpeakString ("",TALKVOLUME_TALK);
            break;
        case 2:
            ActionSpeakString ("",TALKVOLUME_TALK);
            break;
        case 3:
            ActionSpeakString ("",TALKVOLUME_TALK);
            break;
    }
}

void TakeBreak()  // реплики во время перерыва
{
    switch(Random(4))
    {
        case 0:
            ActionSpeakString ("",TALKVOLUME_TALK);
            break;
        case 1:
            ActionSpeakString ("",TALKVOLUME_TALK);
            break;
        case 2:
            ActionSpeakString ("I",TALKVOLUME_TALK);
            break;
        case 3:
            ActionSpeakString ("",TALKVOLUME_TALK);
            break;
    }
}

void GetMyPay()    // gjctnbntkb jnlf.n gkfne
{
    string payAmount;

    switch(d4())
    {
        case 1:
            payAmount = "Вот твои деньги сдачи не надо";
            break;
        case 2:
            payAmount = "";
            break;
        case 3:
            payAmount = "";
            break;
        case 4:
            payAmount = "";
            break;
    }
    SetLocalString(OBJECT_SELF,"PAY_AMOUNT",payAmount);
}




void main() {

    int nUser = GetUserDefinedEventNumber();
    string sQuery;
    string sOrder;
    int myZone = GetLocalInt(OBJECT_SELF,"MyZone");
    string myPatron=CountPatrons();
    string sAmount;
    string payAmount;
    string patronOrder;
    string sBarkeepR;
    int isKid;
    object oCustomer = GetLocalObject(OBJECT_SELF, "CUSTOMER");
    object oBar;
    object oBar2;
    switch(myZone)
    {
        // Добавляйте или убирайте кол-во case в зависимости от того сколько зон вам надо обслуживать
        case 1:
          oBar = GetWaypointByTag("WP_WTCommon_Bar");    //Здесь официантка берет напитки
          oBar2 = GetWaypointByTag("Rest1");  //Сюда она возвращается когда разнесет напитки
          break;

    }
    if (nUser == 1001)
    {
        if (!GetIsObjectValid(oCustomer) && (GetLocalInt(OBJECT_SELF, "BARMAID_STATE") < 1))
        {
            // идет к своему клиенту не игроку
            oCustomer = GetObjectByTag(myPatron);
            if (oCustomer != GetObjectByTag("Barkeeper") &&
            oCustomer != OBJECT_SELF && GetIsObjectValid(oCustomer))
            {
                // подходит к клиенту и спрашивает чего он хочет
                SetLocalInt (OBJECT_SELF, "BARMAID_STATE", 1);
                SetLocalObject (OBJECT_SELF, "CUSTOMER", oCustomer);
                ActionForceMoveToObject(oCustomer, FALSE, 0.5, 60.0);
                GetQueryString();
                isKid = GetLocalInt(oCustomer,"IAmAKid");
                if (isKid == 1)
                {
                    DrinkOrderKid();
                }
                else
                {
                    DrinkOrder();
                }
                ActionWait(1.0);
                patronOrder = GetLocalString(OBJECT_SELF,"PATRON_ORDER");
                ActionDoCommand(AssignCommand(oCustomer,SpeakString(patronOrder,TALKVOLUME_TALK)));
                ActionWait(3.0); //ждет 3 сек

                // идет к бару за напитками
                ActionDoCommand (SetLocalInt(OBJECT_SELF, "BARMAID_STATE", 2));
                ActionForceMoveToObject(oBar, FALSE, 0.5, 60.0);

                sOrder = GetLocalString(OBJECT_SELF,"WG_ORDER");
                sBarkeepR = GetLocalString(OBJECT_SELF, "WG_BARKEEP");

                ActionSpeakString (sOrder);
                ActionWait(3.0);

                // проверяет к тому ли бару она идет
                if(myZone == 1)
                {
                    ActionDoCommand(AssignCommand(GetObjectByTag("wt_Barkeeper1"), ActionSpeakString

(sBarkeepR,TALKVOLUME_TALK)));
                }
                else
                {
                    ActionDoCommand(AssignCommand(GetObjectByTag("wt_Barkeeper2"), ActionSpeakString

(sBarkeepR,TALKVOLUME_TALK)));
                }
                ActionWait(3.0);
                // возвращается к клиенту и отдает напитки
                ActionDoCommand (SetLocalInt(OBJECT_SELF, "BARMAID_STATE", 3));
                ActionForceMoveToObject (oCustomer, FALSE, 0.5, 60.0);
                sAmount = GetLocalString(OBJECT_SELF,"WG_AMOUNT");
                GetMyPay();
                payAmount = GetLocalString(OBJECT_SELF,"PAY_AMOUNT");
                if (sAmount == "**") // реакция на выражения
                {
                    PlaySound("cb_ht_critical"); //звук
                    payAmount = ""; // фраза
                }
                ActionSpeakString (sAmount);
                ActionWait(2.0);
                ActionDoCommand(AssignCommand(oCustomer,SpeakString(payAmount,TALKVOLUME_TALK)));
                ActionDoCommand (SetLocalObject(OBJECT_SELF, "CUSTOMER", OBJECT_INVALID));

                // возвращается к бару и берет перерыв
                ActionForceMoveToObject(oBar2, FALSE, 0.5, 60.0);
                ActionWait(1.0);
                TakeBreak();
                ActionWait(2.0);
                ActionDoCommand (SetLocalInt(OBJECT_SELF, "BARMAID_STATE", 0));
            }
        }
    }
    if (nUser == 1004)
    {

        SetLocalObject (OBJECT_SELF, "CUSTOMER", OBJECT_INVALID);
        SetLocalInt (OBJECT_SELF, "BARMAID_STATE", 0);
    }
}

Этот на onSpawn официанта
NSS
//::///////////////////////////////////////////////
//:: Default: On Spawn In
//:: NW_C2_DEFAULT9
//:: Copyright © 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Determines the course of action to be taken
    after having just been spawned in
*/

//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 25, 2001
//:://////////////////////////////////////////////
#include "NW_O2_CONINCLUDE"
#include "NW_I0_GENERIC"




void main()
{

SetLocalInt(OBJECT_SELF,"MyZone",1); // это значит что данный официант будет обслуживать зону 1.Создать вай

поинт Zone1

// OPTIONAL BEHAVIORS (Comment In or Out to Activate )

****************************************************************************
    //SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
    //SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
                // This causes the creature to say a special greeting in their conversation file
                // upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
                // greeting in order to designate it. As the creature is actually saying this to
                // himself, don't attach any player responses to the greeting.

    //SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
                // This will set the listening pattern on the NPC to attack when allies call
    //SetSpawnInCondition(NW_FLAG_STEALTH);
                // If the NPC has stealth and they are a rogue go into stealth mode
    //SetSpawnInCondition(NW_FLAG_SEARCH);
                // If the NPC has Search go into Search Mode
    //SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
                // This will set the NPC to give a warning to non-enemies before attacking

    //SetSpawnInCondition(NW_FLAG_SLEEP);
                //Creatures that spawn in during the night will be asleep.
    //SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
    //SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
    //SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
    //SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
                //This will play Ambient Animations until the NPC sees an enemy or is cleared.
                //NOTE that these animations will play automatically for Encounter Creatures.

    // NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
    //SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN);    // OPTIONAL BEHAVIOR (Flee to a way point and return a

short time later.)
    //SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE);    // OPTIONAL BEHAVIOR (Flee to a way point and do not

return.)
    //SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE);  // OPTIONAL BEHAVIOR (Teleport to safety and do not

return.)
    //SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN);  // OPTIONAL BEHAVIOR (Teleport to safety and return a

short time later.)

// CUSTOM USER DEFINED EVENTS
/*
    The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD.  Like the
    On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors.  The user

defined
    events user 1000 - 1010
*/

    SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT);        //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
    //SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT);        //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
    //SetSpawnInCondition(NW_FLAG_ATTACK_EVENT);          //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
    //SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT);          //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
    //SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT);        //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
    //SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event

1003
    SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT);      //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
    //SetSpawnInCondition(NW_FLAG_DEATH_EVENT);            //OPTIONAL BEHAVIOR - Fire User Defined Event 1007

// DEFAULT GENERIC BEHAVIOR (DO NOT TOUCH)

*****************************************************************************************
    SetListeningPatterns();    // Goes through and sets up which shouts the NPC will listen to.
    WalkWayPoints();          // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
                              // 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk

them
                              // 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
                              //    combat.
//  GenerateNPCTreasure();    //* Use this to create a small amount of treasure on the creature
}

Этот на onConvercation
NSS
//::///////////////////////////////////////////////
//:: SetListeningPatterns
//:: NW_C2_DEFAULT4
//:: Copyright © 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Determines the course of action to be taken
    by the generic script after dialogue or a
    shout is initiated.
*/

//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 24, 2001
//:://////////////////////////////////////////////

#include "NW_I0_GENERIC"

void main()
{
    int nMatch = GetListenPatternNumber();
    object oShouter = GetLastSpeaker();
    object oIntruder;

    if (nMatch == -1 && GetCommandable(OBJECT_SELF))
    {
        ClearAllActions();
        BeginConversation();
        ActionWait(8.0);
    }
    else
    if(nMatch != -1 && GetIsObjectValid(oShouter) && !GetIsPC(oShouter) && GetIsFriend(oShouter))
    {
        if(nMatch == 4)
        {
            oIntruder = GetLocalObject(oShouter, "NW_BLOCKER_INTRUDER");
        }
        else if (nMatch == 5)
        {
            oIntruder = GetLastHostileActor(oShouter);
            if(!GetIsObjectValid(oIntruder))
            {
                oIntruder = GetAttemptedAttackTarget();
                if(!GetIsObjectValid(oIntruder))
                {
                    oIntruder = GetAttemptedSpellTarget();
                    if(!GetIsObjectValid(oIntruder))
                    {
                        oIntruder = OBJECT_INVALID;
                    }
                }
            }
        }
        RespondToShout(oShouter, nMatch, oIntruder);
    }


    if(GetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT))
    {
        SignalEvent(OBJECT_SELF, EventUserDefined(1004));
    }
}

Этот на onDistr
NSS
//::///////////////////////////////////////////////
//:: Default: On Disturbed
//:: NW_C2_DEFAULT8
//:: Copyright © 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Calls the end of combat script every round
*/

//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 16, 2001
//::///////////////////////////////////////////

// * Make me hostile the faction of my last attacker (TEMP)
//  AdjustReputation(OBJECT_SELF,GetFaction(GetLastAttacker()),-100);
// * Determined Combat Round

#include "NW_I0_GENERIC"

void main()
{
    object oTarget = GetLastDisturbed();

    if(!GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget()))
    {
        if(GetIsObjectValid(oTarget))
        {
            DetermineCombatRound(oTarget);
        }
    }
    if(GetSpawnInCondition(NW_FLAG_DISTURBED_EVENT))
    {
        ActionWait(8.0);
    }
}

Этот сиавится на onSpawn клиента таверны
NSS
//::///////////////////////////////////////////////
//:: Default: On Spawn In
//:: NW_C2_DEFAULT9
//:: Copyright © 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Determines the course of action to be taken
    after having just been spawned in
*/

//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 25, 2001
//:://////////////////////////////////////////////
#include "NW_O2_CONINCLUDE"
#include "NW_I0_GENERIC"

void main()
{
// OPTIONAL BEHAVIORS (Comment In or Out to Activate )

****************************************************************************
    //SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
    //SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
                // This causes the creature to say a special greeting in their conversation file
                // upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
                // greeting in order to designate it. As the creature is actually saying this to
                // himself, don't attach any player responses to the greeting.

    //SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
                // This will set the listening pattern on the NPC to attack when allies call
    //SetSpawnInCondition(NW_FLAG_STEALTH);
                // If the NPC has stealth and they are a rogue go into stealth mode
    //SetSpawnInCondition(NW_FLAG_SEARCH);
                // If the NPC has Search go into Search Mode
    //SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
                // This will set the NPC to give a warning to non-enemies before attacking

    //SetSpawnInCondition(NW_FLAG_SLEEP);
                //Creatures that spawn in during the night will be asleep.
    //SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
    //SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
    //SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
    //SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
                //This will play Ambient Animations until the NPC sees an enemy or is cleared.
                //NOTE that these animations will play automatically for Encounter Creatures.

    // NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
    //SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN);    // OPTIONAL BEHAVIOR (Flee to a way point and return a

short time later.)
    //SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE);    // OPTIONAL BEHAVIOR (Flee to a way point and do not

return.)
    //SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE);  // OPTIONAL BEHAVIOR (Teleport to safety and do not

return.)
    //SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN);  // OPTIONAL BEHAVIOR (Teleport to safety and return a

short time later.)

// CUSTOM USER DEFINED EVENTS
/*


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


Автор: Lex Oct 12 2006, 00:31

Название: Рубка железных деревьев.
Описание: Дерево, которое можно рубить только специальным топором и после некоторых мучений отрубить таки сук. Другое оружие тупится об это дерево.
скрипты:

NSS
// lx_pus_irontree
// ставится на слот onUsed дерева
void main()
{
object oPC = GetLastUsedBy();
object oTree = OBJECT_SELF;
// если мы сук уже срубили - выдаем сообщение
if (GetLocalInt(OBJECT_SELF,"CUTTED"))
    {
    FloatingTextStringOnCreature("**Нет ни одного подходящего сука, который можно было бы отрубить**",oPC);
    }
else // если еще не срубили, тоже сообщение
    {
    FloatingTextStringOnCreature("**У дерева есть сук, котороый вполне можно отрубить**",oPC);
// и начинаем рубить
    DelayCommand(0.8,AssignCommand(oPC,ClearAllActions()));
    DelayCommand(1.0,AssignCommand(oPC,ActionAttack(oTree)));
    }
}


NSS
// lx_pat_irontree
// скрипт на слот onAttacked дерева
void main()
{
object oPC = GetLastAttacker();
// если рубить нечего - сообщение и выход (можно добавить сброс рубки, по желанию)
if (GetLocalInt(OBJECT_SELF,"CUTTED"))
    {
    FloatingTextStringOnCreature("**Нет ни одного подходящего сука, который можно было бы отрубить**",oPC);
    return;
    }
// оружие, которым ведется рубка
object oW = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
// если это особый топор (он у меня двуручный, поэтому проверяю только правую руку)
if (GetTag(oW)=="ITM_GAXE_FORIRON")
    {
    // снимаем плот с дерева, теперь его можно дамажить (а до этого плот стоял по умочанию)
    SetPlotFlag(OBJECT_SELF,FALSE);
    }
else // если же мы пытаемся рубить не нужным топором
    {
    // ставим плот
    SetPlotFlag(OBJECT_SELF,TRUE);
    // если оружие есть, то одно сообщение
    if (GetIsObjectValid(oW))
          FloatingTextStringOnCreature("**Я только испорчу "+GetName(oW)+ " об это железное дерево**",oPC);
    // если нет - другое
    else  FloatingTextStringOnCreature("**Я только себе руки в кровь разобью об это железное дерево**",oPC);
    }
}


NSS
// lx_pdm_irontree
// скрипт на слот onDamage дерева
void main()
{
object oPC = GetLastDamager();
// если уже отрезано - чистим действия (сообщение было в *_pat_*)
if (GetLocalInt(OBJECT_SELF,"CUTTED"))
    {
    AssignCommand(oPC,ClearAllActions(TRUE));
    return;
    }
// оружие, которым рубим
object oW = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
// если нужное - все ок
if (GetTag(oW)=="ITM_GAXE_FORIRON")
    { // как только у дерева меньше 100 хп, значит сук мы срубили (у меня вначале стоит 150 хп)
    if (GetCurrentHitPoints()<100)
        {
        // отмечаем, что сук срублен
        SetLocalInt(OBJECT_SELF,"CUTTED",TRUE);
        // даем срубленный сук игроку
        CreateItemOnObject("ITM_IRONWOOD",oPC);
        // чистим действия и даем сообщение
        AssignCommand(oPC,ClearAllActions(TRUE));
        FloatingTextStringOnCreature("**Вы срубили сук железного дерева**",oPC);
        }
    }
else
    {
    // если рубим "левым" оружием
    SetPlotFlag(OBJECT_SELF,TRUE);
    if (GetIsObjectValid(oW))
        {
        // то на оружии накапливается повреждение
        int SPL = GetLocalInt(oW,"SPOILING");
        // и после 5 ударов по дереву
        if (SPL == 5)
            {
            // оружие тупится
            FloatingTextStringOnCreature("**Ваш "+GetName(oW)+ " затупился**",oPC);
            AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAttackPenalty(2),oW);
            AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamagePenalty(2),oW);
            SetLocalInt(oW,"SPOILING",6);
            }
        else
            {
            SetLocalInt(oW,"SPOILING",SPL+1);
            }
        }
    }
}



установка:
- ставим в локации дерево, даем ему 150-200 хитов, ставим плот, настраиваем (я Hardness ставлю около 10)
- ставим с слоты вышеуказанные скрипты
- создаем в палитре предмет ITM_IRONWOOD

ps: тут есть пара моментов, которые я упустил (ну мне они не очень актуальны)
1. не учитывается магия.. а надо бы smile.gif Думаю простого плота на onSpellCast будет достаточно
2. не учитывается вариант атаки дерева дальнобойным оружием. В этом случае не должно оно тупиться. Но это так же легко проверить, немного дописав скрит lx_pdm_irontree

smile.gif

Автор: virusman Jan 27 2007, 16:11

Пара скриптов посадки на стул:

NSS
void main()
{
    object oPC = GetLastUsedBy();
    object oChair = OBJECT_SELF;
    if (!GetIsObjectValid (GetSittingCreature(oChair))) {
        AssignCommand(oPC, ActionSit(oChair));
    }
}


NSS
void main()
{
  object oPlayer = GetLastUsedBy ();
  object oChair = OBJECT_SELF;
  object oSitter=GetSittingCreature(oChair);
  if (GetIsPC (oPlayer))
    {
        if (GetIsObjectValid(oChair) && !GetIsObjectValid
            (oSitter))
        {
            AssignCommand (oPlayer, ActionSit (oChair));
        }
    }
  else if(!GetIsObjectValid(oSitter))
  {
    AssignCommand(oPlayer, ActionSit(oChair));
  }
}

Автор: 2_advanced Jan 29 2007, 13:44

но не для шардов :-)

Автор: virusman Jan 29 2007, 18:47

QUOTE(2_advanced @ Jan 29 2007, 13:44) [snapback]103439[/snapback]
но не для шардов :-)
Работало без проблем более 3 лет.

Автор: 2_advanced Jan 30 2007, 08:18

если сидячий персонаж выйдет из игры / перезайдет, уйдет в другую локу, то стульчик накроется:
GetSittingCreature на стуле останется до рестарта => проверять нужно GetSittingCreature не с запоротого стула, а с объекта, на который перс садится + место где он находится =) может уже в другой локе, а не рядом со стулом

древний извращенский метод:

NSS
void main()
{
    object oPC = GetLastUsedBy();
    object oChair = OBJECT_SELF;

    if(GetIsObjectValid(oChair) && GetIsObjectValid(oPC))
    {
        object oSurf = GetLocalObject(oChair, "surf"); // +очистка

        if(GetIsObjectValid(oSurf))
        {
            object oSitter = GetSittingCreature(oSurf);

            if(!GetIsObjectValid(oSitter) || GetArea(oSitter) != GetArea(oChair))
                DestroyObject(oSurf);
            else
                return;
        }

        vector vSurf = GetPosition(oChair);

        // сабж усаживал много персов на 1 скамейку smile.gif найду- выложу
        //vector vSurf = GenerateNewSurfPos(oChair, GetSubRace(oPC), GetGender(oPC));

        location lSurf = Location(GetArea(oChair), vSurf, GetFacing(oChair));

        object oNewSurf = CreateObject(OBJECT_TYPE_PLACEABLE, "sittingsurface", lSurf, FALSE);

        SetLocalObject(oChair, "surf", oNewSurf);

        AssignCommand(oPC, ActionSit(oNewSurf));
    }
}

Автор: virusman Jan 30 2007, 08:57

О глюках при перезаходе ни разу не слышал.
Может, это уже давно пофиксили в 1.67?

Lex:

QUOTE(virusman @ Jan 30 2007, 08:57) [snapback]103489[/snapback]
О глюках при перезаходе ни разу не слышал.

на Аксисе такие "запоротые" стулья были сто пудов, сам видел. А вот фиксено это на 1.67 или нет - мне не ведомо.

Автор: ReyBrujo Jun 10 2010, 14:01

Один из простых вариантов создания случайно генерируемой комнаты.

Нужно сделать комнату, в ней расставить все нужные предметы, делаем триггер, потом в переменных триггера ставим int "roomclean" = число (здесь ставим, сколько раз будет очищаться комната). Скрипт ставим на ОнЕнтер триггера. Сам триггер ставим возле двери (там, где должен появиться игрок). Если нужно несколько таких комнат - просто копируем комнаты(локации) в меню слева.
Действие : удаляет случайно, с шансом 1 к 2, предметы (в т.ч. создания). Если нужно, могу переделать так, чтобы удаляло только итемы и плейсеблы.

Neverwinter Script
void main()
{
object oArea = GetArea(GetEnteringObject()); // локациЯ игрока
int nClean = GetLocalInt(OBJECT_SELF, "roomclean"); // считываем переменную

while(nClean>0) // пока переменнаЯ больше 0 - исполнЯем скрипт
{
nClean == nClean - 1; // изменЯем переменную
object oClean = GetFirstObjectInArea(oArea); // задаем обьект
while(GetIsObjectValid(oClean)) // пока обьект ЯвлЯетсЯ валидным (существующим) - исполнЯем код
{
if(GetIsPC(oClean) == FALSE) // здесь вставлЯем ограничениЯ длЯ типа объекта
{
switch(d2()) // разбор объектов
{
case 1: DestroyObject(oClean); break; // удалЯем
case 2: // ничего не делаем
}
}
oClean = GetNextObjectInArea(oArea); // берем следующий объект
}
}
DeleteLocalInt(OBJECT_SELF, "roomclean"); // удалЯем локалку
}


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

Универсальный скрипт для рычагов, открывающий ближайшую дверь.
Скрипт ставим на OnUsed рычага. Рычаг ставим возле нужной двери.
Neverwinter Script
void main()
{
object oSelf = OBJECT_SELF;// Рычаг
int nUsed = GetLocalInt(oSelf, "used");//ПеременнаЯ использованиЯ
object oDoor = GetNearestObject(OBJECT_TYPE_DOOR);//БлижайшаЯ дверь
SetLocalInt(oSelf, "used", 1-nUsed);//ПроставлЯем переменную
if(nUsed == 0)//Проверка переменной
{
//Отпираем и открываем запертую дверь
PlayAnimation(ANIMATION_PLACEABLE_ACTIVATE);
AssignCommand(oDoor, ActionOpenDoor(oDoor));
}
else//иначе
{
//Закрываем и запираем открытую дверь
PlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE);
AssignCommand(oDoor, ActionCloseDoor(oDoor));
}
}


Исцеление сидящих обьектов (скрипт хорошо подойдет для таверн).
Скрипт ставим на OnHeartbeat стула (дивана, кровати).
Neverwinter Script
void main()
{
object oPC = GetSittingCreature(OBJECT_SELF); // Берем сидЯщий обьект
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(1), oPC); // ИсцелЯем его
}

Автор: Talarasha Aug 28 2010, 21:28

Универсальный скрипт триггеров для начала разговора с NPC. Успешно работает и в случае, если в разговоре участвуют члены партии. Вешается на OnEnter триггера; в локальных переменных триггера указываем string'и "NPC" и "DIALOG" - тэг парня, с которым будем разговаривать и название диалога соответственно. MAX_PARTY_SIZE меняем по своим надобностям, я обычно выношу это в инклюд. Легко разбавляется любыми необходимыми проверками.

Neverwinter Script
const int MAX_PARTY_SIZE = 4; // Максимальный размер партии

void Talk(string sDIALOG, object oPC)
{
    BeginConversation(sDIALOG, oPC);
}

void main()
{
    // Срабатывает 1 раз...
    if(GetLocalInt(OBJECT_SELF, "DONE") == 1) return;
    SetLocalInt(OBJECT_SELF, "DONE",1);
    // ...и только для PC
    object oPC = GetEnteringObject();
    if(GetIsPC(oPC) == FALSE) return;

    int i;
    string sDIALOG = GetLocalString(OBJECT_SELF,"DIALOG");
    object oNPC = GetNearestObjectByTag(GetLocalString(OBJECT_SELF,"NPC"));

    AssignCommand(oPC, ClearAllActions());
    // Если член партии участвует в диалоге и находится слишком далеко от PC, то диалог может не сработать или оборваться. Поэтому перемещаем партийцев к PC.
    for(i=0;i<MAX_PARTY_SIZE;i++) AssignCommand(GetHenchman(oPC,i),JumpToObject(oPC)
);
    DelayCommand(1.0,AssignCommand(oNPC, Talk(sDIALOG,oPC)));
}

Рекомендуется также установить у всех участвующих в разговоре NPC "длинное" расстояние чувствительности.

Автор: Talarasha Aug 29 2010, 21:40

Цитата(Aiwan @ Aug 14 2004, 01:50) *
Вот простой скриптик, ставится на строку НПС и во время длинного расказа, происходит, как бы временной интервал с потухшим экраном. Что то навроде, как в кино: "Прошло два года..." :?)

Neverwinter Script
//:://////////////////////////////////////////////
//:: Created By: WRG! Aiwan aiwan@e-mail.ru
//:: Created On: 21.12.2003
//:://////////////////////////////////////////////
/*
            ПАУЗА В РАЗГОВОРЕ С НПС
*/

//:://////////////////////////////////////////////
void main()
{
    object oPC = GetPCSpeaker();
    AssignCommand(OBJECT_SELF, ActionPauseConversation());
    AssignCommand(OBJECT_SELF, FadeToBlack(oPC, FADE_SPEED_SLOW));
    AssignCommand(OBJECT_SELF, ActionWait(4.0));
    AssignCommand(OBJECT_SELF, FadeFromBlack(oPC, FADE_SPEED_SLOW));
    SetTime(GetTimeHour()+(Random(4)), GetTimeMinute()+(Random(60)), 0, 0);
    AssignCommand(OBJECT_SELF, ActionResumeConversation());
}

Скрипт работает некорректно. ActionWait никоим образом не разделяет FadeToBlack и FadeFromBlack, независимо от указанной задержки затухание-появление всегда будет дергано-моментальным. AssignCommand тоже лишние. Нормальное затухание будет так:
Neverwinter Script
void main()
{
    object oPC = GetPCSpeaker();
    AssignCommand(OBJECT_SELF, ActionPauseConversation());
    FadeToBlack(oPC, FADE_SPEED_SLOW);
    DelayCommand(4.0,FadeFromBlack(oPC, FADE_SPEED_SLOW));
    DelayCommand(4.0,AssignCommand(OBJECT_SELF, ActionResumeConversation()));
    //SetTime(GetTimeHour()+(Random(4)), GetTimeMinute()+(Random(60)), 0, 0);
}

P.S. Кроме того, скрипт выложен в теме дважды:
http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=1972
http://www.city-of-masters.ru/forums/index.php?s=&showtopic=5&view=findpost&p=9967
Видать полезный.

Автор: Aiwan Aug 31 2010, 10:36

Talarasha, а кто тебе сказал, что пауза ДЛЯ РАЗДЕЛЕНИЯ FadeToBlack и FadeFromBlack? smile.gif Зачем игроку ЧЕТЫРЕ(!) секунды черноты, которая плавно и так наступает. Пауза нужна НПС, что бы не появлялось веток диалога 4 секунды. Посмотри внимательно код, который кстати написан мной семь лет назад lol.gif А вот в твоем коде может быть сбой (теоретически), так как несколько команд на одном тайминге задержки могут не сработать. Во втором делей лучше поставить 4.1. И этот скрипт работает как и задумано, причем не единожды вставлен и нигде сбоя нет. Одна особенность кода, все команды отдаются OBJECT_SELF-ом, так как я часто писал скрипты катсцен, то это просто кусок оттуда.

п.с. К тому же Биовар частенько поправляет функции и то что семь лет назад затухало плавно, сейчас может просто моргать. А насчет дубля. Удалить свое сообщение я не могу (попробовал только что), там ошибка какая-то базы два сообщения склеились и не объединились. Видишь в сообщении две надписис об редактировании. В 2005 году модератор пытался стереть и не смог. Лучше пусть будет два сообщения чем крах БД smile.gif

Автор: Talarasha Aug 31 2010, 13:42

Цитата
Зачем игроку ЧЕТЫРЕ(!) секунды черноты, которая плавно и так наступает.

Если бы она наступала, то конечно незачем rolleyes.gif Мне бы тогда и скрипт не было нужды переписывать.
Цитата
Пауза нужна НПС, что бы не появлялось веток диалога 4 секунды.

Ветки диалога действительно не появляются 4 секунды. Четыре секунды после того, как экран просветлеет.
Цитата
А вот в твоем коде может быть сбой (теоретически)

С удовольствием приму и рассмотрю любые жалобы на сбои, проявившиеся из-за использования моих скриптов thank_you.gif
Цитата
К тому же Биовар частенько поправляет функции и то что семь лет назад затухало плавно, сейчас может просто моргать.

Можно рассматривать это как 1.69-апдейт. Пока я не проверю работу на более старых версиях rolleyes.gif

А вообще за комментарий спасибо, теперь хотя бы понятно, почему скрипт написан "так" =)

Автор: Lex Oct 15 2010, 09:54

http://www.wrg.ru/download.php?view.175

Набор скриптов позволяет реализовать «производственный/собирательный» крафт практически любой сложности.
Система включает 70 скриптов, 1 общий управляющий диалог, 10 чертежей палитры (инструмент-существо, инструмент-предмет, инструмент-плейсабл, инструмент-триггер, шаблоны различных предметов класса «сырье», специальные инструменты), все чертежи палитры находятся во вкладках «Специальная->Настройка1-2».

Особенность системы - ее наращивание не путем создания инструментов в палитре и строчек в скрипте – а создание конечных продуктов переработки в тулсете и присваивание им переменных определяющих, что требуется для производства.

Подробные инструкции и описание системы приложены в Word документе с картинками в архиве.

Автор: DNAlchemist Oct 11 2011, 17:44

для скрипта дежурящих ночью гвардов

Цитата(Ilharess @ Nov 24 2004, 13:40) *
if ( !GetIsInCombat() || GetCurrentAction() != ACTION_DIALOGOBJECT)

Сдается мне, что скрипт не будет срабатывать только тогда, когда нпс будет в бою и в диалоге одновременно
О_о
Недоглядели, благородный дон

То был скрипт со второй страницы
Вот еще один, с первой страницы.


Цитата
Код
  while ((pos = FindSubString(sProperties, "@")) != -1)
    {
        sProperties = GetStringRight(sProperties, GetStringLength(sProperties) - pos - 1);

        pos = FindSubString(sProperties, "@");
        if (pos == -1)
            pos = GetStringLength(sProperties);

        sTemp = GetStringLeft(sProperties, pos);

        //SendMessageToPC(GetFirstPC(), "sTemp["+ IntToString(i) +"] == "+ sTemp);
        SetProperty(oItem, sTemp);

        i++;
    }


Тут есть счетчик i, который используется только при дебагге. Так то ничего страшного, но он стоит в цикле while, и мы будем делать десятки ненужных вычислений.
//SendMessageToPC(GetFirstPC(), "sTemp["+ IntToString(i) +"] == "+ sTemp);i++;
А нужно всего то ее закомментить

Автор: DNAlchemist Oct 16 2011, 11:22

Здесь описанная часть системы поджигания, я ее использую чтобы с помощью факела можно было поджечь деревья, дома, и т.д.
Я выложил три скрипта, с подробным описанием.
SetFire - ставит огонь по указанным координатам
DestroyFire - уничтожает все огни.
локальные переменные
Fire - хранит индикатор, насколько разгорелся объект
FireObject - Содержит количество созданных огней

Я постарался сделать как можно более детальное описание каждой строчки кода, надеюсь, моя работа кому-нибудь, да пригодится)

"Спасибо" приветствуется :rolleyes:

Код
///////////////////////////////////////////////////////////////////////////////
//               * Функциz удалzет все пробелы из строки *                   //
///////////////////////////////////////////////////////////////////////////////
string RemoveSpace(string str)
{
string        str2; // Результат

              while(str!="")// Пока в строке есть хоть один символ
              {
              // Если символ первой строки - не пробел, то
              // добавлzем его к переменной результата
              if(GetStringLeft(str , 1)!=" ")
              str2 += GetStringLeft(str , 1);
              // Берем строку с конца до второго символа
              // (то есть избавлzемсz от первого символа)
              str  = GetStringRight(str , GetStringLength(str)-1);
              }
// Возвращаем результат строки без пробелов
return str2;
}



///////////////////////////////////////////////////////////////////////////////
//         * Функциz устанавливает огни по заданным точкам *
// К примеру, "1*0.2,0.1,0.0;", где
//       1  - номер устанавливаемого огнz (они должны
// всегда идти по порzдку),
//       *  - тип огнz (* - огонек, ! - искры), должны
// создаватьсz отдельно, резрефы заменить ниже, blueprint003 и blueprint033
// соответственно. Используйте длz огонька костер, а длz искр -
// магическую вспышку, в котором бы неплохо было вырезать с помощью 3dmax'a
// верхний zркий огонек в виде шарика).
//       0.2 - изменение координаты относительно oObject по оси x (ширине)    x \
//       0.1 - изменение координаты относительно oObject по оси y (длине)     y |>  координаты огонька
//       0.1 - изменение координаты относительно oObject по оси z (высоте)    z /
// "," разделzет оси координат (их должно быть обzзательно 3)
// ";" разделzет огни друг от друга
//
// Все пробелы из функции удалzютсz. Оформлzйте данные так, как вам удобнее
// читаетсz.
//
// >> P.S.Сейчас z работаю над системой дебагга вводных данных, но z надеюсь, вы
//        люди не глупые, перечитаете верхние правила ввода данных, не
//        будете злоупотреблzть количеством огоньков, и... удачи :)
///////////////////////////////////////////////////////////////////////////////
void SetFire(object oObject = OBJECT_SELF, string str = "1* 0.0,0.0,0.0;   2! 0.0,0.0,1.0;" )

{
//
str = RemoveSpace(str);

    int iFire = GetLocalInt(oObject,"Fire");
    int iFireObject = GetLocalInt(oObject,"FireObject");
        iFire++;


   //  Сохранzем переменную
   SetLocalInt(oObject,"Fire", iFire);
   //  * Если что то пойдет не так по причине некорректного
   //  * ввода данных при вызове функции, то, поскольку мы уже сохранили локальную
   //  * переменную, мы сможем в дальнейшем использовать ее, чтобы наносить
   //  * повреждение объекту
   //  Длz нанесениz повреждений можно использовать такие строчки
   //  iFire = GetLocalInt("имz объекта, которому наносим повреждение","Fire")
   //  ApplyEffectToObject(1,EffectDamage(iFire, DAMAGE_TYPE_FIRE),"имz объекта, которому наносим повреждение");


// Берем координаты длz созданиz будущего огонька
object   oArea = GetArea(oObject);
vector vVector = GetPosition(oObject);


     while(str!="")//Пока строчка не станет пустой
          {
          // Переменнаz отвечает за визуальный вид огонька
          // FALSE если искры
          int bCheck = FALSE;

          // С помощью этой переменной проверzем номер введенного объекта,
          // это длz того, чтобы уменьшить объем повреждений от неверно введенных данных
          int iCheckFireObject;

          //* Ниже код разбирает по косточкам введенный текст в переменную str.
          //* Каждый раз то символа ";".
          //vvvvvvvvvvvvvvvvvvvvvvvvvvv->S T R<-vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv//

          // Определzем тип огнz, котороый мы ставим ("-1" возвращаетсz, если символ не найден)
          if((FindSubString(str, "*")<FindSubString(str, "!") && FindSubString(str, "*")!=-1)||FindSubString(str, "!")==-1)
          {
          // Визуальный вид огонька. TRUE если огонек
          bCheck = TRUE;

          // Соответственно берем номер объекта устанавленного огнz
          iCheckFireObject = StringToInt     (GetStringLeft (str, FindSubString(str, "*")));
          }
          else
          {
          iCheckFireObject = StringToInt     (GetStringLeft (str, FindSubString(str, "!")));
          }

          // Выделzем из строчки str координаты x, y и z в другую строку
          string xyz = GetStringLeft   (GetStringRight(str, GetStringLength(str) - 2),FindSubString(str, ";")-2);
          // Убираем обработанную строчку из кода
                 str = GetStringRight  (str, GetStringLength(str)-GetStringLength(xyz)-3);

          // Проверzем, если выделенный номер объекта следует за уже существующим номером
          // то каждые три индикатора огнz ставим огонек
          if(iCheckFireObject == iFireObject + 1  &&  iFire>iFireObject*3)
          {
          // Разбиваем строку с координатами xyz на отдельные координаты
          float x = StringToFloat(GetStringLeft   (xyz, FindSubString(xyz, ",")));
              xyz = GetStringRight  (xyz, GetStringLength(xyz)-FindSubString(xyz,",")-1);
          float y = StringToFloat(GetStringLeft   (xyz, FindSubString(xyz, ",")));
          float z = StringToFloat(GetStringRight  (xyz, GetStringLength(xyz)-FindSubString(xyz,",")-1));
          //^^^^^^^^^^^^^^^^^^^^^^^^^^^->S T R<-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//

       // Устанавливаем точку, на которую поставим огонек
       location lLoc = Location(oArea,Vector(vVector.x+x, vVector.y+y, vVector.z+z) , IntToFloat(Random(360)));
       // Регистрируем установку огонька
       iFireObject++;

       // Ставим модель огонька соответственно установленной ранее переменной. TRUE - огонь, FALSE - искры
       if(bCheck == TRUE)
       CreateObject(OBJECT_TYPE_PLACEABLE, "blueprint003", lLoc, FALSE, "fplace" + IntToString(iFireObject) );
       else
       CreateObject(OBJECT_TYPE_PLACEABLE, "blueprint033", lLoc, FALSE, "fplace" + IntToString(iFireObject) );
       // Сохранzем переменную, так как огонь мы уже поставили
       SetLocalInt(oObject,"FireObject", iFireObject);
          }
          }
}

///////////////////////////////////////////////////////////////////////////////
//             * Функциz удалzет все установленные огоньки *                 //
///////////////////////////////////////////////////////////////////////////////
void DestroyFire(object oObject)
{
// Объzвлzем счетчик и переменную, в которую заносим количество установленных огней в объекте
int i, iFireObject = GetLocalInt(oObject, "FireObject");

// Удалzем огни
for(i=iFireObject;i>0;i--)
DestroyObject(GetObjectByTag("fplace" + IntToString(i)));

// Очищаем объект от локальных переменных, хранzщих огонь
DeleteLocalInt(oObject, "FireObject");
DeleteLocalInt(oObject, "Fire");

}

Автор: Lex Oct 19 2011, 10:41

поставь патч dumbo на русскую букву "я" в скриптах. ( http://wrg.ru/download.php?view.109 )

Автор: DNAlchemist Oct 21 2011, 07:27

У меня стоит.
Просто жаль тех людей, кому лень этот патч ставить)
Им тем более будет лень исправлять все "я" на не "я"
rolleyes.gif

Автор: Melisse Oct 21 2011, 16:01

Как-то давно мне пришла в голову интересная мысль и захотелось ее реализовать - деньги в нвн не просто золотые, а монеты с весом. На ваулте лежало несколько реализаций, но меня они не устраивали, в виду некоторых причин их реализации.

Для работы системы нужен NWNX и 2 плагина nwnx_events и nwnx_fixes

Суть:
2 типа магазина: скупщик и продающий
Зацепляем событие на Еxamine item в nwnx_events
Берем голд-стоимость итема, вычисляем. В мое случае это 1 электрум = 100 золото = 10000 серебро
3 вида вычислений стоимости:
1). Когда еxamine item производиться просто в инвентаре, без открытого магазина.
-выдается стоимость без всяких надбавок + экономическое изменение (можно регулировать общее подорожание или удешевление)
2). С открытым магазине типа продающий
-производиться оценка, обоюдный бросок – в зависимости от этого скидки или наценка + экономическое изменение

3). в инвентаре при открытом магазине типа скупщик
-производиться оценка, обоюдный бросок – в зависимости от этого скидки или наценка + экономическое изменение

Надо добавить, что при реализации идеи использовались наработки КЛ, в частности - по поломке предметов, так что его (предмета) состояние непосредственно влияло на стоимость продажи/покупки

Результат выводиться виде сообщения игроку, когда он смотрит свойства предмета.
Продажа/Покупка осуществляется через REMOVE_DISTURBED_ITEM, простым перетаскиванием, без всяких диалогов. На магазин вешается переменная с ДЦ ОЦЕНКИ и типом магазина.

Всего два действия по сути: первое вы смотрите стоимость во время просмотра свойств, второе – покупка/продажа =)

Значит, обычный плэйс, с инвентарем. На нем 2 локалки типа int
TD_MERCANT_DC - ДЦ для ОЦЕНКИ
и
TD_MERCANT - тип магазина 1 и 2

Название валют можно придумать свои, для простоты ориентации в скрипте:
MonE - это сама дорогая (Электрумовая) = 100 золотым = 10000 серебра
MonG - средняя (Золотая) = 100 серебрянным
MonS - нифиля (Сребрянная)

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

Была идея сделать разные наценки в городах, в зависимости от типов предмета. Например, на мечи - такая, на бронь - такая. Что-то типо предложения спроса в городе. Идея не воплотилась)

Скрипты:

nwnx_events

Neverwinter Script
const int TD_SECS_IN_HOUR = 120.0f;

// Melisse: Берет goldvalue предмета и переводит его в валюту и выдает ввиде сообщения игроку
void td_SendMessageItemMoneyCost (object oPC, object oInvent, object oTarget);


// Main
void main( ){

    object  oPC     = OBJECT_SELF;
    object  oTarget = GetNWNXEventTarget( );
    int     nEvent  = GetNWNXEventType( );

    switch( nEvent ){

        case EVENT_EXAMINE:
        {
            if(GetObjectType(oTarget) == OBJECT_TYPE_ITEM)
            {
               object oInvent = GetItemPossessor(oTarget);

               if(GetPlotFlag(oTarget) == FALSE)
                 td_SendMessageItemMoneyCost (oPC, oInvent, oTarget);
            }
            else
              SendMessageToPC( oPC, "NWNX Knows you just examined "+GetName( oTarget )+"!" );

           break;
        }

    }

}



void td_SendMessageItemMoneyCost (object oPC, object oInvent, object oTarget)
{
    int nInvent = (GetObjectType(oInvent) == OBJECT_TYPE_PLACEABLE);
    int nCost = GetGoldPieceValue(oTarget);

    SendMessageToPC (oPC, "=============================================
====");
    //SendMessageToPC (oPC, "Value = "+IntToString(nCost));
    SendMessageToPC (oPC, td_ColorText(GetName(oTarget),TD_TXT_COLOR_GRAY));
/*
    Закоментровано. Это относитсья к системе поломки, которую тут не выкладываю.
    // Вычислим стоимость, если итем сломан
    struct strItemDur strMyItemDur = td_GetItemDur(oTarget);
    int nDurCur = strMyItemDur.nDurCur;
    int nDurMax = strMyItemDur.nDurMax;
    int nDurResult = nDurMax - nDurCur;

    if(nDurResult > 0)
    {
          float fBroken = IntToFloat(nCost)/100.0*IntToFloat(nDurResult);
          nCost -= FloatToInt(fBroken);
          SendMessageToPC (oPC, "Сломан! = -"+IntToString(nDurResult)+ "% от полной цены");
    }*/


    // Если просмотр производиться в чьем-то инвентаре
    if(GetIsObjectValid(oInvent))
    {
       // Магазин
       // При просмотре описания с открытым магазином
       // стоимость товара учитывает со скидкой/наценкой
       if(GetLocalInt(oInvent, "TD_MERCANT"))
       {
              int nSell = FALSE;

              object oStore;
              if (oPC == oInvent)
              {   // Игрок продает
                  oStore = GetLocalObject(oPC, "TD_MERCANT_OBJ");
                  nSell  = TRUE;
              }
              else if(nInvent)
              {   // Игрок покупает
                  oStore = oInvent;
              }
              else
                return;

              string sCharID  = IntToString(GetLocalInt (oPC, "nCharID"));
              int nDiscount   = GetLocalInt (oStore, "TD_DISCOUNT"+sCharID);
              int nTime       = GetLocalInt (oStore, "TD_DISCOUNT_TIME"+sCharID);
              int nEcoKingdom = GetLocalInt (GetModule(), "TD_MOD_ECO"
                                      +GetSubString(GetTag(GetArea(oPC)), 2, 1));

              SendMessageToPC (oPC, "Экономическая ситуация = "+IntToString(nEcoKingdom)+"%");

              // Рачитаем на сколько поднимиться цена в этой стране на этот предмет
              nEcoKingdom = FloatToInt(IntToFloat(nCost)/100.0*IntToFloat(nEcoKingdom));

              // Скидки нет или время пришло (1 раз в сутки)
              if(!nDiscount || nTime < td_Uptime())
              {
                 int nDC    = GetLocalInt(oStore, "TD_MERCANT_DC");
                 int nSkill = GetSkillRank(SKILL_APPRAISE, oPC);

                 nDiscount = nDC - nSkill;

                 if(nDiscount < 0)
                   nDiscount *= -1;

                 if(nDiscount == 0)
                   nDiscount = 1;

                 if(GetIsSkillSuccessful(oPC, SKILL_APPRAISE, nDC))
                 {
                      if(!nSell)
                      {
                           nDiscount += 100;
                      }

                      SetLocalInt (oStore, "TD_DISCOUNT"+sCharID, nDiscount);
                 }
                 else
                 {
                      if(nSell)
                      {
                           nDiscount += 100;
                      }

                      SetLocalInt (oStore, "TD_DISCOUNT"+sCharID, nDiscount);
                 }

                 SetLocalInt (oStore, "TD_DISCOUNT_TIME"+sCharID,
                                                                     td_Uptime ()+24*TD_SECS_IN_HOUR );
             }

             // Скидка есть - расчитаем
             if(nDiscount >= 100)
             {
                    nDiscount -= 100;
                    float fDiscount = IntToFloat(nCost)/100.0*IntToFloat(nDiscount);

                    if(nSell)
                    {
                        SendMessageToPC (oPC, "Продажа: цена = +"+IntToString(nDiscount)+"%");
                        nCost += FloatToInt(fDiscount)-nEcoKingdom; // С учетом общего экономического состояния в стране
                    }           
                    else
                    {
                        nCost -= FloatToInt(fDiscount)+nEcoKingdom; // С учетом общего экономического состояния в стране
                        SendMessageToPC (oPC, "Покупка: скидка = -"+IntToString(nDiscount)+"%");
                    }
             }
             else
             {
                    float fDiscount = IntToFloat(nCost)/100.0*IntToFloat(nDiscount);

                    if(nSell)
                    {
                        SendMessageToPC (oPC, "Продажа: цена = -"+IntToString(nDiscount)+"%");
                        nCost -= FloatToInt(fDiscount)-nEcoKingdom; // С учетом общего экономического состояния в стране
                    }
                    else
                    {
                        nCost += FloatToInt(fDiscount)+nEcoKingdom; // С учетом общего экономического состояния в стране
                        SendMessageToPC (oPC, "Покупка: цена = +"+IntToString(nDiscount)+ "%");
                    }
             }

             //SendMessageToPC (oPC, "Игрок = "+GetName(oPC));
             //SendMessageToPC (oPC, "Магазин = "+GetName(oStore));
        }


    }

    // Переведем в денежынй эквивалент
    int nMonE = nCost/10000;                     // Электрумовые
    int nMonG = (nCost - nMonE*10000)/100;       // Золотые
    int nMonS = nCost - (nMonG*100+nMonE*10000); // Серебряные

    // Покажем игроку результаты
    SendMessageToPC (oPC, td_ColorText("*СТОИМОСТЬ:",TD_TXT_COLOR_GRAY));
    SendMessageToPC (oPC, td_MoneyName(GetArea(oPC),nMonS,nMonG,nMonE));
}



на OnOpen на плэйсе
Neverwinter Script
void main()
{
   object oPC = GetLastOpenedBy();

   // Магазин, который скупает
   if(GetIsPC(oPC) && GetLocalInt(OBJECT_SELF, "WS_MERCANT") == 2)
   {
     SetLocalInt(oPC, "WS_MERCANT", TRUE);
     SetLocalObject(oPC, "WS_MERCANT_OBJ", OBJECT_SELF);
   }

   // Запускается проверка на "Опознание" предметов в инвентаре магазина
   // 1 раз за рестарт, при 1-вом открытии
   if(!GetLocalInt(OBJECT_SELF, "nActiveted"))
   {
       object oItem = GetFirstItemInInventory(OBJECT_SELF);
       while (GetIsObjectValid(oItem))
       {
           if(!GetIdentified(oItem))
             SetIdentified(oItem, TRUE);

           int nBaseType = GetBaseItemType(oItem);

           // Выставляем на итемы со стэком > 1
           // Это необходимо для того, чтобы они не стыкались с теми что в инвентаре
           // nwnx_fixed убирает баг, при котором стэкались итемы, когда у них локалки
            if(nBaseType == BASE_ITEM_ARROW ||
              nBaseType == BASE_ITEM_BOLT ||
              nBaseType == BASE_ITEM_BULLET ||
              nBaseType == BASE_ITEM_DART ||
              nBaseType == BASE_ITEM_POTIONS ||
              nBaseType == BASE_ITEM_THROWINGAXE)
           {
              SetLocalInt(oItem, "WS_MERCANT_ITEM", TRUE);
           }


           oItem = GetNextItemInInventory(OBJECT_SELF);
       }

     SetLocalInt(OBJECT_SELF, "nActiveted", TRUE);
   }

}



на OnDisturbed на плэйсе
Neverwinter Script
/**************************************\
            td_pds_shop
       --------------------------
    Author    : Melisse
    E-mail    :
    ICQ       :

    Started   :

       --------------------------

          Скрипт магазина

\**************************************/


//#include "td_inc_craft"

void td_ReturnItem (object oSubject, object oItem);
void main()
{
    object oMerchant = OBJECT_SELF;
    object oPC    = GetLastDisturbed();
    object oItem  = GetInventoryDisturbItem();
    object oArea  = GetArea(oPC);

    string sMonE = td_GetTagMoney(GetTag(oArea), "sMonE");
    string sMonG = td_GetTagMoney(GetTag(oArea), "sMonG");
    string sMonS = td_GetTagMoney(GetTag(oArea), "sMonS");
    string sTradeType = GetLocalString(oMerchant, "sTradeType");

    int nDistType = GetInventoryDisturbType();
    int nMoneyPC  = td_GetCountAllMoney (oPC, sMonE, sMonG, sMonS);
    int nCost     = GetGoldPieceValue(oItem);

   
/*
    Закоментровано. Это относитсья к системе поломки, которую тут не выкладываю. 

    // Вычислим стоимость, если итем сломан
    struct strItemDur strMyItemDur = td_GetItemDur(oItem);
    int nDurCur = strMyItemDur.nDurCur;
    int nDurMax = strMyItemDur.nDurMax;

    if((nDurMax - nDurCur) > 0)
    {
          float fCost = IntToFloat(nCost)/100.0*IntToFloat(nDurCur);
          nCost -= FloatToInt(fCost);
    }

*/


    // стоимость товара учитывает со скидкой/наценкой
    string sCharID = IntToString(GetLocalInt (oPC, "nCharID"));
    int nDiscount  = GetLocalInt (oMerchant, "TD_DISCOUNT"+sCharID);
    int nTime      = GetLocalInt (oMerchant, "TD_DISCOUNT_TIME"+sCharID);
    int nSell      = FALSE;
    int nEcoKingdom = GetLocalInt (GetModule(), "TD_MOD_ECO_"
                                      +GetSubString(GetTag(GetArea(oPC)), 2, 1));

    if(GetLocalInt(oMerchant, "TD_MERCANT") == 2)
     nSell = TRUE;

    // Рачитаем на сколько поднимиться цена в этой стране на этот предмет
    nEcoKingdom = FloatToInt(IntToFloat(nCost)/100.0*IntToFloat(nEcoKingdom));

    // ----
    // Вычисление скидки/наценки
    // ----

    if(!nDiscount || nTime < td_Uptime())
    {

         int nDC    = GetLocalInt(oMerchant, "TD_MERCANT_DC");
         int nSkill = GetSkillRank(SKILL_APPRAISE, oPC);

         nDiscount = nDC - nSkill;

         if(nDiscount < 0)
           nDiscount *= -1;

         if(nDiscount == 0)
           nDiscount = 1;

         if(GetIsSkillSuccessful(oPC, SKILL_APPRAISE, nDC))
         {
              if(!nSell)
              {
                  nDiscount += 100;
              }

              SetLocalInt (oMerchant, "TD_DISCOUNT"+sCharID, nDiscount);
         }
         else
         {
              if(nSell)
              {
                  nDiscount += 100;
              }

              SetLocalInt (oMerchant, "TD_DISCOUNT"+sCharID, nDiscount);
         }

         SetLocalInt (oMerchant, "TD_DISCOUNT_TIME"+sCharID,td_Uptime()+24*TD_SECS_IN_HOUR );
     }

     // Скидка есть - расчитаем
     if(nDiscount >= 100)
     {
           nDiscount -= 100;
           float fDiscount = IntToFloat(nCost)/100.0*IntToFloat(nDiscount);

           if(nSell)
           {
                  //SendMessageToPC (oPC, "Повышение цены = "+IntToString(nDiscount)+ "%");
                  nCost += FloatToInt(fDiscount)-nEcoKingdom; // С учетом общего экономического состояния в стране
           }                                               
           else
           {
                  nCost -= FloatToInt(fDiscount)+nEcoKingdom; // С учетом общего экономического состояния в стране
                  //SendMessageToPC (oPC, "Скидка = "+IntToString(nDiscount)+ "%");
           }
      }
      else
      {
           float fDiscount = IntToFloat(nCost)/100.0*IntToFloat(nDiscount);

           if(nSell)
           {
                 //SendMessageToPC (oPC, "Снижение цены = "+IntToString(nDiscount)+ "%");
                 nCost -= FloatToInt(fDiscount)-nEcoKingdom; // С учетом общего экономического состояния в стране
           }
           else
           {
                 nCost += FloatToInt(fDiscount)+nEcoKingdom; // С учетом общего экономического состояния в стране
                 //SendMessageToPC (oPC, "Наценка = "+IntToString(nDiscount)+ "%");
           }
      }


    // ----
    // Процесс Покупка/Продажа
    // ----

    if(nDistType == INVENTORY_DISTURB_TYPE_REMOVED)
    {
         if(GetPlotFlag(oItem) || GetLocalInt(oMerchant, "TD_MERCANT") != 1)
         {
               td_ReturnItem (oMerchant, oItem);
               FloatingTextStringOnCreature ("Этот предмет не продается.", oPC, FALSE);
         }
         else if(nMoneyPC < nCost)
         {
               td_ReturnItem (oMerchant, oItem);
               FloatingTextStringOnCreature ("Не хватает денег для покупки этой вещи.", oPC, FALSE);
         }
         else
         {
               // -------
               // Транзакция денег и выдача предмета
               // -------

               td_MoneyTransaction (oPC, TRUE, nMoneyPC, nCost, sMonE, sMonG, sMonS);
               CopyItem (oItem, oMerchant, TRUE);
               DeleteLocalInt(oItem, "TD_MERCANT_ITEM");
         }

         AssignCommand(oPC, ActionInteractObject(oMerchant));
         DelayCommand(0.5f, AssignCommand(oPC, ActionInteractObject(oMerchant)));
    }
    else if (nDistType == INVENTORY_DISTURB_TYPE_ADDED)
    {
          if(GetPlotFlag(oItem) || GetLocalInt(oMerchant, "TD_MERCANT") != 2)
          {
                td_ReturnItem (oPC, oItem);
                FloatingTextStringOnCreature ("*Вы не можете продать этот предмет здесь.", oPC, FALSE);
          }

          // Нельзя продать не идентифицированый итем или продать предмет который не покупает магазин
          else if (!GetIdentified (oItem) || FindSubString(sTradeType, IntToString(GetBaseItemType (oItem))) == -1)
          {
                td_ReturnItem (oPC, oItem);
                FloatingTextStringOnCreature ("*Вы не можете продать этот предмет здесь.", oPC, FALSE);
          }
          else
          {
               // -------
               // Транзакция денег и удаление проданого предмета
               // -------

               td_MoneyTransaction (oPC, FALSE, nMoneyPC, nCost, sMonE, sMonG, sMonS);

               SetLocalInt(oItem, "TD_DESTROY",TRUE);
               DestroyObject(oItem,0.5f);
          }

         AssignCommand(oPC, ActionInteractObject(oMerchant));
         DelayCommand(0.5f, AssignCommand(oPC, ActionInteractObject(oMerchant)));
    }

}

void td_ReturnItem (object oSubject, object oItem)
{
      CopyItem (oItem, oSubject, TRUE);

      DestroyObject (oItem);
}



Далее выкладываю просто функции и их прототипы:

Neverwinter Script
// Возвращает текстовую строку со стоимость и названиями валют
// Можно устанавливать разные валюты для разных городов и тут высталять названия
string ws_MoneyName(int nMoneyS, int nMoneyG = 0, int nMoneyE = 0);

string ws_MoneyName(int nMoneyS, int nMoneyG = 0, int nMoneyE = 0)
{
      sText = ws_ColorText(IntToString(nMoneyE)+" Хан ",WS_TXT_COLOR_WHITE)
             + ws_ColorText(IntToString(nMoneyG)+" Мон ",WS_TXT_COLOR_YELLOW)
             + ws_ColorText(IntToString(nMoneyS)+ " Шо",WS_TXT_COLOR_CYAN);

   return  sText;
}

// Возвращает полное количество денег в GoldValue
int ws_GetCountAllMoney (object oSubject, string sMonE, string sMonG, string sMonS);

int ws_GetCountAllMoney (object oSubject, string sMonE, string sMonG, string sMonS)
{
     object oMoney = GetFirstItemInInventory(oSubject);
     int i;
     while (GetIsObjectValid(oMoney))
     {
         string sMoney = GetTag(oMoney);

         if(sMoney == sMonE)
          i += GetNumStackedItems(oMoney)*10000;

         else if (sMoney == sMonG)
          i += GetNumStackedItems(oMoney)*100;

         else if (sMoney == sMonS)
          i += GetNumStackedItems(oMoney);


        oMoney = GetNextItemInInventory(oSubject);
     }


  return i;
}

// Производит пересоздание денег у игрока
void ws_MoneyTransaction (object oPC, int nType, int nMoneyPC, int nCost, string sMonE, string sMonG, string sMonS);

void ws_MoneyTransaction (object oPC, int nType, int nMoneyPC, int nCost, string sMonE, string sMonG, string sMonS)
{
    int nResult;

    if(nType)  // Покупка предмета
       nResult = nMoneyPC - nCost;
    else       // Продажа предмета
       nResult = nMoneyPC + nCost;

    SendMessageToPC (oPC, "Было денег = "+IntToString(nMoneyPC)+" Стоимость итема = "+IntToString(nCost)+" Стало денег = "+IntToString(nResult) );

    int nMonE = nResult/10000; // Электрумовые
    int nMonG = (nResult - nMonE*10000)/100; // Золотые
    int nMonS = nResult - (nMonG*100+nMonE*10000); // Серебряные

/*    SendMessageToPC (oPC, "Эле = "+IntToString(nMonE)+" Золо = "+IntToString(nMonG)+" Сере = "+IntToString(nMonS) );*/

    object oItem = GetFirstItemInInventory(oPC);
    while (GetIsObjectValid(oItem))
    {
        string sTag = GetTag(oItem);

        if (sTag == sMonE ||
            sTag == sMonG ||
            sTag == sMonS)
        {
            SetLocalInt(oItem, "WS_DESTROY",TRUE);
            DestroyObject(oItem);
        }


      oItem = GetNextItemInInventory(oPC);
    }

    object oNew;

    if(nMonS)
    {
         oNew = CreateItemOnObject(sMonS, oPC);
         SetItemStackSize (oNew, nMonS);
    }

    if(nMonG)
    {
         oNew = CreateItemOnObject(sMonG, oPC);
         SetItemStackSize (oNew, nMonG);
    }

    if(nMonE)
    {
         oNew = CreateItemOnObject(sMonE, oPC);
         SetItemStackSize (oNew, nMonE);
    }
}

// Возвращает тэг валюты sMoneyType используемой в этом городе
string ws_GetTagMoney (string sAreaTag, string sMoneyType);

string ws_GetTagMoney (string sAreaTag, string sMoneyType)
{
   string sTown = sAreaTag;
   string sMoneyTag;

   if(sTown == "Area001")
   {
       if(sMoneyType == "sMonE")
          sMoneyTag = "IT_MON_FE";
       else if (sMoneyType == "sMonG")
          sMoneyTag = "IT_MON_FG";
       else if (sMoneyType == "sMonS")
          sMoneyTag = "IT_MON_FS";
   }


  return sMoneyTag;
}



Скрипты и функции выдернуты из целого комплекса систем, поэтому могут быть какие-то не компиляции, но суть мысли должна быть понятна.

Автор: Flaristan Jun 29 2013, 21:04

Люди только осваивающие скрипты в тулсете довольно часто спрашивают как сделать, чтоб объект появлялся в локации только в определенное время (эдакие лунные руны по Толкиену smile.gif). Продвинутые модульмэйкеры знают сотню способов как это реализовать, однако недавно копался в очередной раз над наиболее лаконичным ответом на этот вопрос в тулсете (пользуясь случаем передаю привет Аконит biggrin.gif) – и обнаружил довольно универсальную формулу скрипта:..

Neverwinter Script
void main()
{
object oTarget = OBJECT_SELF;
effect eEffect = EffectDisappearAppear(GetLocation(OBJECT_SELF), 1);
int DoOnce = GetLocalInt(OBJECT_SELF, GetTag(OBJECT_SELF));
float fHour = 60.0//<- hour longitude in module (in seconds)
int iHour = 0;        //<- hour of appear (from 0 to 23)
int iTimeout = 1;    //<- longitude of appear (in hours, from 1 to 23)
int iDifferent;

iDifferent = iHour+iTimeout;
if (iDifferent > 23)
  {
  iDifferent = iDifferent-24;
  }
if ((GetTimeHour()==iDifferent)&&(DoOnce==FALSE))
  {
  ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEffect, oTarget, fHour*(24-iTimeout));
  SetLocalInt(OBJECT_SELF, GetTag(OBJECT_SELF), TRUE);
  DelayCommand(fHour*(24-iTimeout), SetLocalInt(OBJECT_SELF, GetTag(OBJECT_SELF), FALSE));
  }
}
...Комментарии на английском из-за возможных боков с "я" вот их перевод для не знающих:
<- hour longitude in module (in seconds)/длительность игрового часа в модуле (в секундах)
<- hour of appear (from 0 to 23)/игровой час появления объекта (от 0 до 23)
<- longitude of appear (in hours, from 1 to 23)/длительность появления объекта (в игровых часах, от 1 до 23)
Эти значения вы должны подставить в скрипт сами в соответствии с особенностями модуля и собственно эвента с объектом. Скрипт нужно ставить на OnHeartbeat существа/объекта, при этом если это объект - он не должен иметь в своих свойствах галочку в окошке "статик", иначе скрипт не сработает (однако при этом объект не обязательно должен быть "активным").

У скрипта есть единственный недостаток - при старте модуля объект будет видимым, пока и если в модуле не наступит час его исчезновения. Далее скрипт будет работать исправно.

Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)