Помощь - Поиск - Пользователи - Календарь
Полная версия: Скрипты
Город Мастеров > РЕДАКТОРЫ > Neverwinter Nights Aurora Toolset
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74
Kavin
Lex, попробовал - не сработало. Если верить лексикону, то получается, что PlaySound() не выполняется до тех пор, пока в стеке что-то есть. Глюк биоваревский. Т.е. очередь действий кончилась - начался звук.
Поэтому нужно делать так, чтобы PlaySound срабатывал, когда стек пуст, а затем он начинал заполняться. Разница в доли секунды получится, и глазу юзера будет незаметна.
..::SERGO::..
NSS
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"));
    switch (Random(30))
        {
        case 0: s1="×òî ìû òåïåðü äåëàòü-òî áóäåì?";s2=" Íåçíàé! Âðåìÿ ïîêàæåò...";break;
        case 1: s1="À ó íàñ åñòü ÷å ïîåñòü òî, à?";s2="Ñõîäèì â òàâåðíó, òàì äîëæíû áûòü áîè, íàâåðíÿêà ìîíåòêè òî ïîñûïÿòñÿ íà çåìëþ, õåõå...";break;
        case 2: s1="Ó ìåíÿ â æèâîòå óð÷èò";s2="Òàê ñõîäè, ïîåøü, ñòàðóøêà äðÿõëàÿ ìîÿ!";break;
        case 3: s1="À íàøà äî÷êà íàâåðíî æèâåò ñ÷àñòëèâîé æèçíü...";s2="Ïðèøåë áû ÿ äîìîé íà ïÿòü ìèíóò ðàíüøå, ÿ áû èç Ñàí÷åçà âñþ äóðü òî âûáèë!! Ýõ ÿ åìó...";break;

        }
    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("oldman1");
object oD2 = GetNearestObjectByTag("oldwoman1");
if (GetIsInCombat(oD1)) return;
if (GetIsInCombat(oD2)) return;
if ( (IsInConversation(oD1)) || (IsInConversation(oD2)) ) return;
if (GetDistanceToObject(oPC)>10.0) return;
AssignCommand(oD1,SetFacingPoint(GetPosition(oD2)));
AssignCommand(oD2,SetFacingPoint(GetPosition(oD1)));
DIALOG(oD1,oD2);
ANIMATION(oD1);
ANIMATION(oD2);
}

Два вопроса.
1 - почему не составляется(хотя в игре все ОК)
2 - почему НПСы болтают вроде бы, но не слова не появляется!?
PS 1 - при английских словах все ОК
2 - при английских словах такаяже лажаsad.gif
Dik Morris
1.
Избавляйся от маленькой буквы я, либо ставь патч от dumbo.

NSS
...
"Избавл"+ya+"йся"
...


2.
Ты точно указал таги NPC ?
Lex
QUOTE(..::SERGO::.. @ Jun 6 2006, 17:35) [snapback]83853[/snapback]
switch (Random(30))

а кейса 4. У тебя вероятность 4 к 30 что раз в 6 секунд они что-то скажут.
+ смотри, там же стоит проверка на дистанцию: те если игрок далеко, то фраз видно не будет.
ЗЫ: хм.. лучше поменять очередность.. анимация, потом проверка на дистанцию, потом слова. Так реалистичнее
gennady
QUOTE(..::SERGO::.. @ Jun 6 2006, 17:35) [snapback]83853[/snapback]
Два вопроса.
1 - почему не составляется(хотя в игре все ОК)
2 - почему НПСы болтают вроде бы, но не слова не появляется!?
PS 1 - при английских словах все ОК
2 - при английских словах такаяже лажа

SERGO, у тебя не правильно составлены стринги. Смотри как надо, и правь последнею строку сам. Если скрипт стоял на ХБ перса, то скрипт поэтому и не работал, он написан у тебя для работы с третьего перса. Маленький совет: копируй скрипт при русском шрифте в обоих редакторах, как в редакторе скриптов, так и в текстовом редакторе, должен стоять русский шрифт.

