Level 5
Класс: Обыватель
Характер: Lawful Neutral
Раса: Человек
NWN: Модмейкер
Проклятие Левора
Порядок Времени
|
СЕРИЯ "СКРИПТЫ ПРОКЛЯТИЯ ЛЕВОРА" ЦИКЛ "СКРИПТЫ ДЯДЮШКИ LEX'А"
Цель: сделать 2 (можно и более) НПС которые как будто между собой разговаривают. (те, кто играл ПЛ в Тсурлаголе видели такие примеры. Особенно в тавернах.) Реализация: ставим 2х НПС, даем соотв. тэги и ставим между ними нивидимый объект, в ХБ которого вносим этот скрипт.
"+" - эффект диалога. Так как фразы стыкуются (вы сами их пишите так, что на вопрос дается ответ и прочее.) так как они все парные. "-" - на каждую уникальную группу свой скрипт. Текст разговора пишется в скрипте.
Neverwinter Script Source | //:://///////////////////////////////////////////// //:: Name lm_2speakers //:: Copyright © 2004 -=WRG!=- //::////////////////////////////////////////////// /* скрипт разговора 2-х НПС. Шаблон. */ //::////////////////////////////////////////////// //:: Created By: Lex //:: Created On: Agust 2004 //:://////////////////////////////////////////////
void ANIMATION(object oD) /// Рандомная анимация во время разговора. настраивайте сами. { int A=0; float T,S; switch (Random(8)+1) { case 2: A=ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD;T=3.0;S=1.0;break; case 3: A=ANIMATION_FIREFORGET_TAUNT;T=3.0;S=1.0;break; case 4: A=ANIMATION_FIREFORGET_PAUSE_BORED;S=1.0;break; case 5: A=ANIMATION_LOOPING_LISTEN;T=5.0;S=1.0;break; case 6: A=ANIMATION_LOOPING_LISTEN;T=5.0;S=1.0;break; } if (A==0) return; AssignCommand(oD,PlayAnimation(A,S,T)); }
void DIALOG(object oD1,object oD2) { string s1="",s2=""; string ya = GetName(GetObjectByTag("ya")); // "+ya+" switch (Random(30)) { case 0: s1="Как дела, друг?";s2="Да идут по маленьку..";break; case 1: s1="И как она? Симпатична"+ya+"?";s2="А как же! Ты мен"+ya+" обижаешь!";break; /// и так далее 20 фраз типа вопрос-выссказывание и ответ на это дело } AssignCommand(oD1,SpeakString(s1)); /// первый НПС говорит фразу AssignCommand(oD2,DelayCommand(5.0,SpeakString(s2))); /// второй отвечает }
void main() { object oPC = GetFirstPC(); if (GetArea(oPC)!=GetArea(OBJECT_SELF)) return; // если нет игрока, то молчим object oD1 = GetNearestObjectByTag("SPEAKING_NPC_1"); // первый НПС object oD2 = GetNearestObjectByTag("SPEAKING_NPC_1"); // второй НПС if (GetIsInCombat(oD1)) return; // если первый НПС дерется то молчим if (GetIsInCombat(oD2)) return; // если второй НПС дерется то молчим if ( (IsInConversation(oD1)) || (IsInConversation(oD2)) ) return; /// если один из НПС разговаривает с игроком if (GetDistanceToObject(oPC)>10.0) return; // если игрок далеко (больше 10 футов) то он как будто ничего не слышит. AssignCommand(oD1,SetFacingPoint(GetPosition(oD2))); // повернуться навтречу друг другу AssignCommand(oD2,SetFacingPoint(GetPosition(oD1))); DIALOG(oD1,oD2); ANIMATION(oD1); ANIMATION(oD2); } |
================================================================================
Небольшой простенький скрипт на слот onDamage плэйсебла. (ТЭГ плэйса "DANGER")
Плэйс взрывается, если его повредить. Если у вас есть Проклятие Левора, то в пещере почти все бочки это объекты с таким скриптом. Сила взрыва растет, если рядом есть такие же объекты. ВНИМАНИЕ: больше таких 5 рядом не ставить. Тормозит....скрипт не оптимален. Делалася под СоУ, поэтому использованны не локалки, а поле KeyTag. Скрипт старый и давно мной не улучшавшийся. Это вам просто для работы. (как юзать в таком варианте KeyTaG: ставим флаг Закрыто и Требуется ключ. Поле открывается. Теперь пишем туда что надо и снимаем флаг Закрыто. ограничение: скрипт лучше не ставить на закрытые объекты, так как поле KeyTaG нужно для работы.) в поле KeyTag радиус и сила взрыва: X_Y X - сила по нижепреведенной шкале. По умолчанию 2 1 - слабый 2 - средний 3 - сильный Y - радиус в футах. (не более 9). По умолчанию 5 футов. подрыв объекта происходит при повреждении более чем на 30%.
Neverwinter Script Source | //:://///////////////////////////////////////////// //:: Name ****** //:: FileName lm_damage_danger //:: Copyright © 2003 -=WRG!=-. //::////////////////////////////////////////////// /* THIS SCRIPT CHECKS IF ANYBODY DAMAGED DANGER OBJECT MORE THEN 30% THEN THE OBJECT EXPLOSE EXPLOSION DEPENDS ON STRONG EXPLOSION RADIUS. EXPLOSION RADIUS & STRONG ARE IN TrapKeyTag of object */ //::////////////////////////////////////////////// //:: Created By: Lex //:: Created On: October 2003 //:: Special thanks to: //:: Baal (WRG) for advice about calculation power //:://////////////////////////////////////////////
void DamageObject(float ExplosionRadius, int Strong, object oDamager, location lCenter) { float modifier=1.0; effect eAddition; int DamagePower=DAMAGE_POWER_PLUS_ONE; float fDistance = GetDistanceBetweenLocations(GetLocation(oDamager),lCenter); switch(Strong) { case 1: modifier=0.5; DamagePower=DAMAGE_POWER_NORMAL; eAddition = EffectFrightened(); break; case 2: modifier=1.0; DamagePower=DAMAGE_POWER_PLUS_ONE; eAddition = EffectFrightened(); break; case 3: modifier=1.5; DamagePower=DAMAGE_POWER_PLUS_TWO; eAddition = EffectParalyze(); break; default:modifier=2.0; DamagePower=DAMAGE_POWER_PLUS_THREE; eAddition = EffectParalyze(); break; } int iDamage = FloatToInt((ExplosionRadius*ExplosionRadius/2 - fDistance*fDistance/2)*modifier+modifier*5); effect eDamage = EffectDamage(iDamage,DAMAGE_TYPE_FIRE,DamagePower); AssignCommand(oDamager,ClearAllActions()); AssignCommand(oDamager,DelayCommand(0.2,SetCommandable(FALSE,oDamager))); if (GetObjectType(oDamager)==OBJECT_TYPE_CREATURE) if (Random(2)==1) AssignCommand(oDamager,PlayAnimation(ANIMATION_LOOPING_DEAD_FRONT,0.6,2.0)); else AssignCommand(oDamager,PlayAnimation(ANIMATION_LOOPING_DEAD_BACK,0.6,2.0)); AssignCommand(oDamager,DelayCommand(0.8,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectVisualEffect(VFX_COM_HIT_FIRE),oDamager,1.0))); if (fDistance<=ExplosionRadius/3) { float time = modifier*ExplosionRadius/fDistance; AssignCommand(oDamager,DelayCommand(0.8,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eAddition,oDamager,time))); } AssignCommand(oDamager,DelayCommand(0.3,ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oDamager))); AssignCommand(oDamager,DelayCommand(2.5,SetCommandable(TRUE,oDamager))); } void main() { //======================================================== int iDamage; float ExplosionRadius; int Strong; location lCenter; int Next=TRUE; int Filter; int Explosion; object oDamager; string STR; int Critical=0; Filter = OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE; lCenter = GetLocation(OBJECT_SELF); if (GetTrapKeyTag(OBJECT_SELF)!="**") { ExplosionRadius=5.0; Strong=2; } else if (GetTag(OBJECT_SELF)!="ITM_FIREMINE") { iDamage = GetMaxHitPoints()-GetCurrentHitPoints(); STR = GetStringRight(GetTrapKeyTag(OBJECT_SELF),1); if (STR!="") ExplosionRadius = StringToFloat(STR); STR = GetStringLeft(GetTrapKeyTag(OBJECT_SELF),1); if (STR!="") Strong = StringToInt(STR); if ((Strong>3)||(Strong==0)) Strong=2; if ((ExplosionRadius>10.0)||(ExplosionRadius==0.0)) ExplosionRadius=5.0; if (iDamage*10 < GetMaxHitPoints()*3) return; } else { ExplosionRadius = 6.5; Strong = 2; SendMessageToPC(GetFirstPC(),"MINE"); } Strong = GetLocalInt(OBJECT_SELF,"ADD_STRONG")+Strong; if (Strong<3) Explosion = VFX_FNF_GAS_EXPLOSION_FIRE; else Explosion = VFX_FNF_FIREBALL; if ((iDamage<GetMaxHitPoints()/3)&&(GetDamageDealtByType(DAMAGE_TYPE_FIRE)==0)) return; if (GetLocalInt(OBJECT_SELF,"ALREADY")) return; SetLocalInt(OBJECT_SELF,"ALREADY",TRUE); oDamager = GetFirstObjectInShape(SHAPE_SPHERE,ExplosionRadius,lCenter,TRUE,Filter); object oPC = GetFirstPC(); DestroyObject(OBJECT_SELF); if ((GetLocalInt(GetObjectByTag("TS_LOCALS"),"FIRECAMP_DESTROED"))&&(GetTag(GetArea(OBJECT_SELF))=="TSUR_SUB_EASTFOREST_BOMBCAVE")) return; ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY,EffectVisualEffect(VFX_IMP_PULSE_FIRE),lCenter,1.5); ApplyEffectAtLocation(DURATION_TYPE_PERMANENT,EffectVisualEffect(Explosion),lCenter); while (GetIsObjectValid(oDamager)) { if ((GetTag(oDamager)=="DANGER")&&(!GetLocalInt(oDamager,"ALREADY"))&&(GetDistanceToObject(oDamager)<=ExplosionRadius/2)) { if (Next) SetLocalInt(oDamager,"ADD_STRONG",1); ExplosionRadius = ExplosionRadius + 2.0; Critical++; } if (Critical==3) { Next=TRUE; } if (Critical==5) { Strong++; Critical=0; } AssignCommand(oDamager,DamageObject(ExplosionRadius,Strong,oDamager,lCenter)); oDamager = GetNextObjectInShape(SHAPE_SPHERE,ExplosionRadius,lCenter,TRUE,Filter); } } |
|