Пример #1
0
float CStructure::VisibleRange() const
{
	if (IsConstructing())
		return GetBoundingRadius()*2;

	return BaseClass::VisibleRange();
}
Пример #2
0
float CSupplier::AvailableArea(int iArea) const
{
	if (iArea == 1)
		return GetDataFlowRadius() + GetBoundingRadius();

	return BaseClass::AvailableArea(iArea);
}
Пример #3
0
void CDigitanksEntity::InterceptSupplyLines()
{
	// Haha... no.
	if (dynamic_cast<CSupplyLine*>(this))
		return;

	if (!GetPlayerOwner())
		return;

	for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++)
	{
		CBaseEntity* pEntity = CBaseEntity::GetEntity(i);
		if (!pEntity)
			continue;

		CSupplyLine* pSupplyLine = dynamic_cast<CSupplyLine*>(pEntity);
		if (!pSupplyLine)
			continue;

		if (pSupplyLine->GetPlayerOwner() == GetPlayerOwner())
			continue;

		if (!pSupplyLine->GetPlayerOwner())
			continue;

		if (!pSupplyLine->GetSupplier() || !pSupplyLine->GetEntity())
			continue;

		Vector vecEntity = GetGlobalOrigin();
		vecEntity.z = 0;

		Vector vecSupplier = pSupplyLine->GetSupplier()->GetGlobalOrigin();
		vecSupplier.z = 0;

		Vector vecUnit = pSupplyLine->GetEntity()->GetGlobalOrigin();
		vecUnit.z = 0;

		if (DistanceToLineSegment(vecEntity, vecSupplier, vecUnit) > GetBoundingRadius()+4)
			continue;

		bool bFound = false;
		for (size_t j = 0; j < m_ahSupplyLinesIntercepted.size(); j++)
		{
			if (pSupplyLine == m_ahSupplyLinesIntercepted[j])
			{
				bFound = true;
				break;
			}
		}

		if (!bFound)
		{
			pSupplyLine->Intercept(0.2f);
			m_ahSupplyLinesIntercepted.push_back(pSupplyLine);
		}
	}
}
Пример #4
0
bool Entity::HasCollidedWith(Entity* other)
{
  double distanceSqr = GetPosition().DistanceToSqr(other->GetPosition());
  
  double totalRadius = GetBoundingRadius() + other->GetBoundingRadius();
  double totalRadiusSqr = totalRadius * totalRadius;

  return distanceSqr < totalRadiusSqr;
}
Пример #5
0
void CStructure::FindGround()
{
	float flHeight = DigitanksGame()->GetTerrain()->GetHeight(GetGlobalOrigin().x, GetGlobalOrigin().y);
	float flCornerHeight;

	flCornerHeight = DigitanksGame()->GetTerrain()->GetHeight(GetGlobalOrigin().x + GetBoundingRadius(), GetGlobalOrigin().y + GetBoundingRadius());
	if (flCornerHeight > flHeight)
		flHeight = flCornerHeight;

	flCornerHeight = DigitanksGame()->GetTerrain()->GetHeight(GetGlobalOrigin().x + GetBoundingRadius(), GetGlobalOrigin().y - GetBoundingRadius());
	if (flCornerHeight > flHeight)
		flHeight = flCornerHeight;

	flCornerHeight = DigitanksGame()->GetTerrain()->GetHeight(GetGlobalOrigin().x - GetBoundingRadius(), GetGlobalOrigin().y + GetBoundingRadius());
	if (flCornerHeight > flHeight)
		flHeight = flCornerHeight;

	flCornerHeight = DigitanksGame()->GetTerrain()->GetHeight(GetGlobalOrigin().x - GetBoundingRadius(), GetGlobalOrigin().y - GetBoundingRadius());
	if (flCornerHeight > flHeight)
		flHeight = flCornerHeight;

	SetGlobalOrigin(Vector(GetGlobalOrigin().x, GetGlobalOrigin().y, flHeight + GetBoundingRadius()/2 + 2));
}
Пример #6
0
bool D_PAD::HitTest( const wxPoint& aPosition )
{
    int     dx, dy;
    double  dist;

    wxPoint shape_pos = ReturnShapePos();

    wxPoint delta = aPosition - shape_pos;

    // first test: a test point must be inside a minimum sized bounding circle.
    int radius = GetBoundingRadius();

    if( ( abs( delta.x ) > radius ) || ( abs( delta.y ) > radius ) )
        return false;

    dx = m_Size.x >> 1; // dx also is the radius for rounded pads
    dy = m_Size.y >> 1;

    switch( m_PadShape & 0x7F )
    {
    case PAD_CIRCLE:
        dist = hypot( delta.x, delta.y );

        if( KiROUND( dist ) <= dx )
            return true;

        break;

    case PAD_TRAPEZOID:
    {
        wxPoint poly[4];
        BuildPadPolygon( poly, wxSize(0,0), 0 );
        RotatePoint( &delta, -m_Orient );
        return TestPointInsidePolygon( poly, 4, delta );
    }

    default:
        RotatePoint( &delta, -m_Orient );

        if( (abs( delta.x ) <= dx ) && (abs( delta.y ) <= dy) )
            return true;

        break;
    }

    return false;
}
Пример #7
0
void DynamicBody::CalcExternalForce()
{
	// gravity
	Body *body = GetFrame()->GetBodyFor();
	if (body && !body->IsType(Object::SPACESTATION)) {	// they ought to have mass though...
		vector3d b1b2 = GetPosition();
		double m1m2 = GetMass() * body->GetMass();
		double invrsqr = 1.0 / b1b2.LengthSqr();
		double force = G*m1m2 * invrsqr;
		m_externalForce = -b1b2 * sqrt(invrsqr) * force;
	}
	else m_externalForce = vector3d(0.0);
	m_gravityForce = m_externalForce;

	// atmospheric drag
	const double speed = m_vel.Length();
	if ((speed > 0) && body && body->IsType(Object::PLANET))
	{
		Planet *planet = static_cast<Planet*>(body);
		double dist = GetPosition().Length();
		double pressure, density;
		planet->GetAtmosphericState(dist, &pressure, &density);
		const double radius = GetBoundingRadius();
		const double AREA = radius;
		// ^^^ yes that is as stupid as it looks
		const double DRAG_COEFF = 0.1; // 'smooth sphere'
		vector3d dragDir = -m_vel.Normalized();
		vector3d fDrag = 0.5*density*speed*speed*AREA*DRAG_COEFF*dragDir;

		// make this a bit less daft at high time accel
		// only allow atmosForce to increase by .1g per frame
		vector3d f1g = m_atmosForce + dragDir * GetMass();
		if (fDrag.LengthSqr() > f1g.LengthSqr()) m_atmosForce = f1g;
		else m_atmosForce = fDrag;

		m_externalForce += m_atmosForce;
	}

	// centrifugal and coriolis forces for rotating frames
	vector3d angRot = GetFrame()->GetAngVelocity();
	if (angRot.LengthSqr() > 0.0) {
		m_externalForce -= m_mass * angRot.Cross(angRot.Cross(GetPosition()));	// centrifugal
		m_externalForce -= 2 * m_mass * angRot.Cross(GetVelocity());			// coriolis
	}

}
Пример #8
0
bool D_PAD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
    EDA_RECT arect = aRect;
    arect.Normalize();
    arect.Inflate( aAccuracy );

    wxPoint shapePos = ShapePos();

    EDA_RECT shapeRect;

    int r;

    EDA_RECT bb = GetBoundingBox();

    wxPoint endCenter;
    int radius;

    if( !arect.Intersects( bb ) )
        return false;

    // This covers total containment for all test cases
    if( arect.Contains( bb ) )
        return true;

    switch( GetShape() )
    {
    case PAD_SHAPE_CIRCLE:
        return arect.IntersectsCircle( GetPosition(), GetBoundingRadius() );
    case PAD_SHAPE_RECT:
        shapeRect.SetOrigin( shapePos );
        shapeRect.Inflate( m_Size.x / 2, m_Size.y / 2 );
        return arect.Intersects( shapeRect, m_Orient );
    case PAD_SHAPE_OVAL:

        // Circlular test if dimensions are equal
        if( m_Size.x == m_Size.y )
            return arect.IntersectsCircle( shapePos, GetBoundingRadius() );

        shapeRect.SetOrigin( shapePos );

        // Horizontal dimension is greater
        if( m_Size.x > m_Size.y )
        {
            radius = m_Size.y / 2;

            shapeRect.Inflate( m_Size.x / 2 - radius, radius );

            endCenter = wxPoint( m_Size.x / 2 - radius, 0 );
            RotatePoint( &endCenter, m_Orient );

            // Test circular ends
            if( arect.IntersectsCircle( shapePos + endCenter, radius ) ||
                arect.IntersectsCircle( shapePos - endCenter, radius ) )
            {
                return true;
            }
        }
        else
        {
            radius = m_Size.x / 2;

            shapeRect.Inflate( radius, m_Size.y / 2 - radius );

            endCenter = wxPoint( 0, m_Size.y / 2 - radius );
            RotatePoint( &endCenter, m_Orient );

            // Test circular ends
            if( arect.IntersectsCircle( shapePos + endCenter, radius ) ||
                arect.IntersectsCircle( shapePos - endCenter, radius ) )
            {
                return true;
            }
        }

        // Test rectangular portion between rounded ends
        if( arect.Intersects( shapeRect, m_Orient ) )
        {
            return true;
        }

        break;
    case PAD_SHAPE_TRAPEZOID:
        /* Trapezoid intersection tests:
         * A) Any points of rect inside trapezoid
         * B) Any points of trapezoid inside rect
         * C) Any sides of trapezoid cross rect
         */
        {

        wxPoint poly[4];
        BuildPadPolygon( poly, wxSize( 0, 0 ), 0 );

        wxPoint corners[4];

        corners[0] = wxPoint( arect.GetLeft(),  arect.GetTop() );
        corners[1] = wxPoint( arect.GetRight(), arect.GetTop() );
        corners[2] = wxPoint( arect.GetRight(), arect.GetBottom() );
        corners[3] = wxPoint( arect.GetLeft(),  arect.GetBottom() );

        for( int i=0; i<4; i++ )
        {
            RotatePoint( &poly[i], m_Orient );
            poly[i] += shapePos;
        }

        for( int ii=0; ii<4; ii++ )
        {
            if( TestPointInsidePolygon( poly, 4, corners[ii] ) )
            {
                return true;
            }

            if( arect.Contains( poly[ii] ) )
            {
                return true;
            }

            if( arect.Intersects( poly[ii], poly[(ii+1) % 4] ) )
            {
                return true;
            }
        }

        return false;

        }
    case PAD_SHAPE_ROUNDRECT:
        /* RoundRect intersection can be broken up into simple tests:
         * a) Test intersection of horizontal rect
         * b) Test intersection of vertical rect
         * c) Test intersection of each corner
         */


        r = GetRoundRectCornerRadius();

        /* Test A - intersection of horizontal rect */
        shapeRect.SetSize( 0, 0 );
        shapeRect.SetOrigin( shapePos );
        shapeRect.Inflate( m_Size.x / 2, m_Size.y / 2 - r );

        // Short-circuit test for zero width or height
        if( shapeRect.GetWidth() > 0 && shapeRect.GetHeight() > 0 &&
            arect.Intersects( shapeRect, m_Orient ) )
        {
            return true;
        }

        /* Test B - intersection of vertical rect */
        shapeRect.SetSize( 0, 0 );
        shapeRect.SetOrigin( shapePos );
        shapeRect.Inflate( m_Size.x / 2 - r, m_Size.y / 2 );

        // Short-circuit test for zero width or height
        if( shapeRect.GetWidth() > 0 && shapeRect.GetHeight() > 0 &&
            arect.Intersects( shapeRect, m_Orient ) )
        {
            return true;
        }

        /* Test C - intersection of each corner */

        endCenter = wxPoint( m_Size.x / 2 - r, m_Size.y / 2 - r );
        RotatePoint( &endCenter, m_Orient );

        if( arect.IntersectsCircle( shapePos + endCenter, r ) ||
            arect.IntersectsCircle( shapePos - endCenter, r ) )
        {
            return true;
        }

        endCenter = wxPoint( m_Size.x / 2 - r, -m_Size.y / 2 + r );
        RotatePoint( &endCenter, m_Orient );

        if( arect.IntersectsCircle( shapePos + endCenter, r ) ||
            arect.IntersectsCircle( shapePos - endCenter, r ) )
        {
            return true;
        }

        break;
    default:
        break;
    }

    return false;
}
Пример #9
0
bool D_PAD::HitTest( const wxPoint& aPosition ) const
{
    int dx, dy;

    wxPoint shape_pos = ShapePos();

    wxPoint delta = aPosition - shape_pos;

    // first test: a test point must be inside a minimum sized bounding circle.
    int radius = GetBoundingRadius();

    if( ( abs( delta.x ) > radius ) || ( abs( delta.y ) > radius ) )
        return false;

    dx = m_Size.x >> 1; // dx also is the radius for rounded pads
    dy = m_Size.y >> 1;

    switch( GetShape() )
    {
    case PAD_SHAPE_CIRCLE:
        if( KiROUND( EuclideanNorm( delta ) ) <= dx )
            return true;

        break;

    case PAD_SHAPE_TRAPEZOID:
    {
        wxPoint poly[4];
        BuildPadPolygon( poly, wxSize(0,0), 0 );
        RotatePoint( &delta, -m_Orient );

        return TestPointInsidePolygon( poly, 4, delta );
    }

    case PAD_SHAPE_OVAL:
    {
        RotatePoint( &delta, -m_Orient );
        // An oval pad has the same shape as a segment with rounded ends
        // After rotation, the test point is relative to an horizontal pad
        int dist;
        wxPoint offset;
        if( dy > dx )   // shape is a vertical oval
        {
            offset.y = dy - dx;
            dist = dx;
        }
        else    //if( dy <= dx ) shape is an horizontal oval
        {
            offset.x = dy - dx;
            dist = dy;
        }
        return TestSegmentHit( delta, - offset, offset, dist );
    }
        break;

    case PAD_SHAPE_RECT:
        RotatePoint( &delta, -m_Orient );

        if( (abs( delta.x ) <= dx ) && (abs( delta.y ) <= dy) )
            return true;

        break;

    case PAD_SHAPE_ROUNDRECT:
    {
        // Check for hit in polygon
        SHAPE_POLY_SET outline;
        const int segmentToCircleCount = 32;
        TransformRoundRectToPolygon( outline, wxPoint(0,0), GetSize(), m_Orient,
                                 GetRoundRectCornerRadius(), segmentToCircleCount );

        const SHAPE_LINE_CHAIN &poly = outline.COutline( 0 );
        return TestPointInsidePolygon( (const wxPoint*)&poly.CPoint(0), poly.PointCount(), delta );
    }
        break;

    case PAD_SHAPE_CUSTOM:
        // Check for hit in polygon
        RotatePoint( &delta, -m_Orient );

        if( m_customShapeAsPolygon.OutlineCount() )
        {
            const SHAPE_LINE_CHAIN& poly = m_customShapeAsPolygon.COutline( 0 );
            return TestPointInsidePolygon( (const wxPoint*)&poly.CPoint(0), poly.PointCount(), delta );
        }
        break;
    }

    return false;
}
Пример #10
0
void CDigitanksEntity::OnRender(CGameRenderingContext* pContext) const
{
	BaseClass::OnRender(pContext);

	if (GameServer()->GetRenderer()->IsRenderingTransparent() && IsImprisoned())
	{
		CGameRenderingContext c(GameServer()->GetRenderer(), true);
		c.SetBackCulling(false);
		c.SetBlend(BLEND_ADDITIVE);
		c.Scale(GetBoundingRadius(), GetBoundingRadius(), GetBoundingRadius());
		c.Rotate((float)GameServer()->GetGameTime() * 90, Vector(0, 0, 1));

		float flVisibility = GetVisibility() * 0.6f;
		c.UseProgram("scroll");
		c.SetUniform("iTexture", 0);
		c.SetUniform("flAlpha", flVisibility);
		c.SetUniform("flTime", (float)-GameServer()->GetGameTime());
		c.SetUniform("flSpeed", 1.0f);

		c.RenderModel(m_iCageModel, this);
	}

	if (GameServer()->GetRenderer()->IsRenderingTransparent() && IsImprisoned())
	{
		CGameRenderingContext c(GameServer()->GetRenderer(), true);
		c.SetBackCulling(false);
		c.SetBlend(BLEND_ADDITIVE);
		c.Scale(GetBoundingRadius()+1, GetBoundingRadius()+1, GetBoundingRadius()+1);
		c.Rotate(-(float)GameServer()->GetGameTime() * 90, Vector(0, 0, 1));

		float flVisibility = GetVisibility() * 0.6f;
		c.UseProgram("scroll");
		c.SetUniform("iTexture", 0);
		c.SetUniform("flAlpha", flVisibility);
		c.SetUniform("flTime", (float)-GameServer()->GetGameTime());
		c.SetUniform("flSpeed", 1.0f);

		c.RenderModel(m_iCageModel);
	}

	if (!GameServer()->GetRenderer()->IsRenderingTransparent())
		return;

	if (!DigitanksGame()->GetTerrain()->GetBit(CTerrain::WorldToArraySpace(GetGlobalOrigin().x), CTerrain::WorldToArraySpace(GetGlobalOrigin().y), TB_TREE))
		return;

	if (GetVisibility() < 0.6f)
		return;

	CGameRenderingContext c(GameServer()->GetRenderer(), true);
	c.SetBlend(BLEND_NONE);
	c.SetAlpha(1);
	c.BindTexture(0);

	TStubbed("Tank outlines in trees");

	/*
	// Draw outlines of objects in trees.
	glPushAttrib( GL_ALL_ATTRIB_BITS );

	glDisable( GL_TEXTURE_2D );
	glEnable( GL_POLYGON_OFFSET_FILL );
	glPolygonOffset( -3.5f, -3.5f );

	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
	glDepthMask(true);
	glEnable(GL_DEPTH_TEST);
	pContext->RenderModel(GetModel());

	glDisable( GL_POLYGON_OFFSET_FILL );
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	glDepthMask(false);
	glEnable(GL_DEPTH_TEST);
	glLineWidth( 2.0f );
	glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
	glColor3ubv( Color(0, 0, 0) );
	pContext->RenderModel(GetModel());

	glPopAttrib();
	*/
}
Пример #11
0
void CSupplier::PostRender() const
{
	BaseClass::PostRender();

	if (!GameServer()->GetRenderer()->IsRenderingTransparent())
		return;

	float flGrowthTime = (float)(GameServer()->GetGameTime() - m_flTendrilGrowthStartTime);

	if (flGrowthTime < 0)
		return;

	if (m_flTendrilGrowthStartTime == 0)
	{
		DigitanksGame()->GetDigitanksRenderer()->AddTendrilBatch(this);
		return;
	}

	COverheadCamera* pCamera = DigitanksGame()->GetOverheadCamera();
	Vector vecCamera = pCamera->GetGlobalOrigin();
	float flDistanceSqr = GetGlobalOrigin().DistanceSqr(vecCamera);
	float flFadeDistance = tendril_fade_distance.GetFloat();

	float flFadeAlpha = RemapValClamped(flDistanceSqr, flFadeDistance*flFadeDistance, (flFadeDistance+20)*(flFadeDistance+20), 1.0f, 0.0f);

	if (flFadeAlpha <= 0)
		return;

	float flTreeAlpha = 1.0f;
	if (DigitanksGame()->GetTerrain()->GetBit(CTerrain::WorldToArraySpace(GetGlobalOrigin().x), CTerrain::WorldToArraySpace(GetGlobalOrigin().y), TB_TREE))
		flTreeAlpha = 0.3f;

	CRenderingContext r(GameServer()->GetRenderer(), true);
	if (DigitanksGame()->ShouldRenderFogOfWar())
		r.UseFrameBuffer(DigitanksGame()->GetDigitanksRenderer()->GetVisibilityMaskedBuffer());
	r.SetDepthMask(false);
	r.UseMaterial(s_hTendrilBeam);

	r.SetUniform("flTime", (float)GameServer()->GetGameTime());
	r.SetUniform("iTexture", 0);
	r.SetUniform("flAlpha", flFadeAlpha * flTreeAlpha);

	Color clrTeam = GetPlayerOwner()?GetPlayerOwner()->GetColor():Color(255,255,255,255);
	clrTeam = (Vector(clrTeam) + Vector(1,1,1))/2;

	if (m_flTendrilGrowthStartTime > 0)
	{
		float flTotalSize = (float)m_aTendrils.size() + GetBoundingRadius();

		for (size_t i = 0; i < m_aTendrils.size(); i++)
		{
			if (i < m_aTendrils.size() - 15)
				continue;

			const CTendril* pTendril = &m_aTendrils[i];

			float flGrowthLength = RemapVal(flGrowthTime, 0, GROWTH_TIME, pTendril->m_flLength-flTotalSize, pTendril->m_flLength);

			if (flGrowthLength < 0)
				continue;

			Vector vecDestination = GetGlobalOrigin() + (pTendril->m_vecEndPoint - GetGlobalOrigin()).Normalized() * flGrowthLength;

			Vector vecPath = vecDestination - GetGlobalOrigin();
			vecPath.y = 0;

			float flDistance = vecPath.Length2D();
			Vector vecDirection = vecPath.Normalized();
			size_t iSegments = (size_t)(flDistance/3);

			r.SetUniform("flSpeed", pTendril->m_flSpeed);

			clrTeam.SetAlpha(105);

			CRopeRenderer oRope(GameServer()->GetRenderer(), s_hTendrilBeam, DigitanksGame()->GetTerrain()->GetPointHeight(GetGlobalOrigin()) + Vector(0, 0, 1), 1.0f);
			oRope.SetColor(clrTeam);
			oRope.SetTextureScale(pTendril->m_flScale);
			oRope.SetTextureOffset(pTendril->m_flOffset);
			oRope.SetForward(Vector(0, 0, -1));

			for (size_t i = 1; i < iSegments; i++)
			{
				clrTeam.SetAlpha((int)RemapVal((float)i, 1, (float)iSegments, 100, 30));
				oRope.SetColor(clrTeam);

				float flCurrentDistance = ((float)i*flDistance)/iSegments;
				oRope.AddLink(DigitanksGame()->GetTerrain()->GetPointHeight(GetGlobalOrigin() + vecDirection*flCurrentDistance) + Vector(0, 0, 1));
			}

			oRope.Finish(DigitanksGame()->GetTerrain()->GetPointHeight(vecDestination) + Vector(0, 0, 1));
		}
	}
}
Пример #12
0
void CSupplier::UpdateTendrils()
{
	if (IsConstructing())
		return;

	TStubbed("Tendrils");
#if 0
	if (!GetPlayerOwner())
	{
		if (m_iTendrilsCallList)
			glDeleteLists((GLuint)m_iTendrilsCallList, 1);

		m_iTendrilsCallList = 0;

		DigitanksGame()->GetTerrain()->DirtyChunkTexturesWithinDistance(GetGlobalOrigin(), GetDataFlowRadius() + GetBoundingRadius());
		return;
	}

	if (GameServer()->IsLoading())
		return;

	bool bUpdateTerrain = false;
	size_t iRadius = (size_t)GetDataFlowRadius();
	while (m_aTendrils.size() < iRadius)
	{
		m_aTendrils.push_back(CTendril());
		CTendril* pTendril = &m_aTendrils[m_aTendrils.size()-1];
		pTendril->m_flLength = (float)m_aTendrils.size() + GetBoundingRadius();
		pTendril->m_vecEndPoint = DigitanksGame()->GetTerrain()->GetPointHeight(GetGlobalOrigin() + AngleVector(EAngle(0, RandomFloat(0, 360), 0)) * pTendril->m_flLength);
		pTendril->m_flScale = RandomFloat(3, 7);
		pTendril->m_flOffset = RandomFloat(0, 1);
		pTendril->m_flSpeed = RandomFloat(0.5f, 2);

		bUpdateTerrain = true;
	}

	if (bUpdateTerrain)
		DigitanksGame()->GetTerrain()->DirtyChunkTexturesWithinDistance(GetGlobalOrigin(), GetDataFlowRadius() + GetBoundingRadius());

	if (m_iTendrilsCallList)
		glDeleteLists((GLuint)m_iTendrilsCallList, 1);

	m_iTendrilsCallList = glGenLists(1);

	Color clrTeam = GetPlayerOwner()->GetColor();
	clrTeam = (Vector(clrTeam) + Vector(1,1,1))/2;

	glNewList((GLuint)m_iTendrilsCallList, GL_COMPILE);
	for (size_t i = 0; i < m_aTendrils.size(); i++)
	{
		// Only show the longest tendrils, for perf reasons.
		if (i < iRadius - 15)
			continue;

		CTendril* pTendril = &m_aTendrils[i];

		Vector vecDestination = pTendril->m_vecEndPoint;

		Vector vecPath = vecDestination - GetGlobalOrigin();
		vecPath.y = 0;

		float flDistance = vecPath.Length2D();
		Vector vecDirection = vecPath.Normalized();
		size_t iSegments = (size_t)(flDistance/3);

		GLuint iScrollingTextureProgram = (GLuint)CShaderLibrary::GetScrollingTextureProgram();

		GLuint flSpeed = glGetUniformLocation(iScrollingTextureProgram, "flSpeed");
		glUniform1f(flSpeed, pTendril->m_flSpeed);

		clrTeam.SetAlpha(105);

		CRopeRenderer oRope(GameServer()->GetRenderer(), s_iTendrilBeam, DigitanksGame()->GetTerrain()->GetPointHeight(GetGlobalOrigin()) + Vector(0, 0, 1), 1.0f);
		oRope.SetColor(clrTeam);
		oRope.SetTextureScale(pTendril->m_flScale);
		oRope.SetTextureOffset(pTendril->m_flOffset);
		oRope.SetForward(Vector(0, 0, -1));

		for (size_t i = 1; i < iSegments; i++)
		{
			clrTeam.SetAlpha((int)RemapVal((float)i, 1, (float)iSegments, 100, 30));
			oRope.SetColor(clrTeam);

			float flCurrentDistance = ((float)i*flDistance)/iSegments;
			oRope.AddLink(DigitanksGame()->GetTerrain()->GetPointHeight(GetGlobalOrigin() + vecDirection*flCurrentDistance) + Vector(0, 0, 1));
		}

		oRope.Finish(DigitanksGame()->GetTerrain()->GetPointHeight(vecDestination) + Vector(0, 0, 1));
	}
	glEndList();
#endif
}
Пример #13
0
float CSupplier::GetDataFlow(Vector vecPoint) const
{
	return RemapValClamped((vecPoint - GetGlobalOrigin()).Length(), GetBoundingRadius(), GetDataFlowRadius()+GetBoundingRadius(), (float)m_iDataStrength, 0);
}
Пример #14
0
float CSupplier::GetDataFlowRadius() const
{
	// Opposite of formula for area of a circle.
	return sqrt((float)m_iDataStrength.Get()/M_PI) + GetBoundingRadius();
}
Пример #15
0
float CStructure::AvailableArea(int iArea) const
{
	return GetBoundingRadius();
}
Пример #16
0
bool D_PAD::HitTest( const wxPoint& aPosition ) const
{
    int     dx, dy;

    wxPoint shape_pos = ShapePos();

    wxPoint delta = aPosition - shape_pos;

    // first test: a test point must be inside a minimum sized bounding circle.
    int radius = GetBoundingRadius();

    if( ( abs( delta.x ) > radius ) || ( abs( delta.y ) > radius ) )
        return false;

    dx = m_Size.x >> 1; // dx also is the radius for rounded pads
    dy = m_Size.y >> 1;

    switch( GetShape() )
    {
    case PAD_SHAPE_CIRCLE:
        if( KiROUND( EuclideanNorm( delta ) ) <= dx )
            return true;

        break;

    case PAD_SHAPE_TRAPEZOID:
    {
        wxPoint poly[4];
        BuildPadPolygon( poly, wxSize(0,0), 0 );
        RotatePoint( &delta, -m_Orient );
        return TestPointInsidePolygon( poly, 4, delta );
    }

    case PAD_SHAPE_OVAL:
    {
        RotatePoint( &delta, -m_Orient );
        // An oval pad has the same shape as a segment with rounded ends
        // After rotation, the test point is relative to an horizontal pad
        int dist;
        wxPoint offset;
        if( dy > dx )   // shape is a vertical oval
        {
            offset.y = dy - dx;
            dist = dx;
        }
        else    //if( dy <= dx ) shape is an horizontal oval
        {
            offset.x = dy - dx;
            dist = dy;
        }
        return TestSegmentHit( delta, - offset, offset, dist );
    }
        break;

    case PAD_SHAPE_RECT:
        RotatePoint( &delta, -m_Orient );

        if( (abs( delta.x ) <= dx ) && (abs( delta.y ) <= dy) )
            return true;

        break;
    }

    return false;
}
Пример #17
0
void CSupplier::OnTeamChange()
{
	if (!GetPlayerOwner())
	{
		for (size_t i = 0; i < m_ahChildren.size(); i++)
		{
			if (!m_ahChildren[i])
				continue;

			m_ahChildren[i]->SetSupplier(NULL);

			CStructure* pStructure = dynamic_cast<CStructure*>(m_ahChildren[i].GetPointer());
			if (!pStructure)
				continue;

			if (pStructure->GetPlayerOwner())
			{
				pStructure->GetPlayerOwner()->RemoveUnit(pStructure);
				DigitanksGame()->OnDisabled(pStructure, NULL, NULL);
			}
		}
	}

	BaseClass::OnTeamChange();
	UpdateTendrils();

	// This happens in UpdateTendrils() but do it again here anyway because UpdateTendrils only does it if there's a new tendril created.
	DigitanksGame()->GetTerrain()->DirtyChunkTexturesWithinDistance(GetGlobalOrigin(), GetDataFlowRadius() + GetBoundingRadius());
}