Beispiel #1
0
CObject* CAutoEgg::SearchAlien()
{
    Math::Vector cPos = m_object->GetPosition();
    float min = 100000.0f;
    CObject* best = nullptr;
    for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
    {
        if (IsObjectBeingTransported(obj))  continue;

        ObjectType type = obj->GetType();
        if ( type != OBJECT_ANT    &&
             type != OBJECT_BEE    &&
             type != OBJECT_SPIDER &&
             type != OBJECT_WORM   )  continue;

        Math::Vector oPos = obj->GetPosition();
        float dist = Math::DistanceProjected(oPos, cPos);
        if ( dist < 8.0f && dist < min )
        {
            min = dist;
            best = obj;
        }
    }
    return best;
}
Beispiel #2
0
CObject* CTarget::DetectFriendObject(Math::Point pos)
{
    int objRank = m_engine->DetectObject(pos);

    for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
    {
        CObject* target = obj;
        if ( obj->Implements(ObjectInterfaceType::PowerContainer) && IsObjectBeingTransported(obj) )
        {
            target = dynamic_cast<CTransportableObject*>(obj)->GetTransporter();
        }

        if ( !target->GetDetectable() )  continue;
        if ( target->GetProxyActivate() )  continue;
        if ( target->Implements(ObjectInterfaceType::Controllable) && dynamic_cast<CControllableObject*>(target)->GetSelect() )  continue;
        if ( !m_main->IsSelectable(target) )  continue;

        if (!target->Implements(ObjectInterfaceType::Old)) continue; // TODO: To be removed after COldObjectInterface is gone

        for (int j=0 ; j<OBJECTMAXPART ; j++ )
        {
            int rank = obj->GetObjectRank(j);
            if ( rank == -1 )  continue;
            if ( rank != objRank )  continue;
            return target;
        }
    }

    return nullptr;
}
Beispiel #3
0
CObject* CLightning::SearchObject(Math::Vector pos)
{
    // Lightning conductors
    std::vector<CObject*> paraObj;
    paraObj.reserve(100);
    std::vector<Math::Vector> paraObjPos;
    paraObjPos.reserve(100);

    // Seeking the object closest to the point of impact of lightning.
    CObject* bestObj = nullptr;
    float min = 100000.0f;
    for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
    {
        if (!obj->GetDetectable()) continue;  // inactive object?

        if (IsObjectBeingTransported(obj)) continue;

        ObjectType type = obj->GetType();
        if ( type == OBJECT_BASE ||
             type == OBJECT_PARA )  // building a lightning effect?
        {
            paraObj.push_back(obj);
            paraObjPos.push_back(obj->GetPosition());
            continue;
        }

        if (!obj->Implements(ObjectInterfaceType::Destroyable)) continue;

        float detect = m_magnetic * dynamic_cast<CDestroyableObject*>(obj)->GetLightningHitProbability();
        if (detect == 0.0f) continue;

        Math::Vector oPos = obj->GetPosition();
        float dist = Math::DistanceProjected(oPos, pos);
        if (dist > detect) continue;
        if (dist < min)
        {
            min = dist;
            bestObj = obj;
        }
    }

    if (bestObj == nullptr)
        return nullptr;  // nothing found

    // Under the protection of a lightning conductor?
    Math::Vector oPos = bestObj->GetPosition();
    for (int i = paraObj.size()-1; i >= 0; i--)
    {
        float dist = Math::DistanceProjected(oPos, paraObjPos[i]);
        if (dist <= LTNG_PROTECTION_RADIUS)
            return paraObj[i];
    }

    return bestObj;
}
Beispiel #4
0
void CAutoPowerCaptor::ChargeObject(float rTime)
{
    Math::Vector sPos = m_object->GetPosition();

    for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
    {
        Math::Vector oPos = obj->GetPosition();
        float dist = Math::Distance(oPos, sPos);
        if ( dist > 20.0f )  continue;

        if (! IsObjectBeingTransported(obj) && obj->Implements(ObjectInterfaceType::PowerContainer) )
        {
            CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(obj);
            if (powerContainer->IsRechargeable())
            {
                float energy = powerContainer->GetEnergy();
                energy += rTime/2.0f;
                if ( energy > 1.0f )  energy = 1.0f;
                powerContainer->SetEnergy(energy);
            }
        }

        if (obj->Implements(ObjectInterfaceType::Powered))
        {
            CObject* power = dynamic_cast<CPoweredObject*>(obj)->GetPower();
            if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) )
            {
                CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power);
                if (powerContainer->IsRechargeable())
                {
                    float energy = powerContainer->GetEnergy();
                    energy += rTime/2.0f;
                    if ( energy > 1.0f )  energy = 1.0f;
                    powerContainer->SetEnergy(energy);
                }
            }
        }

        if (obj->Implements(ObjectInterfaceType::Carrier))
        {
            CObject* power = dynamic_cast<CCarrierObject*>(obj)->GetCargo();
            if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) )
            {
                CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power);
                if (powerContainer->IsRechargeable())
                {
                    float energy = powerContainer->GetEnergy();
                    energy += rTime/2.0f;
                    if ( energy > 1.0f )  energy = 1.0f;
                    powerContainer->SetEnergy(energy);
                }
            }
        }
    }
}
Beispiel #5
0
CObject* CAutoFactory::SearchCargo()
{
    for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
    {
        ObjectType type = obj->GetType();
        if ( type != OBJECT_METAL )  continue;
        if (IsObjectBeingTransported(obj))  continue;

        Math::Vector oPos = obj->GetPosition();
        float dist = Math::Distance(oPos, m_cargoPos);

        if ( dist < 8.0f )  return obj;
    }

    return nullptr;
}
Beispiel #6
0
CObject* CAutoConvert::SearchStone(ObjectType type)
{
    Math::Vector cPos = m_object->GetPosition();

    for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
    {
        ObjectType oType = obj->GetType();
        if ( oType != type )  continue;
        if (IsObjectBeingTransported(obj)) continue;

        Math::Vector oPos = obj->GetPosition();
        float dist = Math::Distance(oPos, cPos);

        if ( dist <= 5.0f )  return obj;
    }

    return nullptr;
}
Beispiel #7
0
CObject* CTaskTake::SearchTakeObject(float &angle,
                                     float dLimit, float aLimit)
{
    CObject     *pBest;
    Math::Vector    iPos, oPos;
    float       min, iAngle, bAngle, a, distance;

    iPos   = m_object->GetPosition();
    iAngle = m_object->GetRotationY();
    iAngle = Math::NormAngle(iAngle);  // 0..2*Math::PI

    min = 1000000.0f;
    pBest = nullptr;
    bAngle = 0.0f;
    for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
    {
        if ( !pObj->Implements(ObjectInterfaceType::Transportable) )  continue;

        if (IsObjectBeingTransported(pObj))  continue;
        if ( pObj->GetLock() )  continue;
        if ( pObj->GetScaleY() != 1.0f )  continue;

        oPos = pObj->GetPosition();
        distance = Math::Distance(oPos, iPos);
        if ( distance >= 4.0f-dLimit &&
             distance <= 4.0f+dLimit )
        {
            angle = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z);  // CW !
            if ( Math::TestAngle(angle, iAngle-aLimit, iAngle+aLimit) )
            {
                a = fabs(angle-iAngle);
                if ( a > Math::PI )  a = Math::PI*2.0f-a;
                if ( a < min )
                {
                    min = a;
                    pBest = pObj;
                    bAngle = angle;
                }
            }
        }
    }
    angle = bAngle;
    return pBest;
}
Beispiel #8
0
bool CTaskTake::IsFreeDeposeObject(Math::Vector pos)
{
    Math::Matrix* mat = m_object->GetWorldMatrix(0);
    Math::Vector iPos = Transform(*mat, pos);

    for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
    {
        if ( pObj == m_object )  continue;
        if ( !pObj->GetDetectable() )  continue;  // inactive?
        if (IsObjectBeingTransported(pObj))  continue;

        for (const auto& crashSphere : pObj->GetAllCrashSpheres())
        {
            if ( Math::Distance(iPos, crashSphere.sphere.pos)-(crashSphere.sphere.radius+1.0f) < 1.0f )
            {
                return false;  // location occupied
            }
        }
    }
    return true;  // location free
}
Beispiel #9
0
CObject* CObjectManager::Radar(CObject* pThis, Math::Vector thisPosition, float thisAngle, std::vector<ObjectType> type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes)
{
    CObject     *pObj, *pBest;
    Math::Vector    iPos, oPos;
    float       best, iAngle, d, a;
    ObjectType  oType;

    minDist *= g_unit;
    maxDist *= g_unit;

    iPos   = thisPosition;
    iAngle = thisAngle+angle;
    iAngle = Math::NormAngle(iAngle);  // 0..2*Math::PI

    int filter_team = filter & 0xFF;
    RadarFilter filter_flying = static_cast<RadarFilter>(filter & (FILTER_ONLYLANDING | FILTER_ONLYFLYING));
    RadarFilter filter_enemy = static_cast<RadarFilter>(filter & (FILTER_FRIENDLY | FILTER_ENEMY | FILTER_NEUTRAL));

    if ( !furthest )  best = 100000.0f;
    else              best = 0.0f;
    pBest = nullptr;
    for ( auto it = m_objects.begin() ; it != m_objects.end() ; ++it )
    {
        pObj = it->second.get();
        if ( pObj == pThis )  continue; // pThis may be nullptr but it doesn't matter

        if (pObj == nullptr) continue;
        if (IsObjectBeingTransported(pObj))  continue;
        if ( !pObj->GetDetectable() )  continue;
        if ( pObj->GetProxyActivate() )  continue;

        oType = pObj->GetType();

        if (cbotTypes)
        {
            // TODO: handle this differently (new class describing types? CObjectType::GetBaseType()?)
            if ( oType == OBJECT_RUINmobilew2 ||
                oType == OBJECT_RUINmobilet1 ||
                oType == OBJECT_RUINmobilet2 ||
                oType == OBJECT_RUINmobiler1 ||
                oType == OBJECT_RUINmobiler2 )
            {
                oType = OBJECT_RUINmobilew1;  // any ruin
            }

            if ( oType == OBJECT_BARRIER2 ||
                oType == OBJECT_BARRIER3 )  // barriers?
            {
                oType = OBJECT_BARRIER1;  // any barrier
            }
            // END OF TODO
        }

        if ( std::find(type.begin(), type.end(), oType) == type.end() && type.size() > 0 )  continue;

        if ( (oType == OBJECT_TOTO || oType == OBJECT_CONTROLLER) && type.size() == 0 )  continue; // allow OBJECT_TOTO and OBJECT_CONTROLLER only if explicitly asked in type parameter

        if ( filter_flying == FILTER_ONLYLANDING )
        {
            if ( pObj->Implements(ObjectInterfaceType::Movable) )
            {
                CPhysics* physics = dynamic_cast<CMovableObject*>(pObj)->GetPhysics();
                if ( physics != nullptr )
                {
                    if ( !physics->GetLand() )  continue;
                }
            }
        }
        if ( filter_flying == FILTER_ONLYFLYING )
        {
            if ( !pObj->Implements(ObjectInterfaceType::Movable) ) continue;
            CPhysics* physics = dynamic_cast<CMovableObject*>(pObj)->GetPhysics();
            if ( physics == nullptr ) continue;
            if ( physics->GetLand() ) continue;
        }

        if ( filter_team != 0 && pObj->GetTeam() != filter_team )
            continue;

        if( pThis != nullptr )
        {
            RadarFilter enemy = FILTER_NONE;
            if ( pObj->GetTeam() == 0 ) enemy = static_cast<RadarFilter>(enemy | FILTER_NEUTRAL);
            if ( pObj->GetTeam() != 0 && pObj->GetTeam() == pThis->GetTeam() ) enemy = static_cast<RadarFilter>(enemy | FILTER_FRIENDLY);
            if ( pObj->GetTeam() != 0 && pObj->GetTeam() != pThis->GetTeam() ) enemy = static_cast<RadarFilter>(enemy | FILTER_ENEMY);
            if ( filter_enemy != 0 && (filter_enemy & enemy) == 0 ) continue;
        }

        oPos = pObj->GetPosition();
        d = Math::DistanceProjected(iPos, oPos);
        if ( d < minDist || d > maxDist )  continue;  // too close or too far?

        a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z);  // CW !
        if ( Math::TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) || focus >= Math::PI*2.0f )
        {
            if ( (!furthest && d < best) ||
                (furthest && d > best) )
            {
                best = d;
                pBest = pObj;
            }
        }
    }

    return pBest;
}
Beispiel #10
0
CObject* CTaskBuild::SearchMetalObject(float &angle, float dMin, float dMax,
                                       float aLimit, Error &err)
{
    CObject     *pBest;
    Math::Vector    iPos, oPos;
    ObjectType  type;
    float       min, iAngle, a, aa, aBest, distance, magic;
    bool        bMetal;

    iPos   = m_object->GetPosition();
    iAngle = m_object->GetRotationY();
    iAngle = Math::NormAngle(iAngle);  // 0..2*Math::PI

    min = 1000000.0f;
    pBest = nullptr;
    bMetal = false;
    for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
    {
        if ( !pObj->GetActive() )  continue;  // objet inactive?
        if (IsObjectBeingTransported(pObj))  continue;

        type = pObj->GetType();
        if ( type != OBJECT_METAL )  continue;

        bMetal = true;  // metal exists

        oPos = pObj->GetPosition();
        distance = Math::Distance(oPos, iPos);
        a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z);  // CW!

        if ( distance > dMax )  continue;
        if ( !Math::TestAngle(a, iAngle-aLimit, iAngle+aLimit) )  continue;

        if ( distance < dMin )
        {
            err = ERR_BUILD_METALNEAR;  // too close
            return pObj;
        }

        aa = fabs(a-iAngle);
        if ( aa > Math::PI )  aa = Math::PI*2.0f-aa;
        magic = distance*aa;

        if ( magic < min )
        {
            min = magic;
            aBest = a;
            pBest = pObj;
        }
    }

    if ( pBest == nullptr )
    {
        if ( bMetal )  err = ERR_BUILD_METALAWAY;  // too far
        else           err = ERR_BUILD_METALINEX;  // non-existent
    }
    else
    {
        angle = aBest;
        err = ERR_OK;
    }
    return pBest;
}
Beispiel #11
0
Error CTaskBuild::FlatFloor()
{
    ObjectType  type;
    Math::Vector    center, pos, bPos;
    Math::Point     c, p;
    float       radius, max, bRadius = 0.0f, angle, dist;
    bool        bLittleFlat, bBase;

    radius = 0.0f;
    if ( m_type == OBJECT_DERRICK  )  radius =  5.0f;
    if ( m_type == OBJECT_FACTORY  )  radius = 15.0f;
    if ( m_type == OBJECT_REPAIR   )  radius = 12.0f;
    if ( m_type == OBJECT_STATION  )  radius = 12.0f;
    if ( m_type == OBJECT_CONVERT  )  radius = 12.0f;
    if ( m_type == OBJECT_TOWER    )  radius =  7.0f;
    if ( m_type == OBJECT_RESEARCH )  radius = 10.0f;
    if ( m_type == OBJECT_RADAR    )  radius =  5.0f;
    if ( m_type == OBJECT_ENERGY   )  radius =  8.0f;
    if ( m_type == OBJECT_LABO     )  radius = 12.0f;
    if ( m_type == OBJECT_NUCLEAR  )  radius = 20.0f;
    if ( m_type == OBJECT_PARA     )  radius = 20.0f;
    if ( m_type == OBJECT_INFO     )  radius =  5.0f;
    if ( m_type == OBJECT_DESTROYER)  radius = 20.0f;
    //if ( radius == 0.0f )  return ERR_UNKNOWN;

    center = m_metal->GetPosition();
    angle = m_terrain->GetFineSlope(center);
    bLittleFlat = ( angle < Gfx::TERRAIN_FLATLIMIT);

    max = m_terrain->GetFlatZoneRadius(center, radius);
    if ( max < radius )  // area too small?
    {
        if ( bLittleFlat )
        {
            m_main->SetShowLimit(1, Gfx::PARTILIMIT3, m_metal, center, max, 10.0f);
        }
        return bLittleFlat?ERR_BUILD_FLATLIT:ERR_BUILD_FLAT;
    }

    max = 100000.0f;
    bBase = false;
    for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
    {
        if ( !pObj->GetActive() )  continue;  // inactive?
        if (IsObjectBeingTransported(pObj))  continue;
        if ( pObj == m_metal )  continue;
        if ( pObj == m_object )  continue;

        type = pObj->GetType();
        if ( type == OBJECT_BASE )
        {
            Math::Vector oPos = pObj->GetPosition();
            dist = Math::Distance(center, oPos)-80.0f;
            if ( dist < max )
            {
                max = dist;
                bPos = oPos;
                bRadius = 0.0f;
                bBase = true;
            }
        }
        else
        {
            for (const auto& crashSphere : pObj->GetAllCrashSpheres())
            {
                Math::Vector oPos = crashSphere.sphere.pos;
                float oRadius = crashSphere.sphere.radius;

                dist = Math::Distance(center, oPos)-oRadius;
                if ( dist < max )
                {
                    max = dist;
                    bPos = oPos;
                    bRadius = oRadius;
                    bBase = false;
                }
            }
        }
    }
    if ( max < radius )
    {
        m_main->SetShowLimit(1, Gfx::PARTILIMIT2, m_metal, center, max, 10.0f);
        if ( bRadius < 2.0f )  bRadius = 2.0f;
        m_main->SetShowLimit(2, Gfx::PARTILIMIT3, m_metal, bPos, bRadius, 10.0f);
        return bBase?ERR_BUILD_BASE:ERR_BUILD_BUSY;
    }

    max = 100000.0f;
    for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
    {
        if ( !pObj->GetActive() )  continue;  // inactive?
        if (IsObjectBeingTransported(pObj))  continue;
        if ( pObj == m_metal )  continue;
        if ( pObj == m_object )  continue;

        type = pObj->GetType();
        if ( type == OBJECT_DERRICK  ||
             type == OBJECT_FACTORY  ||
             type == OBJECT_STATION  ||
             type == OBJECT_CONVERT  ||
             type == OBJECT_REPAIR   ||
             type == OBJECT_TOWER    ||
             type == OBJECT_RESEARCH ||
             type == OBJECT_RADAR    ||
             type == OBJECT_ENERGY   ||
             type == OBJECT_LABO     ||
             type == OBJECT_NUCLEAR  ||
             type == OBJECT_DESTROYER||
             type == OBJECT_START    ||
             type == OBJECT_END      ||
             type == OBJECT_INFO     ||
             type == OBJECT_PARA     ||
             type == OBJECT_SAFE     ||
             type == OBJECT_HUSTON   )  // building?
        {
            for (const auto& crashSphere : pObj->GetAllCrashSpheres())
            {
                Math::Vector oPos = crashSphere.sphere.pos;
                float oRadius = crashSphere.sphere.radius;

                dist = Math::Distance(center, oPos)-oRadius;
                if ( dist < max )
                {
                    max = dist;
                    bPos = oPos;
                    bRadius = oRadius;
                }
            }
        }
    }
    if ( max-BUILDMARGIN < radius )
    {
        m_main->SetShowLimit(1, Gfx::PARTILIMIT2, m_metal, center, max-BUILDMARGIN, 10.0f);
        m_main->SetShowLimit(2, Gfx::PARTILIMIT3, m_metal, bPos, bRadius+BUILDMARGIN, 10.0f);
        return bBase?ERR_BUILD_BASE:ERR_BUILD_NARROW;
    }

    return ERR_OK;
}
Beispiel #12
0
bool CObjectCondition::CheckForObject(CObject* obj)
{
    if (!this->countTransported)
    {
        if (IsObjectBeingTransported(obj)) return false;
    }

    ObjectType type = obj->GetType();

    ToolType tool = GetToolFromObject(type);
    DriveType drive = GetDriveFromObject(type);
    if (this->tool != ToolType::Other &&
        tool != this->tool)
        return false;

    if (this->drive != DriveType::Other &&
        drive != this->drive)
        return false;

    if (this->tool == ToolType::Other &&
        this->drive == DriveType::Other &&
        type != this->type &&
        this->type != OBJECT_NULL)
        return false;

    if ((this->team > 0 && obj->GetTeam() != this->team) ||
        (this->team < 0 && (obj->GetTeam() == -(this->team) || obj->GetTeam() == 0)))
        return false;

    float energyLevel = -1;
    CPowerContainerObject* power = nullptr;
    if (obj->Implements(ObjectInterfaceType::PowerContainer))
    {
        power = dynamic_cast<CPowerContainerObject*>(obj);
    }
    else if (obj->Implements(ObjectInterfaceType::Powered))
    {
        CObject* powerObj = dynamic_cast<CPoweredObject*>(obj)->GetPower();
        if(powerObj != nullptr && powerObj->Implements(ObjectInterfaceType::PowerContainer))
        {
            power = dynamic_cast<CPowerContainerObject*>(powerObj);
        }
    }

    if (power != nullptr)
    {
        energyLevel = power->GetEnergy();
        if (power->GetCapacity() > 1.0f) energyLevel *= 10; // TODO: Who designed it like that ?!?!
    }
    if (energyLevel < this->powermin || energyLevel > this->powermax) return false;

    Math::Vector oPos;
    if (IsObjectBeingTransported(obj))
        oPos = dynamic_cast<CTransportableObject*>(obj)->GetTransporter()->GetPosition();
    else
        oPos = obj->GetPosition();
    oPos.y = 0.0f;

    Math::Vector bPos = this->pos;
    bPos.y = 0.0f;

    if (Math::DistanceProjected(oPos, bPos) <= this->dist)
        return true;

    return false;
}