Advertisement
Guest User

Spring Impulse Relevant Code

a guest
Jan 4th, 2013
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.17 KB | None | 0 0
  1. impulse and residualimpulse are float3
  2.  
  3. GlobalConstants.h
  4. ...
  5. /**
  6.  * maximum impulse strength an explosion is allowed to impart on a unit
  7.  */
  8. const float MAX_EXPLOSION_IMPULSE = 1e4f;
  9. ...
  10.  
  11. WeaponDefHandler.cpp
  12.     ...
  13.     wd.damages.impulseFactor = wdTable.GetFloat("impulseFactor", 1.0f);
  14.     wd.damages.impulseBoost  = wdTable.GetFloat("impulseBoost",  0.0f);
  15.     wd.damages.craterMult    = wdTable.GetFloat("craterMult",    wd.damages.impulseFactor);
  16.     wd.damages.craterBoost   = wdTable.GetFloat("craterBoost",   0.0f);
  17.     ...
  18.  
  19. GameHelper.cpp
  20. void CGameHelper::DoExplosionDamage
  21.     ...
  22.     const float rawImpulseStrength = damages.impulseFactor * mod1 * (damages.GetDefaultDamage() + damages.impulseBoost)
  23.     ...
  24. void CGameHelper::DoExplosionDamage(CFeature* feature,
  25.     const float3& expPos, float expRad, const DamageArray& damages)
  26.     ...
  27.     float dmgScale = (damages.GetDefaultDamage() + damages.impulseBoost);
  28.     ...
  29.  
  30. MeleeWeapon.cpp->FireImpl()
  31. {
  32.     if(targetType==Target_Unit){
  33.         float3 impulseDir = targetUnit->pos-weaponMuzzlePos;
  34.         impulseDir.Normalize();
  35.         // the heavier the unit, the more impulse it does
  36.         targetUnit->DoDamage(weaponDef->damages, owner, impulseDir * owner->mass * weaponDef->damages.impulseFactor, weaponDef->id);
  37.     }
  38. }
  39.  
  40. Unit.cpp
  41. void CUnit::Update()void CUnit::Update()
  42.     ...
  43.     // 0.968 ** 16 is slightly less than 0.6, which was the old value used in SlowUpdate
  44.     residualImpulse *= 0.968f;
  45.     ...
  46.  
  47. void CUnit::DoDamage(const DamageArray& damages, CUnit* attacker, const float3& impulse, int weaponDefId)
  48.     ...
  49.     float impulseMult = 1.0f;  
  50.     ...
  51.     AddImpulse((impulse * impulseMult) / mass);
  52.     ...
  53.  
  54. void CUnit::AddImpulse(const float3& addedImpulse) {
  55.     residualImpulse += addedImpulse;
  56.  
  57.     if (addedImpulse.SqLength() >= 0.01f) {
  58.         moveType->ImpulseAdded(addedImpulse);
  59.     }
  60. }
  61.  
  62. void CUnit::Kill(const float3& impulse, bool crushKill) {
  63.     crushKilled = crushKill;
  64.  
  65.     DamageArray damage;
  66.     DoDamage(damage * (health + 1.0f), NULL, impulse, -1);
  67. }
  68.  
  69. MeleeWeapon.cpp
  70. void CMeleeWeapon::FireImpl()
  71. {
  72.     if(targetType==Target_Unit){
  73.         float3 impulseDir = targetUnit->pos-weaponMuzzlePos;
  74.         impulseDir.Normalize();
  75.         // the heavier the unit, the more impulse it does
  76.         targetUnit->DoDamage(weaponDef->damages, owner, impulseDir * owner->mass * weaponDef->damages.impulseFactor, weaponDef->id);
  77.     }
  78. }
  79.  
  80. Feature.cpp
  81. void CFeature::DoDamage(const DamageArray& damages, const float3& impulse)
  82.     ...
  83.     residualImpulse = impulse;
  84.     if (health <= 0 && def->destructable) {
  85.         ...
  86.         if (def->drawType >= DRAWTYPE_TREE) {
  87.             if (impulse.SqLength2D() > 0.25f) {
  88.                 treeDrawer->AddFallingTree(pos, impulse, def->drawType - 1);
  89.             }
  90.         }
  91.     }
  92.  
  93. Unit.cpp->Update()
  94.     // 0.968 ** 16 is slightly less than 0.6, which was the old value used in SlowUpdate
  95.     residualImpulse *= 0.968f;
  96.  
  97. GroundMoveType.cpp
  98. void CGroundMoveType::ImpulseAdded(const float3&)
  99. {
  100.     // NOTE: ships must be able to receive impulse too (for collision handling)
  101.     if (owner->beingBuilt)
  102.         return;
  103.  
  104.     float3& impulse = owner->residualImpulse;
  105.     float3& speed = owner->speed;
  106.  
  107.     if (skidding) {
  108.         speed += impulse;
  109.         impulse = ZeroVector;
  110.     }
  111.  
  112.     const float3& groundNormal = ground->GetNormal(owner->pos.x, owner->pos.z);
  113.     const float groundImpulseScale = impulse.dot(groundNormal);
  114.  
  115.     if (groundImpulseScale < 0.0f)
  116.         impulse -= (groundNormal * groundImpulseScale);
  117.  
  118.     if (impulse.SqLength() <= 9.0f && groundImpulseScale <= 0.3f)
  119.         return;
  120.  
  121.     skidding = true;
  122.     useHeading = false;
  123.  
  124.     speed += impulse;
  125.     impulse = ZeroVector;
  126.  
  127.     skidRotSpeed = 0.0f;
  128.     skidRotAccel = 0.0f;
  129.  
  130.     float3 skidDir = owner->frontdir;
  131.  
  132.     if (speed.SqLength2D() >= 0.01f) {
  133.         skidDir = speed;
  134.         skidDir.y = 0.0f;
  135.         skidDir.Normalize();
  136.     }
  137.  
  138.     skidRotVector = skidDir.cross(UpVector);
  139.  
  140.     oldPhysState = owner->physicalState;
  141.     owner->physicalState = CSolidObject::Flying;
  142.  
  143.     if (speed.dot(groundNormal) > 0.2f) {
  144.         skidRotAccel = (gs->randFloat() - 0.5f) * 0.04f;
  145.         flying = true;
  146.     }
  147.  
  148.     ASSERT_SANE_OWNER_SPEED(speed);
  149. }
  150.  
  151. void CGroundMoveType::CheckCollisionSkid()
  152. {
  153.     CUnit* collider = owner;
  154.  
  155.     // NOTE:
  156.     //     the QuadField::Get* functions check o->midPos,
  157.     //     but the quad(s) that objects are stored in are
  158.     //     derived from o->pos (!)
  159.     const float3& pos = collider->pos;
  160.     const UnitDef* colliderUD = collider->unitDef;
  161.     const vector<CUnit*>& nearUnits = qf->GetUnitsExact(pos, collider->radius);
  162.     const vector<CFeature*>& nearFeatures = qf->GetFeaturesExact(pos, collider->radius);
  163.  
  164.     // magic number to reduce damage taken from collisions
  165.     // between a very heavy and a very light CSolidObject
  166.     static const float MASS_MULT = 0.02f;
  167.  
  168.     vector<CUnit*>::const_iterator ui;
  169.     vector<CFeature*>::const_iterator fi;
  170.  
  171.     for (ui = nearUnits.begin(); ui != nearUnits.end(); ++ui) {
  172.         CUnit* collidee = *ui;
  173.         const UnitDef* collideeUD = collider->unitDef;
  174.  
  175.         const float sqDist = (pos - collidee->pos).SqLength();
  176.         const float totRad = collider->radius + collidee->radius;
  177.  
  178.         if ((sqDist >= totRad * totRad) || (sqDist <= 0.01f)) {
  179.             continue;
  180.         }
  181.  
  182.         // stop units from reaching escape velocity
  183.         const float3 dif = (pos - collidee->pos).SafeNormalize();
  184.  
  185.         if (collidee->mobility == NULL) {
  186.             const float impactSpeed = -collider->speed.dot(dif);
  187.             const float impactDamageMult = std::min(impactSpeed * collider->mass * MASS_MULT, MAX_UNIT_SPEED);
  188.  
  189.             const bool doColliderDamage = (modInfo.allowUnitCollisionDamage && impactSpeed > colliderUD->minCollisionSpeed && colliderUD->minCollisionSpeed >= 0.0f);
  190.             const bool doCollideeDamage = (modInfo.allowUnitCollisionDamage && impactSpeed > collideeUD->minCollisionSpeed && collideeUD->minCollisionSpeed >= 0.0f);
  191.  
  192.             if (impactSpeed <= 0.0f)
  193.                 continue;
  194.  
  195.             collider->Move3D(dif * impactSpeed, true);
  196.             collider->speed += ((dif * impactSpeed) * 1.8f);
  197.  
  198.             // damage the collider, no added impulse
  199.             if (doColliderDamage) {
  200.                 collider->DoDamage(DamageArray(impactDamageMult), NULL, ZeroVector);
  201.             }
  202.             // damage the (static) collidee based on collider's mass, no added impulse
  203.             if (doCollideeDamage) {
  204.                 collidee->DoDamage(DamageArray(impactDamageMult), NULL, ZeroVector);
  205.             }
  206.         } else {
  207.             // don't conserve momentum
  208.             assert(collider->mass > 0.0f && collidee->mass > 0.0f);
  209.  
  210.             const float impactSpeed = (collidee->speed - collider->speed).dot(dif) * 0.5f;
  211.             const float colliderRelMass = (collider->mass / (collider->mass + collidee->mass));
  212.             const float colliderRelImpactSpeed = impactSpeed * (1.0f - colliderRelMass);
  213.             const float collideeRelImpactSpeed = impactSpeed * (       colliderRelMass);
  214.  
  215.             const float colliderImpactDmgMult  = std::min(colliderRelImpactSpeed * collider->mass * MASS_MULT, MAX_UNIT_SPEED);
  216.             const float collideeImpactDmgMult  = std::min(collideeRelImpactSpeed * collider->mass * MASS_MULT, MAX_UNIT_SPEED);
  217.             const float3 colliderImpactImpulse = dif * colliderRelImpactSpeed;
  218.             const float3 collideeImpactImpulse = dif * collideeRelImpactSpeed;
  219.  
  220.             const bool doColliderDamage = (modInfo.allowUnitCollisionDamage && impactSpeed > colliderUD->minCollisionSpeed && colliderUD->minCollisionSpeed >= 0.0f);
  221.             const bool doCollideeDamage = (modInfo.allowUnitCollisionDamage && impactSpeed > collideeUD->minCollisionSpeed && collideeUD->minCollisionSpeed >= 0.0f);
  222.  
  223.             if (impactSpeed <= 0.0f)
  224.                 continue;
  225.  
  226.             collider->Move3D(colliderImpactImpulse, true);
  227.             collidee->Move3D(-collideeImpactImpulse, true);
  228.  
  229.             // damage the collider
  230.             if (doColliderDamage) {
  231.                 collider->DoDamage(DamageArray(colliderImpactDmgMult), NULL, dif * colliderImpactDmgMult);
  232.             }
  233.             // damage the collidee
  234.             if (doCollideeDamage) {
  235.                 collidee->DoDamage(DamageArray(collideeImpactDmgMult), NULL, dif * -collideeImpactDmgMult);
  236.             }
  237.  
  238.             collider->speed += colliderImpactImpulse;
  239.             collider->speed *= 0.9f;
  240.             collidee->speed -= collideeImpactImpulse;
  241.             collidee->speed *= 0.9f;
  242.         }
  243.     }
  244.  
  245.     for (fi = nearFeatures.begin(); fi != nearFeatures.end(); ++fi) {
  246.         CFeature* f = *fi;
  247.  
  248.         if (!f->blocking)
  249.             continue;
  250.  
  251.         const float sqDist = (pos - f->pos).SqLength();
  252.         const float totRad = collider->radius + f->radius;
  253.  
  254.         if ((sqDist >= totRad * totRad) || (sqDist <= 0.01f))
  255.             continue;
  256.  
  257.         const float3 dif = (pos - f->pos).SafeNormalize();
  258.         const float impactSpeed = -collider->speed.dot(dif);
  259.         const float impactDamageMult = std::min(impactSpeed * collider->mass * MASS_MULT, MAX_UNIT_SPEED);
  260.         const float3 impactImpulse = dif * impactSpeed;
  261.         const bool doColliderDamage = (modInfo.allowUnitCollisionDamage && impactSpeed > colliderUD->minCollisionSpeed && colliderUD->minCollisionSpeed >= 0.0f);
  262.  
  263.         if (impactSpeed <= 0.0f)
  264.             continue;
  265.  
  266.         collider->Move3D(impactImpulse, true);
  267.         collider->speed += (impactImpulse * 1.8f);
  268.  
  269.         // damage the collider, no added impulse (!)
  270.         if (doColliderDamage) {
  271.             collider->DoDamage(DamageArray(impactDamageMult), NULL, ZeroVector);
  272.         }
  273.  
  274.         // damage the collidee feature based on collider's mass
  275.         f->DoDamage(DamageArray(impactDamageMult), -impactImpulse);
  276.     }
  277.  
  278.     ASSERT_SANE_OWNER_SPEED(collider->speed);
  279. }
  280.  
  281. void CGroundMoveType::HandleUnitCollisions(
  282.     CUnit* collider,
  283.     const float3& colliderCurPos,
  284.     const float3& colliderOldPos,
  285.     const float colliderSpeed,
  286.     const float colliderRadius,
  287.     const float3& sepDirMask,
  288.     const UnitDef* colliderUD,
  289.     const MoveData* colliderMD,
  290.     const CMoveMath* colliderMM
  291. ) {
  292.     const float searchRadius = std::max(colliderSpeed, 1.0f) * (colliderRadius * 2.0f);
  293.  
  294.     const std::vector<CUnit*>& nearUnits = qf->GetUnitsExact(colliderCurPos, searchRadius);
  295.           std::vector<CUnit*>::const_iterator uit;
  296.  
  297.     // NOTE: probably too large for most units (eg. causes tree falling animations to be skipped)
  298.     const float3 crushImpulse = collider->speed * ((reversing)? -collider->mass: collider->mass);
  299.  
  300.     for (uit = nearUnits.begin(); uit != nearUnits.end(); ++uit) {
  301.         CUnit* collidee = const_cast<CUnit*>(*uit);
  302.  
  303.         if (collidee == collider) { continue; }
  304.         if (collidee->moveType->IsSkidding()) { continue; }
  305.         if (collidee->moveType->IsFlying()) { continue; }
  306.  
  307.         const UnitDef*   collideeUD = collidee->unitDef;
  308.         const MoveData*  collideeMD = collidee->mobility;
  309.         const CMoveMath* collideeMM = (collideeMD != NULL)? collideeMD->moveMath: NULL;
  310.  
  311.         const float3& collideeCurPos = collidee->pos;
  312.         const float3& collideeOldPos = collidee->moveType->oldPos;
  313.  
  314.         const bool colliderMobile = (collider->mobility != NULL);
  315.         const bool collideeMobile = (collideeMD != NULL);
  316.  
  317.         const float collideeSpeed = collidee->speed.Length();
  318.         const float collideeRadius = collideeMobile?
  319.             FOOTPRINT_RADIUS(collideeMD->xsize, collideeMD->zsize):
  320.             FOOTPRINT_RADIUS(collidee  ->xsize, collidee  ->zsize);
  321.  
  322.         bool pushCollider = colliderMobile;
  323.         bool pushCollidee = (collideeMobile || collideeUD->canfly);
  324.         bool crushCollidee = false;
  325.  
  326.         const float3 separationVector = colliderCurPos - collideeCurPos;
  327.         const float separationMinDist = (colliderRadius + collideeRadius) * (colliderRadius + collideeRadius);
  328.  
  329.         if ((separationVector.SqLength() - separationMinDist) > 0.01f) { continue; }
  330.         if (collidee->usingScriptMoveType) { pushCollidee = false; }
  331.         if (collideeUD->pushResistant) { pushCollidee = false; }
  332.  
  333.         // if not an allied collision, neither party is allowed to be pushed (bi-directional)
  334.         // if an allied collision, only the collidee is allowed to be crushed (uni-directional)
  335.         const bool alliedCollision =
  336.             teamHandler->Ally(collider->allyteam, collidee->allyteam) &&
  337.             teamHandler->Ally(collidee->allyteam, collider->allyteam);
  338.  
  339.         pushCollider &= (alliedCollision || modInfo.allowPushingEnemyUnits);
  340.         pushCollidee &= (alliedCollision || modInfo.allowPushingEnemyUnits);
  341.         crushCollidee |= (!alliedCollision || modInfo.allowCrushingAlliedUnits);
  342.  
  343.         // don't push/crush either party if the collidee does not block the collider
  344.         if (colliderMM->IsNonBlocking(*colliderMD, collidee)) { continue; }
  345.         if (crushCollidee && !colliderMM->CrushResistant(*colliderMD, collidee)) { collidee->Kill(crushImpulse, true); }
  346.  
  347.         eventHandler.UnitUnitCollision(collider, collidee);
  348.  
  349.         const float  sepDistance    = (separationVector.Length() + 0.01f);
  350.         const float  penDistance    = std::max((colliderRadius + collideeRadius) - sepDistance, 1.0f);
  351.         const float  sepResponse    = std::min(SQUARE_SIZE * 2.0f, penDistance * 0.5f);
  352.  
  353.         const float3 sepDirection   = (separationVector / sepDistance);
  354.         const float3 colResponseVec = sepDirection * sepDirMask * sepResponse;
  355.  
  356.         const float
  357.             m1 = collider->mass,
  358.             m2 = collidee->mass,
  359.             v1 = std::max(1.0f, colliderSpeed), // TODO: precalculate
  360.             v2 = std::max(1.0f, collideeSpeed), // TODO: precalculate
  361.             c1 = 1.0f + (1.0f - math::fabs(collider->frontdir.dot(-sepDirection))) * 5.0f,
  362.             c2 = 1.0f + (1.0f - math::fabs(collidee->frontdir.dot( sepDirection))) * 5.0f,
  363.             s1 = m1 * v1 * c1,
  364.             s2 = m2 * v2 * c2;
  365.  
  366.         // far from a realistic treatment, but works
  367.         const float collisionMassSum  = s1 + s2 + 1.0f;
  368.               float colliderMassScale = std::max(0.01f, std::min(0.99f, 1.0f - (s1 / collisionMassSum)));
  369.               float collideeMassScale = std::max(0.01f, std::min(0.99f, 1.0f - (s2 / collisionMassSum)));
  370.  
  371.         if (!collideeMobile) {
  372.             const float3 colliderNxtPos = colliderCurPos + collider->speed;
  373.             const CMoveMath::BlockType colliderCurPosBits = colliderMM->IsBlocked(*colliderMD, colliderCurPos);
  374.             const CMoveMath::BlockType colliderNxtPosBits = colliderMM->IsBlocked(*colliderMD, colliderNxtPos);
  375.  
  376.             if ((colliderCurPosBits & CMoveMath::BLOCK_STRUCTURE) == 0)
  377.                 continue;
  378.  
  379.             if ((colliderNxtPosBits & CMoveMath::BLOCK_STRUCTURE) != 0) {
  380.                 // applied every frame objects are colliding, so be careful
  381.                 collider->AddImpulse(sepDirection * std::max(currentSpeed, accRate));
  382.                 collider->Move3D(collider->speed, true);
  383.             }
  384.         }
  385.  
  386.         const float3 colliderNewPos = colliderCurPos + (colResponseVec * colliderMassScale);
  387.         const float3 collideeNewPos = collideeCurPos - (colResponseVec * collideeMassScale);
  388.  
  389.         // try to prevent both parties from being pushed onto non-traversable squares
  390.         if (                  (colliderMM->IsBlocked(*colliderMD, colliderNewPos) & CMoveMath::BLOCK_STRUCTURE) != 0) { colliderMassScale = 0.0f; }
  391.         if (collideeMobile && (collideeMM->IsBlocked(*collideeMD, collideeNewPos) & CMoveMath::BLOCK_STRUCTURE) != 0) { collideeMassScale = 0.0f; }
  392.         if (                  colliderMM->GetPosSpeedMod(*colliderMD, colliderNewPos) <= 0.01f) { colliderMassScale = 0.0f; }
  393.         if (collideeMobile && collideeMM->GetPosSpeedMod(*collideeMD, collideeNewPos) <= 0.01f) { collideeMassScale = 0.0f; }
  394.  
  395.         // ignore pushing contributions from idling collidee's
  396.         if (collider->isMoving && !collidee->isMoving && alliedCollision) {
  397.             colliderMassScale *= ((collideeMobile)? 0.0f: 1.0f);
  398.         }
  399.  
  400.         if (pushCollider) { collider->Move3D( colResponseVec * colliderMassScale, true); } else if (colliderMobile) { collider->Move3D(colliderOldPos, false); }
  401.         if (pushCollidee) { collidee->Move3D(-colResponseVec * collideeMassScale, true); } else if (collideeMobile) { collidee->Move3D(collideeOldPos, false); }
  402.  
  403.         #if 0
  404.         if (!((gs->frameNum + collider->id) & 31) && !colliderCAI->unimportantMove) {
  405.             // if we do not have an internal move order, tell units around us to bugger off
  406.             // note: this causes too much chaos among the ranks when groups get large
  407.             helper->BuggerOff(colliderCurPos + collider->frontdir * colliderRadius, colliderRadius, true, false, collider->team, collider);
  408.         }
  409.         #endif
  410.     }
  411. }
  412.  
  413. void CGroundMoveType::HandleFeatureCollisions(
  414.     CUnit* collider,
  415.     const float3& colliderCurPos,
  416.     const float3& colliderOldPos,
  417.     const float colliderSpeed,
  418.     const float colliderRadius,
  419.     const float3& sepDirMask,
  420.     const UnitDef* colliderUD,
  421.     const MoveData* colliderMD,
  422.     const CMoveMath* colliderMM
  423. ) {
  424.     const float searchRadius = std::max(colliderSpeed, 1.0f) * (colliderRadius * 2.0f);
  425.  
  426.     const std::vector<CFeature*>& nearFeatures = qf->GetFeaturesExact(colliderCurPos, searchRadius);
  427.           std::vector<CFeature*>::const_iterator fit;
  428.  
  429.     const float3 crushImpulse = collider->speed * ((reversing)? -collider->mass: collider->mass);
  430.  
  431.     for (fit = nearFeatures.begin(); fit != nearFeatures.end(); ++fit) {
  432.         CFeature* collidee = const_cast<CFeature*>(*fit);
  433.  
  434.     //  const FeatureDef* collideeFD = collidee->def;
  435.         const float3& collideeCurPos = collidee->pos;
  436.  
  437.     //  const float collideeRadius = FOOTPRINT_RADIUS(collideeFD->xsize, collideeFD->zsize);
  438.         const float collideeRadius = FOOTPRINT_RADIUS(collidee  ->xsize, collidee  ->zsize);
  439.  
  440.         const float3 separationVector = colliderCurPos - collideeCurPos;
  441.         const float separationMinDist = (colliderRadius + collideeRadius) * (colliderRadius + collideeRadius);
  442.  
  443.         if ((separationVector.SqLength() - separationMinDist) > 0.01f) { continue; }
  444.  
  445.         if (colliderMM->IsNonBlocking(*colliderMD, collidee)) { continue; }
  446.         if (!colliderMM->CrushResistant(*colliderMD, collidee)) { collidee->Kill(crushImpulse, true); }
  447.  
  448.         eventHandler.UnitFeatureCollision(collider, collidee);
  449.  
  450.         const float  sepDistance    = (separationVector.Length() + 0.01f);
  451.         const float  penDistance    = std::max((colliderRadius + collideeRadius) - sepDistance, 1.0f);
  452.         const float  sepResponse    = std::min(SQUARE_SIZE * 2.0f, penDistance * 0.5f);
  453.  
  454.         const float3 sepDirection   = (separationVector / sepDistance);
  455.         const float3 colResponseVec = sepDirection * sepDirMask * sepResponse;
  456.  
  457.         // multiply the collider's mass by a large constant (so that heavy
  458.         // features do not bounce light units away like jittering pinballs;
  459.         // collideeMassScale ~= 0.01 suppresses large responses)
  460.         const float
  461.             m1 = collider->mass,
  462.             m2 = collidee->mass * 10000.0f,
  463.             v1 = std::max(1.0f, colliderSpeed),
  464.             v2 = 1.0f,
  465.             c1 = (1.0f - math::fabs( collider->frontdir.dot(-sepDirection))) * 5.0f,
  466.             c2 = (1.0f - math::fabs(-collider->frontdir.dot( sepDirection))) * 5.0f,
  467.             s1 = m1 * v1 * c1,
  468.             s2 = m2 * v2 * c2;
  469.  
  470.         const float collisionMassSum  = s1 + s2 + 1.0f;
  471.         const float colliderMassScale = std::max(0.01f, std::min(0.99f, 1.0f - (s1 / collisionMassSum)));
  472.     //  const float collideeMassScale = std::max(0.01f, std::min(0.99f, 1.0f - (s2 / collisionMassSum)));
  473.  
  474.         if (collidee->reachedFinalPos) {
  475.             const float3 colliderNxtPos = colliderCurPos + collider->speed;
  476.             const CMoveMath::BlockType colliderCurPosBits = colliderMM->IsBlocked(*colliderMD, colliderCurPos);
  477.             const CMoveMath::BlockType colliderNxtPosBits = colliderMM->IsBlocked(*colliderMD, colliderNxtPos);
  478.  
  479.             if ((colliderCurPosBits & CMoveMath::BLOCK_STRUCTURE) == 0)
  480.                 continue;
  481.  
  482.             if ((colliderNxtPosBits & CMoveMath::BLOCK_STRUCTURE) != 0) {
  483.                 // applied every frame objects are colliding, so be careful
  484.                 collider->AddImpulse(sepDirection * std::max(currentSpeed, accRate));
  485.                 collider->Move3D(collider->speed, true);
  486.             }
  487.         }
  488.  
  489.         collider->Move3D(colResponseVec * colliderMassScale, true);
  490.     }
  491. }
  492.  
  493. StrafeAirMoveType.cpp
  494. void CStrafeAirMoveType::ImpulseAdded(const float3&)
  495. {
  496.     if (aircraftState == AIRCRAFT_FLYING) {
  497.         owner->speed += owner->residualImpulse;
  498.         owner->residualImpulse = ZeroVector;
  499.     }
  500. }
  501.  
  502. UnitScript.cpp
  503. void CUnitScript::Explode(int piece, int flags)
  504.     ...
  505.     // This means that we are going to do a full fledged piece explosion!
  506.     float3 baseSpeed = unit->speed + unit->residualImpulse * 0.5f;
  507.     float sql = baseSpeed.SqLength();
  508.     ...
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement