Esempio n. 1
0
CUnit* CUnitLoader::LoadUnit(const UnitLoadParams& cparams)
{
    CUnit* unit = NULL;
    UnitLoadParams& params = const_cast<UnitLoadParams&>(cparams);

    {
        GML_RECMUTEX_LOCK(sel); // LoadUnit - for anti deadlock purposes.
        GML_RECMUTEX_LOCK(quad); // LoadUnit - make sure other threads cannot access an incomplete unit

        const UnitDef* ud = params.unitDef;

        if (ud == NULL)
            return unit;
        // need to check this BEFORE creating the instance
        if (!unitHandler->CanAddUnit(cparams.unitID))
            return unit;

        if (params.teamID < 0) {
            // FIXME use gs->gaiaTeamID ?  (once it is always enabled)
            if ((params.teamID = teamHandler->GaiaTeamID()) < 0)
                throw content_error("Invalid team and no gaia team to put unit in");
        }

        if (ud->IsTransportUnit()) {
            unit = new CTransportUnit();
        } else if (ud->IsFactoryUnit()) {
            // special static builder structures that can always be given
            // move orders (which are passed on to all mobile buildees)
            unit = new CFactory();
        } else if (ud->IsMobileBuilderUnit() || ud->IsStaticBuilderUnit()) {
            // all other types of non-structure "builders", including hubs and
            // nano-towers (the latter should not have any build-options at all,
            // whereas the former should be unable to build any mobile units)
            unit = new CBuilder();
        } else if (ud->IsBuildingUnit()) {
            // static non-builder structures
            if (ud->IsExtractorUnit()) {
                unit = new CExtractorBuilding();
            } else {
                unit = new CBuilding();
            }
        } else {
            // regular mobile unit
            unit = new CUnit();
        }

        unit->PreInit(params);

        if (ud->IsTransportUnit()) {
            new CTransportCAI(unit);
        } else if (ud->IsFactoryUnit()) {
            new CFactoryCAI(unit);
        } else if (ud->IsMobileBuilderUnit() || ud->IsStaticBuilderUnit()) {
            new CBuilderCAI(unit);
        } else if (ud->IsStrafingAirUnit()) {
            // non-hovering fighter or bomber aircraft; coupled to StrafeAirMoveType
            new CAirCAI(unit);
        } else if (ud->IsAirUnit()) {
            // all other aircraft; coupled to HoverAirMoveType
            new CMobileCAI(unit);
        } else if (ud->IsGroundUnit()) {
            new CMobileCAI(unit);
        } else {
            new CCommandAI(unit);
        }
    }

    unit->PostInit(params.builder);
    (eventBatchHandler->GetUnitCreatedDestroyedBatch()).enqueue(EventBatchHandler::UD(unit, unit->isCloaked));

    if (params.flattenGround) {
        FlattenGround(unit);
    }

    return unit;
}
Esempio n. 2
0
CUnit* CUnitLoader::LoadUnit(const UnitDef* ud, const float3& pos, int team,
                             bool build, int facing, const CUnit* builder)
{
    CUnit* unit = NULL;

    SCOPED_TIMER("UnitLoader::LoadUnit");

    {
        GML_RECMUTEX_LOCK(sel); // LoadUnit - for anti deadlock purposes.
        GML_RECMUTEX_LOCK(quad); // LoadUnit - make sure other threads cannot access an incomplete unit

        if (team < 0) {
            team = teamHandler->GaiaTeamID(); // FIXME use gs->gaiaTeamID ?  (once it is always enabled)
            if (team < 0)
                throw content_error("Invalid team and no gaia team to put unit in");
        }

        if (ud->IsTransportUnit()) {
            unit = new CTransportUnit();
        } else if (ud->IsFactoryUnit()) {
            // special static builder structures that can always be given
            // move orders (which are passed on to all mobile buildees)
            unit = new CFactory();
        } else if (ud->IsMobileBuilderUnit() || ud->IsStaticBuilderUnit()) {
            // all other types of non-structure "builders", including hubs and
            // nano-towers (the latter should not have any build-options at all,
            // whereas the former should be unable to build any mobile units)
            unit = new CBuilder();
        } else if (ud->IsBuildingUnit()) {
            // static non-builder structures
            if (ud->IsExtractorUnit()) {
                unit = new CExtractorBuilding();
            } else {
                unit = new CBuilding();
            }
        } else {
            // regular mobile unit
            unit = new CUnit();
        }

        unit->PreInit(ud, team, facing, pos, build);

        if (ud->IsTransportUnit()) {
            new CTransportCAI(unit);
        } else if (ud->IsFactoryUnit()) {
            new CFactoryCAI(unit);
        } else if (ud->IsMobileBuilderUnit() || ud->IsStaticBuilderUnit()) {
            new CBuilderCAI(unit);
        } else if (ud->IsNonHoveringAirUnit()) {
            // non-hovering fighter or bomber aircraft; coupled to StrafeAirMoveType
            new CAirCAI(unit);
        } else if (ud->IsAirUnit()) {
            // all other aircraft; coupled to HoverAirMoveType
            new CMobileCAI(unit);
        } else if (ud->IsGroundUnit()) {
            new CMobileCAI(unit);
        } else {
            new CCommandAI(unit);
        }
    }

    unit->PostInit(builder);
    (eventBatchHandler->GetUnitCreatedDestroyedBatch()).enqueue(EventBatchHandler::UD(unit, unit->isCloaked));

    return unit;
}