//custom monkey function to add res ships to world and make them orient themselves correctly void addMonkeyResearchShip(Ship *ship) { SelectCommand selectOne; selectOne.numShips=1; selectOne.ShipPtr[0]=ship; clDock(&universe.mainCommandLayer,&selectOne,DOCK_FOR_RESEARCH|DOCK_INSTANTANEOUSLY,NULL); }
void ResearchShipDied(Ship *ship) { ResearchShipSpec *spec = (ResearchShipSpec *)ship->ShipSpecifics; Node *shipnode = universe.ShipList.head; Ship *obj; MaxSelection selection; //need to slow down/stop first research ship and turn it into a new master! if(ship->dockvars.reserveddocking != -1) { sdword dockpointindex; CommandToDo *command = getShipAndItsCommand(&universe.mainCommandLayer,ship); if(command != NULL) { if(command->ordertype.order == COMMAND_DOCK) { if(command->dock.dockType != DOCK_FOR_RETIRE) { dockpointindex = ship->dockvars.dockstaticpoint->dockindex; dbgAssertOrIgnore(ship->dockvars.reserveddocking == (sbyte)dockpointindex); ship->dockvars.reserveddocking = -1; if(spec->dockwith != NULL) { dbgAssertOrIgnore(spec->dockwith->dockInfo->dockpoints[dockpointindex].thisDockBusy > 0); spec->dockwith->dockInfo->dockpoints[dockpointindex].thisDockBusy--; } } } } } if(spec->dockwith != NULL) { if(ship->shiprace == R1) { ((ResearchShipSpec *)spec->dockwith->ShipSpecifics)->seed = TRUE; //set correct seeding ((ResearchShipSpec *)spec->dockwith->ShipSpecifics)->done = FALSE; } else { ((ResearchShipSpec *)spec->dockwith->ShipSpecifics)->seed = TRUE; //set correct seeding ((ResearchShipSpec *)spec->dockwith->ShipSpecifics)->done = FALSE; } } selection.numShips = 0; if(ship->flags & SOF_Slaveable) { //ship is slaved if(ship->slaveinfo->flags & SF_MASTER) { //ship is a master //ship that died is a master! no worries while(shipnode != NULL) { obj = (Ship *) listGetStructOfNode(shipnode); if(obj->shiptype == ResearchShip) { if(obj->playerowner == ship->playerowner) { if(!bitTest(obj->flags,SOF_Slaveable)) { if(obj != ship) { CommandToDo *command = getShipAndItsCommand(&universe.mainCommandLayer,obj); if(command != NULL && command->ordertype.order == COMMAND_DOCK && (command->dock.dockType & DOCK_FOR_RETIRE||command->dock.dockType & DOCK_PERMANENTLY)) { //don't reorder a dock for research } else if(obj->flags & SOF_Dead) { } else if(!bitTest(obj->flags,SOF_Dead)) { //as long as ship isn't considered dead //need better method CleanResearchShip(obj); selection.ShipPtr[selection.numShips] = obj; selection.numShips++; } } } } } shipnode = shipnode->next; } } else { //ship that died isn't a master } } else { while(shipnode != NULL) { obj = (Ship *) listGetStructOfNode(shipnode); if(obj->shiptype == ResearchShip) { if(obj->playerowner == ship->playerowner) { if(obj != ship) { if(((ResearchShipSpec *) obj->ShipSpecifics)->dockordernumber > spec->dockordernumber) { CommandToDo *command = getShipAndItsCommand(&universe.mainCommandLayer,obj); if(command != NULL && command->ordertype.order == COMMAND_DOCK && (command->dock.dockType & DOCK_FOR_RETIRE||command->dock.dockType & DOCK_PERMANENTLY)) { //don't reorder a dock for research } else if(obj->flags & SOF_Dead) { } else { if(obj->dockvars.reserveddocking != -1) { sdword dockpointindex; dockpointindex = obj->dockvars.dockstaticpoint->dockindex; dbgAssertOrIgnore(obj->dockvars.reserveddocking == (sbyte)dockpointindex); obj->dockvars.reserveddocking = -1; //dbgAssertOrIgnore(((ResearchShipSpec *) obj->ShipSpecifics)->dockwith->dockInfo->dockpoints[dockpointindex].thisDockBusy > 0); if (((ResearchShipSpec *) obj->ShipSpecifics)->dockwith) // Bryce did I fix this right by putting in this check dockwith != NULL ((ResearchShipSpec *) obj->ShipSpecifics)->dockwith->dockInfo->dockpoints[dockpointindex].thisDockBusy = 0; } CleanResearchShip(obj); dbgAssertOrIgnore(selection.numShips < COMMAND_MAX_SHIPS); selection.ShipPtr[selection.numShips] = obj; selection.numShips++; //ship->dockInfo->dockpoints[shippointindex].thisDockBusy = 0; //artificially busy point //selection.ShipPtr[selection.numShips] = obj; //selection.numShips++; } } } } } shipnode = shipnode->next; } } if(selection.numShips >= 1) { clDock(&universe.mainCommandLayer, (SelectCommand *)&selection, DOCK_FOR_RESEARCH, NULL); } }
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; }