void addMonkeyResearchShipChangePosition(Ship *dockwith, Ship *ship,sdword dockindex) { DockStaticPoint *dockwithstaticpoint; vector coneheadingInWorldCoordSysDockWith,DockWithHeading,destination,DockWithUp,destinationoffset; vector desiredHeading,desiredUp,conepositionInWorldCoordSysDockWith,tmpvec; real32 theta; matrix rotmatrix,tmpmat; ResearchShipStatics *resstatics; resstatics = (ResearchShipStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; dbgAssertOrIgnore(dockwith != NULL); //if we're calling this there should be another reserach station available somewhere if(ship->shiprace == R1) { dockwithstaticpoint = &dockwith->staticinfo->dockStaticInfo->dockstaticpoints[dockindex]; matMultiplyMatByVec(&coneheadingInWorldCoordSysDockWith,&dockwith->rotinfo.coordsys,&dockwithstaticpoint->conenormal); matGetVectFromMatrixCol3(DockWithHeading,dockwith->rotinfo.coordsys) destinationoffset.x = coneheadingInWorldCoordSysDockWith.x*resstatics->R1final_dock_distance; destinationoffset.y = coneheadingInWorldCoordSysDockWith.y*resstatics->R1final_dock_distance; destinationoffset.z = coneheadingInWorldCoordSysDockWith.z*resstatics->R1final_dock_distance; vecAdd(destination,dockwith->posinfo.position, destinationoffset); if(((ResearchShipSpec *)ship->ShipSpecifics)->pie_plate_num == 0) { //ship is docking on'a'top so add upwards factor matGetVectFromMatrixCol1(DockWithUp,dockwith->rotinfo.coordsys); vecScalarMultiply(DockWithUp,DockWithUp,resstatics->R1VerticalDockDistance); vecAdd(destination,destination,DockWithUp); } theta = DEG_TO_RAD(60); matMakeRotAboutX(&rotmatrix,(real32) cos(theta),(real32) sin(theta)); matMultiplyMatByMat(&tmpmat, &dockwith->rotinfo.coordsys, &rotmatrix); //share a lot of these things...later... ship->rotinfo.coordsys = tmpmat; ship->posinfo.position = destination; } else { //r2 positioning dockwithstaticpoint = &dockwith->staticinfo->dockStaticInfo->dockstaticpoints[dockindex]; matMultiplyMatByVec(&coneheadingInWorldCoordSysDockWith,&dockwith->rotinfo.coordsys,&dockwithstaticpoint->conenormal); matMultiplyMatByVec(&conepositionInWorldCoordSysDockWith,&dockwith->rotinfo.coordsys,&dockwithstaticpoint->position); vecAddTo(conepositionInWorldCoordSysDockWith,dockwith->posinfo.position); matGetVectFromMatrixCol3(DockWithHeading,dockwith->rotinfo.coordsys) destinationoffset.x = coneheadingInWorldCoordSysDockWith.x*resstatics->R2DockFinalDistance; destinationoffset.y = coneheadingInWorldCoordSysDockWith.y*resstatics->R2DockFinalDistance; destinationoffset.z = coneheadingInWorldCoordSysDockWith.z*resstatics->R2DockFinalDistance; vecAdd(destination,conepositionInWorldCoordSysDockWith, destinationoffset); desiredHeading = coneheadingInWorldCoordSysDockWith; if(dockindex == 0) { matGetVectFromMatrixCol3(desiredUp,dockwith->rotinfo.coordsys); } else if(dockindex == 1) { matGetVectFromMatrixCol3(desiredUp,dockwith->rotinfo.coordsys); } else if(dockindex == 2) { desiredUp = DockWithHeading; } else if(dockindex == 3) { theta = DEG_TO_RAD(60); matMakeRotAboutZ(&rotmatrix,(real32) cos(theta),(real32) sin(theta)); matMultiplyMatByMat(&tmpmat, &dockwith->rotinfo.coordsys, &rotmatrix); matGetVectFromMatrixCol1(desiredUp,tmpmat); } else if(dockindex == 4) { destinationoffset.x = coneheadingInWorldCoordSysDockWith.x*100; destinationoffset.y = coneheadingInWorldCoordSysDockWith.y*100; destinationoffset.z = coneheadingInWorldCoordSysDockWith.z*100; vecAdd(destination,conepositionInWorldCoordSysDockWith, destinationoffset); matGetVectFromMatrixCol1(desiredUp,dockwith->rotinfo.coordsys); vecScalarMultiply(desiredHeading,desiredHeading,-1.0f); } else { dbgAssertOrIgnore(FALSE); //shouldget here. } vecNormalize(&desiredUp); matPutVectIntoMatrixCol1(desiredUp,ship->rotinfo.coordsys); vecCrossProduct(tmpvec,desiredHeading,desiredUp); matPutVectIntoMatrixCol2(tmpvec,ship->rotinfo.coordsys); matPutVectIntoMatrixCol3(desiredHeading,ship->rotinfo.coordsys); ship->posinfo.position = destination; ship->posinfo.velocity.x = 0.0f; ship->posinfo.velocity.y = 0.0f; ship->posinfo.velocity.z = 0.0f; } }
bool MinelayerCorvetteStaticMineDrop(Ship *ship,SpaceObjRotImpTarg *target) { MinelayerCorvetteStatics *minelayercorvettestatics; MinelayerCorvetteSpec *spec = (MinelayerCorvetteSpec *)ship->ShipSpecifics; sdword flag; GunInfo *guninfo = ship->gunInfo; Gun *gun0,*gun1; real32 time; sdword maxmis; minelayercorvettestatics = (MinelayerCorvetteStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; gun0 = ((Gun *) &(ship->gunInfo->guns[0])); maxmis = gun0->gunstatic->maxMissiles; if(ship->gunInfo->numGuns > 1) { //ship has 2 guns (race 1) gun1 = ((Gun *) &(ship->gunInfo->guns[1])); if(gun0->numMissiles == 0 && gun1->numMissiles == 0) return FALSE; if((universe.totaltimeelapsed - gun1->lasttimefired) < minelayercorvettestatics->gunReFireTime && (universe.totaltimeelapsed - gun0->lasttimefired) < minelayercorvettestatics->gunReFireTime) { return(FALSE); } maxmis += gun1->gunstatic->maxMissiles; } else { if(gun0->numMissiles == 0) return FALSE; if((universe.totaltimeelapsed - gun0->lasttimefired) < minelayercorvettestatics->gunReFireTime) return(FALSE); } switch(spec->MiningStatus) { case FIRST_OFF: ////////////////////// //speech event for forcedropped mines //event num: COMM_MLVette_ForceDrop //use battle chatter if(ship->playerowner->playerIndex == universe.curPlayerIndex) { if (battleCanChatterAtThisTime(BCE_COMM_MLVette_ForceDrop, ship)) { battleChatterAttempt(SOUND_EVENT_DEFAULT, BCE_COMM_MLVette_ForceDrop, ship, SOUND_EVENT_DEFAULT); } } ///////////////////////// spec->MiningStatus = FIRST_OFF2; case FIRST_OFF2: if(aitrackZeroRotationAnywhere(ship)) { flag = 2; } if(aitrackZeroVelocity(ship)) { if(flag == 2) { //we're ready for next step MineFormationInfo *mineformationinfo; aitrackForceSteadyShip(ship); //stop movement, stop rotation spec->MiningStatus = BEGIN_WALL_DROP_RIGHT; spec->MiningSideMax = 1; spec->MiningSideCount = 0; matGetVectFromMatrixCol1(spec->formation_up,ship->rotinfo.coordsys); matGetVectFromMatrixCol2(spec->formation_right,ship->rotinfo.coordsys); vecScalarMultiply(spec->formation_up, spec->formation_up, minelayercorvettestatics->MineSpacing); vecScalarMultiply(spec->formation_down, spec->formation_up, -1.0f); vecScalarMultiply(spec->formation_right,spec->formation_right,minelayercorvettestatics->MineSpacing); vecScalarMultiply(spec->formation_left,spec->formation_right,-1.0f); matGetVectFromMatrixCol3(spec->formation_heading,ship->rotinfo.coordsys); vecScalarMultiply(spec->formation_heading,spec->formation_heading,-minelayercorvettestatics->MineDropDistance); //Create Formation Entity Here mineformationinfo = memAlloc(sizeof(MineFormationInfo),"MineFormationInfo",NonVolatile); listAddNode(&universe.MineFormationList,&(mineformationinfo->FormLink),mineformationinfo); listInit(&mineformationinfo->MineList); mineformationinfo->playerowner = ship->playerowner; mineformationinfo->FULL = FALSE; mineformationinfo->wallstate = PULSE_START; mineformationinfo->effect = NULL; spec->mineforminfo = mineformationinfo; time = 29.0; spec->mineforminfo->waittime = time; //set wait time for each pulse spec->formation_number_X = 0; spec->formation_number_Y = 0; vecAdd(spec->formation_position,ship->posinfo.position,spec->formation_heading); spec->mineaistate = MINE_DROP_FORMATION; MinelayerCorvetteFire(ship,target); spec->MineDropNumber = 1; } } break; case BEGIN_WALL_DROP_RIGHT: vecAddTo(spec->formation_position,spec->formation_right); spec->mineaistate = MINE_DROP_FORMATION; MinelayerCorvetteFire(ship,target); spec->MineDropNumber++; spec->formation_number_X++; spec->MiningSideCount++; if(spec->MiningSideCount == spec->MiningSideMax) { spec->MiningSideCount = 0; spec->MiningStatus = BEGIN_WALL_DROP_UP; } break; case BEGIN_WALL_DROP_UP: vecAddTo(spec->formation_position,spec->formation_up); spec->mineaistate = MINE_DROP_FORMATION; MinelayerCorvetteFire(ship,target); spec->MineDropNumber++; spec->formation_number_Y++; spec->MiningSideCount++; if(spec->MiningSideCount == spec->MiningSideMax) { spec->MiningSideMax++; spec->MiningSideCount = 0; spec->MiningStatus = BEGIN_WALL_DROP_LEFT; } break; case BEGIN_WALL_DROP_LEFT: vecAddTo(spec->formation_position,spec->formation_left); spec->mineaistate = MINE_DROP_FORMATION; MinelayerCorvetteFire(ship,target); spec->MineDropNumber++; spec->formation_number_X--; spec->MiningSideCount++; if(spec->MiningSideCount == spec->MiningSideMax) { spec->MiningSideCount = 0; spec->MiningStatus = BEGIN_WALL_DROP_DOWN; } break; case BEGIN_WALL_DROP_DOWN: vecAddTo(spec->formation_position,spec->formation_down); spec->mineaistate = MINE_DROP_FORMATION; MinelayerCorvetteFire(ship,target); spec->MineDropNumber++; spec->formation_number_Y--; spec->MiningSideCount++; if(spec->MiningSideCount == spec->MiningSideMax) { spec->MiningSideMax++; spec->MiningSideCount = 0; spec->MiningStatus = BEGIN_WALL_DROP_RIGHT; } break; case DONE_WAIT: spec->mineaistate = MINE_DROP_ATTACK; return TRUE; break; } if(spec->MineDropNumber == minelayercorvettestatics->NumMinesInSide*minelayercorvettestatics->NumMinesInSide) { if(spec->mineforminfo != NULL) { spec->mineforminfo->FULL = TRUE; spec->mineforminfo = NULL; } spec->mineaistate=MINE_DROP_ATTACK; spec->MiningStatus = DONE_WAIT; spec->MineDropNumber = 0; return(TRUE); //finished Wall } return(FALSE); }
void ResearchShipHouseKeep(Ship *ship) { ResearchShipSpec *spec = (ResearchShipSpec *)ship->ShipSpecifics; SelectCommand selection; vector up,destination,desiredheading,newup; vector univup = {0.0f,0.0f,1.0f}; bool InParadeandMoving = FALSE; matrix rot_matrix,tmpmat,rotmat; real32 radangle; ResearchShipStatics *researchshipstatics; researchshipstatics = (ResearchShipStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; if(bitTest(ship->specialFlags,SPECIAL_StopForResearchDocking)) { vecScalarMultiply(ship->posinfo.velocity,ship->posinfo.velocity,0.94); vecScalarMultiply(ship->rotinfo.rotspeed,ship->rotinfo.rotspeed,0.94); bitSet(ship->dontapplyforceever,1); bitSet(ship->dontrotateever,1); } else { bitClear(ship->dontapplyforceever,1); bitClear(ship->dontrotateever,1); } if(ship->flags & SOF_Slaveable) { if(ship->slaveinfo->flags & SF_MASTER) { CommandToDo *command = getShipAndItsCommand(&universe.mainCommandLayer,ship); if(command != NULL) { //ship may be in parade... if(command->ordertype.order == COMMAND_MILITARY_PARADE) { //ship is in parade CommandToDo *ashipCom = getShipAndItsCommand(&universe.mainCommandLayer,command->militaryParade->aroundShip); if(ashipCom != NULL) { //probably shouldn't be null regardless..should be equal to command..but ohwell if(ashipCom->ordertype.order == COMMAND_MOVE || ashipCom->ordertype.order == COMMAND_ATTACK || ashipCom->ordertype.order == COMMAND_SPECIAL || ashipCom->ordertype.order == COMMAND_MP_HYPERSPACING) { InParadeandMoving = TRUE; spec->rotate_state = ROTATE_WAIT; } } //in parade if(!InParadeandMoving) { if(bitTest(ship->specialFlags,SPECIAL_ParadeNeedTomoveCloser)) { InParadeandMoving = TRUE; spec->rotate_state = ROTATE_WAIT; } } } } } } if(ship->flags & SOF_Slaveable) { //ship is slaveable bitSet(ship->flags,SOF_DontDrawTrails); ship->autostabilizeship = FALSE; // never have univupdate autostabilize research ships if(ship->slaveinfo->flags & SF_MASTER) { //ship is a master if(!InParadeandMoving) { if(ship->shiprace == R1) { //ship is a race 1 MASTER research ship... //i.e. it controls the motion switch(spec->rotate_state) { case ANGLE_ESTABLISH: //establishes the angle at which the station is supposed to rotate at break; case ROTATE_WAIT: //wait to rotate if(ship->slaveinfo->slaves.num >= 5) { //correct # of ships... if(!ship_is_moving(ship)) { if(!spec->prepshipforanother) { //no ships are coming to dock //do up vector tracking! //Later Calculate this vector ONCE at code start up...Let Daly do it //and get as a static value radangle = DEG_TO_RAD(researchshipstatics->RotationAngle); matMakeRotAboutX(&rotmat,(real32) cos(radangle),(real32) sin(radangle)); matMultiplyMatByVec(&newup, &rotmat, &univup); //matGetVectFromMatrixCol3(desiredHeading,ship->rotinfo.coordsys); if(aitrackHeadingWithFlags(ship,&newup,0.96f,AITRACKHEADING_IGNOREUPVEC)) { spec->rotate_state = ROTATE_DO; getRotatePoint(ship, &spec->rotate_point,&spec->rotate_distance); } } } if(!spec->have_removed_from_parade) { spec->have_removed_from_parade = TRUE; selection.numShips = 1; selection.ShipPtr[0] = ship; //RemoveShipsFromDoingStuff(&universe.mainCommandLayer,&selection); //clHalt(&universe.mainCommandLayer,&selection); } } break; case ROTATE_STOP: case ROTATE_STOP_QUICK: case ROTATE_DO: ship->posinfo.isMoving = ISMOVING_MOVING | ISMOVING_ROTATING; make_all_slaves_moving(ship); if(ship->slaveinfo->slaves.num < 5) { //don't rotate anymore because slaves dropped below threhold for whatever reasons! spec->rotate_state = ROTATE_STOP; break; } if(spec->prepshipforanother) { //need to prep ship for a docking ship.. spec->rotate_state = ROTATE_STOP; } else if(ship_is_moving(ship)) { //ship is being moved spec->rotate_state = ROTATE_STOP_QUICK; } else { spec->rotate_state = ROTATE_DO; } //matGetVectFromMatrixCol3(heading,ship->rotinfo.coordsys); matGetVectFromMatrixCol1(up,ship->rotinfo.coordsys); //vecScalarMultiply(rotate_point, heading, -250.0f); //vecAdd(rotate_point,rotate_point, ship->posinfo.position); switch(spec->rotate_state) { case ROTATE_DO: if(spec->theta >= researchshipstatics->max_rotate) spec->theta = researchshipstatics->max_rotate; else spec->theta += researchshipstatics->rotate_acelleration; break; case ROTATE_STOP_QUICK: spec->theta *= researchshipstatics->rotate_slow; spec->theta *= researchshipstatics->rotate_slow; case ROTATE_STOP: if(spec->theta <= 0.00001f) { spec->theta = 0.0f; spec->rotate_state = ROTATE_WAIT; break; } else spec->theta *= researchshipstatics->rotate_slow; break; default: dbgAssertOrIgnore(FALSE); break; } matMakeRotAboutX(&rot_matrix,(real32) cos(spec->theta),(real32) sin(spec->theta)); //matMultiplyMatByMat(&tmpmat, &rot_matrix, &ship->rotinfo.coordsys); matMultiplyMatByMat(&tmpmat, &ship->rotinfo.coordsys, &rot_matrix); //vecSub(tmpvec, ship->posinfo.position, spec->rotate_point); //dist = vecMagnitudeSquared(tmpvec); //dist = fsqrt(dist); matGetVectFromMatrixCol3(desiredheading,tmpmat); vecScalarMultiply(destination, desiredheading, spec->rotate_distance); //old was dist vecAdd(destination,destination,spec->rotate_point); ship->posinfo.position = destination; ship->rotinfo.coordsys = tmpmat; univUpdateObjRotInfo((SpaceObjRot *)ship); break; default: dbgMessagef("Shouldn't Get Here...unknown Research Ship Rotate State"); dbgAssertOrIgnore(FALSE); break; } } else { //Ship is an R2 Master...so rotate differently switch(spec->rotate_state) { case ANGLE_ESTABLISH: break; case ROTATE_WAIT: //wait to rotate if(ship->slaveinfo->slaves.num >= 3) { //correct # of ships... if(!spec->prepshipforanother && !ship_is_moving(ship)) { //no ships are coming to dock radangle = DEG_TO_RAD(researchshipstatics->RotationAngle); matMakeRotAboutX(&rotmat,(real32) cos(radangle),(real32) sin(radangle)); matMultiplyMatByVec(&newup, &rotmat, &univup); if(aitrackHeadingWithFlags(ship,&newup,0.96f,AITRACKHEADING_IGNOREUPVEC)) { spec->rotate_state = ROTATE_DO; } } else { vecSet(ship->rotinfo.rotspeed,0.0f,0.0f,0.0f); vecSet(ship->rotinfo.torque,0.0f,0.0f,0.0f); } } if(ship->slaveinfo->slaves.num >= 1) { //correct # of ships... if(!spec->have_removed_from_parade) { spec->have_removed_from_parade = TRUE; selection.numShips = 1; selection.ShipPtr[0] = ship; //RemoveShipsFromDoingStuff(&universe.mainCommandLayer,&selection); //clHalt(&universe.mainCommandLayer,&selection); } } break; case ROTATE_STOP: case ROTATE_STOP_QUICK: case ROTATE_DO: ship->posinfo.isMoving = ISMOVING_MOVING | ISMOVING_ROTATING; make_all_slaves_moving(ship); if(ship->slaveinfo->slaves.num < 3) { //don't rotate anymore because slaves dropped below threhold for whatever reasons! spec->rotate_state = ROTATE_STOP; break; } if(spec->prepshipforanother) { //need to prep ship for a docking ship.. spec->rotate_state = ROTATE_STOP; } if(ship_is_moving(ship)) { //ship is being moved spec->rotate_state = ROTATE_STOP_QUICK; } switch(spec->rotate_state) { case ROTATE_DO: if(spec->theta >= researchshipstatics->max_rotate) spec->theta = researchshipstatics->max_rotate; else spec->theta += researchshipstatics->rotate_acelleration; break; case ROTATE_STOP_QUICK: spec->theta *= researchshipstatics->rotate_slow; spec->theta *= researchshipstatics->rotate_slow; case ROTATE_STOP: if(spec->theta <= 0.00001f) { spec->theta = 0.0f; spec->rotate_state = ROTATE_WAIT; break; } else spec->theta *= researchshipstatics->rotate_slow; break; default: dbgAssertOrIgnore(FALSE); break; } matMakeRotAboutZ(&rot_matrix,(real32) cos(spec->theta),(real32) sin(spec->theta)); tmpmat = ship->rotinfo.coordsys; matMultiplyMatByMat(&ship->rotinfo.coordsys,&tmpmat,&rot_matrix); univUpdateObjRotInfo((SpaceObjRot *)ship); break; default: dbgMessagef("Shouldn't Get Here...unknown Research Ship Rotate State"); dbgAssertOrIgnore(FALSE); break; } } } } else { vecScalarMultiply(ship->posinfo.velocity,ship->posinfo.velocity, 0.0f); } } }