NSS
void ANIMATION(object oD)

    {
    int A=0;
    float T,S;
    switch (Random(5)+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"));
    switch (Random(30))
        {
        case 0: s1="Что мы теперь делать-то будем? ";s2="Не знаю! Врем"+ya+" покажет…";break;
        case 1: s1="А у нас есть че поесть-то, а? ";s2="Сходим в таверну, там должны быть бои, навер"+ya+"ка монетки-то посып"+ya+"тс"+ya+" на землю, хе-хе…";break;
        case 2: s1="У мен"+ya+" в животе урчит… ";s2="Так сходи, поешь, старуха др"+ya+"хла"+ya+" мо"+ya+"!";break;
        case 3: s1="А наша дочка наверно живет счастливой жизнью… ";s2="Пришел бы Я домой на пЯть минут раньше, Я бы из Санчеса всю дурь то выбил!! Эх Я ему…";break;

        }
    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("oldman1");
object oD2 = OBJECT_SELF;
if (GetIsInCombat(oD1)) return;
if (GetIsInCombat(oD2)) return;
if (IsInConversation(oD1) || IsInConversation(oD2)) return;
if (GetDistanceToObject(oPC)>10.0) return;
AssignCommand(oD1,SetFacingPoint(GetPosition(oD2)));
AssignCommand(oD2,SetFacingPoint(GetPosition(oD1)));
DIALOG(oD1,oD2);
ANIMATION(oD1);
ANIMATION(oD2);
}
..::SERGO::..
QUOTE
object oD2 = OBJECT_SELF;

Так я же ставил на "ХБ невидимого обьекта между ними"

Не пашет, все есть, токо слов не видноsad.gif
Lex
QUOTE(gennady @ Jun 7 2006, 07:37) [snapback]83894[/snapback]
Если скрипт стоял на ХБ перса, то скрипт поэтому и не работал, он написан у тебя для работы с третьего перса

он написан для стороннего контроллера и на его (контроллера) ХБ и стоит.
QUOTE(..::SERGO::.. @ Jun 7 2006, 13:04) [snapback]83897[/snapback]
Не пашет, все есть, токо слов не видно

я тебе сказал, в чем дело скорее всего. У тебя 4 пары фраз? Ну так ставь Рандом(5) а не 30.

____
кстати делай фразы покороче. Большие объемы текста выглядят не очень.

QUOTE(gennady @ Jun 7 2006, 07:37) [snapback]83894[/snapback]
if (GetArea(oPC)!=GetArea(OBJECT_SELF)) return; // Эта проверка здесь лишнЯЯ. Есть проверка дистанции…

не лишняя. Проверка дистанции, если игрок не в локации, даст -1.0, а это меньше 10. Так что проверка на своем месте. Тем более читай выше (поставить проверку дистанции после анимации, но до текста)

__
ЗЫ: у меня в Тсурле этот скрипт и его модификации различные пашут без проболем. Если проблема не в том, что я написал выше, у тебя верные тэги и условия соблюдены, в ХБ неписей ничего сбивающего не стоит, то я хз, почему у тебя не работает.
gennady
QUOTE(..::SERGO::.. @ Jun 7 2006, 13:04) [snapback]83897[/snapback]
Так я же ставил на "ХБ невидимого обьекта между ними"

Не пашет, все есть, токо слов не видно

У меня скрипт пахал на ХБ перса, по скрипту я понял, что у тебя он стоял на невидимом объекте, для данного скрипта он в принципе лишний. Можешь вернуть
NSS
object oD2 = GetNearestObjectByTag("oldwoman1");

Будет усё пахать, только правильно настрой свойства невидимого объекта.
Поставь галку - сюжет
Убери галку - статик
Убери галку – используемый
Но может и глючить, желательно все же ставить «используемый», т.ч. лучше выкидай этот объект.
Проверка дистанции, если игрок не в локации, даст -1.0, а это меньше 10. Точно, Лекс прав. Ну, и голова!
Lex
можно просто без галки статик, у меня все контроллеры такие. Используемый - не обязательно совершенно. Не глючит при этом никогда.
..::SERGO::..
АА! в задницу все! declare.gif Можно ли это заточить только под одного персонажа(типа торговца, который выкрикивает весь день)
Dik Morris
NSS
void ANIMATION(object oD)
{
    int A=0;
    float T,S;
    switch (Random(5)+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)
{
    string s1="";
    string ya = GetName(GetObjectByTag("ya"));
    switch (Random(4)+1)
        {
        case 1: s1="text"; break;
        case 2: s1="text"; break;
        case 3: s1="text"; break;
        case 4: s1="text"; break;
        }
    AssignCommand(oD1,SpeakString(s1));
}

void main()
{
object oPC = GetFirstPC();
if (GetArea(oPC)!=GetArea(OBJECT_SELF)) return;
object oD2 = OBJECT_SELF;
if (GetIsInCombat(oD2)) return;
if (IsInConversation(oD2)) return;
if (GetDistanceToObject(oPC)>10.0) return;
DIALOG(oD2);
ANIMATION(oD2);
}
Mandrake
NSS
void main()
{
    object oPC = OBJECT_SELF;



  if ((GetLevelByClass(CLASS_TYPE_PALEMASTER, oPC)>0))

  {
    int nLevel = GetLevelByClass(CLASS_TYPE_PALEMASTER, OBJECT_SELF);
    effect eSummon;
    float fDelay = 3.0;
    int nDuration = nLevel;
    if (nLevel >= 7)
        eSummon = EffectSummonCreature("NW_S_DOOMKGHT",VFX_FNF_SUMMON_UNDEAD);
    else
        eSummon = EffectSummonCreature("NW_S_GHAST",VFX_FNF_SUMMON_UNDEAD);

    ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eSummon, GetSpellTargetLocation(), HoursToSeconds(nDuration));
    }


Привожу скипт для объяснения ситуации, сам скрипт работает, но у меня проблемы вот с чем. Хочется внести своего самона, ну например чтобы при 10 лвлах ПМа вылезал Командир Дум Найтов. Когда я ставлю его со стандартным его тегом, он вылезает, однако на нем нету скриптов хенчмана(или как их правильно назвать), поэтому управлять им не возможно. Я добавляю ему их, меняю таг, соответствено он перемещается из стандартных монстров, в сделаных мной, и когда я добавляю его в этот скрипт вместо командира вылезает голый дварф с 1 хп и без имени, мобы на него не реагируют declare.gif Объясните пожалуйста как с этим быть.

P.S. Если запостил не в тот раздел, прошу прощения, пока еще не разобрался с форумом.
Lex
все, что тебе нужно это указать резреф твоего ДумКнайта в функции EffectSummonCreature. (резреф, не тэг. Это важно.) те что-то такое
NSS
void main()
{
    object oPC = OBJECT_SELF;



  if ((GetLevelByClass(CLASS_TYPE_PALEMASTER, oPC)>0))

  {
    int nLevel = GetLevelByClass(CLASS_TYPE_PALEMASTER, OBJECT_SELF);
    string sSummon;
    float fDelay = 3.0;
    int nDuration = nLevel;
    if (nLevel >= 10) // с 10 левела твой командир
        sSummon = "твой резреф";
    else if (nLevel >= 7) // с 7 по 10 просто думкнайт
        sSummon = "NW_S_DOOMKGHT";
    else  // до 7го гаст.
        sSummon = "NW_S_GHAST";


    ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectSummonCreature(sSummon,VFX_FNF_SUMMON_UNDEAD), GetSpellTargetLocation(), HoursToSeconds(nDuration));
    }
Mandrake
Огромное спасибо thank_you.gif Теперь все стало работать. Я просто думал раз стандартные мобы указаны через тэги, то и мои должны быть через них smile.gif
Lex
у стандартных совпадаюи тэги и рефы. Тебе тоже стоит делать, чтобы совпадали. Обычно правило такое: реф маленькими буквами, тэг - большими. (и одинаковые по содержанию)
Mandrake
Спасибо, запомню.
mamuc
biggrin.gif
QUOTE
у стандартных совпадаюи тэги и рефы. Тебе тоже стоит делать, чтобы совпадали. Обычно правило такое: реф маленькими буквами, тэг - большими. (и одинаковые по содержанию)


добавлю и я свои 5 юаней biggrin.gif
..а еще лучше -делай кустомные итемы с одинаковым, полностью совпадающим, тэгом и ресрефом( оба маленькими латинскими буквами и не длинее 16 симболов) - тогда не прийдеться задумываться при всяких сравнениях, созданиях и проч yes3.gif
Mandrake
Еще один вопрос, я теме для новичков просил помочь, но наверное не заметили там. Если не трудно, просьба помочь. Ситуация такая, хочу в своем модуле создать локации что-то типа "Дом Теней", где мобы были бы ШД. Соотвествено нужно на onSpawn, onHeartbeet и onCombatRoundEnd поставить скрипты. Я руководствуясь логикой сделал нечто подобное(скрипт на комбат раунд энд):
NSS
object oTarget = OBJECT_SELF;
object oEnemy = GetLastAttacker();

if (GetStealthMode(oTarget) == STEALTH_MODE_DISABLED)
{
ActionMoveAwayFromObject(oEnemy, TRUE, 10.0f);
AssignCommand(oTarget, UseStealthMode());
DelayCommand(5.2,AssignCommand(oTarget, ActionWait(3.0)));
DelayCommand(7.1, AssignCommand(oTarget, ActionAttack(oEnemy)));
}

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

P.S. Есть задумка, что нужно как то делать, чтобы в конце каждого раунда моб из режима атаки переходил в состояние покоя, т.к. когда я становлюсь для него не видимым он выполняет задание отбежать от меня на 10 метров =)
Aiwan
Что то я не понял. unknw.gif Mandrake, видишь ли, кроме твоих скриптов работает тонна скриптов биовар, это надо учитывать. Опиши финальную задачу. ЗАЧЕМ ТЕБЕ ЭТО. Опиши задачу конкретно от А до Я. Что делает НПС, что РС.
Mandrake
Хорошо.
Задача РС понятно, убить НПС =) Мне это нужно, чтобы разнообразить деятельность мобов, а также воплатить в реальность задумку о териториях, скажем домах или лесах, где приключенца ждали бы хайдеры(ну скажем дом теней, действующие персонажи: души бывших убийц, игрок попав в такой дом должен быть все время готов нарваться на ловушку, встретиться врага появляющегося из тени и т.д.)
К самому главному, задача НПС.
Я не хочу удалять скрипты биоварей из выше указаных мной ситуациях,я просто хочу добавить к ним следующие вещи. Задачи НПС которые мне хочется воплоить в жизнь.
1. Спаун в хайде
2. В случае обнаружения игрока также атака из хайда
3. Во время боя после сника уход обратно в режим хайда, для реалистичности, чтобы нпс отбегал на расстояние и как бы на бегу пропадал, ну это так опционально, достаточно, чтобы просто после 1го сника он опять ушел в хайд.
4. После допустим убийста игрока, опять уход в хайд и продолжать жить дальнейшей жизнью.


