JK and MotS Editing >> Cog, AI, and Templates >> fast travelling projectiles     (Moderator: Admins) Previous Topic | Next Topic
Page 1 of 1
 Author 
 Post 
Post 28-May-2007 10:05        

You probably know the erratic collision behaviour of fast travelling projectiles (they tend to collide in mid-air when travelling towards templates with face-collision). I wondered if there has been found a workaround to this problem.
I thought you could work with vectors (compare the lookvector of the shooter with victim positions), but I find it near impossible to produce a fast loop through all potentials. FirstThingInView seems to be buggy (it doesn't always find everything) and a loop through all sectors and all things is too slow and locks up the computer.
Hell Raiser
Site Developer
Post 28-May-2007 21:10        

I had thought of something a while back for TDiR with the no thing limit, but never got around to implementing it.

Here's some psuedo-code:



startup:
   MaxDist=100; //10 JKU's out
   LeastDist=MaxDist;
   StepDist=0.1;
   Vec=VectorSet(0, StepDist, 0);
   MaxThings=MaxDist/StepDist; //1000 things in this case
   HeapNew(MaxThings);
   Count=0;
   CantFire=0;
   ExpPos=VectorSet(0, 0, 0);
   ExpSec=-1;
   BeenRemoved=0;
return;

fire:
   BeenRemoved=0;

   if(CantFire) return;
   CantFire=1;

   Stuff=FireProjectile(Player, A_Proj.....);
   //A_Proj would be setup like a normal weapon
   //set to explode on things and/or level surfaces
   
   HeapSet(Count, Stuff);
   
   for(x=0; x<MaxThings; x=x+1)
   {
      Count=Count+1;
      Stuff=FireProjectile(Stuff, A_Proj, -1, -1, Vec,.....);
      CaptureThing(Stuff);
      SetThingVel(Stuff, VectorNorm(GetThingLVec(Stuff))); //1 JKU a second
      HeapSet(Count, Stuff);
   }

   RemovingThings=0;
   SetTimer(0.5); //Clear the board, create explosion

return;

removed:
   
   if(RemovingThings) return;
   
   BeenRemoved=1;
   
   //The closest one to the player to have
   //been removed is where the explosion should
   //be created... right? =S
   
   CurrentDist=VectorDist(GetThingPos(GetSenderRef()), GetThingPos(Player));
   
   if(CurrentDist < LeastDist)
   {
      LeastDist=CurrentDist;
      LeastThing=GetSenderRef();
      ClearThingFlags(GetSenderRef(), 0x2); //Don't destroy me plzkthx!
      
   }

return;

timer:

   RemovingThings=1;
   for(x=0; x<Count; x=x+1)
   {
      if(GetThingType(HeapGet(x)) > 0)
      {
         if(HeapGet(x) != LeastThing) DestroyThing(HeapGet(x));
      }
   }

   if(!BeenRemoved)
   {
      //Didn't collide with a darn thing
   }
   else
   {
      //Create explosion
      //SendTrigger/MessageEx, pass LeastThing through
      //Set CantFire to 0 AFTER explosion has been created
   }

return;



This string of projectiles would all travel a small distance and at some point one of them will hit a thing or level geometry. The first one to be removed in the string is where you'd create the explosion/damage a thing.

All this should happen locally, except the explosion creation. There's a few holes as to what should happen, but the idea is there. Hopefully I haven't confused you any, I have a knack for that.
Post 29-May-2007 06:56        

No, I get it. It's a clever idea that reminds me of the "faster than light" approach my physics professor once told me about.
It could produce weird results in close-combat, though, as distances up to 10m would be covered by one relatively slow projectile...against targets, which are moving from horizontally, it could look as though the "shot" moved right through them without harming them.

I think I'll stick with my vector-based implementation. It's for a railgun anyway, so LOS-checks are not necessary (those would be a problem in 3do-based levels, I think). And looping through all players is easy enough (a for loop from 0 to 32 and GetPlayerThing() do the trick). Only problem is with NPCs, as it's not feasible to loop through all things to find them, and FirstThingInView doesn't always find everything it should, but yeah, who plays SP anymore?
*** Post commands are unavailable for guests. ***