//to OPTIMIZE THIS: ONLY CALCULATE SLAVED SHIPS AVERAGE POSITION when slaves are added! void toFakeOneShip(Ship *ship, vector *oldpos, real32 *oldradius) { Node *slavenode; Ship *slave; vector newcenter; real32 newradius,tempreal; if(!(ship->flags & SOF_Slaveable)) return; dbgAssertOrIgnore(ship->slaveinfo->flags & SF_MASTER); //must be a master slavenode = ship->slaveinfo->slaves.head; newcenter = ship->collInfo.collPosition; while(slavenode != NULL) { //add all slaves positions together slave = (Ship *) listGetStructOfNode(slavenode); vecAddTo(newcenter,slave->collInfo.collPosition); slavenode = slavenode->next; } vecDivideByScalar(newcenter,(float) ship->slaveinfo->slaves.num+1,tempreal); //take average of slavemaster position if(ship->shiprace == R1) { newradius = ship->staticinfo->staticheader.staticCollInfo.approxcollspheresize*2.5f; } else { //Must be R2 newradius = (float) ship->slaveinfo->slaves.num+1; newradius = ship->staticinfo->staticheader.staticCollInfo.approxcollspheresize*(newradius/4.0f)*1.25f; } *oldpos = ship->collInfo.collPosition; *oldradius = ship->staticinfo->staticheader.staticCollInfo.approxcollspheresize; ship->staticinfo->staticheader.staticCollInfo.approxcollspheresize = newradius; ship->collInfo.collPosition = newcenter; }
void GenericDefenderAttack(Ship *ship,SpaceObjRotImpTarg *target,real32 maxdist) { ShipStaticInfo *shipstaticinfo = (ShipStaticInfo *)ship->staticinfo; GenericDefenderStatics *defenderstat = (GenericDefenderStatics *)shipstaticinfo->custstatinfo; real32 newrange; //newrange = maxdist - defenderstat->gunRange; //newrange = defenderstat->gunRange - newrange; //newrange = defenderstat->gunRange - maxdist + defenderstat->gunRange; //could do check if maxdist == gunRange, then don't do calcs, just use //max dist vector trajectory; real32 dist; real32 range; real32 temp; real32 rightvelocity; vector right; newrange = (defenderstat->gunRange[ship->tacticstype]*2) - maxdist; if(newrange < 0.0f) newrange = defenderstat->tooCloseRange[ship->tacticstype] + 100.0f; else if(newrange > defenderstat->gunRange[ship->tacticstype]) { newrange = defenderstat->gunRange[ship->tacticstype]; } switch (ship->aistateattack) { case 0: ship->aistateattack = DEFENDER_APPROACH; // fall through to DEFENDER_APPROACH case DEFENDER_APPROACH: aishipGetTrajectory(ship,target,&trajectory); dist = fsqrt(vecMagnitudeSquared(trajectory)); range = RangeToTargetGivenDist(ship,target,dist); if (range > newrange) { aishipFlyToShipAvoidingObjsWithVel(ship,target,AISHIP_FastAsPossible|AISHIP_PointInDirectionFlying,0.0f,&target->posinfo.velocity); break; } #ifdef DEBUG_DEFENDER dbgMessagef("\n%x Changing to circle",ship); #endif ship->aistateattack = DEFENDER_CIRCLE; goto circleAlreadyCalculatedTrajectory; case DEFENDER_CIRCLE: aishipGetTrajectory(ship,target,&trajectory); dist = fsqrt(vecMagnitudeSquared(trajectory)); range = RangeToTargetGivenDist(ship,target,dist); if (range > newrange) { #ifdef DEBUG_DEFENDER dbgMessagef("\n%x Changing back to approach",ship); #endif ship->aistateattack = DEFENDER_APPROACH; break; } circleAlreadyCalculatedTrajectory: vecDivideByScalar(trajectory,dist,temp); aitrackHeading(ship,&trajectory,FLYSHIP_ATTACKACCURACY); matGetVectFromMatrixCol2(right,ship->rotinfo.coordsys); rightvelocity = vecDotProduct(right,ship->posinfo.velocity); if (rightvelocity < defenderstat->CIRCLE_RIGHT_VELOCITY) { physApplyForceToObj((SpaceObj *)ship,ship->nonstatvars.thruststrength[TRANS_RIGHT]*defenderstat->CIRCLE_RIGHT_THRUST,TRANS_RIGHT); } if (range < defenderstat->tooCloseRange[ship->tacticstype]) { aitrackZeroForwardVelocity(ship); } if (ship->attackvars.multipleAttackTargets) { gunShootGunsAtMultipleTargets(ship); } else { gunShootGunsAtTarget(ship,target,range,&trajectory); } break; default: dbgAssert(FALSE); break; } // attackStraightForward(ship,target,newrange,defenderstat->tooCloseRange[ship->tacticstype]); }