Надеюсь теперь мои мысли понятны unsure.gif
azathoth
-- AssignCommand(oTarget, UseStealthMode()); не заставляет НПС входить в хайд
кстати, вот что он делает:
NSS
// If stealth mode is active, turn on the appropriate skills.
void UseStealthMode()
{
//        SetActionMode(OBJECT_SELF,ACTION_MODE_STEALTH,TRUE);
}

попробуй
NSS
void ActionUseSkill(int nSkill, object oTarget, int nSubSkill=0, object oItemUsed=OBJECT_INVALID )


-- ActionMoveAwayFromObject(oEnemy, TRUE, 10.0f); - если игрок последует за монстром (а это наверняка так и будет), то экшн может не завершиться, и следующий экшн (по, собственно, уходу в хайд) не начаться.
попробуй
NSS
АctionMoveAwayFromLocation(GetLocation(GetLastAttacker()), TRUE, 10.0f);


--
QUOTE
1. Спаун в хайде

хайд при спауне.
gennady
QUOTE(Mandrake @ Jun 9 2006, 21:07) [snapback]84280[/snapback]
Еще один вопрос, я теме для новичков просил помочь, но наверное не заметили там. Если не трудно, просьба помочь. Ситуация такая, хочу в своем модуле создать локации что-то типа "Дом Теней", где мобы были бы ШД. Соотвествено нужно на onSpawn, onHeartbeet и onCombatRoundEnd поставить скрипты. Я руководствуясь логикой сделал нечто подобное(скрипт на комбат раунд энд):

Если я правильно вас понял, то вам нужна подлая атака из невидимого положения, по типу скрытых атак Baldur’s Gate. Завалялось тут у меня пара скриптов… Один на OnSpawn, другой на ХБ персонажа, начально персонаж фракции «Простолюдин».
на OnSpawn
NSS
// ***  ТЕНЕВАЯ АТАКА  *** OnSpawn
void main()
{
object oTarget = OBJECT_SELF;
effect eCUT = EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eCUT, oTarget);
}

на ХБ персонажа
NSS
// ***  ТЕНЕВАЯ АТАКА  ***
// Снимаем эффект
void DelEffectOnPC(object oObject)
{
effect eOne = GetFirstEffect(oObject);
while (GetIsEffectValid(eOne))
{
  RemoveEffect(oObject, eOne);
  eOne = GetNextEffect(oObject);
}
}
// Генерируем случайную точку
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 = GetFirstPC();
object oTarget = OBJECT_SELF;

if (GetDistanceBetween(oPC, oTarget) > 10.0) return;
else if (GetLocalInt(oTarget, "ATTACK") == 0)
{
  location lFree = CreateRandomLocation(oTarget, 5.0); // Генерим точку в радиусе 5 метров
  effect eCUT = EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY);
  effect eDamage = EffectDamage(GetCurrentHitPoints(oPC)/7);
  ChangeToStandardFaction(oTarget, STANDARD_FACTION_HOSTILE); // Менaем фракцию на враждебный;
  AssignCommand(oTarget, ClearAllActions(TRUE));
  AssignCommand(oTarget, ActionJumpToObject(oPC, TRUE));
  DelayCommand(1.0, AssignCommand(oTarget, ActionAttack(oPC)));
  DelayCommand(1.0, DelEffectOnPC(oTarget)); // Снимаем эффект
  DelayCommand(1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oPC)); // Наносим удар
  DelayCommand(1.5, SendMessageToPC(oPC, "<cу  >ВАМ НАНЕСЛИ ПОДЛЫЙ УДАР</c>"));
  DelayCommand(2.0, AssignCommand(oPC, ActionAttack(oTarget)));
  DelayCommand(9.0, SurrenderToEnemies());   // Снимаем атаку
  //DelayCommand(9.3, ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectInvisibility(INVISIBILITY_TYPE_NORMAL), oTarget));
  DelayCommand(9.3, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eCUT, oTarget));
  DelayCommand(9.5, AssignCommand(oTarget, ActionMoveToLocation(lFree, TRUE)));
  SetLocalInt(oTarget,"ATTACK", 1);
  DelayCommand(18.5, SetLocalInt(oTarget,"ATTACK", 0));
}
}

Если хотите, то можете поставить другую невидимость, по своему вкусу.
Aiwan
Mandrake, не поверишь smile.gif ВСЕ ЭТО ДААВНО НАПИСАНО БИОВАР и работает. Если тебе не в лом, глянь мой скрипт спавна. Могу тут поместить. Настрой его по уму, не поленись прочти комменты. И все о чем ты мечтаешь будет работать. Патрулирование в хайде по точкам, атака из хайда. И прочее. Я его где-то уже выкладывал, но этот я малость доработал.
NSS
//::///////////////////////////////////////////////
//:: Name x2_def_spawn
//:: Copyright © 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Default On Spawn script

    2003-07-28: Georg Zoeller:
    If you set a ninteger on the creature named
    "X2_USERDEFINED_ONSPAWN_EVENTS"
    The creature will fire a pre and a post-spawn
    event on itself, depending on the value of that
    variable
    1 - Fire Userdefined Event 1510 (pre spawn)
    2 - Fire Userdefined Event 1511 (post spawn)
    3 - Fire both events
*/

//:://////////////////////////////////////////////
//:: Created By: Keith Warner, Georg Zoeller
//:: Created On: June 11/03
//:://////////////////////////////////////////////

const int EVENT_USER_DEFINED_PRESPAWN = 1510;
const int EVENT_USER_DEFINED_POSTSPAWN = 1511;
#include "x0_i0_anims"
#include "x0_i0_treasure"
#include "x2_inc_switches"
void main()
{
    // User defined OnSpawn event requested?
    int nSpecEvent = GetLocalInt(OBJECT_SELF,"X2_USERDEFINED_ONSPAWN_EVENTS");
    // Pre Spawn Event requested
    if (nSpecEvent == 1  || nSpecEvent == 3  )
    {
    SignalEvent(OBJECT_SELF,EventUserDefined(EVENT_USER_DEFINED_PRESPAWN ));
    }
    /*  Fix for the new golems to reduce their number of attacks */
    int nNumber = GetLocalInt(OBJECT_SELF,CREATURE_VAR_NUMBER_OF_ATTACKS);
    if (nNumber >0 )
    {
        SetBaseAttackBonus(nNumber);
    }
//::====================== Add By Aiwan / WRG! Team / ==========================
//:://////////////////////////////////////////////
//:: OnSpawn  am_csp_common
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
  Добавляем стандартные свойства НПС, модифицируя
  скрипт NW_C2_DEFAULT9.

                  КОММЕНТАРИИ

  Каждому свойству принадлежит локальная переменная,
  которую необходимо установить на НПС в редакторе.
  Все они начинаются на "FLAG_+Спавн_Свойство_НПС"
  Далее...

  * Если на модуль повесить LocalInt
  "X2_SWITCH_CROSSAREA_WALKWAYPOINTS" равную TRUE;
  то все НПС ходят по вейпам из локации в локацию.
  В противном случае только по вейпоинтам в одной
  локации.

  * Если повесить на дневной пост POST_ или ночной
  пост NIGHT_ локальную переменную LocalInt
  "X2_L_WAYPOINT_SETFACING" равную TRUE, то НПС
  становится лицом в сторну вепоинта. И возвращется
  в ту сторону даже после диалога/боя.

*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Original idea By: DBColl
//:: Created On: 06.07.2005
//:://////////////////////////////////////////////
    //--------------------------------------------------------------------------
    // Запускает скрипты на объект при локальном стринге
    //--------------------------------------------------------------------------
    string sRunScript = GetLocalString(OBJECT_SELF, "RUN_SCRIPT");
    if(sRunScript!="")
    {
      ExecuteScript(sRunScript, OBJECT_SELF);
    }
//==============================================================================
//              Стандартные еванты скрипта NW_C2_DEFAULT9
//==============================================================================
    if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_STEALTH) == TRUE)
      {SetSpawnInCondition(NW_FLAG_STEALTH);}
    if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_SEARCH) == TRUE)
      {SetSpawnInCondition(NW_FLAG_SEARCH);}
    if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_AMBIENT_IMMOBILE) == TRUE)
      {SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);}
    if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_AMBIENT) == TRUE)
      {SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);}
    //--------------------------------------------------------------------------
    // НПС ходит скрытно, когда выполняется WalkWaypoints(). Хорошо для убийц.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_STEALTH") == TRUE)
      {SetSpawnInCondition(NW_FLAG_STEALTH);}
    //--------------------------------------------------------------------------
    // То же самое, только в режиме поиска. Хорошо для стражи.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_SEARCH") == TRUE)
      {SetSpawnInCondition(NW_FLAG_SEARCH);}
    //--------------------------------------------------------------------------
    // НПС появится используя "EffectAppear", т.е. Свалится с неба.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_APPEAR_ANIMATION") == TRUE)
      {SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);}
    //--------------------------------------------------------------------------
    // НПС будет постоянно воспроизводить анимацию, даже если игрок уйдет из его
    // поля зрения.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_CONSTANT") == TRUE)
      {SetSpawnInCondition(NW_ANIM_FLAG_CONSTANT);}
    //--------------------------------------------------------------------------
    //  Цивилизованные творения взаимодействуют с placeables в их области, что
    //  имеют таг "NW_INTERACTIVE"
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_CIVILIZED") == TRUE)
      {SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);}
    //--------------------------------------------------------------------------
    //  НПС с бродячей анимацией ходят бродят по городу часто возвращаясь в свой
    //  SPAWN пункт, арену в которой они спавнятся (желательно внутреннюю) и
    //  которая содержит один из тагов: "NW_HOME", "NW_TAVERN", "NW_SHOP"
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_CLOSE_RANGE") == TRUE)
      {SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);}
    //--------------------------------------------------------------------------
    //  При наступлении ночи, запускает скрипт сна на НПС. Имя скрипта вешается
    //  на модуль, как LocalString "X2_S_SLEEP_AT_NIGHT_SCRIPT" равное имени
    //  скрипта "имя_скрипта_на_ночь".
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_SLEEPING_AT_NIGHTT") == TRUE)
      {SetSpawnInCondition(NW_FLAG_SLEEPING_AT_NIGHT);}
    //--------------------------------------------------------------------------
    //  НПС поднимает тревогу, сообщит при атаке всем не враждебным НПС.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_WARNINGS") == TRUE)
      {SetSpawnInCondition(NW_FLAG_SET_WARNINGS);}
    //--------------------------------------------------------------------------
    //  Ходит на ночные/дневные поинты. Днем ходит по стандартным поинтам, ночью
    //  "WN_" + NPC Tag + "_##. Ночной пост - "NIGHT_" + NPC tag.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_DAY_NIGHT_POSTING") == TRUE)
      {SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);}
    //--------------------------------------------------------------------------
    //  НПС болтает с дружественными НПС, воспроизводит анимацию, эмитирует
    //  оживление и активность.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_IMMOBILE_ANIMATIONS") == TRUE)
      {SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);}
    //--------------------------------------------------------------------------
    // Почти то же что и выше, за исключением того, что НПС бродит по округе.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_AMBIENT_ANIMATIONS") == TRUE)
      {SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);}

//==============================================================================
//      Атакующие свойства НПС - устанавливается ТОЛЬКО ОДНО ИЗ НИХ!
//==============================================================================
    //--------------------------------------------------------------------------
    //  Старается атаковать издали, дальнобойным оружием.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_RANGED") == TRUE)
        {SetCombatCondition(X0_COMBAT_FLAG_RANGED);}
    //--------------------------------------------------------------------------
    //  Использует защитные фиты и паррирование
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_DEFENSIVE") == TRUE)
        {SetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE);}
    //--------------------------------------------------------------------------
    //  Будет невидимым и попытается атаковать, выйдет из невидимости и снова
    //  будет пытаться атаковать.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_AMBUSHER") == TRUE)
        {SetCombatCondition(X0_COMBAT_FLAG_AMBUSHER);}
    //--------------------------------------------------------------------------
    //  При атаке убегает
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_COWARDLY") == TRUE)
        {SetCombatCondition(X0_COMBAT_FLAG_COWARDLY);}
//==============================================================================
//        Защитныеые свойства НПС - устанавливается ТОЛЬКО ОДНО ИЗ НИХ!
//==============================================================================
    //--------------------------------------------------------------------------
    // НПС Убегает в точку и возвращается через короткое время позже.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_ESCAPE_RETURN") == TRUE)
        {SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN);}
    //--------------------------------------------------------------------------
    // Убегает в точку и не возвращается.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_ESCAPE_LEAVE") == TRUE)
        {SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE);}
    //--------------------------------------------------------------------------
    // Телепортируется в безопасность и не возвращается.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_TELEPORT_LEAVE") == TRUE)
        {SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE);}
    //--------------------------------------------------------------------------
    // Телепортируется в безопасность и возвращается через короткое время.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_TELEPORT_RETURN") == TRUE)
        {SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN);}
//==============================================================================
//            Добавляем свои настройки для персональных нужд.
//==============================================================================
    //--------------------------------------------------------------------------
    // Создаем автоматически группы разговаривающих рандомно НПС, используя
    // библиотеку SlavaZ-а. Теперь создавая поинты фразы, учитывайте, что группы
    // НПС будут Speaker+Локалтьная переменная "FLAG_WP_SPEAK". Если
    // Она будет ровна 3, то значение (Value) строки на Waypoint с именем
    // "NAME_wp_speak" должны начинаться с Speaker3. Читайте мануал Славы...
    //--------------------------------------------------------------------------
    int iSpeaker = GetLocalInt(OBJECT_SELF, "FLAG_WP_SPEAK");
    if (iSpeaker >= 1) // Если локалка равна 1 или больше, то...
      {
      /* Присвоим этого НПС к группе Speaker+локалка "FLAG_WP_SPEAK" */
      SetLocalString(OBJECT_SELF, "SpeakGroup", "Speaker"+(IntToString(iSpeaker)));
      }
    //--------------------------------------------------------------------------
    //  Садим на стул или закрываем стэк команд. + UserDefained скрипт сидения.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_SIT_CHAIR") == TRUE)
      {
        SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT);
        ActionSit(GetNearestObjectByTag("SIT_CHAIR"));
        }
        if (GetLocalInt(OBJECT_SELF, "FLAG_SIT_CHAIR") == 2)
          {
          ActionSit(GetNearestObjectByTag("SIT_CHAIR"));
          SetCommandable(FALSE);
          }
    //--------------------------------------------------------------------------
    //  Садим НПС на землю. + UserDefained скрипт сидения.
    //--------------------------------------------------------------------------
    if (GetLocalInt(OBJECT_SELF, "FLAG_SIT_CROSS") == TRUE)
      {
        SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT);
        SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT);
        SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT);
        ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0, 99999.9);
        }
    //--------------------------------------------------------------------------
    //  Присваиваем НПС координаты, что бы он стоял лицом в одном направлении.
    //--------------------------------------------------------------------------
    if (GetLocalFloat(OBJECT_SELF,"initFacing") == 0.0)
    {
        location loc = GetLocation(OBJECT_SELF);
        SetLocalFloat(OBJECT_SELF, "initFacing", GetFacingFromLocation(loc));
        SetLocalLocation(OBJECT_SELF, "initLoc", loc);
    }
//==============================================================================
//                  Запускаем стандартные еванты на НПС
//==============================================================================
    //--------------------------------------------------------------------------
    // Если вы присвоите локальную переменную "FLAG_USER_DEFINED_EVENT" равную
    // TRUE, то все еванты присвоятся сразу. В противном случае присваивайте
    // По одному для каждого события.
    //--------------------------------------------------------------------------
    int iUserDef = GetLocalInt(OBJECT_SELF, "FLAG_USER_DEFINED_EVENT");

    // * Fire User Defined Event 1001 in the OnHeartbeat
    if (iUserDef==TRUE || GetLocalInt(OBJECT_SELF, "FLAG_HEARTBEAT") == TRUE)
        {SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT);}

    // * Fire User Defined Event 1002
    if (iUserDef==TRUE || GetLocalInt(OBJECT_SELF, "FLAG_PERCIEVE") == TRUE)
        {SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT);}

    // * Fire User Defined Event 1003
    if (iUserDef==TRUE || GetLocalInt(OBJECT_SELF, "FLAG_END_COMBAT_ROUND") == TRUE)
        {SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT);}

    // * Fire User Defined Event 1004
    if (iUserDef==TRUE || GetLocalInt(OBJECT_SELF, "FLAG_ON_DIALOGUE") == TRUE)
        {SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT);}

    // * Fire User Defined Event 1005
    if (iUserDef==TRUE || GetLocalInt(OBJECT_SELF, "FLAG_ATTACK") == TRUE)
        {SetSpawnInCondition(NW_FLAG_ATTACK_EVENT);}

    // * Fire User Defined Event 1006
    if (iUserDef==TRUE || GetLocalInt(OBJECT_SELF, "FLAG_DAMAGED") == TRUE)
        {SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT);}

    // * Fire User Defined Event 1007 (Считается ненадежным BioWare)
    if (iUserDef==TRUE || GetLocalInt(OBJECT_SELF, "FLAG_DEATH") == TRUE)
        {SetSpawnInCondition(NW_FLAG_DEATH_EVENT);}

    // * Fire User Defined Event 1008
    if (iUserDef==TRUE || GetLocalInt(OBJECT_SELF, "FLAG_DISTURBED") == TRUE)
        {SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT);}

    // * Fire User Defined Event
    if (iUserDef==TRUE || GetLocalInt(OBJECT_SELF, "FLAG_SPELL_CAST_AT") == TRUE)
        {SetSpawnInCondition(NW_FLAG_SPELL_CAST_AT_EVENT);}
    //--------------------------------------------------------------------------
    // Создает небольшую сумму сокровища в инвентаре
    //--------------------------------------------------------------------------
    if ((GetLocalInt(GetModule(), "X2_L_NOTREASURE") == FALSE)  &&
        (GetLocalInt(OBJECT_SELF, "X2_L_NOTREASURE") == FALSE)  )
    {
        CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF);
    }
    //--------------------------------------------------------------------------
    SetListeningPatterns();
    //--------------------------------------------------------------------------
    // nRun - если нужно что бы стражник бегал или ждал на поинтах больше чем по
    // умолчанию, то присвойте нужные значения на OBJECT_SELF.
    // LocalInt "FLAG_WALK_RUN" - равная TRUE, заставит НПС бегать по точкам.
    // LocalFloat "FLAG_WALK_PAUSE" - время паузы на поинтах. По умолчанию f1.0
    // Для верной работы надо править еще эту функцию на HertBeat скрипте и в
    // после завершения диалога с НПС. Иначе все настройки будут по умолчанию
    // после первого боя или диалога.
    //--------------------------------------------------------------------------
    int nRun = GetLocalInt(OBJECT_SELF, "FLAG_WALK_RUN");
    float fPause = GetLocalFloat(OBJECT_SELF, "FLAG_WALK_PAUSE");
    if (fPause == 0.0f)
    {
        fPause = 1.0f;
    }
    WalkWayPoints(nRun, fPause);
//=========================== End Aiwan's Edition ==============================
    //Post Spawn event requeste
    if (nSpecEvent == 2 || nSpecEvent == 3)
    {
      SignalEvent(OBJECT_SELF,EventUserDefined(EVENT_USER_DEFINED_POSTSPAWN));
    }
}

В слоте хертбит ищем функцию:
NSS
// If we have the 'constant' waypoints flag set, walk to the next
    // waypoint.
    else if ( GetWalkCondition(NW_WALK_FLAG_CONSTANT) )
    {
        WalkWayPoints();
    }

Заменяем на это:
NSS
//======================== Add By Aiwan / WRG! Team / ==========================
    // Если НПС ходит по вейпоинтам, то он отправится на следующий.
    //--------------------------------------------------------------------------
    // nRun - если нужно что бы стражник бегал или ждал на поинтах больше чем по
    // умолчанию, то присвойте нужные значения на OBJECT_SELF.
    // LocalInt "FLAG_WALK_RUN" - равная TRUE, заставит НПС бегать по точкам.
    // LocalFloat "FLAG_WALK_PAUSE" - время паузы на поинтах. По умолчанию f1.0
    //-------------------------------------------------------------------------
    else if ( GetWalkCondition(NW_WALK_FLAG_CONSTANT) )
    {
    int nRun = GetLocalInt(OBJECT_SELF, "FLAG_WALK_RUN");
    float fPause = GetLocalFloat(OBJECT_SELF, "FLAG_WALK_PAUSE");
      if (fPause == 0.0f) // Значит ее нет на объекте
      {
        fPause = 1.0f; // Присвоим паузу по умолчанию 1.0 секунду
      }
      WalkWayPoints(nRun, fPause);
    }
//=================================== End ======================================

