Wildcat, I'm not sure if I can help you, but I'll post some data probably is wrong or you already know.
Basically I think this could be solved by getting the speed of player at the moment the NPC wants to fire. Then based on speed of projectil and distance to player, you would have an suposed target. If the player keeps a uniform movement, he will be hit. Also would be nice to do a trace to be shure it will not hit anything before the position the NPC think the player will be. This is a nice thing you came to, and it could be used to make different inteligences. Easy enemies would do this with some random error range, and difficult ones would do this calculating also acceleration.
I just can see it working on a very, very slow projectil. Since the player is always changing velocity and direction. And he would also noticed that was spot and would easyly flee.
Unfortunatelly my scripts at the moment are more like the guided rocket than the future prediction style.
-------------------------------------------
AcidCrow,
I'll post my code till now for my cinematic script. There are a lot of useless variables because I am also trying to implement smooth movement trought path points. Also there is a lot of room for optimizations and corrections, but my bigger problem is the fact I can't get the entidade's vector. If you would like to test it, create a entity with the action cinematica, an entity with the name "camalvo_#" and a path with the name "caminho_#" where # is the number of the group. In the entity with cinematica action, put the following skills:
Skill 1 - Time to start the # camera movement;
Skill 2 - Time to end it;
Skill 5 - How many ticks it must take to fly from one to the next point of the path;
Skill 8 - The # of the group.
You can make several groups, making always the end time of one += 1 to it's predecessor take.
I would also enjoy any comment more on the script, any criticism, and obviously, any suggestion on how to improve it. And, how usable do you think this idea is? I thought it would be nice for non-programers. Eventually, I plan to make the cinematics follow an event, other than level load. The lines in red is where I think may be something wrong. I ask you to substitue the entidade.xyz part for distancia2.xyz just for testing porpouse. See? It works if I give a specific vector.
Thanks in advance,
--------------------------------------------------------------------------------
////////////////////////////////////////////////////////////
// Início do código de cinemáticas plug N play.
////////////////////////////////////////////////////////////
VAR crono = 1;
VAR ponto_anterior[3];
VAR ponto_atual1[3];
VAR ponto_atual2[3];
VAR ponto_proximo[3];
VAR distancia[3];
VAR distancia2[3] = 604,0,330;
VAR qpptemp = 1;
VAR cronometro_var = 0;
STRING caminho_num = " ";
STRING camalvo_num = " ";
STRING cine_numstr = " ";
STRING mensagem = " ";
SYNONYM entidade { type entity; }
FUNCTION cronometro () {
WHILE (1) {
cronometro_var += 1;
WAITT(1);
}
}
ACTION cinematica
{
WHILE (cronometro_var < MY.skill1) {waitt(1);}
loucas_cameras();
}
// Lembrar de transformar muitas das variáveis em SKILL
// para não tê-las correndo globalmente.
FUNCTION loucas_cameras () {
exclusive_global;
// Transforma a entidade num fantasma invisível
MY.invisible = ON;
MY.passable = ON;
DEFINE inico = MY.skill1; // Quando começa o take em ticks desde o começo do nível
DEFINE fim = MY.skill2; // Quando termina, em ticks após o começo do nível
DEFINE qpp = MY.skill5; // Define quantos intervalos deve levar de um ponto a outro do caminho
DEFINE cine_num = MY.skill8; // # para definir o conjunto Câmera, Caminho e Alvo
to_string cine_numstr, cine_num;
// DEFINE qual caminho e qual alvo usar para a entidade através de STRINGS
str_cpy(caminho_num,"caminho_");
str_cat(caminho_num,cine_numstr);
str_cpy(camalvo_num,"camalvo_");
str_cat(camalvo_num,cine_numstr);
entidade = syn_for_name(camalvo_num);
msg.visible = on;
msg.string = camalvo_num;
ent_path(caminho_num); // Localiza o caminho correspondente
ent_waypoint(ponto_anterior.x,1);
ent_nextpoint(ponto_atual1.x);
MY.x = ponto_atual1.x;
MY.y = ponto_atual1.y;
MY.z = ponto_atual1.z;
ent_nextpoint(ponto_atual2.x);
crono = inico;
while (crono < fim)
{
ent_nextpoint(ponto_proximo.x);
// Percorre a distância de um ponto ao outro em tantas etapas (my.skill5)
WHILE (qpptemp <= qpp)
{
distancia.x = (ponto_atual2.x - ponto_atual1.x) / qpp;
distancia.y = (ponto_atual2.y - ponto_atual1.y) / qpp;
distancia.z = (ponto_atual2.z - ponto_atual1.z) / qpp;
move (my, nullvector, distancia);
temp.X = entidade.x - MY.X;
temp.Y = entidade.y - MY.Y;
temp.Z = entidade.z - MY.Z;
vec_to_angle(my.pan,temp.x);
CAMERA.x = MY.x;
CAMERA.y = MY.y;
CAMERA.z = MY.z;
CAMERA.pan = MY.pan;
CAMERA.tilt = MY.tilt;
qpptemp += 1;
crono += 1;
waitt(1);
}
// Redefine dados necessários, e prepara dados já computados para o próximo ponto
qpptemp = 1;
MY.x = ponto_atual2.x;
MY.y = ponto_atual2.y;
MY.z = ponto_atual2.z;
vec_set(ponto_anterior,ponto_atual1);
vec_set(ponto_atual1,ponto_atual2);
vec_set(ponto_atual2,ponto_proximo);
WAIT(1);
}
}
////////////////////////////////////////////////////////////
// Fim do código de cinemáticas plug N play.
////////////////////////////////////////////////////////////
--------------------------------------------------------------------------------