void DefenseFighterPassiveAttack(Ship *ship,Ship *target,bool rotate) { vector heading; if(!rotate) return; vecSub(heading,target->posinfo.position,ship->posinfo.position); vecNormalize(&heading); aitrackHeading(ship,&heading,0.9999f); }
void DefenseFighterAttack(Ship *ship,SpaceObjRotImpTarg *target,real32 maxdist) { vector trajectory; real32 range; aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); if (range < 1000.0f) { aitrackZeroVelocity(ship); vecNormalize(&trajectory); aitrackHeading(ship,&trajectory,0.9999f); } else { aishipFlyToPointAvoidingObjs(ship,&target->posinfo.position,AISHIP_PointInDirectionFlying,0.0f); } }
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]); }
bool refuelRepairShips(Ship *ship, SelectAnyCommand *targets,real32 rangetoRefuel) { //remove unwantedships from this selection //optimize by doing only once for this ship SelectCommand selectOne; sdword i; SpaceObjRotImpTarg *target,*targettemp; vector trajectory,curheading; real32 range,dotprod; CommandToDo *targetCommand; //filter target list for unrepairable ships! for(i=0;i<targets->numTargets;) { if(targets->TargetPtr[i]->objtype != OBJ_ShipType) { targets->numTargets--; targets->TargetPtr[i] = targets->TargetPtr[targets->numTargets]; continue; } targetCommand = getShipAndItsCommand(&universe.mainCommandLayer,(Ship *)targets->TargetPtr[i]); if(targetCommand != NULL) { if(targetCommand->ordertype.order == COMMAND_DOCK) { //remove docking ships from the list if(((Ship *)targets->TargetPtr[i])->dockingship != NULL) { //only if in final stages targets->numTargets--; targets->TargetPtr[i] = targets->TargetPtr[targets->numTargets]; continue; } } } //object is a ship if((((Ship *)targets->TargetPtr[i])->staticinfo->shipclass != CLASS_Fighter && ((Ship *)targets->TargetPtr[i])->staticinfo->shipclass != CLASS_Corvette) || ((Ship *)targets->TargetPtr[i])->playerowner != ship->playerowner) { if(ship->staticinfo->repairBeamCapable) { //repair corvette can repair capital ships! //class doesn't matter if(((Ship *)targets->TargetPtr[i])->playerowner == ship->playerowner) { //ship is not a fighter or a corvette, but is ours, so we can fix it! i++; continue; } } targets->numTargets--; targets->TargetPtr[i] = targets->TargetPtr[targets->numTargets]; } else { i++; } } if (targets->numTargets <= 0) { return TRUE; } target = targets->TargetPtr[0]; //need to add //repairBeamCapable // real32 healthPerSecond,CapitalDistanceRepairStart; // real32 CapitalDistanceRepairStart2; if(ship->staticinfo->repairBeamCapable) { //assume target is a ship!!!! //targets might be a capital ship if(((Ship *)target)->staticinfo->shipclass != CLASS_Fighter) { //target is such that it should be BEAM repaired! //so lets fly upto it and ZAP repair it! real32 range1,range2; aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); vecNormalize(&trajectory); aitrackHeading(ship,&trajectory,0.999f); if(((Ship *)target)->shiptype == Mothership) { range1 = 2*ship->staticinfo->CapitalDistanceRepairStart; range2 = 2*ship->staticinfo->CapitalDistanceRepairStart2; } else { range1 = ship->staticinfo->CapitalDistanceRepairStart; range2 = ship->staticinfo->CapitalDistanceRepairStart2; } //we add 300 to the range checker for a sort of hysterysis! if(range > range1) { aishipFlyToShipAvoidingObjs(ship,target,AISHIP_PointInDirectionFlying + AISHIP_FastAsPossible,0.0f); if(range > range2) { //far enough away to stop the effect and ONLY fly towards ship if(ship->rceffect != NULL) { //turn off ships effect stopRepairEffect(ship); } return FALSE; } } else { aitrackZeroVelocity(ship); } //in range to repair this li'l ship matGetVectFromMatrixCol3(curheading,ship->rotinfo.coordsys); dotprod = vecDotProduct(trajectory,curheading); if(!areAllHealthy(ship,targets)) { if(dotprod > ship->staticinfo->AngleDotProdThreshold) { //within angle of 'repair beam' if(ship->rceffect == NULL) { //turn on effect if we should! startRepairEffect(ship,target,&trajectory,range); } else { //fix up effect ModifyRepairEffect(ship->rceffect,ship,&trajectory,range, target); } target->health+=ship->staticinfo->healthPerSecond*universe.phystimeelapsed; if(((Ship *)target)->health > ((Ship *)target)->staticinfo->maxhealth) { if(ship->rceffect != NULL) { //turn off ships effect stopRepairEffect(ship); } target->health = ((Ship *)target)->staticinfo->maxhealth; //fix this in a bit targettemp = targets->TargetPtr[0]; for(i=0;i<(targets->numTargets-1);i++) { targets->TargetPtr[i]=targets->TargetPtr[i+1]; } targets->TargetPtr[targets->numTargets-1] = targettemp; //if(targets->numTargets <= 0) // return TRUE; //targets->TargetPtr[0] = targets->TargetPtr[targets->numTargets]; return FALSE; } } else { //not pointing at ship, turn off effect and other //needed things! if(ship->rceffect != NULL) { //turn off ships effect stopRepairEffect(ship); } } } else { if(ship->rceffect != NULL) { //turn off ships effect stopRepairEffect(ship); } } return FALSE; } } aishipGetTrajectory(ship,target,&trajectory); aishipFlyToShipAvoidingObjs(ship,target,AISHIP_PointInDirectionFlying + AISHIP_FastAsPossible +AISHIP_FirstPointInDirectionFlying,0.0f); range = RangeToTarget(ship,target,&trajectory); if(range <= rangetoRefuel) { //within repair range selectOne.numShips = 1; selectOne.ShipPtr[0] = (Ship *) target; if(target->objtype == OBJ_ShipType) { ((Ship *)target)->fuel += 300.0f; //??? appropriate ammount? if(((Ship *)target)->fuel > ((Ship *)target)->staticinfo->maxfuel) ((Ship *)target)->fuel = ((Ship *)target)->staticinfo->maxfuel; //"speech event? Switching to Emergency Docking Fuel Supply? //cldock clDock(&universe.mainCommandLayer,&selectOne,DOCK_AT_SPECIFIC_SHIP,ship); } targets->numTargets--; if(targets->numTargets <= 0) return TRUE; targets->TargetPtr[0] = targets->TargetPtr[targets->numTargets]; } return FALSE; }