И все. Настрой и сохрани скрипты с другими именами, не правь стандартные. Некоторые строки тебе не нужны. Например деления на спекеров, сидение и прочее. Это надо мне. Думаю выкинешь сам. Локалки вешаются в редакторе на НПС.
Mandrake
azathoth, gennady спасибо большое, сейчас буду примеряться smile.gif

Aiwan, спасибо и тебе большое. thank_you.gif Насчет Биоварей скажу, что пока не научился полностью понимать ими написаное, поэтому в большинстве случаев стараюсь придумать уже давно придуманое scratch_one-s_head.gif

Добавил:

Поизучал я твой спаун скрипт Aiwan, действительно все что хотел по поводу хайдеров сделал good.gif Тут мой пытливый ум решил поэксперементировать дальше и у меня возникли кое какие наблюдения.
1. Это с так называемыми гвардами, которые в режиме поиска. Они когда видят меня почему то не сбрасывают режим, а как инвалиды медлено в мою сторону ползут. Режим естестсвенно скидывается после попадания по мне, т.е. будуч магом можно запросто порхать даже без хаста вокруг них и пулять спелами =)
2. Это теже гварды, которые не возвращаются к режиму поиска после атаки.
3. Это хайдеры, которые идут медлено в хайде к тебе, если ты их атакуешь из лука или спелами(допустим у игрока трусинг или же высокий спот\листен) vava.gif

Подскажите пожалуйста, чего я в очередной раз не увидел или пропустил и как эти глюки у мобов исправить scratch_one-s_head.gif
Vhall
Скажите пожалуйста, можно ли выдать фиты персу (и будут ли они работать) без выполнения всех требований к фиту?
Aiwan
QUOTE(Mandrake @ Jun 10 2006, 13:43) [snapback]84343[/snapback]
Подскажите пожалуйста, чего я в очередной раз не увидел или пропустил и как эти глюки у мобов исправить

Скорость движения НПС у тебя стоит скорее всего не дефолт. Исправляй в свойствах НПС.

Можешь на ОнДамадж повесить снятие всех невидимостей, очистку акций и сразу атаку РС если не поможет что я сказал. А попробуй создай визардом НОВОГО нпс и проверь на нем.
Белатрис
NSS
void main()
{
object oHome = GetObjectByTag("TORBEN_HOME");
location lHome = GetLocation(oHome);
JumpToLocation(lHome);
}

Хочу, чтобы в конце диалога ПС улетел к точке в другой локации. Не получается... prankster2.gif
Dik Morris
Нужно просто определить игрока.

NSS
object oPC = GetPCSpeaker();
object oHome = GetObjectByTag("TORBEN_HOME");
location lHome = GetLocation(oHome);

AssignCommand(oPC, JumpToLocation(lHome));
-fenix-
QUOTE(Vhall @ Jun 13 2006, 11:00) [snapback]84575[/snapback]

Скажите пожалуйста, можно ли выдать фиты персу (и будут ли они работать) без выполнения всех требований к фиту?

Выдать персу не льзя.
Можно добавить на шкурку.
Sharklike
Кто в курсе на каких 2да таблицах основывается функция GetGoldPieceValue при вычислении стоимости предмета?
Требуется вычислить стоимость(либо уровень) итема, зная его свойства, но не имея под рукой.
Lex
тут нет какой-то одной таблицы. Если ты обратил внимание, то все таблицы свойств айтемов (их там порядка 10-15) имеют колонку Cost (там модификаторы цены) + у каждого айтема есть базовая стоимость (в baseitem). Все это как-то вместе собирается в 1 форумулу... unknw.gif А вот вроде стоимость - уровень есть таблица.. но если ты не знаешь ни того, ни другого, она не поможет.
Sharklike
QUOTE(Lex @ Jun 16 2006, 12:29) [snapback]84874[/snapback]

тут нет какой-то одной таблицы. Если ты обратил внимание, то все таблицы свойств айтемов (их там порядка 10-15) имеют колонку Cost (там модификаторы цены) + у каждого айтема есть базовая стоимость (в baseitem). Все это как-то вместе собирается в 1 форумулу... unknw.gif А вот вроде стоимость - уровень есть таблица.. но если ты не знаешь ни того, ни другого, она не поможет.

Вообще-то мне формулу надо, использующую эти таблицы.
Если кто разбирался со связью значений Cost в таблицах itempropdef.2da, iprp_*cost.2da и реальной ценой итема, поделитесь, пожалуйста результатами.

Формулу вывел. Вопрос снят.
Aiwan
QUOTE(Sharklike @ Jun 16 2006, 15:53) [snapback]84879[/snapback]
Формулу вывел. Вопрос снят.

Ну дык, взял бы и написал тут. Кто-то может тоже искать будет...
Mandrake
NSS
#include "x2_inc_compon"
#include "x0_i0_spawncond"
void main()
{

    object oKiller = GetLastKiller();
    object oTarget = OBJECT_SELF;
  if(GetSpawnInCondition(NW_FLAG_DEATH_EVENT))
    {
        SignalEvent(OBJECT_SELF, EventUserDefined(1007));
    }

    craft_drop_items(oKiller);
    // destroy objectt
    DelayCommand(120.0, DestroyObject(oTarget));
    GiveGoldToCreature (OBJECT_SELF, d20(2)+10);
}


Ситуация:
Есть моб, с которого при смерти падают вещи на него одетые и труп становится доступным для ограбления. Чтобы не было перегрузов системы после того, как убивается много таких мобов, я запускаю уничтожение этого трупа со всем лутом через 2 минуты. Все казалось бы работает. Но... На месте где лежал труп остается маленькая светящаяся точка, которая видна только при использовании клавиши TAB. Ее воздействие на ресурсы системы как мне показалось тоже негативное. Сначала я думал дело в инклудах, я их убрал оставил только последние 2 строчки скрипта(уничтожение трупа и выдача золота), но все равно она появляется. Помогите понять, что это за объект неизвестного происхождения и как от нее избавится или же может есть альтернативный способ сгружать вещи во что нибудь, а потом это что нибудь уничтожать.
Aiwan
QUOTE(Mandrake @ Jun 17 2006, 00:18) [snapback]84935[/snapback]
На месте где лежал труп остается маленькая светящаяся точка, которая видна только при использовании клавиши TAB.

Может ты имел ввиду мешочек? scratch_one-s_head.gif
Mandrake
Нет, я в свойствах персонажа ставил "оставить труп для грабежа" =) Соответствено этот труп дестроится, а там где он был остается выше описаное.
Sharklike
Такие подсвечивающиеся точки остаются в любом тайлсете?
Neo
QUOTE(Aiwan @ Jun 16 2006, 21:01) [snapback]84922[/snapback]
Ну дык, взял бы и написал тут. Кто-то может тоже искать будет...

wink3.gif

4.4. Cost Calculation
The cost of an item is determined by the following formula:

ItemCost = [BaseCost + 1000*(Multiplier^2 - NegMultiplier^2) + SpellCosts]*MaxStack*BaseMult + AdditionalCost;

, where:
BaseMult = ItemMultiplier column value from baseitems.2da.
AdditionalCost = AddCost Field from the Item Struct.
and the other terms are as defined in the following subsections:

