int BrigadeClass::RallyUnit (int minutes)
	{
	Unit	e;
	int		rallied = 1;
	int		role, gotnon = 0;

	role = GetUnitNormalRole();
	e = GetFirstUnitElement();
	while (e)
		{
		if (e->RallyUnit(minutes))
			rallied = 0;
		if (role != GRO_FIRESUPPORT && e->GetUnitNormalRole() != GRO_FIRESUPPORT)
			gotnon = 1;
		e = GetNextUnitElement();
		}

	// KCK: We're going to convert Infantry/Armored/Etc Brigades which have lost all combat
	// battalions into another brigade type (ie: Artillery, if that's all that's left). This
	// Will allow the artillery to then do something usefull rather than sitting on reserve
	// missions
	if (!gotnon && role != GRO_FIRESUPPORT)
		{
		e = GetFirstUnitElement();
		if (e)
			SetUnitSType(e->GetSType());
		}

	if (rallied)
		SetBroken(0);

	return Broken();
	}
bool CVXS_Bond::UpdateBondStrain(vfloat CurStrainIn)
{
	CurStrain = CurStrainIn;

	//Single material optimize possibilities
	if (!p_Sim->IsPlasticityEnabled() || CurStrainIn >= MaxStrain){ //if we're in new territory on the stress-strain curve or plasticity is not enabled...
		MaxStrain = CurStrainIn; //set the high-water mark on the strains

		if (HomogenousBond){
			bool TmpYielded, TmpBroken;
			CurStress = pVox1->CalcVoxMatStress(CurStrainIn, &TmpYielded, &TmpBroken);
			if (!Yielded && TmpYielded) SetYielded(); //if any part of the bond yielded, its all yielded
			if (!Broken && TmpBroken) SetBroken(); //if any part of the bond broke, its all broke

			//Update the rest distance for the voxels...
			if (p_Sim->IsPlasticityEnabled())
				RestDist = OrigDist*(1+(MaxStrain - CurStress/E));

		}
		else {
			//All this to set CurStrain, bond yield/broken		
			vfloat Stress1, Stress2;
			bool Yielded1, Yielded2, Broken1, Broken2;
		

			vfloat Strain1 = CurStrainIn; //initial guesses at strains
			vfloat Strain2 = CurStrainIn;

			//get stiffness of each voxel in question...
			Stress1 = pVox1->CalcVoxMatStress(Strain1, &Yielded1, &Broken1);
			Stress2 = pVox2->CalcVoxMatStress(Strain2, &Yielded2, &Broken2);

			int MaxCount = 3;
			int count = 0;
			vfloat StressDiff = (Stress1 >= Stress2) ? Stress1-Stress2 : Stress2-Stress1;
			vfloat StressSum = Stress1+Stress2;
			if (StressSum<0) StressSum = -StressSum;

			while (StressDiff > StressSum*.0005 && count<MaxCount){ //refine guesses at the strains until difference is less than .05% of average stress
				Strain1 = 2*Stress2/(Stress1+Stress2)*Strain1;
				Strain2 = 2*Stress1/(Stress1+Stress2)*Strain2;

				Stress1 = pVox1->CalcVoxMatStress(Strain1, &Yielded1, &Broken1);
				Stress2 = pVox2->CalcVoxMatStress(Strain2, &Yielded2, &Broken2);
				StressDiff = (Stress1 >= Stress2) ? Stress1-Stress2 : Stress2-Stress1; //recalc stressDiff
				StressSum = Stress1+Stress2;
				if (StressSum<0) StressSum = -StressSum;
				count++;
			}

			CurStress = (Stress1+Stress2)/2; //average just in case we didn't quite converge to the exact same stress

			if (!Yielded && (Yielded1 || Yielded2)) SetYielded(); //if any part of the bond yielded, its all yielded
			if (!Broken && (Broken1 || Broken2)) SetBroken(); //if any part of the bond broke, its all broke

			//Update the rest distance for the voxels...
			if (p_Sim->IsPlasticityEnabled())
				RestDist = OrigDist*(1+(MaxStrain - CurStress/E));

		}
	}
	else { //if we've backed off a max strain and linearly drop back down at the elastic modulus
		CurStress = E*(CurStrainIn-(sqrt(RestDist.Length2()/OrigDist.Length2())-1.0));
	}

	return true;
}
bool CVXS_BondInternal::UpdateBondStrain(vfloat CurStrainIn)
{
    CurStrainTot = CurStrainIn;
    bool IsPlasticityEnabled = p_Sim->IsFeatureEnabled(VXSFEAT_PLASTICITY);
    bool IsVolEffectsEnabled = p_Sim->IsFeatureEnabled(VXSFEAT_VOLUME_EFFECTS);

    //Single material optimize possibilities
    if (!IsPlasticityEnabled || CurStrainIn >= MaxStrain){ //if we're in new territory on the stress-strain curve or plasticity is not enabled...
        MaxStrain = CurStrainIn; //set the high-water mark on the strains
        bool CurYielded, CurBroken;

        if (HomogenousBond){
            if (IsVolEffectsEnabled){
                //		vfloat Eh = E/((1-2*u)*(1+u));
                CurStress = Eh*(1-u)*CurStrainIn + Eh*u*(TStrainSum1+TStrainSum2)/2; // - E*alpha*DTemp/(1-2*u);
            }
            else {
                CurStress = pVox1->CalcVoxMatStress(CurStrainIn, &CurYielded, &CurBroken);

            }
            CurStrainV1 = CurStrainV2 = CurStrainIn; //equal strains...
            MidPoint = 0.5;
            //if (!Yielded && CurYielded) SetYielded(); //if any part of the bond yielded, its all yielded
            //if (!Broken && CurBroken) SetBroken(); //if any part of the bond broke, its all broke

            //if (p_Sim->IsPlasticityEnabled()){RestDist = OrigDist*(1+(MaxStrain - CurStress/E));}	//Update the rest distance for the voxels...
        }
        //		else if(LinearBond){ //TODO: linear, but different materials
        //
        //		}
        else { //TODO: very inefficient
            if (IsVolEffectsEnabled){
                //		vfloat Eh = E/((1-2*u)*(1+u));
                CurStress = Eh*(1-u)*CurStrainIn + Eh*u*(TStrainSum1+TStrainSum2)/2; // - E*alpha*DTemp/(1-2*u);
            }
            else {
                //All this to set CurStrainTot, bond yield/broken
                vfloat Stress1, Stress2;
                bool Yielded1, Yielded2, Broken1, Broken2;


                CurStrainV1 = CurStrainIn; //initial guesses at strains (could be MUCH smarter based on current strains, but need to initialize correctly somewhere
                CurStrainV2 = CurStrainIn;

                //get stiffness of each voxel in question...
                Stress1 = pVox1->CalcVoxMatStress(CurStrainV1, &Yielded1, &Broken1);
                Stress2 = pVox2->CalcVoxMatStress(CurStrainV2, &Yielded2, &Broken2);

                int MaxCount = 3;
                int count = 0;
                vfloat StressDiff = (Stress1 >= Stress2) ? Stress1-Stress2 : Stress2-Stress1;
                vfloat StressSum = Stress1+Stress2;
                if (StressSum<0) StressSum = -StressSum;

                while (StressDiff > StressSum*.0005 && count<MaxCount){ //refine guesses at the strains until difference is less than .05% of average stress
                    CurStrainV1 = 2*Stress2/(Stress1+Stress2)*CurStrainV1;
                    CurStrainV2 = 2*Stress1/(Stress1+Stress2)*CurStrainV2;

                    Stress1 = pVox1->CalcVoxMatStress(CurStrainV1, &Yielded1, &Broken1);
                    Stress2 = pVox2->CalcVoxMatStress(CurStrainV2, &Yielded2, &Broken2);
                    StressDiff = (Stress1 >= Stress2) ? Stress1-Stress2 : Stress2-Stress1; //recalc stressDiff
                    StressSum = Stress1+Stress2;
                    if (StressSum<0) StressSum = -StressSum;
                    count++;
                }


                CurStress = (Stress1+Stress2)/2; //average just in case we didn't quite converge to the exact same stress
                CurYielded = Yielded1 || Yielded2;
                CurBroken = Broken1 || Broken2;

                //	if (!Yielded && (Yielded1 || Yielded2)) SetYielded(); //if any part of the bond yielded, its all yielded
                //	if (!Broken && (Broken1 || Broken2)) SetBroken(); //if any part of the bond broke, its all broke


                //			if (p_Sim->IsPlasticityEnabled()) RestDist = OrigDist*(1+(MaxStrain - CurStress/E)); //Update the rest distance for the voxels...

            }
        }

        if (!Yielded && CurYielded) SetYielded(); //if any part of the bond yielded, its all yielded
        if (!Broken && CurBroken) SetBroken(); //if any part of the bond broke, its all broke


        if (IsPlasticityEnabled) StrainOffset = MaxStrain - CurStress/E;

    }
    else { //if we've backed off a max strain and linearly drop back down at the elastic modulus
        //		CurStress = E*(CurStrainIn-(sqrt(RestDist.Length2()/OrigDist.Length2())-1.0));
        CurStress = E*(CurStrainIn-StrainOffset);

    }


    //Todo: clean this up? see if its worth it by profiling
    if(IsVolEffectsEnabled && p_Sim->IsFeatureEnabled(VXSFEAT_TEMPERATURE)){ // pEnv->IsTempEnabled()){
        //vfloat TempFact1 = 1.0, TempFact2 = 1.0;
        //		vfloat ThisTemp1 = p_Sim->pEnv->pObj->GetBaseMat(pVox1->GetMaterial())->GetCurMatTemp();
        //		vfloat ThisTemp2 = p_Sim->pEnv->pObj->GetBaseMat(pVox2->GetMaterial())->GetCurMatTemp();
        vfloat ThisTemp1 = pVox1->GetpMaterial()->GetCurMatTemp();
        vfloat ThisTemp2 = pVox2->GetpMaterial()->GetCurMatTemp();
        vfloat TempBase =  p_Sim->pEnv->GetTempBase();

        vfloat Stress1 = E1*CTE1*(ThisTemp1 - TempBase)/(1-2*u1);
        vfloat Stress2 = E2*CTE2*(ThisTemp2 - TempBase)/(1-2*u2);

        CurStress -= (Stress1 + Stress2)/2;

    }

    switch (ThisBondAxis){
    case AXIS_X: pVox1->SetStrainDir(BD_PX, CurStrainV1); pVox2->SetStrainDir(BD_NX, CurStrainV2); break;
    case AXIS_Y: pVox1->SetStrainDir(BD_PY, CurStrainV1); pVox2->SetStrainDir(BD_NY, CurStrainV2); break;
    case AXIS_Z: pVox1->SetStrainDir(BD_PZ, CurStrainV1); pVox2->SetStrainDir(BD_NZ, CurStrainV2); break;
    default: break;
    }

    return true;
}
int BrigadeClass::MoveUnit (CampaignTime time)
	{
	Unit			e;
	int				en,me,be,te,toorder,role;
	F4PFList		nearlist = NULL;
	Objective		o;
	
	// Check if we have a valid objective
	o = GetUnitObjective();
	if (!o || !TeamInfo[GetTeam()]->gtm->IsValidObjective(GetOrders(),o))
		{
		if (o && (GetOrders() == GORD_CAPTURE || GetOrders() == GORD_ASSAULT || GetOrders() == GORD_AIRBORNE))
			SetUnitOrders(GORD_SECURE,o->Id());
		else
			{
			o = FindRetreatPath(this,3,FIND_SECONDARYONLY);
			if (!o)
				{
				// We've been cut off - surrender?
				CheckForSurrender();
				return -1;
				}
			SetUnitOrders(GORD_RESERVE,o->Id());
			}
		}

	// Check if we have elements requesting orders
	role = GetUnitCurrentRole();
	toorder = te = 0;
	e = GetFirstUnitElement();
	while (e)
		{
		te++;
		if (!e->Assigned())
			toorder++;
		e = GetNextUnitElement();
		}
	if (!te)
		{
		KillUnit();
		return 0;
		}

	// Support brigades just update their position and return
	if (FindUnitSupportRole(this))
		{
		UpdateParentStatistics();
		return 0;
		}

	// Check to make sure our orders are still valid.
//	if (!CheckTactic(GetUnitTactic()))
	ChooseTactic();

	// Upon new orders, reset our element's ordered flags && collect list of possible positions
	if (Ordered() || toorder)
		{
		Objective	o;

		o = GetUnitObjective();
		if (role == GRO_ATTACK)
			nearlist = GetChildObjectives(o, MAXLINKS_FROM_SO_OFFENSIVE, FIND_STANDARDONLY);
		else
			nearlist = GetChildObjectives(o, MAXLINKS_FROM_SO_DEFENSIVE, FIND_STANDARDONLY);

		// Eliminate any objectives we've previously been unable to find a path to

		// Clear all but attack orders (once we attack, we only stop when we break)
		e = GetFirstUnitElement();
		while (e)
			{
			if (!e->Broken() && !e->Engaged() && e->Assigned() && e->GetUnitCurrentRole() != GRO_ATTACK)
				{
				e->SetAssigned(0);
				toorder++;
				}
			else if (e->Assigned() && !OnValidObjective(e, e->GetUnitCurrentRole(), nearlist))
				{
				e->SetAssigned(0);
				toorder++;
				}
			e = GetNextUnitElement();
			}

		// Loop in here until all our elements are assigned
		while (toorder)
			{
			// Order elements
			e = GetFirstUnitElement();
			while (e)
				{
				if (!e->Assigned())
					OrderElement(e, nearlist);
				e = GetNextUnitElement();
				}
			// Check for pre-empted elements
			for (en=toorder=0; en<te; en++)
				{
				e = GetUnitElement(en);
				if (e && !e->Assigned())
					toorder++;
				}
			}

		if (nearlist)
			{
			nearlist->DeInit();
			delete nearlist;
			nearlist = NULL;
			}
		}

	// Make sure at least somebody is doing our job
	for (me=be=en=0; en<te; en++)
	{
		e = GetUnitElement(en);
		if (e)
		{
			if (e->Broken())
			{
				be++;
			}
			else if (e->GetUnitCurrentRole() == role)
			{
				me++;
			}
		}
	}

	// Check for broken status
	if (be > me)
		SetBroken(1);

	// Check if we're still valid to perform our orders
	if (!me)
		{
		if (role == GRO_ATTACK)
			SetOrders (GORD_DEFEND);				// Switch to defense orders
		else if (GetOrders() != GORD_RESERVE)
			SetUnitObjective(FalconNullId);		// We'll pick a reserve location next time through
		}

	UpdateParentStatistics();

	return 0;
	}
Exemple #5
0
void MapUpdater::ReActivate(uint32 threads)
{
    deactivate();
    activate(threads);
    SetBroken(false);
}