Tremulous Forum
Mods => Mod Releases => Gameplay Changing => Topic started by: ==Troy== on August 18, 2008, 09:00:43 pm
-
A small patch (diff from latest Lakitu) which allows swarms to follow players around the corners. Its not the most optimal way to do it, but it works nicely and it is quite hard to get rid of the swarm, only doors or complicated brushwork will help.
Index: src/game/g_local.h
===================================================================
--- src/game/g_local.h (revision 87)
+++ src/game/g_local.h (working copy)
@@ -242,6 +242,10 @@
int lastDamageTime;
int bdnumb; // buildlog entry ID
+
+ #define MAX_WPA 31
+ vec3_t WPA[ MAX_WPA + 1 ];
+ int TotalWP;
};
typedef enum
Index: src/game/g_missile.c
===================================================================
--- src/game/g_missile.c (revision 87)
+++ src/game/g_missile.c (working copy)
@@ -582,34 +582,127 @@
*/
void AHive_SearchAndDestroy( gentity_t *self )
{
+
vec3_t dir;
- trace_t tr;
-
+ trace_t tr, tr2, tr3;
+ vec3_t Torigin;
+ gentity_t *traceEnt;
+
+ if (self->TotalWP == 0 )
+ {
+ self->TotalWP++;
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ 0 ]);
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ self->TotalWP ]);
+ }
trap_Trace( &tr, self->r.currentOrigin, self->r.mins, self->r.maxs,
self->target_ent->r.currentOrigin, self->r.ownerNum, self->clipmask );
+ traceEnt = &g_entities[ tr.entityNum ];
//if there is no LOS or the parent hive is too far away or the target is dead or notargeting, return
- if( tr.entityNum == ENTITYNUM_WORLD ||
- Distance( self->r.currentOrigin, self->parent->r.currentOrigin ) > ( HIVE_RANGE * 5 ) ||
+ if( Distance( self->r.currentOrigin, self->parent->r.currentOrigin ) > ( HIVE_RANGE * 30 ) ||
self->target_ent->health <= 0 || self->target_ent->flags & FL_NOTARGET )
{
self->r.ownerNum = ENTITYNUM_WORLD;
self->think = AHive_ReturnToHive;
self->nextthink = level.time + FRAMETIME;
+ return;
}
else
{
- VectorSubtract( self->target_ent->r.currentOrigin, self->r.currentOrigin, dir );
+ if ( tr.entityNum == ENTITYNUM_WORLD || traceEnt->s.eType == ET_BUILDABLE)
+ {
+ trap_Trace( &tr2, self->WPA[ self->TotalWP - 1 ], self->r.mins, self->r.maxs,
+ self->target_ent->r.currentOrigin, self->r.ownerNum, self->clipmask );
+ traceEnt = &g_entities[ tr2.entityNum ];
+ if ( tr2.entityNum == ENTITYNUM_WORLD || traceEnt->s.eType == ET_BUILDABLE )
+ {
+ trap_Trace( &tr3, self->WPA[ self->TotalWP ], self->r.mins, self->r.maxs,
+ self->target_ent->r.currentOrigin, self->r.ownerNum, self->clipmask ); // if the player turned around another corner while we were thinking, drop the target.
+ traceEnt = &g_entities[ tr3.entityNum ];
+ if ( tr3.entityNum == ENTITYNUM_WORLD || traceEnt->s.eType == ET_BUILDABLE )
+ {
+ self->r.ownerNum = ENTITYNUM_WORLD;
+
+ self->think = AHive_ReturnToHive;
+ self->nextthink = level.time + FRAMETIME;
+ //trap_SendServerCommand( -1, va( "print \"Lost Target\n\""));
+ return; // lost the track, get back home
+ }
+ else
+ {
+ if (self->TotalWP < MAX_WPA)
+ {
+ self->TotalWP++;
+ //trap_SendServerCommand( -1, va( "print \"New Waypoint, %i\n\"", self->TotalWP - 1));
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ self->TotalWP ]);
+ }
+ else
+ {
+ self->r.ownerNum = ENTITYNUM_WORLD;
+
+ self->think = AHive_ReturnToHive;
+ self->nextthink = level.time + FRAMETIME;
+ //trap_SendServerCommand( -1, va( "print \"Out Of memory\n\""));
+ return; // out of memory, get back home
+ }
+ }
+ }
+ else
+ {
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ self->TotalWP ]); //update latest waypoint without creating a new one, if there is a LOS from the old one
+ }
+ }
+ else
+ {
+ int i;
+ if (self->TotalWP > 1)
+ {
+ self->TotalWP = 1;
+ //trap_SendServerCommand( -1, va( "print \"Direct Line of Sight\n\""));
+ }
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ 0 ]);
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ self->TotalWP ]);
+
+
+ }
+
+ if (Distance( self->r.currentOrigin, self->WPA[ 0 ]) < 64 && self->TotalWP > 1) // snap the swarm to the waypoint if it is close enough.
+ {
+ int i;
+ VectorCopy(self->WPA[ 0 ], self->r.currentOrigin);
+ for (i = 0; i <= MAX_WPA; i++)
+ {
+ VectorCopy(self->WPA[i+1], self->WPA[i]);
+ }
+ self->TotalWP--;
+ if (self->TotalWP < 1) self->TotalWP = 1;
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ self->TotalWP ]);
+ //trap_SendServerCommand( -1, va( "print \"Waypoint Reached\n\""));
+ }
+
+ trap_Trace( &tr, self->r.currentOrigin, self->r.mins, self->r.maxs,
+ self->WPA[ 0 ], self->r.ownerNum, self->clipmask );
+ traceEnt = &g_entities[ tr.entityNum ];
+ if ( tr.entityNum == ENTITYNUM_WORLD || traceEnt->s.eType == ET_BUILDABLE ) // check for doors closing
+ {
+
+ self->r.ownerNum = ENTITYNUM_WORLD;
+
+ self->think = AHive_ReturnToHive;
+ self->nextthink = level.time + FRAMETIME;
+ //trap_SendServerCommand( -1, va( "print \"Invalid Waypoint\n\""));
+ return;
+ }
+
+ VectorSubtract( self->WPA[ 0 ], self->r.currentOrigin, dir );
VectorNormalize( dir );
-
//change direction towards the player
VectorScale( dir, HIVE_SPEED, self->s.pos.trDelta );
SnapVector( self->s.pos.trDelta ); // save net bandwidth
VectorCopy( self->r.currentOrigin, self->s.pos.trBase );
self->s.pos.trTime = level.time;
-
- self->nextthink = level.time + HIVE_DIR_CHANGE_PERIOD;
+ self->nextthink = level.time + HIVE_DIR_CHANGE_PERIOD/2;
}
}
@@ -641,7 +734,8 @@
bolt->methodOfDeath = MOD_SWARM;
bolt->clipmask = MASK_SHOT;
bolt->target_ent = self->target_ent;
-
+ bolt->TotalWP = 0;
+
bolt->s.pos.trType = TR_LINEAR;
bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame
VectorCopy( start, bolt->s.pos.trBase );
-
Yay, even more annoying hives! :P
But good work!
-
Hmm, nice idea and nice work. I'm going to poke Norf and see what he thinks about trying a change like this on mgdev...
-
I'm not sure how often people actually try to run away from the swarms (I usually just dance around in the alien base until I die) but they do still need something, and this sounds like something good to try.
-
Updated the code a little, added a WORKING check for doors now. :)
-
I'd like to see swarms being more efficient ;-) Nice work!
-
I honestly think that they should either move slightly faster or slightly slower. With them moving at the same speed as a non-sprinting human, one can run in circles for a while until the swarm gets bored and runs back to the hive. Between non-sprint and sprint would be best, in my honest opinion.
Also, they should be unable to travel through water, even though water is seldom used in Tremulous maps.
-
fixed a memory leak, the top post is updated.
-
Added to the P-G-Qvm porting list.
Soon ill have patched up and released a new version.
-
i like this idea
hows this though... u get a trapper :trapper: and mix it wit a hive :hive: then when the hummys come the swarm carrys the trapper juice and chases the hummy :human:
and its stuck till a friendly tyrant :tyrant: or granger :granger: wit :grenade: comes along!
-
i like this idea
hows this though... u get a trapper :trapper: and mix it wit a hive :hive: then when the hummys come the swarm carrys the trapper juice and chases the hummy :human:
and its stuck till a friendly tyrant :tyrant: or granger :granger: wit :grenade: comes along!
(http://lizrevision.com/wp-content/uploads/royal-fail.jpg)
-
I'm starting to get visions of System Shock 2's bees. Good work!
-
http://i148.photobucket.com/albums/s16/r3v3r3nd_album/fail1.jpg
http://forum.alsacreations.com/upload/2043-fail-camera.jpg
and u thought i was bad
-
Hives can now shoot around corners (or rather, learn to shoot around corners). I am posting this separately, even though it uses the same principle as the above patch, but is not a realy improvement, just a different feature.
In this patch the hives learn to shoot around buildables/corners and the swarm itself follows the player around the corners/buildables, Yet again diff from Lakitu.
Index: src/game/g_buildable.c
===================================================================
--- src/game/g_buildable.c (revision 87)
+++ src/game/g_buildable.c (working copy)
@@ -1106,8 +1106,24 @@
//==================================================================================
+qboolean Hive_CheckWP( vec3_t org1, vec3_t org2, gentity_t *ent )
+{
+ trace_t tr;
+ gentity_t *traceEnt;
+ trap_Trace( &tr, org1, NULL, NULL, org2, ent->s.number, MASK_SHOT );
+ traceEnt = &g_entities[ tr.entityNum ];
+
+ if( tr.entityNum == ENTITYNUM_WORLD || traceEnt->s.eType == ET_BUILDABLE )
+ return qfalse;
+ return qtrue;
+}
+
+
+
+
+
/*
================
AHive_Think
@@ -1120,10 +1136,14 @@
int entityList[ MAX_GENTITIES ];
vec3_t range = { ACIDTUBE_RANGE, ACIDTUBE_RANGE, ACIDTUBE_RANGE };
vec3_t mins, maxs;
- int i, num;
+ int i, num, j, k;
gentity_t *enemy;
vec3_t dirToTarget;
-
+ qboolean visible, fvisible;
+ int TWP = -1, freeTWP = -1, createTWP = -1;
+ qboolean WP1, WP2;
+
+
self->powered = G_IsOvermindBuilt( );
self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex );
@@ -1140,31 +1160,141 @@
if( self->timestamp < level.time )
self->active = qfalse; //nothing has returned in HIVE_REPEAT seconds, forget about it
-
+
+ if( self->RecheckTime < level.time)
+ {
+ self->RecheckTime = level.time + HIVE_RECHECK;
+ ;//trap_SendServerCommand( -1, va( "print \"Rechecking Hive, number of waypoints : %i\n\"", self->TotalWP));
+ for(j = 1; j <= self->TotalWP; j++)
+ {
+ while ( j <= self->TotalWP && (!Hive_CheckWP(self->r.currentOrigin, self->WPA[j-1], self) || (!Hive_CheckWP(self->WPA[j-1], self->WPA2[j-1], self) && self->inUse[j-1])))
+ {
+ for(k = j; k <= self->TotalWP; k++)
+ {
+ VectorCopy(self->WPA[k], self->WPA[k-1]);
+ VectorCopy(self->WPA2[k], self->WPA2[k-1]);
+ self->inUse[k-1] = self->inUse[k];
+ }
+ self->TotalWP--;
+ ;//trap_SendServerCommand( -1, va( "print \"Removed invalid waypoint\n\""));
+ }
+ }
+ }
+
+
if( self->spawned && !self->active && G_FindOvermind( self ) )
{
//do some damage
num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
+ self->targWP = -1;
for( i = 0; i < num; i++ )
{
enemy = &g_entities[ entityList[ i ] ];
if( enemy->flags & FL_NOTARGET )
- continue;
+ continue;
- if( enemy->health <= 0 )
+ if( enemy->health <= 0 || !enemy->client || enemy->client->ps.stats[ STAT_PTEAM ] != PTE_HUMANS)
continue;
+
+ ;//trap_SendServerCommand( -1, va( "print \"Target Detected\n\""));
+ if( !Hive_CheckWP( self->r.currentOrigin, enemy->r.currentOrigin, self ) )
+ {
+ ;//trap_SendServerCommand( -1, va( "print \"no LOS, checking waypoints\n\""));
+ TWP = freeTWP = createTWP = -1;
+ for (j = 1; j <= self->TotalWP; j++)
+ {
+ WP1 = Hive_CheckWP( self->WPA[j-1], enemy->r.currentOrigin, self );
+ if( self->inUse[j-1] )
+ WP2 = Hive_CheckWP( self->WPA2[j-1], enemy->r.currentOrigin, self );
+ else
+ WP2 = qfalse;
+
+ if (!WP1 && WP2) { TWP = -2 - (j-1); break; }
+ if (WP1 && WP2) { TWP = j-1; break; }
+ if (WP1 && !WP2 && self->inUse[j-1] ) createTWP = j-1;
+ if (WP1 && !self->inUse[j-1] ) freeTWP = j-1;
+ }
+
+ if (TWP == -1)
+ {
+ if (freeTWP == -1)
+ {
+ if (createTWP != -1 && self->TotalWP <= MAX_WPA)
+ {
+ VectorCopy( self->WPA[createTWP], self->WPA[self->TotalWP]);
+ VectorCopy( enemy->r.currentOrigin, self->WPA2[self->TotalWP]);
+ self->inUse[self->TotalWP] = qtrue;
+ self->TotalWP++;
+ self->targWP = createTWP;
+ ;//trap_SendServerCommand( -1, va( "print \"Waypoint cloned\n\""));
+ }
+ }
+ else
+ {
+ VectorCopy( enemy->r.currentOrigin, self->WPA2[freeTWP]);
+ self->inUse[freeTWP] = qtrue;
+ self->targWP = freeTWP;
+ ;//trap_SendServerCommand( -1, va( "print \"Secondary Assigned\n\""));
+ }
+ }
+ else
+ {
+ self->targWP = TWP;
+ ;//trap_SendServerCommand( -1, va( "print \"Firing normally\n\""));
+ }
+
+
+ if (self->targWP == -1)
+ continue;
+ else
+ ;//trap_SendServerCommand( -1, va( "print \"Found Waypoint, here it goes!\n\""));
+
+ }
+ else
+ {
+ ;//trap_SendServerCommand( -1, va( "print \"We have LOS, record waypoint\n\""));
+ if (self->TotalWP <= MAX_WPA)
+ {
+ visible = qfalse;
+ fvisible = qfalse;
+ for (j = 1; j <= self->TotalWP; j++)
+ {
+ if ( (self->inUse[j-1] && (visible = Hive_CheckWP(self->WPA2[j-1], enemy->r.currentOrigin, self))) ||
+ (!self->inUse[j-1] && (fvisible = Hive_CheckWP(self->WPA[j-1], enemy->r.currentOrigin, self)))) break;
+ }
+ if (!visible)
+ {
+ if (fvisible)
+ {
+ VectorCopy( enemy->r.currentOrigin, self->WPA[j-1]);
+ ;//trap_SendServerCommand( -1, va( "print \"Waypoint Replaced\n\""));
+ }
+ else
+ {
+ VectorCopy( enemy->r.currentOrigin, self->WPA[self->TotalWP]);
+ self->inUse[self->TotalWP] = qfalse;
+ self->TotalWP++;
+ ;//trap_SendServerCommand( -1, va( "print \"Waypoint Stored\n\""));
+ }
+ }
+ else
+ ;//trap_SendServerCommand( -1, va( "print \"Unnessesary Waypoint, ignored\n\""));
+ }
+ else
+ ;//trap_SendServerCommand( -1, va( "print \"Out of Memory, ignored\n\""));
+ }
+
+ ;//trap_SendServerCommand( -1, va( "print \"Launching the swarm!\n\""));
- if( !G_Visible( self, enemy ) )
- continue;
-
- if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
- {
self->active = qtrue;
self->target_ent = enemy;
self->timestamp = level.time + HIVE_REPEAT;
-
- VectorSubtract( enemy->s.pos.trBase, self->s.pos.trBase, dirToTarget );
+ if (self->targWP == -1)
+ VectorSubtract( enemy->s.pos.trBase, self->s.pos.trBase, dirToTarget );
+ else
+ VectorSubtract( self->WPA[self->targWP], self->s.pos.trBase, dirToTarget );
+
VectorNormalize( dirToTarget );
vectoangles( dirToTarget, self->turretAim );
@@ -1172,7 +1302,7 @@
FireWeapon( self );
G_SetBuildableAnim( self, BANIM_ATTACK1, qfalse );
return;
- }
+
}
}
Index: src/game/g_local.h
===================================================================
--- src/game/g_local.h (revision 87)
+++ src/game/g_local.h (working copy)
@@ -242,6 +242,15 @@
int lastDamageTime;
int bdnumb; // buildlog entry ID
+
+ #define MAX_WPA 31
+ #define HIVE_RECHECK 30000
+ vec3_t WPA[ MAX_WPA + 1 ];
+ vec3_t WPA2[ MAX_WPA + 1 ];
+ qboolean inUse[ MAX_WPA + 1];
+ int TotalWP;
+ int targWP;
+ int RecheckTime;
};
typedef enum
Index: src/game/g_missile.c
===================================================================
--- src/game/g_missile.c (revision 87)
+++ src/game/g_missile.c (working copy)
@@ -582,34 +582,127 @@
*/
void AHive_SearchAndDestroy( gentity_t *self )
{
+
vec3_t dir;
- trace_t tr;
-
+ trace_t tr, tr2, tr3;
+ vec3_t Torigin;
+ gentity_t *traceEnt;
+
+ if (self->TotalWP == 0 )
+ {
+ self->TotalWP++;
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ 0 ]);
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ self->TotalWP ]);
+ }
trap_Trace( &tr, self->r.currentOrigin, self->r.mins, self->r.maxs,
self->target_ent->r.currentOrigin, self->r.ownerNum, self->clipmask );
+ traceEnt = &g_entities[ tr.entityNum ];
//if there is no LOS or the parent hive is too far away or the target is dead or notargeting, return
- if( tr.entityNum == ENTITYNUM_WORLD ||
- Distance( self->r.currentOrigin, self->parent->r.currentOrigin ) > ( HIVE_RANGE * 5 ) ||
+ if( Distance( self->r.currentOrigin, self->parent->r.currentOrigin ) > ( HIVE_RANGE * 30 ) ||
self->target_ent->health <= 0 || self->target_ent->flags & FL_NOTARGET )
{
self->r.ownerNum = ENTITYNUM_WORLD;
self->think = AHive_ReturnToHive;
self->nextthink = level.time + FRAMETIME;
+ return;
}
else
{
- VectorSubtract( self->target_ent->r.currentOrigin, self->r.currentOrigin, dir );
+ if ( tr.entityNum == ENTITYNUM_WORLD || traceEnt->s.eType == ET_BUILDABLE)
+ {
+ trap_Trace( &tr2, self->WPA[ self->TotalWP - 1 ], self->r.mins, self->r.maxs,
+ self->target_ent->r.currentOrigin, self->r.ownerNum, self->clipmask );
+ traceEnt = &g_entities[ tr2.entityNum ];
+ if ( tr2.entityNum == ENTITYNUM_WORLD || traceEnt->s.eType == ET_BUILDABLE )
+ {
+ trap_Trace( &tr3, self->WPA[ self->TotalWP ], self->r.mins, self->r.maxs,
+ self->target_ent->r.currentOrigin, self->r.ownerNum, self->clipmask ); // if the player turned around another corner while we were thinking, drop the target.
+ traceEnt = &g_entities[ tr3.entityNum ];
+ if ( tr3.entityNum == ENTITYNUM_WORLD || traceEnt->s.eType == ET_BUILDABLE )
+ {
+ self->r.ownerNum = ENTITYNUM_WORLD;
+
+ self->think = AHive_ReturnToHive;
+ self->nextthink = level.time + FRAMETIME;
+ //;//trap_SendServerCommand( -1, va( "print \"Lost Target\n\""));
+ return; // lost the track, get back home
+ }
+ else
+ {
+ if (self->TotalWP < MAX_WPA)
+ {
+ self->TotalWP++;
+ //;//trap_SendServerCommand( -1, va( "print \"New Waypoint, %i\n\"", self->TotalWP - 1));
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ self->TotalWP ]);
+ }
+ else
+ {
+ self->r.ownerNum = ENTITYNUM_WORLD;
+
+ self->think = AHive_ReturnToHive;
+ self->nextthink = level.time + FRAMETIME;
+ //;//trap_SendServerCommand( -1, va( "print \"Out Of memory\n\""));
+ return; // out of memory, get back home
+ }
+ }
+ }
+ else
+ {
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ self->TotalWP ]); //update latest waypoint without creating a new one, if there is a LOS from the old one
+ }
+ }
+ else
+ {
+ int i;
+ if (self->TotalWP > 1)
+ {
+ self->TotalWP = 1;
+ //;//trap_SendServerCommand( -1, va( "print \"Direct Line of Sight\n\""));
+ }
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ 0 ]);
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ self->TotalWP ]);
+
+
+ }
+
+ if (Distance( self->r.currentOrigin, self->WPA[ 0 ]) < 64 && self->TotalWP > 1) // snap the swarm to the waypoint if it is close enough.
+ {
+ int i;
+ VectorCopy(self->WPA[ 0 ], self->r.currentOrigin);
+ for (i = 0; i <= MAX_WPA; i++)
+ {
+ VectorCopy(self->WPA[i+1], self->WPA[i]);
+ }
+ self->TotalWP--;
+ if (self->TotalWP < 1) self->TotalWP = 1;
+ VectorCopy(self->target_ent->r.currentOrigin, self->WPA[ self->TotalWP ]);
+ //;//trap_SendServerCommand( -1, va( "print \"Waypoint Reached\n\""));
+ }
+
+ trap_Trace( &tr, self->r.currentOrigin, self->r.mins, self->r.maxs,
+ self->WPA[ 0 ], self->r.ownerNum, self->clipmask );
+ traceEnt = &g_entities[ tr.entityNum ];
+ if ( tr.entityNum == ENTITYNUM_WORLD || traceEnt->s.eType == ET_BUILDABLE ) // check for doors closing
+ {
+
+ self->r.ownerNum = ENTITYNUM_WORLD;
+
+ self->think = AHive_ReturnToHive;
+ self->nextthink = level.time + FRAMETIME;
+ //;//trap_SendServerCommand( -1, va( "print \"Invalid Waypoint\n\""));
+ return;
+ }
+
+ VectorSubtract( self->WPA[ 0 ], self->r.currentOrigin, dir );
VectorNormalize( dir );
-
//change direction towards the player
VectorScale( dir, HIVE_SPEED, self->s.pos.trDelta );
SnapVector( self->s.pos.trDelta ); // save net bandwidth
VectorCopy( self->r.currentOrigin, self->s.pos.trBase );
self->s.pos.trTime = level.time;
-
- self->nextthink = level.time + HIVE_DIR_CHANGE_PERIOD;
+ self->nextthink = level.time + HIVE_DIR_CHANGE_PERIOD/2;
}
}
@@ -641,7 +734,29 @@
bolt->methodOfDeath = MOD_SWARM;
bolt->clipmask = MASK_SHOT;
bolt->target_ent = self->target_ent;
-
+ bolt->TotalWP = 0;
+
+ if(self->targWP != -1)
+ {
+ if(self->targWP >= 0)
+ {
+ bolt->TotalWP++;
+ VectorCopy(self->WPA[self->targWP], bolt->WPA[ 0 ]);
+ VectorCopy(self->WPA[self->targWP], bolt->WPA[ bolt->TotalWP ]);
+ ;//trap_SendServerCommand( -1, va( "print \"Swarm : Waypoint Received, proceeding to target\n\""));
+ }
+ else
+ {
+ int TW;
+ TW = abs(self->targWP) - 2;
+ bolt->TotalWP += 2;
+ VectorCopy(self->WPA[TW], bolt->WPA[ 0 ]);
+ VectorCopy(self->WPA2[TW], bolt->WPA[ 1 ]);
+ VectorCopy(self->WPA2[TW], bolt->WPA[ bolt->TotalWP ]);
+ ;//trap_SendServerCommand( -1, va( "print \"Swarm : 2 Waypoints received, proceeding to target\n\""));
+ }
+ }
+
bolt->s.pos.trType = TR_LINEAR;
bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame
VectorCopy( start, bolt->s.pos.trBase );
Edit : pwef! added even more complicated algorythm, since the first one did not solve the problem for all cases that could happen. Not the best way to implement, but it is quite effective.