4.4.1. Base Cost
BaseCost = BaseCost column value from baseitems.2da for all items except armor.
For armor, BaseCost is the cost in armor.2da for the armor's base AC. The armor's base AC is the ACBONUS from parts_chest.2da, using the part number of the chest as the index into parts_chest.2da.

4.4.2. Multipliers
Multiplier is the sum of the costs of all the Item Properties whose costs are positive. That is:
NegMultiplier is the sum of the costs of all Item Properties whose costs are negative.
If an Item Property has a PropertyName of 15 (Cast Spell), then omit it from the Multiplier/NegMultiplier totals. It will be handled when calculating the SpellCosts instead.
To calculate the cost of a single Item Property, use the following formula:
ItemPropertyCost = PropertyCost + SubtypeCost + CostValue
Add the ItemProperty's cost to the Multiplier total if it is positive. Add it to the NegMultiplier total if it is negative.
Note that Item Property Params do not affect Item Property cost.
The PropertyCost, SubtypeCost, and CostValue terms are obtained as described below.
PropertyCost
In itempropdef.2da, get the floating point value in the Cost column, at the row indexed by the PropertyName Field of the ItemProperty Struct. If the Cost column value is ****, treat it as 0. This floating point value is the PropertyCost.
SubtypeCost
If the PropertyCost obtained above from itempropdef.2da was 0, then get the ResRef in the SubTypeResRef column of itempropdef.2da, at the row indexed by the 2PropertyName Field of the ItemProperty Struct. This is the resref of the subtype table 2da.
In the subtype 2da, get the floating point value in the Cost column at the row indexed by the Subtype Field of the ItemProperty Struct. This floating point value is the SubtypeCost.
Only get the SubtypeCost if the PropertyCost was 0. If the PropertyCost was greater than 0, then the SubtypeCost is automatically 0 instead.
CostValue
In iprp_costtable.2da, get the string in the Name column at the row indexed by the CostTable Field in the ItemProperty Struct. This is the ResRef of the cost table 2da.
In the cost table, get the floating point value in the Cost column in the row indexed by the CostValue Field in the ItemProperty Struct. This floating point value is the CostValue.

4.4.3. Cast Spell Costs
To calculate the cost of a single Cast Spell Item Property, use the following formula:
CastSpellCost = (PropertyCost + CostValue)* SubtypeCost
The PropertyCost, SubtypeCost, and CostValue terms are obtained in the same way as for non-CastSpell Item Properties.
After calculating all the CastSpellCost values for all the Cast Spell Item Properties, modify them as follows:
• Most expensive: multiply by 100%
• Second most expensive: multiply by 75%
• All others: multiply by 50%
After adjusting the CastSpellCosts, add them up to obtain the total SpellCosts value. Use the total SpellCosts to calculate the total ItemCost using the formula given at the very beginning of Section 4.4.

Да, забыл дописать - официальная инфа от бварей pardon.gif лежит открыто на ихнем сайте
azathoth
QUOTE(Aiwan @ Jun 17 2006, 00:16) [snapback]84945[/snapback]
На месте где лежал труп остается маленькая светящаяся точка
Это не точка, это душа погибшего существа.

Чтобы удалить труп доступный для ограбления не нужно так прямо его дестроить, достаточно убрать с него все вещи и деньги, и он сам исчезнет через время указаное в поле "Corpse Decay Time".
Mandrake
QUOTE
Такие подсвечивающиеся точки остаются в любом тайлсете?


Да, в любом =)

QUOTE
Это не точка, это душа погибшего существа.

Чтобы удалить труп доступный для ограбления не нужно так прямо его дестроить, достаточно убрать с него все вещи и деньги, и он сам исчезнет через время указаное в поле "Corpse Decay Time".


Я в курсе того что он исчезает при снятии всех вещей, но допустим там есть то что мне абсолютно не нужно, конечно я могу во избежании этих точек ходить и собирать все что падает, но это ведь как "Смерть лечит от всех болезней" vava.gif

А насчет души, душа обычно к небу стремится angel.gif А не на земле лежит.


Aiwan
NSS
// All clients in oArea will recompute the static lighting.
// This can be used to update the lighting after changing any tile lights or if
// placeables with lights have been added/deleted.
void RecomputeStaticLighting(object oArea)

Попробуй сделать этой функцией пересчет света. Выйди с локации и зайди заново, если это эффект света на объекте то должно пропасть.
azathoth
QUOTE(Mandrake @ Jun 17 2006, 13:24) [snapback]84964[/snapback]
Я в курсе того что он исчезает при снятии всех вещей, но допустим там есть то что мне абсолютно не нужно, конечно я могу во избежании этих точек ходить и собирать все что падает, но это ведь как "Смерть лечит от всех болезней"


Я имел в виду не собирать самому, а вместо DestroyObject скриптом через DelayCommand снимать все вещи и деньги:
NSS
DelayCommand(120.0, TakeGoldFromCreature(GetGold(oCreature), oCreature, TRUE));
таким образом ты уберешь тело.
Mandrake
QUOTE
Я имел в виду не собирать самому, а вместо DestroyObject скриптом через DelayCommand снимать все вещи и деньги


Потом я понял твой пост, но дело в том, что стоит через скрипт внести другие вещи для выпадения, которые не надеты на объекте, как эта схема перестает работать, поэтому я и не стал править свой предыдущий пост vava.gif
Исчезают только те вещи, которые при спавне были на обджекте, а те которые добавляются к нему после смерти, почему то остаются.Вот собствено тот скрипт.
NSS
object oPC = OBJECT_SELF;


object oItem;
oItem = GetFirstItemInInventory(oPC);

while (GetIsObjectValid(oItem))
  {
  if (GetPlotFlag(oItem))
      SetPlotFlag(oItem, FALSE);

    DelayCommand(20.0, DestroyObject(oItem));

  oItem = GetNextItemInInventory(oPC);
  }

int nInt;
for (nInt=0; nInt<NUM_INVENTORY_SLOTS; nInt++)
  {
  oItem = GetItemInSlot(nInt, oPC);

  if (GetPlotFlag(oItem))
        SetPlotFlag(oItem, FALSE);

  DelayCommand(20.0, DestroyObject(oItem));
  }

Выданный скрипт эдитором, который я подправил.(Установил задержку на дестрой)

Aiwan, спасибо попробую.

Добавил.
Попробывал, как сказал Aiwan
NSS
//Put OnExit
void main()
{
object oPC =  GetExitingObject();
object oArea = GetArea(oPC);
RecomputeStaticLighting(oArea);
}


Не помогло aggressive.gif unsure.gif
azathoth
Попробуй вынести удаление вещей в отдельную функцию и ее заDelay'ить.

Твой измененный скрипт будет выглядеть примерно так:
NSS
void Clear(object oPC)
{
    object oItem = GetFirstItemInInventory(oPC);
    while (GetIsObjectValid(oItem))
    {
        SetPlotFlag(oItem, FALSE);
        DestroyObject(oItem);

        oItem = GetNextItemInInventory(oPC);
    }

    TakeGoldFromCreature(GetGold(oPC), oPC, TRUE)
}

void main()
{
    object oPC = OBJECT_SELF;
    DelayCommand(120.0, Clear(oPC));
}

