Level 5
Класс: Обыватель
Характер: Lawful Neutral
Раса: Человек
NWN: Модмейкер
Проклятие Левора
Порядок Времени
|
СЕРИЯ "СКРИПТЫ СТАРОЙ БАЗЫ" ЦИКЛ "СКРИПТЫ ДЯДЮШКИ 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 (так как спасбросок делается встроенной функцией). При желание спасбросок можно делать вручную, но встроенная функция уж больно красиво пишет о спасброске в логах :) 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; } } |
Это предпоследний скрипт из цикла скриптов, реализующих окружающую среду по АДиД. Последним будет скрипт для штормов, но там уже в принципе все просто: это в основном смесь осадков и ветра.
************************************************************************************
|