bool CCannon::TryTarget(const float3 &pos, bool userTarget, CUnit* unit) { if (!CWeapon::TryTarget(pos, userTarget, unit)) { return false; } if (!weaponDef->waterweapon) { if (unit) { if (unit->isUnderWater) { return false; } } else { if (pos.y < 0) { return false; } } } if (projectileSpeed == 0) { return true; } float3 dif(pos - weaponMuzzlePos); float3 dir(GetWantedDir(dif)); if (dir.SqLength() == 0) { return false; } float3 flatdir(dif.x, 0, dif.z); float flatlength = flatdir.Length(); if (flatlength == 0) { return true; } flatdir /= flatlength; float gc = ground->TrajectoryGroundCol(weaponMuzzlePos, flatdir, flatlength - 10, dir.y , gravity / (projectileSpeed * projectileSpeed) * 0.5f); if (gc > 0) { return false; } const float quadratic = gravity / (projectileSpeed * projectileSpeed) * 0.5f; const float spread = ((accuracy + sprayAngle) * 0.6f) * ((1.0f - owner->limExperience * weaponDef->ownerExpAccWeight) * 0.9f); if (avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos, flatdir, flatlength - 30, dir.y, quadratic, spread, 3, owner, CGameHelper::TEST_ALLIED)) { return false; } if (avoidNeutral && helper->TestTrajectoryCone(weaponMuzzlePos, flatdir, flatlength - 30, dir.y, quadratic, spread, 3, owner, CGameHelper::TEST_NEUTRAL)) { return false; } return true; }
bool CCannon::TryTarget(const float3 &pos,bool userTarget,CUnit* unit) { if(!CWeapon::TryTarget(pos,userTarget,unit)) return false; if(unit) { if(unit->isUnderWater) return false; } else { if(pos.y<0) return false; } if (projectileSpeed == 0) return true; float3 dif(pos-weaponPos); float predictTime=dif.Length()/projectileSpeed; if(predictTime==0) return true; if(highTrajectory) predictTime=(minPredict+maxPredict)*0.5f; dif.y-=predictTime*predictTime*gs->gravity*0.5f; float length=dif.Length(); float3 dir(dif/length); float3 flatdir(dif.x,0,dif.z); float flatlength=flatdir.Length(); if(flatlength==0) return true; flatdir/=flatlength; float gc=ground->TrajectoryGroundCol(weaponPos,flatdir,flatlength-10,dif.y/flatlength,gs->gravity/(projectileSpeed*projectileSpeed)*0.5f); if(gc>0) return false; /* gc=ground->LineGroundCol(wpos+dir*(length*0.5f),pos,false); if(gc>0 && gc<length*0.40f) return false; */ if(avoidFriendly && helper->TestTrajectoryCone(weaponPos,flatdir,flatlength-30,dif.y/flatlength,gs->gravity/(projectileSpeed*projectileSpeed)*0.5f,(accuracy+sprayangle)*0.6f*(1-owner->limExperience*0.9f)*0.9f,3,owner->allyteam,owner)) { return false; } /* if(helper->TestCone(weaponPos,dir,length*0.5f,(accuracy+sprayangle)*1.2f*(1-owner->limExperience*0.9f)*0.9f,owner->allyteam,owner)){ return false; } float3 dir2(dif); dir2.y+=predictTime*predictTime*gs->gravity; //compensate for the earlier up prediction dir2.Normalize(); if(helper->TestCone(weaponPos+dir*(length*0.5f),dir2,length*0.5f,(accuracy+sprayangle)*!userTarget*(1-owner->limExperience*0.9f)*0.6f,owner->allyteam,owner)){ return false; }*/ return true; }
bool CMissileLauncher::TryTarget(const float3& pos,bool userTarget,CUnit* unit) { if(!CWeapon::TryTarget(pos,userTarget,unit)) return false; if(unit){ if(unit->isUnderWater){ return false; } } else { if(pos.y<0) return false; } float3 dir=pos-weaponPos; if(weaponDef->trajectoryHeight>0){ //do a different test depending on if the missile has a high trajectory or not float3 flatdir(dir.x,0,dir.z); dir.Normalize(); float flatlength=flatdir.Length(); if(flatlength==0) return true; flatdir/=flatlength; float linear=dir.y+weaponDef->trajectoryHeight; float quadratic=-weaponDef->trajectoryHeight/flatlength; float gc=ground->TrajectoryGroundCol(weaponPos,flatdir,flatlength-30,linear,quadratic); if(gc>0) return false; if(helper->TestTrajectoryCone(weaponPos,flatdir,flatlength-30,linear,quadratic,0,8,owner->allyteam,owner)){ return false; } } else { float length=dir.Length(); if(length==0) return true; dir/=length; if(!onlyForward){ //skip ground col testing for aircrafts float g=ground->LineGroundCol(weaponPos,pos); if(g>0 && g<length*0.9) return false; } else { float3 goaldir=pos-owner->pos; goaldir.Normalize(); if(owner->frontdir.dot(goaldir) < maxAngleDif) return false; } if(helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner)) return false; } return true; }
bool CCannon::TryTarget(const float3 &pos, bool userTarget, CUnit* unit) { if (!CWeapon::TryTarget(pos, userTarget, unit)) { return false; } if (!weaponDef->waterweapon) { if (unit) { if (unit->isUnderWater) { return false; } } else { if (pos.y < 0) { return false; } } } if (projectileSpeed == 0) { return true; } float3 dif(pos - weaponMuzzlePos); float3 dir(GetWantedDir(dif)); if (dir.SqLength() == 0) { return false; } float3 flatdir(dif.x, 0, dif.z); float flatlength = flatdir.Length(); if (flatlength == 0) { return true; } flatdir /= flatlength; const float linear = dir.y; const float quadratic = gravity / (projectileSpeed * projectileSpeed) * 0.5f; const float gc = ((collisionFlags & Collision::NOGROUND) == 0)? ground->TrajectoryGroundCol(weaponMuzzlePos, flatdir, flatlength - 10, linear, quadratic): -1.0f; if (gc > 0.0f) { return false; } const float spread = ((accuracy + sprayAngle) * 0.6f) * ((1.0f - owner->limExperience * weaponDef->ownerExpAccWeight) * 0.9f); if (avoidFriendly && TraceRay::TestTrajectoryAllyCone(weaponMuzzlePos, flatdir, flatlength - 30, dir.y, quadratic, spread, 3, owner->allyteam, owner)) { return false; } if (avoidNeutral && TraceRay::TestTrajectoryNeutralCone(weaponMuzzlePos, flatdir, flatlength - 30, dir.y, quadratic, spread, 3, owner)) { return false; } return true; }
bool CMissileLauncher::TryTarget(const float3& pos, bool userTarget, CUnit* unit) { if (!CWeapon::TryTarget(pos, userTarget, unit)) return false; if (!weaponDef->waterweapon) { if (unit) { if (unit->isUnderWater) { return false; } } else { if (pos.y < 0) return false; } } float3 dir = pos - weaponMuzzlePos; if (weaponDef->trajectoryHeight > 0) { // do a different test depending on if the missile has a high trajectory or not float3 flatdir(dir.x, 0, dir.z); dir.Normalize(); float flatlength = flatdir.Length(); if (flatlength == 0) return true; flatdir /= flatlength; const float linear = dir.y + weaponDef->trajectoryHeight; const float quadratic = -weaponDef->trajectoryHeight / flatlength; const float gc = ((collisionFlags & Collision::NOGROUND) == 0)? ground->TrajectoryGroundCol(weaponMuzzlePos, flatdir, flatlength - 30, linear, quadratic): -1.0f; if (gc > 0.0f) return false; if (avoidFriendly && TraceRay::TestTrajectoryAllyCone(weaponMuzzlePos, flatdir, flatlength - 30, linear, quadratic, 0, 8, owner->allyteam, owner)) { return false; } if (avoidNeutral && TraceRay::TestTrajectoryNeutralCone(weaponMuzzlePos, flatdir, flatlength - 30, linear, quadratic, 0, 8, owner)) { return false; } } else { float length = dir.Length(); if (length == 0) return true; dir /= length; if (!onlyForward) { if (!HaveFreeLineOfFire(weaponMuzzlePos, dir, length)) { return false; } } else { float3 goaldir = pos - owner->pos; goaldir.Normalize(); if (owner->frontdir.dot(goaldir) < maxAngleDif) return false; } if (avoidFriendly && TraceRay::TestAllyCone(weaponMuzzlePos, dir, length, (accuracy + sprayAngle), owner->allyteam, owner)) { return false; } if (avoidNeutral && TraceRay::TestNeutralCone(weaponMuzzlePos, dir, length, (accuracy + sprayAngle), owner)) { return false; } } return true; }