QUOTE(Lex @ Nov 24 2006, 15:48) [snapback]99068[/snapback]
ууу.. ну тут все немного похуже. Летит то она скорее всего по параболике, но параметры какие у функции никто кроме тварей не знает, хотя это не беда - можно расчитать по 2м точкам. (старт и финиш собсна). Потом делается анализ координат НПС по отношению к функции траектории полета (фактически нужно оценить длину нормали, опущенной из точки на параболику), и если он оказываются в опасной зоне (те нормаль меньше критического значения), происходит редирект с точки на данного несчастливого НПС. И все.. но заставить снаряд лететь как летел и сымитировать взрыв от ударв в НПС у тя не получится... те это можно но с таким допущением: снаряд полетит дальше, а вот сам взрыв будет у НПС.
Но подумай, надо ли тебе такой геморой. Конечно круто, но это один небольшой эпизод, который и не все игроки то заметят.
При стрельбе из баллисты - да, херня пока выходит. Но с катапультой у меня все получилось. Проводил испытательные стрельбы по двухуровневому замку. Все потенциальные противники успешно поражены. Полеты ядра при попаданиях нормальные (а если никого нет в локации, то то что заряд на высоте сквозь стену проходит - не беда! Не попал, значит!). При одноуровневом замке - и того проще. Попадание в стену разочарований больших не вызывает, а перелет - взрыв во дворе замка.
Вот мой скрипт на выстрел из катапульты:
(Формула горбатая, но зато выведенная эксперементальным путем. И можно улучшить при желании.)
NSS
#include "cat_damage"
void main()
{
object oCurrentArea = GetArea(OBJECT_SELF);
object oPC = GetPCSpeaker();
object oBomber = GetLastUsedBy();
vector vCurrentPosition = GetPosition(OBJECT_SELF);
float fCurrentFacing = GetFacing(OBJECT_SELF);
/*int iRange = GetLocalInt(OBJECT_SELF,"Range");*/
float varz = 0.5;
SetLocalInt(OBJECT_SELF,"high",FloatToInt(varz));
if (fCurrentFacing > 360.0)
{
fCurrentFacing = 720 - fCurrentFacing;
}
/* ActionWait(10.0);*/
int iRange = 0;
SetLocalInt(OBJECT_SELF,"line",iRange);
vector vDelta;
vDelta.x = cos(fCurrentFacing) * iRange;
vDelta.y = sin(fCurrentFacing) * iRange;
vDelta.z = varz;
vector vImpact;
vImpact.x = vCurrentPosition.x + vDelta.x;
vImpact.y = vCurrentPosition.y + vDelta.y;
vImpact.z = vDelta.z;
vector vImpact1 = vImpact;
location lImpact = Location(oCurrentArea, vImpact, fCurrentFacing);
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE,6.0,lImpact,TRUE,OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_CREATURE);
if (GetIsObjectValid(oTarget))
{
if (GetDistanceToObject(oTarget)<=6.5 || GetIsDead(oTarget))
{
oTarget = OBJECT_INVALID;
}
}
while (oTarget==OBJECT_INVALID && iRange < GetLocalInt(OBJECT_SELF,"Range") && LineOfSightVector(vImpact1,vImpact)==TRUE && GetLocalInt(OBJECT_SELF,"high")>=0)
{
iRange = GetLocalInt(OBJECT_SELF,"line")+2;
SetLocalInt(OBJECT_SELF,"line",iRange);
if (FloatToInt(iRange * 1.66) <= GetLocalInt(OBJECT_SELF,"Range"))
{
varz = GetLocalInt(OBJECT_SELF,"high")+1.9;
SetLocalInt(OBJECT_SELF,"high",FloatToInt(varz));
}
else
{
if (FloatToInt(iRange * 1.5) <= GetLocalInt(OBJECT_SELF,"Range"))
{
varz = IntToFloat(GetLocalInt(OBJECT_SELF,"high"));
SetLocalInt(OBJECT_SELF,"high",FloatToInt(varz));
}
else
{
varz = GetLocalInt(OBJECT_SELF,"high")-3.2;
if (varz<0.3)
{
varz =0.3;
}
SetLocalInt(OBJECT_SELF,"high",FloatToInt(varz));
}
}
vector vDelta;
vDelta.x = cos(fCurrentFacing) * iRange;
vDelta.y = sin(fCurrentFacing) * iRange;
vDelta.z = varz;
vector vImpact;
vImpact.x = vCurrentPosition.x + vDelta.x;
vImpact.y = vCurrentPosition.y + vDelta.y;
vImpact.z = vDelta.z;
lImpact = Location(oCurrentArea, vImpact, fCurrentFacing);
oTarget = GetNextObjectInShape(SHAPE_SPHERE,6.0,lImpact,TRUE,OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_CREATURE);
if (GetIsObjectValid(oTarget))
{
if (GetDistanceToObject(oTarget)<=6.5 || GetIsDead(oTarget))
{
oTarget = OBJECT_INVALID;
}
}
}
if (oTarget != OBJECT_INVALID)
{
lImpact = GetLocation(oTarget);
SpeakString("Цель в фокусе:"+GetName(oTarget),TALKVOLUME_TALK);
}
float fImpactDelay = IntToFloat(iRange)/12;
effect eImpact = EffectVisualEffect(VFX_FNF_FIREBALL);
effect eBump = EffectVisualEffect(VFX_FNF_SCREEN_BUMP);
ActionCastFakeSpellAtLocation(SPELL_FIREBALL, lImpact, PROJECTILE_PATH_TYPE_BALLISTIC);
ActionWait(fImpactDelay);
ActionDoCommand(ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lImpact));
ActionDoCommand(ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eBump, lImpact));
DelayCommand(fImpactDelay,cDamage(lImpact,oBomber));
}
Инклуд - для функции cDamage(lImpact,oBomber).
Чтоб не загромождать не буду его писать. Если напишите - приведу потом. Его нетрудно и самим дописать как угодно.
Для настройки CurrentFacing и GetLocalInt(OBJECT_SELF,"Range") - свои несложные функции.
***К слову - все свершается через диалог и выстрел и повороты/регулировка дальности, вид ядер и тд
В догонку - тут еще проблемы!
Как ее (баллисту) установить и создать?? Что то CreateObject на заказные объекты не работает никак. А то все зря
И еще: а как свои звуки вставлять в игру - куда копировать ресурсы?