По-моему, ясно - то скрипт заклинания, вернее, двух. Одно создает "гекатомбу", очаг насыщенной смерти после одновременной гибели множества созданий. Эту силу может использовать некромант, но гекатомба невидима. Второе заклинание заставляет искать ее живое существо, которое идет в сторону гекатомбы, указывая некроманту путь, и там умирает, если добирается. Работают ли скрипты, вот вопрос?
Еще два заклинания:
Neverwinter Script
/// Заклинание Биополь. Некромантия. 8 уровень. Время наложения - 1. Длится три раунда. Выпускает жизненную силу мага, чтобы укрыть его и тех, кто рядом, от всякого прямого вреда и дает бонус к спасброскам Крепости. Жизненная сила, однако, быстро тает, а с ней и защита. До конца действия чар маг не в состоянии двигаться, даже когда заклинание его уже практически не оберегает. Поэтому возможно умереть, не рассчитав своих возможностей, или от мощной атаки на последнем раунде действия. Механика поощряет заблаговременное вытягивание чужой энергии, чтобы повысить эффективность и несколько обезопасить некроманта, но во время трех раундов действия он не подлежит лечению и регенерации никакими средствами. Заклинание для крайних случаев.
void main()
{
location lSelf = GetLocation(oTarget);
float fDuration = 18.0; /// продолжительность - три раунда
int nAmount = (GetCurrentHitPoints(OBJECT_SELF) / 15) * GetHitDice(OBJECT_SELF); /// за каждый уровень после начального, 15-го, начинает собираться небольшой бонус
int nMetaMagic = GetMetaMagicFeat(OBJECT_SELF);
int nStartingHealth;
int nBackToWounded;
effect eShield = EffectDamageResistance(DAMAGE_TYPE_ACID | DAMAGE_TYPE_BASE_WEAPON DAMAGE_TYPE_BLUDGEONING | DAMAGE_TYPE_DIVINE | DAMAGE_TYPE_ELECTRICAL | DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_NEGATIVE | DAMAGE_TYPE_PIERCING | DAMAGE_TYPE_POSITIVE | DAMAGE_TYPE_SLASHING | DAMAGE_TYPE_SONIC, nAmount, nAmount);
effect eSave = EffectSavingThrowIncrease(SAVING_THROW_FORTITUDE, nAmount / 8, SAVING_THROW_TYPE_ALL);
effect eCantMove = EffectParalyze(); /// если только при этом нет опасности coup de grace, иначе лучше Stun
effect eVisFreeze = EffectVisualEffect(VFX_DUR_FREEZE_ANIMATION); ///
effect eVisGlow = EffectVisualEffect(VFX_DUR_LIGHT_WHITE_15); ///
effect eVisAura = EffectVisualEffect(VFX_DUR_AURA_WHITE); /// /// или эквиваленты
effect eDamage = SupernaturalEffect(EffectDamage(1, DAMAGE_POWER_PLUS_SIX)); /// или эквивалент всепроникающего урона в NWN2
effect eLink1 = MagicalEffect(EffectLinkEffects(eShield, eSave));
effect eLink2 = MagicalEffect(EffectLinkEffects(eLink1, eCantMove));
effect eLink3 = MagicalEffect(EffectLinkEffects(eVisGlow, eVisAura));
effect eLink4 = MagicalEffect(EffectLinkEffects(eVisFreeze, eLink3));
effect eLink5 = MagicalEffect(EffectLinkEffects(eLink2, eLink4));
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 3.0f, lSelf, TRUE, OBJECT_TYPE_CREATURE); /// радиус в метрах?
SetLocalInt(OBJECT_SELF, "starting_health", nAmount);
if (nMetaMagic == METAMAGIC_EXTEND)
{
fDuration = 36.0; /// запомнив чары как 9-й уровень, можно получить шесть раундов защиты, но это опасно (смотри ниже)
}
while (GetIsDead(OBJECT_SELF) != TRUE & fDuration > 0)
{
ApplyEffectToObject(DURATION_TYPE_Temporary, eLink5, OBJECT_SELF, 0.5f);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, OBJECT_SELF); /// постоянная потеря сил
DelayCommand(0.5, fDuration = fDuration - 0.5) /// это сработает? следующий виток всей функции - через полсекунды
if (nAmount > nAmount) /// попытки повысить hp, пока действуют чары, ни к чему не приводят
{
nStartingHealth = GetLocalInt(OBJECT_SELF, "starting_health");
nBacktoWounded = nStartingHealth - nAmount;
ApplyEffectToObject(DURATION_TYPE_INSTANT, SupernaturalEffect(EffectDamage(nBackToWounded, DAMAGE_POWER_PLUS_SIX), OBJECT_SELF));
nAmount = nAmount; /// здесь у меня сомнения
}
if (GetIsEffectValid(eLink5) = FALSE) /// если развеяли общий эффект, то остановка
break;
}
while (GetisEnemy(oTarget) != FALSE & GetRacialType(oTarget) != RACIAL_TYPE_UNDEAD)
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 0.5f);
oTarget = GetNextObjectInShape(SHAPE_SPHERE, 3.0f, lSelf, TRUE, OBJECT_TYPE_CREATURE);
if (oTarget != OBJECT_INVALID & nDuration > 0)
{
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 3.0f, lSelf, TRUE, OBJECT_TYPE_CREATURE); /// если перебрал всех существ в радиусе, начинай сначала
}
if (GetIsEffectValid(eLink5) = FALSE) /// если аура уже не излучается
break;
}
}
Другое заклинание - ESP (Чтение мыслей). Здесь несколько скриптов-добавлений к скриптам. Тоже прошу указать на ошибки или протестировать.
Neverwinter Script
/// Заклинание "Чтение мыслей" (Divination, Enchantment). 2 уровень. Время сотворения 5. Добавление к OnAreaTransitionClick модуля или шарда. Удаляет переменную ESP, стоит персонажу покинуть зону.
void CancelESP()
{
object oLeaving = GetClickingObject();
if (GetIsPC(oLeaving) = TRUE)
{
DeleteLocalString(oLeaving, "ESP"); /// отдельной функцией, чтобы несуществующий string не мешал выполнению остальной части скрипта ухода
}
}
Neverwinter Script
/// Заклинание "Чтение мыслей" (Divination, Enchantment). 2 уровень. Время сотворения 5. Добавление к OnConversation модуля или шарда (или, возможно, к OnUserDefined). Используя GetLastSpeaker, записывает и передает все, что говорит заколдованный персонаж, покуда он не покинет зону.
void main()
{
object oSpyOn = GetLastSpeaker();
object oListener = GetFirstPC();
int nESPPattern = GetListenPatternNumber();
string sListener = GetLocalString(oSpyOn, "ESP");
string sspyOn = GetName(oSpyOn);
while (sListener != "" && oListener != OBJECT_INVALID && GetName(oListener) != sListener)
{
oListener = GetNextPC();
}
if (oListener != OBJECT_INVALID)
{
if (nESPPattern = 1)
{
string sAha = "~" + GetStringLowerCase(GetMatchedSubstring(0)) + "~"; /// записываем каждое слово
FloatingTextStringOnCreature(oListener, sAha, FALSE); /// и передаем его кому следует
}
}
}
Neverwinter Script
/// Заклинание "Чтение мыслей" (Divination, Enchantment). 2 уровень. Время сотворения 5. Основной скрипт.
void main()
{
object oSpyOn = GetSpellTargetObject();
string sPattern = "**";
int nListenPatternNum = 1; /// желательно сделать struct с индексами всех схем для ListenPattern
int nDuration = GetCasterLevel() * 60; /// длится минуту за уровень мага
effect eEffect = SupernaturalEffect(EffectParalyze());
SignalEvent(OBJECT_SELF, EventSpellCastAt(oSpyOn, SPELL_ESP, FALSE)); /// не вредное заклинание, может быть полезно и внутри компаний
if (GetMetaMagicFeat() = METAMAGIC_EXTEND)
{
nDuration * 2;
}
if (GetLocalString(oSpyOn, "ESP") != "" && sListener != GetName(OBJECT_SELF)) /// если кто-то уже слушает...
{
string sFormer = GetLocalString(oSpyOn, "ESP"); /// ...то устраиваем единоборство...
object oFormer = GetFirstPC();
while (oFormer != OBJECT_INVALID && GetName(oFormer) != sFormer)
{
oFormer = GetNextPC();
}
SetListening(oSpyOn, FALSE));
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEffect, OBJECT_SELF, 11.0f);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEffect, oFormer, 11.0f);
FloatingTextStringOnCreature(OBJECT_SELF, "Вы обнаруживаете в разуме этого человека другого наблюдателя!", FALSE);
DelayCommand(1.0, FloatingTextStringOnCreature(OBJECT_SELF, "Напрягшись, пытаетесь вытеснить чужака...", FALSE));
DelayCommand(2.3, FloatingTextStringOnCreature(OBJECT_SELF, "...Ваши мышцы скрутились в узлы, пот сочится по лбу...", FALSE));
DelayCommand(6.0, FloatingTextStringOnCreature(OBJECT_SELF, "...Не в состоянии шевельнуть и пальцем, вы превратились в чистое ментальное усилие", FALSE));
string sWho = sSpyOn? + " ...Нет. Творится что-то неладное.";
FloatingTextStringOnCreature(oFormer, sWho, FALSE);
DelayCommand(1.0, FloatingTextStringOnCreature(oFormer, "Кто-то другой внедрился в это сознание и пытается выбросить вас!", FALSE));
DelayCommand(2.3, FloatingTextStringOnCreature(oFormer, "Сцепив зубы, вы вступаете на мысленную арену...", FALSE));
DelayCommand(6.0, FloatingTextStringOnCreature(oFormer, "Невидимая борьба умов высекает огромные, как звезды, искры у вас за переносицей...", FALSE));
float fOwnPower = GetHitDice(OBJECT_SELF);
float fTheirPower = GetHitDice(oListener);
float fSuperiority = fabs(fOwnPower - fTheirPower);
int nSuperiority = FloatToInt(fSuperiority);
if (fOwnPower => fTheirPower) /// ...в котором побеждает чаще всего сильнейший
{
if (d100() > nSuperiority * 10)
{
DelayCommand(10.0, FloatingTextStringOnCreature(oFormer, "Трах! Телепатическую связь уводят у вас из-под носа!", TRUE)); /// переключаем канал на себя и даем знать ему и всей его шатии - ради интриги
DelayCommand(10.0, FloatingTextStringOnCreature(OBJECT_SELF, "Прикрыв глаза, вы вплываете в чужой разум", FALSE));
DelayCommand(10.0, GiveXP(OBJECT_SELF, (10 - nSuperiority) * 20)); /// небольшая награда активно нападающему, но не защищавшемуся
SetListenPattern(oSpyOn, sPattern, 1);
DelayCommand(11.0, SetListening(oSpyOn, TRUE));
DelayCommand(11.0, SetLocalString(oSpyOn, "ESP", GetName(OBJECT_SELF)));
DelayCommand(nDuration, DeleteLocalString(oSpyOn, "ESP"));
DelayCommand(nDuration, SetListening(oSpyOn, FALSE));
}
else
{
sWho = "Есть! Усилием воли вы изгоняете нахала. Это был кто-то по имени " + GetName(OBJECT_SELF) + ".";
DelayCommand(11.0, FloatingTextStringOnCreature(oFormer, sWho, FALSE));
DelayCommand(10.0, FloatingTextStringOnCreature(OBJECT_SELF, "...Но тот, другой, слишком силен.", FALSE));
sWho = "Вы отступаете, узнав имя соперника -" + sFormer + ".";
DelayCommand(11.0, FloatingTextStringOnCreature(OBJECT_SELF, sWho, FALSE));
DelayCommand(10.0, FloatingTextStringOnCreature(oSpyOn, "У вас путаются мысли.", FALSE);
DelayCommand(12.0, SetListening(oSpyOn, TRUE));
DelayCommand(nDuration, DeleteLocalString(oSpyOn, "ESP"));
DelayCommand(nDuration, SetListening(oSpyOn, FALSE));
}
}
else if (d100() > nSuperiority * 10)
{
sWho = "Есть! Усилием воли вы изгоняете нахала. Это был кто-то по имени " + GetName(OBJECT_SELF) + ".";
DelayCommand(11.0, FloatingTextStringOnCreature(oFormer, sWho, FALSE));
DelayCommand(10.0, FloatingTextStringOnCreature(OBJECT_SELF, "...Но тот, другой, слишком силен.", FALSE));
sWho = "Вы отступаете, узнав имя соперника -" + sFormer + ".";
DelayCommand(11.0, FloatingTextStringOnCreature(OBJECT_SELF, sWho, FALSE));
DelayCommand(10.0, FloatingTextStringOnCreature(oSpyOn, "У вас путаются мысли.", FALSE);
DelayCommand(12.0, SetListening(oSpyOn, TRUE));
DelayCommand(nDuration, DeleteLocalString(oSpyOn, "ESP"));
DelayCommand(nDuration, SetListening(oSpyOn, FALSE));
}
else
{
DelayCommand(10.0, FloatingTextStringOnCreature(oFormer, "Трах! Телепатическую связь уводят у вас из-под носа!", TRUE)); /// переключаем канал на себя и даем знать ему и всей его шатии - ради интриги
DelayCommand(10.0, FloatingTextStringOnCreature(OBJECT_SELF, "Прикрыв глаза, вы вплываете в чужой разум", FALSE));
DelayCommand(10.0, GiveXP(OBJECT_SELF, (10 - nSuperiority) * 20)); /// небольшая награда активно нападающему, но не защищавшемуся
SetListenPattern(oSpyOn, sPattern, 1);
DelayCommand(11.0, SetListening(oSpyOn, TRUE));
DelayCommand(11.0, SetLocalString(oSpyOn, "ESP", GetName(OBJECT_SELF)));
DelayCommand(nDuration, DeleteLocalString(oSpyOn, "ESP"));
DelayCommand(nDuration, SetListening(oSpyOn, FALSE));
}
}
else
{
DelayCommand(10.0, FloatingTextStringOnCreature(OBJECT_SELF, "Прикрыв глаза, вы вплываете в чужой разум", FALSE));
SetListenPattern(oSpyOn, sPattern, 1);
SetListening(oSpyOn, TRUE);
SetLocalString(oSpyOn, "ESP", GetName(OBJECT_SELF));
DelayCommand(nDuration, DeleteLocalString(oSpyOn, "ESP"));
DelayCommand(nDuration, SetListening(oSpyOn, FALSE));
}
}