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; }
void MapUpdater::ReActivate(uint32 threads) { deactivate(); activate(threads); SetBroken(false); }