Exemple #1
0
bool ship_is_moving(Ship *ship)
{
    CommandToDo *commy = getShipAndItsCommand(&universe.mainCommandLayer,ship);
    if(commy != NULL)
    {
        if(commy->ordertype.order == COMMAND_MOVE)
        {
            return TRUE;
        }
    }
    return FALSE;
    /*
    if(isBetweenInclusive(ship->posinfo.velocity.x,NOTMOVINGNEG,NOTMOVINGPOS))
    {
        if(isBetweenInclusive(ship->posinfo.velocity.y,NOTMOVINGNEG,NOTMOVINGPOS))
        {
            if(isBetweenInclusive(ship->posinfo.velocity.z,NOTMOVINGNEG,NOTMOVINGPOS))
            {
                return(FALSE);
            }
        }
    }
    return(TRUE);
    */
}
Exemple #2
0
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);
        }

    }
}
Exemple #3
0
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;
}