I've finally finished with the sensor model.
Sensor components themselves store a lookup table of values, where the signature of any particular ship just needs to be plugged in to get the appropriate value.
int getActiveDetectionRange(activeSensor *sensor, int TCS, int MSP)
{
//limits of the array
if( TCS > 499 || TCS < 0 )
{
return -1;
}
int range;
if( TCS != 0 )//ships
{
/*int shipTCS = TCS - 1;
if( shipTCS > 499 )
shipTCS = 499;*/
range = sensor->lookUpST[ TCS ];
}
else //missiles
{
range = sensor->lookUpMT[ MSP ];
}
return range;
}
Next up are ships, which store their signatures, a pointer to a sorted linked list of all 3 detection values, and an indicator for whether or not a player has IDed this ship this tick:
//Detection related statistics
int TCS; //Total Cross Section for active scanners. modified by cloaks
int tSig; //thermal signature of ship. modified by thermal reduction
int maxTSig; //maximum thermal signature of the ship.
int eSig; //EM signature of ship. no way to reduce this, shields and actives are always detected.
//which players have detected this ship and how.
unsigned int thermalDet[32];
unsigned int EMDet[32];
unsigned int activeDet[32];
//this ship's placement in the linked list of thermal/em/TCS lists.
sortList *thermal;
sortList *EM;
sortList *active;
At the taskforce level I have a distance table, a pointer to each of the best passive sensors, an active sensor que for which active sensors are on and working, and a lookuptable that addresses the active sensor que, which can then be used to access that particular sensor's lookup table, and finally the heads and tails of each of the sorted linked lists of all the ships in this taskforce, from least to greatest.
if( TG->activeCount != 0 )
{
for( int loop = 0; loop < 500; loop++ )
{
//TG->tfLookUpST is different from ->lookUpST. the first stores an index to the active que, the second
//stores a range value at that particular resolution. In effect tfLookUpST points you at the best sensor to
//look for that resolution value with its lookUpST.
if( TG->activeQue[ TG->activeCount ]->lookUpST[ loop ] > TG->activeQue[ TG->tfLookUpST[ loop ] ]->lookUpST[ loop ] ) //<<<
{
TG->tfLookUpST[ loop ] = TG->activeCount;
}
}
for( int loop = 0; loop < 15; loop++ )
{
if( TG->activeQue[ TG->activeCount ]->lookUpMT[ loop ] > TG->activeQue[ TG->tfLookUpMT[ loop ] ]->lookUpMT[ loop ] )
{
TG->tfLookUpMT[ loop ] = TG->activeCount;
}
}
}
at the player level I store global taskforce contacts, any taskforce that I no longer need to search because it has been detected, or cannot be detected(EM signature = 0)
Likewise I do a per player sensor sweep that touches on every taskforce in the global list, and every ship in that taskforce. First I check to see if none of the ships are detected(comparing best sensor vs biggest signature), then I check to see if they all are via the smallest signature against the appropriate sensor, and finally I run backwards through the linked list marking everything that is detected as detected
if( P->contactACTGlobal[ loop2 ] != tick && P->TFList[ loop ]->activeCount != 0 )
{
noDet = 0;
allDet = 0;
shipSig = tfListGlobal[ loop2 ]->tfShipList[ tfListGlobal[ loop2 ]->aTail->index ]->TCS;
shipSig = shipSig - 1;
if( shipSig > 499 )
shipSig = 499;
shipDet = getActiveDetectionRange( P->TFList[ loop ]->activeQue[ P->TFList[ loop ]->tfLookUpST[ shipSig ] ], shipSig, 0);
//First check the biggest ship, which should be paired correspondingly to the longest ranged sensor
//If a smaller vessel would be detected at this range, then the biggest vessel must definitely be detected by that sensor or any better sensor
//barring a bug of course, but that doesn't detract from the logic
if( dist > shipDet ) //no detections
{
noDet = 1;
}
if( noDet == 0 )
{
shipSig = tfListGlobal[ loop2 ]->tfShipList[ tfListGlobal[ loop2 ]->aHead->index ]->TCS;
shipSig = shipSig - 1;
if( shipSig > 499 )
shipSig = 499;
shipDet = getActiveDetectionRange( P->TFList[ loop ]->activeQue[ P->TFList[ loop ]->tfLookUpST[ shipSig ] ], shipSig, 0);
if( dist <= shipDet ) //in this case the smallest ship is detected, which means that all larger ships must also be detected
{
allDet = 1; //either by this sensor, or by a better one
for( int loop3 = 0; loop3 < tfListGlobal[ loop2 ]->shipCount; loop3++ )
{
ship *enemyShip = tfListGlobal[ loop2 ]->tfShipList[ loop3 ];
enemyShip->activeDet[ P->ID ] = tick;
}
P->contactACTGlobal[ loop2 ] = tick; //all ships in this taskforce are detected
}
}//end if all detected
if( noDet == 0 && allDet == 0 ) //the larger ships are definitely detected, smaller ones may not be
{
sortList *aDet = tfListGlobal[ loop2 ]->aTail;
while( aDet != NULL )
{
ship *enemyShip = tfListGlobal[ loop2 ]->tfShipList[ aDet->index ];
if( enemyShip->activeDet[ P->ID ] != tick ) //this ship is already detected
{
shipSig = enemyShip->TCS;
shipSig = shipSig - 1;
if( shipSig > 499 )
shipSig = 499;
shipDet = getActiveDetectionRange( P->TFList[ loop ]->activeQue[ P->TFList[ loop ]->tfLookUpST[ shipSig ] ], shipSig, 0);
if( dist <= shipDet )
{
enemyShip->activeDet[ P->ID ] = tick;
}
else //once again, if this ship is not detected, but a smaller one is, then it would stand to reason that this ship would also be detected by that sensor.
{
break;
}
}
aDet = aDet->next;
}//end while
}//end if some detected
}//end if contactACTGlobal = tick
In this 1st picture, I have 32 players, 10 taskforces per player, and 7 ships per taskforce, I can do ~40fps with this happening every 16 ms.
http://imageshack.us/f/10/stress1h.jpg/printing strings is horridly painful though.
http://imageshack.us/f/14/stress2e.jpg/So I have working mechanics for engines and sensors now, though I'll probably scale back the player/taskforce count in the future.