Пример #1
0
//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);


}
Пример #2
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;
}