P.S. К тому же в твоем варианте вещи удаляются даже если игрок заберет их.
P.P.S. Plot'овые вещи лучше не удалять, а если они не критичны, то и Plot флаг с них лучше убрать.
P.P.P.S. А вообще лежащий труп напряжет систему не больше, чем бегающий монстр, так что если у тебя монстры не появляются все время, то лучше оставлять - так реалистичнее.
Aiwan
У меня есть система удаления лута с слокаций. На OnExit локации ставь или по смыслу и своим условиям.
Mandrake
NSS
//:://////////////////////////////////////////////
//:: OnExit  am_aex_random
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
    Удаление лута на локации случайных боев.
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 24.05.2005
//:://///////////////////////////////////////////
int GetIsAssociate(object oMaster, object oAssociate)
{
    object oMaster = GetMaster(oAssociate);
    if(oMaster != OBJECT_INVALID)
      {
      return TRUE;
      }
        return FALSE;
}

void main()
{
object oPC = GetExitingObject();
object oDestr = GetFirstObjectInArea(OBJECT_SELF);
if (!GetIsPC(oPC)) return;

while (oDestr!=OBJECT_INVALID)
  {
//------------------------------------------------------------------------------
    if (GetHasInventory(oDestr) && GetTag(oDestr)=="BodyBag") // Лут - сумка стандартная
    {
      object oItem = GetFirstItemInInventory(oDestr);
      while (GetIsObjectValid(oItem))
      {
        DestroyObject(oItem);
        oItem = GetNextItemInInventory(oDestr);
      }
      DestroyObject(oDestr);
    }
//------------------------------------------------------------------------------
if (GetObjectType(oDestr) == OBJECT_TYPE_PLACEABLE
//      || GetObjectType(oDestr) == OBJECT_TYPE_CREATURE
      && !GetIsAssociate(oPC, oDestr))
        {
        {
          CopyItem(oDestr, oPC, TRUE);

        }
    }
//------------------------------------------------------------------------------*/
    oDestr = GetNextObjectInArea(OBJECT_SELF);
    }
}


Aiwan! good.gif НЛО исчезло, после небольшой доработки твоего скрипта. thank_you.gif Но у меня вопрос теперь такого плана. Подставив
QUOTE
GetObjectType(oDestr) == OBJECT_TYPE_PLACEABLE
я не подверг ли опасности какие нибудь другие объекты, носящие стратегически важную цель для модуля? vava.gif
Aiwan
Слушай, я правил тот скрипт и конечно же накосячил в нем, так как вырезал куски для тебя. Ща убрал тока одину локалку вверху. Так что смотри мой скрипт выше, я там пометил что я лишнее удалил. Извини.

Перечитал свой пост, это ты там у себя накосячил что-то wacko.gif Короче этот блок либо поправь либол возьми мой я пометил что там он делает.
NSS
//:://////////////////////////////////////////////
//:: OnExit  am_aex_random
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
    Удаление лута на локации случайных боев.
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 24.05.2005
//:://///////////////////////////////////////////
int GetIsAssociate(object oMaster, object oAssociate)
{
    object oMaster = GetMaster(oAssociate);
    if(oMaster != OBJECT_INVALID)
      {
      return TRUE;
      }
        return FALSE;
}

void main()
{
object oPC = GetExitingObject();
object oDestr = GetFirstObjectInArea(OBJECT_SELF);
if (!GetIsPC(oPC)) return;

while (oDestr!=OBJECT_INVALID)
  {
//------------------------------------------------------------------------------
    if (GetHasInventory(oDestr) && GetTag(oDestr)=="BodyBag")
    {
      object oItem = GetFirstItemInInventory(oDestr);
      while (GetIsObjectValid(oItem))
      {
        string sTag = GetTag(oItem); // Debag message
        SendMessageToPC(oPC, "Destroy Item - "+sTag);
        DestroyObject(oItem);
        oItem = GetNextItemInInventory(oDestr);
      }
      string sTag = GetTag(oDestr); // Debag message
      string sResRef = GetResRef(oDestr);
      SendMessageToPC(oPC, "Destroy Object - "+sTag+" Resref-"+sResRef); // Debag message
      DestroyObject(oDestr);
    }
//------------------------------------------------------------------------------
  if (GetObjectType(oDestr) == OBJECT_TYPE_ITEM        // Если это предмет
      || GetIsEncounterCreature(oDestr)                // или монстр из енкаучера
      && !GetIsAssociate(oPC, oDestr))                  // но не наш помощник
      {
      // Если это предмет плотовый, якобы мы его уронили или не подняли случайно
      if (GetPlotFlag(oDestr) == TRUE && GetObjectType(oDestr) == OBJECT_TYPE_ITEM)
      {
          CopyItem(oDestr, oPC, TRUE); // копируем его в инвентарь РС
          SendMessageToPC(oPC, "Перед тем, как идти дальше, вы вернулись и побдобрали важный предмет.");
      }
      string sTag = GetTag(oDestr); // Debag message
      string sResRef = GetResRef(oDestr);
      SendMessageToPC(oPC, "Destroy Object - "+sTag+" Resref-"+sResRef); // Debag message
      DestroyObject(oDestr); // Удаляем то что валялось или бегало и пугало нас
      }
//------------------------------------------------------------------------------*/
    oDestr = GetNextObjectInArea(OBJECT_SELF);
    }
}
Mandrake
Все, нашел консенсус. От трупов отказался, вернулся к мешкам лута стандартным, пусть будет так, зато все работает.

Спасибо всем за помощь.

Aiwan, вам отдельное спасибо за нахождение решения проблемы thank_you.gif

P.S. Пытался выловить этот светящийся объект путем того, что через скрипт Aiwan'a удалял все плейсиблы с локи, потом заходил в нее еще раз и после убийства мобов опять выходил. Функция сообщения указывающего что удалялось показало 2 объекта с тэгом стандартного мешочка лута... Вот так. Неразрешенная загадка осталось таковой
Zirrex
Mandrake, это старый баг данного флажка. Удаляется этот светящийся объект только тогда, когда игрок полностью забирает все вещи с трупа, но если труп с вещами удаляется сам по истечение определенного времени, то точка остается. В свое время долго боролся с этой проблемой, но так и не получилось избавиться от этих точек. Похоже, что в месте смерти остается невидимый объект, который после удаления тела перестает быть активным, но сам не исчезает.

Кстати, ты написал
QUOTE
вернулся к мешкам лута стандартным
Каким именно? В моем модуле создается на месте смерти невидимый объект из палитры, в который сразу же копируются все выпавшие вещи с монстра. Через 1 минуту все это добро, вместе с телом монстра, удаляется. Работает хорошо, и не вызывает каких-либо проблем. И главное, что смотрится отлично. Если интересует, могу поделиться скриптом.
Mandrake
Мешок который по умолчанию, с тэгом "BodyBag". Именно он удаляется скриптом Aiwan'a, после того, как с локи уходит игрок. Но если я понял правильно, то он действует в сингле, а в онлайн может доставить неудобство, ибо с локации может выйти кто то другой, а игрок который убил моба останется без законно выбитого добра.

Я конечно планированием сетевых шардов заниматься не думаю, но для просвещения, не отказался бы увидеть ваш скрипт, Zirrex smile.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Invision Power Board © 2001-2024 Invision Power Services, Inc.