Esempio n. 1
0
void MyFrame::OnMoveComplete(wxThreadEvent& event)
{
    try
    {
        Mount *pThisMount = event.GetPayload<Mount *>();
        assert(pThisMount->IsBusy());
        pThisMount->DecrementRequestCount();

        Mount::MOVE_RESULT moveResult = static_cast<Mount::MOVE_RESULT>(event.GetInt());

        pMount->LogGuideStepInfo();

        if (moveResult != Mount::MOVE_OK)
        {
            if (moveResult == Mount::MOVE_STOP_GUIDING)
            {
                Debug.Write("mount move error indicates guiding should stop\n");
                pGuider->StopGuiding();
            }

            throw ERROR_INFO("Error reported moving");
        }
    }
    catch (wxString Msg)
    {
        POSSIBLY_UNUSED(Msg);
    }
}
Esempio n. 2
0
bool MyFrame::FlipRACal()
{
    bool bError = false;
    Mount *scope = TheScope();

    if (scope)
    {
        bError = scope->FlipCalibration();

        if (!bError)
        {
            EvtServer.NotifyCalibrationDataFlipped(scope);
        }
    }

    return bError;
}
bool MyFrame::FlipRACal()
{
    bool bError = false;
    Mount *mount = pSecondaryMount ? pSecondaryMount : pMount;

    if (mount)
    {
        bError = mount->FlipCalibration();

        if (!bError)
        {
            EvtServer.NotifyCalibrationDataFlipped(mount);
        }
    }

    return bError;
}
Esempio n. 4
0
void MyFrame::OnMoveComplete(wxThreadEvent& event)
{
    try
    {
        Mount *mount = event.GetPayload<Mount *>();
        assert(mount->IsBusy());
        mount->DecrementRequestCount();

        Mount::MOVE_RESULT moveResult = static_cast<Mount::MOVE_RESULT>(event.GetInt());

        mount->LogGuideStepInfo();

        // deliver the outstanding GuidingStopped notification if this is a late-arriving
        // move completion event
        if (!pGuider->IsCalibratingOrGuiding() &&
            (!pMount || !pMount->IsBusy()) &&
            (!pSecondaryMount || !pSecondaryMount->IsBusy()))
        {
            pFrame->NotifyGuidingStopped();
        }

        if (moveResult != Mount::MOVE_OK)
        {
            mount->IncrementErrorCount();

            if (moveResult == Mount::MOVE_STOP_GUIDING)
            {
                Debug.Write("mount move error indicates guiding should stop\n");
                pGuider->StopGuiding();
            }

            throw ERROR_INFO("Error reported moving");
        }
    }
    catch (const wxString& Msg)
    {
        POSSIBLY_UNUSED(Msg);
    }
}
Esempio n. 5
0
File::File(Mount& mnt,
           const fs::path& p,
           yt::FDMode fdmode,
           CreateIfNecessary create_if_necessary)
    : ctx_(mnt.ctx_)
{

    /* mode is not the same for both nfs_creat and nfs_open. For nfs_open
     * mode has the same meaning as flags but for nfs_creat is the mode used
     * for file creation. The newer version of libnfs makes this difference
     * obvious by introducing a second field 'flags' along with mode. We should
     * consider upgrading to the latest libnfs then and drop the workaround
     * introduced below.
     */
    const int mode = create_if_necessary == CreateIfNecessary::T ?
        translate_create_mode(fdmode) : translate_mode(fdmode);

    LOG_TRACE(mnt.share_name() << ", " << p << ", mode " << mode <<
              ", create: " << create_if_necessary);

    nfsfh* fh;
    int ret;

    if (create_if_necessary == CreateIfNecessary::T)
    {
        ret = nfs_creat(ctx_.get(),
                        p.string().c_str(),
                        mode,
                        &fh);
    }
    else
    {
        ret = nfs_open(ctx_.get(),
                       p.string().c_str(),
                       mode,
                       &fh);
    }

    if (ret < 0)
    {
        const char* err = nfs_get_error(ctx_.get());
        std::stringstream ss;
        ss << "Failed to open " << p << ": " << err;
        LOG_ERROR(ss.str());
        throw Exception(ss.str().c_str());
    }
    else
    {
        fh_ = std::shared_ptr<nfsfh>(fh, FhDeleter(ctx_));
    }
}
Esempio n. 6
0
void AdvancedDialog::AddMountPage(void)
{
    const long ID_NOMOUNT = 99999;
    Mount *mount = pMount;

    if (mount)
    {
        wxWindow *noMsgWindow = m_pScopeSettingsPanel->FindWindow(ID_NOMOUNT);
        if (noMsgWindow)
            noMsgWindow->Destroy();
        m_pMountPane = mount->GetConfigDialogPane(m_pScopeSettingsPanel);
        m_pMountPane->LayoutControls(m_pScopeSettingsPanel, m_brainCtrls);
        m_pMountPane->Layout();
    }
    else
    {
        m_pMountPane = new Mount::MountConfigDialogPane(m_pScopeSettingsPanel, _("Mount"), mount);
        wxStaticText *pNoMount = new wxStaticText(m_pScopeSettingsPanel, ID_NOMOUNT, _("No mount specified"));
        m_pMountPane->Add(pNoMount);
    }

    m_pScopeSettingsPanel->GetSizer()->Add(m_pMountPane, wxSizerFlags(0).Border(wxTOP, 10).Expand());
    m_pScopeSettingsPanel->Layout();
}
Esempio n. 7
0
void MyFrame::OnEEGG(wxCommandEvent& evt)
{
    if (evt.GetId() == EEGG_RESTORECAL || evt.GetId() == EEGG_REVIEWCAL)
    {
        wxString savedCal = pConfig->Profile.GetString("/scope/calibration/timestamp", wxEmptyString);
        if (savedCal.IsEmpty())
        {
            wxMessageBox(_("There is no calibration data available."));
            return;
        }

        if (!pMount)
        {
            wxMessageBox(_("Please connect a mount first."));
            return;
        }

        if (evt.GetId() == EEGG_RESTORECAL)
        {
            CalRestoreDialog(this).ShowModal();
        }
        else
        {
            if (pCalReviewDlg)                                          // Review dialog is non-modal
                pCalReviewDlg->Destroy();
            pCalReviewDlg = new CalReviewDialog(this);
            pCalReviewDlg->Show();
        }
    }
    else if (evt.GetId() == EEGG_MANUALCAL)
    {
        if (pMount)
        {
            Calibration cal;
            cal.xRate  = pMount->xRate();
            cal.yRate  = pMount->yRate();
            cal.xAngle = pMount->xAngle();
            cal.yAngle = pMount->yAngle();
            cal.declination = pPointingSource->GetGuidingDeclination();
            cal.pierSide = pPointingSource->SideOfPier();
            cal.rotatorAngle = Rotator::RotatorPosition();

            if (!pMount->IsCalibrated())
            {
                cal.xRate       = 1.0;
                cal.yRate       = 1.0;
                cal.xAngle      = 0.0;
                cal.yAngle      = M_PI / 2.;
                cal.declination = 0.0;
            }

            ManualCalDialog manualcal(cal);
            if (manualcal.ShowModal () == wxID_OK)
            {
                manualcal.GetValues(&cal);
                pMount->SetCalibration(cal);
            }
        }
    }
    else if (evt.GetId() == EEGG_CLEARCAL)
    {
        wxString devicestr = "";
        if (!(pGuider && pGuider->IsCalibratingOrGuiding()))
            if (pMount)
            {
                if (pMount->IsStepGuider())
                    devicestr = _("AO");
                else
                    devicestr = _("Mount");
            }
            if (pSecondaryMount)
            {
                devicestr += _(", Mount");
            }
            if (devicestr.Length() > 0)
            {
                if (wxMessageBox(wxString::Format(_("%s calibration will be cleared - calibration will be re-done when guiding is started."), devicestr),
                    _("Clear Calibration"), wxOK | wxCANCEL) == wxOK)
                {
                    if (pMount)
                        pMount->ClearCalibration();
                    if (pSecondaryMount)
                        pSecondaryMount->ClearCalibration();
                    Debug.AddLine("User cleared calibration on " + devicestr);
                }
            }
    }
    else if (evt.GetId() == EEGG_FLIPRACAL)
    {
        Mount *scope = TheScope();

        if (scope)
        {
            double xorig = degrees(scope->xAngle());
            double yorig = degrees(scope->yAngle());

            Debug.AddLine("User-requested FlipRACal");

            if (FlipRACal())
            {
                wxMessageBox(_("Failed to flip RA calibration"));
            }
            else
            {
                double xnew = degrees(scope->xAngle());
                double ynew = degrees(scope->yAngle());
                wxMessageBox(wxString::Format(_("RA calibration angle flipped: (%.2f, %.2f) to (%.2f, %.2f)"),
                    xorig, yorig, xnew, ynew));
            }
        }
    }
    else if (evt.GetId() == EEGG_MANUALLOCK)
    {
        if (!pFrame->pNudgeLock)
            pFrame->pNudgeLock = NudgeLockTool::CreateNudgeLockToolWindow();

        pFrame->pNudgeLock->Show();
    }
    else if (evt.GetId() == EEGG_STICKY_LOCK)
    {
        bool sticky = evt.IsChecked();
        pFrame->pGuider->SetLockPosIsSticky(sticky);
        pConfig->Global.SetBoolean("/StickyLockPosition", sticky);
        NudgeLockTool::UpdateNudgeLockControls();
    }
    else
    {
        evt.Skip();
    }
}
void GameUnit< UnitType >::Draw( const Transformation &parent, const Matrix &parentMatrix )
{
    //Quick shortcut for camera setup phase
    bool myparent = ( this == _Universe->AccessCockpit()->GetParent() );


    Matrix         *ctm;
    Matrix invview;
    Transformation *ct;

    this->cumulative_transformation = linear_interpolate( this->prev_physical_state,
                                                          this->curr_physical_state,
                                                          interpolation_blend_factor );
    this->cumulative_transformation.Compose( parent, parentMatrix );
    this->cumulative_transformation.to_matrix( this->cumulative_transformation_matrix );

    ctm = &this->cumulative_transformation_matrix;
    ct  = &this->cumulative_transformation;
    if (this->graphicOptions.FaceCamera == 1) {
        Vector  p, q, r;
        QVector pos( ctm->p );
        float   wid, hei;
        float   magr = parentMatrix.getR().Magnitude();
        float   magp = parentMatrix.getP().Magnitude();
        float   magq = parentMatrix.getQ().Magnitude();
        CalculateOrientation( pos, p, q, r, wid, hei, 0, false, ctm );
        VectorAndPositionToMatrix( invview, p*magp, q*magq, r*magr, ctm->p );
        ctm = &invview;
    }

#ifdef PERFRAMESOUND
    AUDAdjustSound( sound.engine, cumulative_transformation.position, GetVelocity() );
#endif

    unsigned int i;
    if ( (this->hull < 0) && (!cam_setup_phase) )
        Explode( true, GetElapsedTime() );
    
    float damagelevel = 1.0f;
    unsigned char chardamage = 0;
    
    // We might need to scale rSize, this "average scale" takes the transform matrix into account
    float avgscale = 1.0f;
    
    bool On_Screen = false;
    float Apparent_Size = 0.0f;
    int cloak = this->cloaking;
    Matrix wmat;

    if (!cam_setup_phase) {
        // Following stuff is only needed in actual drawing phase
        if (this->cloaking > this->cloakmin) {
            cloak = (int) (this->cloaking-interpolation_blend_factor*this->pImage->cloakrate*SIMULATION_ATOM);
            cloak = cloakVal( cloak, this->cloakmin, this->pImage->cloakrate, this->pImage->cloakglass );
        }
        if (this->hull < this->maxhull) {
            damagelevel = this->hull/this->maxhull;
            chardamage  = ( 255-(unsigned char) (damagelevel*255) );
        }
        avgscale = sqrt((ctm->getP().MagnitudeSquared() + ctm->getR().MagnitudeSquared()) * 0.5);
        wmat = this->WarpMatrix( *ctm );
    }
    
    if ( ( !(this->invisible&UnitType::INVISUNIT) ) && ( ( !(this->invisible&UnitType::INVISCAMERA) ) || (!myparent) ) ) {
        if (!cam_setup_phase) {
            Camera *camera = _Universe->AccessCamera();
            QVector camerapos = camera->GetPosition();
            
            float minmeshradius =
                ( camera->GetVelocity().Magnitude()+this->Velocity.Magnitude() )*SIMULATION_ATOM;
            
            unsigned int numKeyFrames = this->graphicOptions.NumAnimationPoints;
            for (i = 0; i <= this->nummesh(); i++) {
                //NOTE LESS THAN OR EQUALS...to cover shield mesh
                if (this->meshdata[i] == NULL)
                    continue;
                if (  i == this->nummesh() && (this->meshdata[i]->numFX() == 0 || this->hull < 0) )
                    continue;
                if (this->meshdata[i]->getBlendDst() == ONE) {
                    if ( (this->invisible & UnitType::INVISGLOW) != 0 )
                        continue;
                    if (damagelevel < .9)
                        if ( flickerDamage( this, damagelevel ) )
                            continue;
                }
                QVector TransformedPosition = Transform( *ctm, this->meshdata[i]->Position().Cast() );

                //d can be used for level of detail shit
                float mSize = this->meshdata[i]->rSize() * avgscale;
                double d = ( TransformedPosition-camerapos ).Magnitude();
                double rd  = d-mSize;
                float pixradius = Apparent_Size = mSize*perspectiveFactor(
                    (rd < g_game.znear) ? g_game.znear : rd );
                float lod = pixradius*g_game.detaillevel;
                if (this->meshdata[i]->getBlendDst() == ZERO) {
                    if (UnitType::isUnit() == PLANETPTR && pixradius > 10) {
                        Occlusion::addOccluder(TransformedPosition, mSize, true);
                    } else if (pixradius >= 10.0) {
                        Occlusion::addOccluder(TransformedPosition, mSize, false);
                    }
                }
                if (lod >= 0.5 && pixradius >= 2.5) {
                    double frustd = GFXSphereInFrustum( 
                        TransformedPosition,
                        minmeshradius+mSize );
                    if (frustd) {
                        //if the radius is at least half a pixel at detail 1 (equivalent to pixradius >= 0.5 / detail)
                        float currentFrame = this->meshdata[i]->getCurrentFrame();
                        this->meshdata[i]->Draw( lod, wmat, d, 
                                                 i == this->meshdata.size()-1 ? -1 : cloak,
                                                 (camera->GetNebula() == this->nebula && this->nebula != NULL) ? -1 : 0, 
                                                 chardamage );                                                                                                                                                            //cloakign and nebula
                        On_Screen = true;
                        unsigned int numAnimFrames = 0;
                        static const string default_animation;
                        if ( this->meshdata[i]->getFramesPerSecond()
                            && ( numAnimFrames = this->meshdata[i]->getNumAnimationFrames( default_animation ) ) ) {
                            float currentprogress = floor(
                                this->meshdata[i]->getCurrentFrame()*numKeyFrames/(float) numAnimFrames );
                            if (numKeyFrames
                                && floor( currentFrame*numKeyFrames/(float) numAnimFrames ) != currentprogress) 
                            {
                                this->graphicOptions.Animating = 0;
                                this->meshdata[i]->setCurrentFrame( .1+currentprogress*numAnimFrames/(float) numKeyFrames );
                            } else if (!this->graphicOptions.Animating) {
                                this->meshdata[i]->setCurrentFrame( currentFrame );                                 //dont' budge
                            }
                        }
                    }
                }
            }
        }
        {
            Unit  *un;
            double backup = interpolation_blend_factor;
            int    cur_sim_frame = _Universe->activeStarSystem()->getCurrentSimFrame();
            for (un_iter iter = this->getSubUnits(); (un = *iter); ++iter) {
                float backup = SIMULATION_ATOM;
                if (this->sim_atom_multiplier && un->sim_atom_multiplier)
                    SIMULATION_ATOM = SIMULATION_ATOM*un->sim_atom_multiplier/this->sim_atom_multiplier;
                interpolation_blend_factor = calc_blend_factor( saved_interpolation_blend_factor,
                                                                un->sim_atom_multiplier,
                                                                un->cur_sim_queue_slot,
                                                                cur_sim_frame );
                (un)->Draw( *ct, *ctm );

                SIMULATION_ATOM = backup;
            }
            interpolation_blend_factor = backup;
        }
    } else {
        _Universe->AccessCockpit()->SetupViewPort();         ///this is the final, smoothly calculated cam
        //UpdateHudMatrix();
    }
    /***DEBUGGING cosAngleFromMountTo
     *  UnitCollection *dL = _Universe->activeStarSystem()->getUnitList();
     *  UnitCollection::UnitIterator *tmpiter = dL->createIterator();
     *  GameUnit<UnitType> * curun;
     *  while (curun = tmpiter->current()) {
     *  if (curun->selected) {
     *   float tmpdis;
     *   float tmpf = cosAngleFromMountTo (curun, tmpdis);
     *   VSFileSystem::vs_fprintf (stderr,"%s: <%f d: %f\n", curun->name.c_str(), tmpf, tmpdis);
     *
     *  }
     *  tmpiter->advance();
     *  }
     *  delete tmpiter;
     **/
    if (cam_setup_phase) return;
    int nummounts = this->GetNumMounts();
    for (i = 0; (int) i < nummounts; i++) {
        Mount *mahnt = &this->mounts[i];
        if (game_options.draw_weapons && On_Screen)
            if (mahnt->xyscale != 0 && mahnt->zscale != 0) {
                Mesh *gun = mahnt->type->gun;
                if (gun && mahnt->status != Mount::UNCHOSEN) {
                    Transformation mountLocation( mahnt->GetMountOrientation(), mahnt->GetMountLocation().Cast() );
                    mountLocation.Compose( *ct, wmat );
                    Matrix mat;
                    mountLocation.to_matrix( mat );
                    if (GFXSphereInFrustum( mountLocation.position, gun->rSize()*avgscale ) > 0) {
                        float d   = ( mountLocation.position-_Universe->AccessCamera()->GetPosition() ).Magnitude();
                        float pixradius = gun->rSize()*perspectiveFactor(
                            (d-gun->rSize() < g_game.znear) ? g_game.znear : d-gun->rSize() );
                        float lod = pixradius * g_game.detaillevel;
                        if (lod > 0.5 && pixradius > 2.5) {
                            ScaleMatrix( mat, Vector( mahnt->xyscale, mahnt->xyscale, mahnt->zscale ) );
                            gun->setCurrentFrame( this->mounts[i].ComputeAnimatedFrame( gun ) );
                            gun->Draw( lod, mat, d, cloak,
                                       (_Universe->AccessCamera()->GetNebula() == this->nebula && this->nebula != NULL) ? -1 : 0,
                                       chardamage,
                                       true );                                                                                                                                      //cloakign and nebula
                        }
                        if (mahnt->type->gun1) {
                            pixradius = gun->rSize()*perspectiveFactor(
                                (d-gun->rSize() < g_game.znear) ? g_game.znear : d-gun->rSize() );
                            lod = pixradius * g_game.detaillevel;
                            if (lod > 0.5 && pixradius > 2.5) {
                                gun = mahnt->type->gun1;
                                gun->setCurrentFrame( this->mounts[i].ComputeAnimatedFrame( gun ) );
                                gun->Draw( lod, mat, d, cloak,
                                           (_Universe->AccessCamera()->GetNebula() == this->nebula && this->nebula
                                            != NULL) ? -1 : 0,
                                           chardamage, true );                                                                                                                              //cloakign and nebula
                            }
                        }
                    }
                }
            }
        if (this->mounts[i].type->type == weapon_info::BEAM)
            if (this->mounts[i].ref.gun)
                this->mounts[i].ref.gun->Draw( *ct, wmat,
                                               ( (this->mounts[i].size&weapon_info::AUTOTRACKING)
                                                && (this->mounts[i].time_to_lock <= 0)
                                                && Unit::TargetTracked() ) ? Unit::Target() : NULL, 
                                               this->computer.radar.trackingcone );
    }
    if ( On_Screen && (phalos->NumHalos() > 0) && !( this->docked&(UnitType::DOCKED|UnitType::DOCKED_INSIDE) ) && (Apparent_Size > 5.0f) ) {
        Vector linaccel = this->GetAcceleration();
        Vector angaccel = this->GetAngularAcceleration();
        float  maxaccel = this->GetMaxAccelerationInDirectionOf( wmat.getR(), true );
        Vector velocity = this->GetVelocity();

        float  cmas = this->computer.max_ab_speed()*this->computer.max_ab_speed();
        if (cmas == 0)
            cmas = 1;
        Vector Scale( 1, 1, 1 );         //Now, HaloSystem handles that
        //WARNING: cmas is not a valid maximum speed for the upcoming multi-direction thrusters,
        //nor is maxaccel. Instead, each halo should have its own limits specified in units.csv
        float nebd = (_Universe->AccessCamera()->GetNebula() == this->nebula && this->nebula != NULL) ? -1 : 0;
        float hulld = this->GetHull() > 0 ? damagelevel : 1.0;
        phalos->Draw( wmat, Scale, cloak, nebd, hulld, velocity, linaccel, angaccel, maxaccel, cmas, this->faction );
    }
    if ( On_Screen && !UnitType::graphicOptions.NoDamageParticles
        && !( this->docked&(UnitType::DOCKED|UnitType::DOCKED_INSIDE) ) ) {
        if (damagelevel < .99 && this->nummesh() > 0 && this->GetHull() > 0) {
            unsigned int switcher    = (damagelevel > .8) ? 1
                                       : (damagelevel > .6) ? 2 : (damagelevel > .4) ? 3 : (damagelevel > .2) ? 4 : 5;
            sparkle_accum += GetElapsedTime()*game_options.sparklerate;
            int spawn = (int) (sparkle_accum);
            sparkle_accum -= spawn;
            while (spawn-- > 0) {
                switch (switcher)
                {
                case 5:
                    LaunchOneParticle( *ctm, this->GetVelocity(), ( (long) this )+165, this, damagelevel, this->faction );
                case 4:
                    LaunchOneParticle( *ctm, this->GetVelocity(), ( (long) this )+47, this, damagelevel, this->faction );
                case 3:
                    LaunchOneParticle( *ctm, this->GetVelocity(), ( (long) this )+61, this, damagelevel, this->faction );
                case 2:
                    LaunchOneParticle( *ctm, this->GetVelocity(), ( (long) this )+65537, this, damagelevel, this->faction );
                default:
                    LaunchOneParticle( *ctm, this->GetVelocity(), ( (long) this )+257, this, damagelevel, this->faction );
                }
            }
        } else {
            sparkle_accum = 0;
        }
    } else {
        sparkle_accum = 0;
    }
}
void GameUnit< UnitType >::DrawNow( const Matrix &mato, float lod )
{
    static const void *rootunit = NULL;
    if (rootunit == NULL) rootunit = (const void*) this;
    float damagelevel = 1.0;
    unsigned char chardamage    = 0;
    if (this->hull < this->maxhull) {
        damagelevel = this->hull/this->maxhull;
        chardamage  = ( 255-(unsigned char) (damagelevel*255) );
    }
#ifdef VARIABLE_LENGTH_PQR
    const float  vlpqrScaleFactor = SizeScaleFactor;
#else
    const float  vlpqrScaleFactor = 1.f;
#endif
    unsigned int i;
    Matrix mat( mato );
    if (this->graphicOptions.FaceCamera) {
        Vector  p, q, r;
        QVector pos( mato.p );
        float   wid, hei;
        CalculateOrientation( pos, p, q, r, wid, hei, 0, false, &mat );
        pos = mato.p;
        VectorAndPositionToMatrix( mat, p, q, r, pos );
    }
    int cloak = this->cloaking;
    if (this->cloaking > this->cloakmin)
        cloak = cloakVal( cloak, this->cloakmin, this->pImage->cloakrate, this->pImage->cloakglass );
    for (i = 0; i <= this->nummesh(); i++) {
        //NOTE LESS THAN OR EQUALS...to cover shield mesh
        if (this->meshdata[i] == NULL)
            continue;
        QVector TransformedPosition = Transform( mat,
                                                this->meshdata[i]->Position().Cast() );
        float   d = GFXSphereInFrustum( TransformedPosition, this->meshdata[i]->clipRadialSize()*vlpqrScaleFactor );
        if (d)          //d can be used for level of detail
                        //this->meshdata[i]->DrawNow(lod,false,mat,cloak);//cloakign and nebula
            this->meshdata[i]->Draw( lod, mat, d, cloak );
    }
    Unit *un;
    for (un_iter iter = this->getSubUnits(); (un = *iter); ++iter) {
        Matrix temp;
        un->curr_physical_state.to_matrix( temp );
        Matrix submat;
        MultMatrix( submat, mat, temp );
        (un)->DrawNow( submat, lod );
    }
    float  cmas = this->computer.max_ab_speed()*this->computer.max_ab_speed();
    if (cmas == 0)
        cmas = 1;
        Vector Scale( 1, 1, 1 );         //Now, HaloSystem handles that
    int    nummounts = this->GetNumMounts();
    Matrix wmat = this->WarpMatrix( mat );
    for (i = 0; (int) i < nummounts; i++) {
        Mount *mahnt = &this->mounts[i];
        if (game_options.draw_weapons)
            if (mahnt->xyscale != 0 && mahnt->zscale != 0) {
                Mesh *gun = mahnt->type->gun;
                if (gun && mahnt->status != Mount::UNCHOSEN) {
                    Transformation mountLocation( mahnt->GetMountOrientation(), mahnt->GetMountLocation().Cast() );
                    mountLocation.Compose( Transformation::from_matrix( mat ), wmat );
                    Matrix mmat;
                    mountLocation.to_matrix( mmat );
                    if (GFXSphereInFrustum( mountLocation.position, gun->rSize()*vlpqrScaleFactor ) > 0) {
                        float d   = ( mountLocation.position-_Universe->AccessCamera()->GetPosition() ).Magnitude();
                        float lod = gun->rSize()*g_game.detaillevel*perspectiveFactor(
                            (d-gun->rSize() < g_game.znear) ? g_game.znear : d-gun->rSize() );
                        ScaleMatrix( mmat, Vector( mahnt->xyscale, mahnt->xyscale, mahnt->zscale ) );
                        gun->setCurrentFrame( this->mounts[i].ComputeAnimatedFrame( gun ) );
                        gun->Draw( lod, mmat, d, cloak,
                                   (_Universe->AccessCamera()->GetNebula() == this->nebula && this->nebula != NULL) ? -1 : 0,
                                   chardamage,
                                   true );                                                                                                                                       //cloakign and nebula
                        if (mahnt->type->gun1) {
                            gun = mahnt->type->gun1;
                            gun->setCurrentFrame( this->mounts[i].ComputeAnimatedFrame( gun ) );
                            gun->Draw( lod, mmat, d, cloak,
                                       (_Universe->AccessCamera()->GetNebula() == this->nebula && this->nebula
                                        != NULL) ? -1 : 0,
                                       chardamage, true );                                                                                                                               //cloakign and nebula
                        }
                    }
                }
            }
    }
    Vector linaccel = this->GetAcceleration();
    Vector angaccel = this->GetAngularAcceleration();
    float  maxaccel = this->GetMaxAccelerationInDirectionOf( mat.getR(), true );
    Vector velocity = this->GetVelocity();
    if ( !( this->docked & (UnitType::DOCKED | UnitType::DOCKED_INSIDE) ) )
        phalos->Draw( mat, Scale, cloak, 0, this->GetHullPercent(), velocity, linaccel, angaccel, maxaccel, cmas, this->faction );
    if (rootunit == (const void*) this) {
        Mesh::ProcessZFarMeshes();
        Mesh::ProcessUndrawnMeshes();
        rootunit = NULL;
    }
}