本文整理汇总了C++中CFeature类的典型用法代码示例。如果您正苦于以下问题:C++ CFeature类的具体用法?C++ CFeature怎么用?C++ CFeature使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了CFeature类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: FeatureLoaderLoadFeature
CObject_pointer<CFeature>* FeatureLoaderLoadFeature( string name, float3 pos, int team )
{
FeatureDef *def = featureHandler->GetFeatureDef(name);
CFeature* feature = new CFeature();
feature->Initialize( pos,def,0, 0, team,"" );
return new CObject_pointer<CFeature>(feature);
}
示例2: GetFeatureDef
CFeature* CFeatureHandler::CreateWreckage(const float3& pos, const std::string& name,
float rot, int facing, int iter, int team, int allyteam, bool emitSmoke, std::string fromUnit,
const float3& speed)
{
const FeatureDef* fd;
const std::string* defname = &name;
int i = iter;
do {
if (defname->empty()) return NULL;
fd = GetFeatureDef(*defname);
if (!fd) return NULL;
defname = &(fd->deathFeature);
}while (--i > 0);
if (luaRules && !luaRules->AllowFeatureCreation(fd, team, pos))
return NULL;
if (!fd->modelname.empty()) {
if (fd->resurrectable==0 || (iter>1 && fd->resurrectable<0))
fromUnit = "";
CFeature* f = new CFeature;
f->Initialize(pos, fd, (short int) rot, facing, team, allyteam, fromUnit, speed, fd->smokeTime);
return f;
}
return NULL;
}
示例3: float3
void CFeatureHandler::TerrainChanged(int x1, int y1, int x2, int y2)
{
ASSERT_SYNCED_MODE;
vector<int> quads=qf->GetQuadsRectangle(float3(x1*SQUARE_SIZE,0,y1*SQUARE_SIZE),
float3(x2*SQUARE_SIZE,0,y2*SQUARE_SIZE));
// logOutput.Print("Checking feature pos %i",quads.size());
for(vector<int>::iterator qi=quads.begin();qi!=quads.end();++qi){
list<CFeature*>::iterator fi;
list<CFeature*>& features = qf->baseQuads[*qi].features;
for(fi = features.begin(); fi != features.end(); ++fi) {
CFeature* feature = *fi;
float3& fpos = feature->pos;
if (fpos.y > ground->GetHeight(fpos.x, fpos.z)) {
SetFeatureUpdateable(feature);
if (feature->def->floating){
feature->finalHeight = ground->GetHeight(fpos.x, fpos.z);
} else {
feature->finalHeight = ground->GetHeight2(fpos.x, fpos.z);
}
feature->CalculateTransform ();
}
}
}
}
示例4: GetFeatureDef
CFeature* CFeatureHandler::CreateWreckage(const float3& pos, const std::string& name,
float rot, int facing, int iter, int team, int allyteam, bool emitSmoke, std::string fromUnit,
const float3& speed)
{
ASSERT_SYNCED_MODE;
if (name.empty()) {
return NULL;
}
const FeatureDef* fd = GetFeatureDef(name);
if (!fd) {
return NULL;
}
if (iter > 1) {
return CreateWreckage(pos, fd->deathFeature, rot, facing, iter - 1, team, allyteam, emitSmoke, "", speed);
}
else {
if (luaRules && !luaRules->AllowFeatureCreation(fd, team, pos)) {
return NULL;
}
if (!fd->modelname.empty()) {
CFeature* f = SAFE_NEW CFeature;
f->Initialize(pos, fd, (short int) rot, facing, team, fromUnit, speed);
// allow area-reclaiming wrecks of all units, including your own (they set allyteam = -1)
f->allyteam = allyteam;
if (emitSmoke && f->blocking)
f->emitSmokeTime = 300;
return f;
}
}
return NULL;
}
示例5: SCOPED_TIMER
void CFeatureHandler::Update()
{
SCOPED_TIMER("Feature::Update");
if ((gs->frameNum & 31) == 0) {
// let all areareclaimers choose a target with a different id
bool dontClear = false;
for (std::list<int>::iterator it = toBeFreedIDs.begin(); it != toBeFreedIDs.end(); ++it) {
if (CBuilderCAI::IsFeatureBeingReclaimed(*it)) {
// postpone recycling
dontClear = true;
break;
}
}
if (!dontClear)
freeIDs.splice(freeIDs.end(), toBeFreedIDs, toBeFreedIDs.begin(), toBeFreedIDs.end());
}
if(!toBeRemoved.empty()) {
GML_RECMUTEX_LOCK(feat); // Update
GML_RECMUTEX_LOCK(quad); // Update
while (!toBeRemoved.empty()) {
CFeatureSet::iterator it = activeFeatures.find(toBeRemoved.back());
toBeRemoved.pop_back();
if (it != activeFeatures.end()) {
CFeature* feature = *it;
toBeFreedIDs.push_back(feature->id);
activeFeatures.erase(feature);
if (feature->drawQuad >= 0) {
DrawQuad* dq = &drawQuads[feature->drawQuad];
dq->features.erase(feature);
}
if (feature->inUpdateQue) {
updateFeatures.erase(feature);
}
fadeFeatures.erase(feature);
fadeFeaturesS3O.erase(feature);
delete feature;
}
}
}
CFeatureSet::iterator fi = updateFeatures.begin();
while (fi != updateFeatures.end()) {
CFeature* feature = *fi;
++fi;
if (!feature->Update()) {
// remove it
feature->inUpdateQue = false;
updateFeatures.erase(feature);
}
}
}
示例6: int
int CUnitHandler::TestBuildSquare(const float3& pos, const UnitDef* unitdef, CFeature*& feature, int allyteam)
{
if (pos.x < 0 || pos.x >= gs->mapx * SQUARE_SIZE || pos.z < 0 || pos.z >= gs->mapy * SQUARE_SIZE) {
return 0;
}
int ret = 2;
int yardxpos = int(pos.x + 4) / SQUARE_SIZE;
int yardypos = int(pos.z + 4) / SQUARE_SIZE;
CSolidObject* s;
if ((s = groundBlockingObjectMap->GroundBlocked(yardypos * gs->mapx + yardxpos))) {
CFeature* f;
if ((f = dynamic_cast<CFeature*>(s))) {
if ((allyteam < 0) || f->IsInLosForAllyTeam(allyteam)) {
if (!f->def->reclaimable) {
return 0;
}
feature = f;
}
} else if (!dynamic_cast<CUnit*>(s) || (allyteam < 0) ||
(((CUnit*) s)->losStatus[allyteam] & LOS_INLOS)) {
if (s->immobile) {
return 0;
} else {
ret = 1;
}
}
}
const float groundheight = ground->GetHeight2(pos.x, pos.z);
if (!unitdef->floater || groundheight > 0.0f) {
// if we are capable of floating, only test local
// height difference if terrain is above sea-level
const float* heightmap = readmap->GetHeightmap();
int x = (int) (pos.x / SQUARE_SIZE);
int z = (int) (pos.z / SQUARE_SIZE);
float orgh = readmap->orgheightmap[z * (gs->mapx + 1) + x];
float h = heightmap[z * (gs->mapx + 1) + x];
float hdif = unitdef->maxHeightDif;
if (pos.y > orgh + hdif && pos.y > h + hdif) { return 0; }
if (pos.y < orgh - hdif && pos.y < h - hdif) { return 0; }
}
if (!unitdef->floater && groundheight < -unitdef->maxWaterDepth) {
// ground is deeper than our maxWaterDepth, cannot build here
return 0;
}
if (groundheight > -unitdef->minWaterDepth) {
// ground is shallower than our minWaterDepth, cannot build here
return 0;
}
return ret;
}
示例7: StringToLower
void CFeatureHandler::LoadFeaturesFromMap(bool onlyCreateDefs)
{
// add default tree and geo FeatureDefs defined by the map
const int numFeatureTypes = readmap->GetNumFeatureTypes();
for (int a = 0; a < numFeatureTypes; ++a) {
const string& name = StringToLower(readmap->GetFeatureTypeName(a));
if (GetFeatureDef(name, false) == NULL) {
if (name.find("treetype") != string::npos) {
AddFeatureDef(name, CreateDefaultTreeFeatureDef(name));
}
else if (name.find("geovent") != string::npos) {
AddFeatureDef(name, CreateDefaultGeoFeatureDef(name));
}
else {
LOG_L(L_ERROR, "[%s] unknown map feature type \"%s\"",
__FUNCTION__, name.c_str());
}
}
}
// add a default geovent FeatureDef if the map did not
if (GetFeatureDef("geovent", false) == NULL) {
AddFeatureDef("geovent", CreateDefaultGeoFeatureDef("geovent"));
}
if (!onlyCreateDefs) {
// create map-specified feature instances
const int numFeatures = readmap->GetNumFeatures();
MapFeatureInfo* mfi = new MapFeatureInfo[numFeatures];
readmap->GetFeatureInfo(mfi);
for (int a = 0; a < numFeatures; ++a) {
const string& name = StringToLower(readmap->GetFeatureTypeName(mfi[a].featureType));
map<string, const FeatureDef*>::iterator def = featureDefs.find(name);
if (def == featureDefs.end()) {
LOG_L(L_ERROR, "Unknown feature named '%s'", name.c_str());
continue;
}
const float ypos = ground->GetHeightReal(mfi[a].pos.x, mfi[a].pos.z);
const float3 fpos = float3(mfi[a].pos.x, ypos, mfi[a].pos.z);
const FeatureDef* fdef = def->second;
CFeature* f = new CFeature();
f->Initialize(fpos, fdef, (short int) mfi[a].rotation, 0, -1, -1, NULL);
}
delete[] mfi;
}
}
示例8: GML_RECMUTEX_LOCK
std::vector<CSolidObject*> CQuadField::GetSolidsExact(
const float3& pos,
const float radius,
const unsigned int physicalStateBits,
const unsigned int collisionStateBits
) {
GML_RECMUTEX_LOCK(qnum); // GetSolidsExact
const std::vector<int>& quads = GetQuads(pos, radius);
const int tempNum = gs->tempNum++;
std::vector<CSolidObject*> solids;
std::vector<int>::const_iterator qi;
std::list<CUnit*>::iterator ui;
std::list<CFeature*>::iterator fi;
for (qi = quads.begin(); qi != quads.end(); ++qi) {
for (ui = baseQuads[*qi].units.begin(); ui != baseQuads[*qi].units.end(); ++ui) {
CUnit* u = *ui;
if (u->tempNum == tempNum)
continue;
if (!u->HasPhysicalStateBit(physicalStateBits))
continue;
if (!u->HasCollidableStateBit(collisionStateBits))
continue;
if ((pos - u->midPos).SqLength() >= Square(radius + u->radius))
continue;
u->tempNum = tempNum;
solids.push_back(u);
}
for (fi = baseQuads[*qi].features.begin(); fi != baseQuads[*qi].features.end(); ++fi) {
CFeature* f = *fi;
if (f->tempNum == tempNum)
continue;
if (!f->HasPhysicalStateBit(physicalStateBits))
continue;
if (!f->HasCollidableStateBit(collisionStateBits))
continue;
if ((pos - f->midPos).SqLength() >= Square(radius + f->radius))
continue;
f->tempNum = tempNum;
solids.push_back(f);
}
}
return solids;
}
示例9: GML_RECMUTEX_LOCK
float CGameHelper::GuiTraceRayFeature(const float3& start, const float3& dir, float length, CFeature*& feature)
{
float nearHit = length;
GML_RECMUTEX_LOCK(quad); // GuiTraceRayFeature
std::vector<int> quads = qf->GetQuadsOnRay(start, dir, length);
std::vector<int>::iterator qi;
for (qi = quads.begin(); qi != quads.end(); ++qi) {
const CQuadField::Quad& quad = qf->GetQuad(*qi);
std::list<CFeature*>::const_iterator ui;
// NOTE: switch this to custom volumes fully?
// (not used for any LOF checks, maybe wasteful)
for (ui = quad.features.begin(); ui != quad.features.end(); ++ui) {
CFeature* f = *ui;
if (!gu->spectatingFullView && !f->IsInLosForAllyTeam(gu->myAllyTeam)) {
continue;
}
if (f->noSelect) {
continue;
}
CollisionVolume* cv = f->collisionVolume;
const float3& midPosOffset = cv? cv->GetOffsets(): ZeroVector;
const float3 dif = (f->midPos + midPosOffset) - start;
float closeLength = dif.dot(dir);
if (closeLength < 0)
continue;
if (closeLength > nearHit)
continue;
float3 closeVect = dif - dir * closeLength;
if (closeVect.SqLength() < f->sqRadius) {
nearHit = closeLength;
feature = f;
}
}
}
return nearHit;
}
示例10: GetFeatureDef
void CFeatureHandler::LoadSaveFeatures(CLoadSaveInterface* file, bool loading)
{
if(loading)
freeIDs.clear();
for(int a=0;a<MAX_FEATURES;++a){
bool exists=!!features[a];
file->lsBool(exists);
if(exists){
if(loading){
overrideId=a;
float3 pos;
file->lsFloat3(pos);
string def;
file->lsString(def);
if(featureDefs.find(def)==featureDefs.end())
GetFeatureDef(def);
short rotation;
file->lsShort(rotation);
string fromUnit;
file->lsString(fromUnit);
CFeature* f = SAFE_NEW CFeature;
f->Initialize (pos,featureDefs[def],rotation,0,-1,fromUnit);
} else {
file->lsFloat3(features[a]->pos);
file->lsString(features[a]->def->myName);
file->lsShort(features[a]->heading);
file->lsString(features[a]->createdFromUnit);
}
CFeature* f=features[a];
file->lsFloat(f->health);
file->lsFloat(f->reclaimLeft);
file->lsInt(f->allyteam);
} else {
if(loading)
freeIDs.push_back(a);
}
}
overrideId=-1;
}
示例11: while
void CFeatureHandler::Update()
{
ASSERT_SYNCED_MODE;
START_TIME_PROFILE
while (!toBeRemoved.empty()) {
CFeature* feature = features[toBeRemoved.back()];
toBeRemoved.pop_back();
if (feature) {
freeIDs.push_back(feature->id);
features[feature->id] = 0;
if (feature->drawQuad >= 0) {
DrawQuad* dq = &drawQuads[feature->drawQuad];
dq->features.erase(feature);
}
if (feature->inUpdateQue) {
updateFeatures.erase(feature->id);
}
delete feature;
}
}
SPRING_HASH_SET<int>::iterator fi=updateFeatures.begin();
while(fi!= updateFeatures.end()){
CFeature* feature = features[*fi];
const bool remove = !feature->Update();
if (remove) {
feature->inUpdateQue = false;
updateFeatures.erase(fi++);
} else {
++fi;
}
}
END_TIME_PROFILE("Feature::Update");
}
示例12: TraceRay
// called by {CRifle, CBeamLaser, CLightningCannon}::Fire(), CWeapon::HaveFreeLineOfFire(), and Skirmish AIs
float TraceRay(
const float3& start,
const float3& dir,
float length,
int avoidFlags,
const CUnit* owner,
CUnit*& hitUnit,
CFeature*& hitFeature,
CollisionQuery* hitColQuery
) {
const bool ignoreEnemies = ((avoidFlags & Collision::NOENEMIES ) != 0);
const bool ignoreAllies = ((avoidFlags & Collision::NOFRIENDLIES) != 0);
const bool ignoreFeatures = ((avoidFlags & Collision::NOFEATURES ) != 0);
const bool ignoreNeutrals = ((avoidFlags & Collision::NONEUTRALS ) != 0);
const bool ignoreGround = ((avoidFlags & Collision::NOGROUND ) != 0);
const bool ignoreUnits = ignoreEnemies && ignoreAllies && ignoreNeutrals;
hitFeature = NULL;
hitUnit = NULL;
if (dir == ZeroVector)
return -1.0f;
if (!ignoreFeatures || !ignoreUnits) {
GML_RECMUTEX_LOCK(quad); // TraceRay
CollisionQuery cq;
int* begQuad = NULL;
int* endQuad = NULL;
quadField->GetQuadsOnRay(start, dir, length, begQuad, endQuad);
// locally point somewhere non-NULL; we cannot pass hitColQuery
// to DetectHit directly because each call resets it internally
if (hitColQuery == NULL)
hitColQuery = &cq;
// feature intersection
if (!ignoreFeatures) {
for (int* quadPtr = begQuad; quadPtr != endQuad; ++quadPtr) {
const CQuadField::Quad& quad = quadField->GetQuad(*quadPtr);
for (std::list<CFeature*>::const_iterator ui = quad.features.begin(); ui != quad.features.end(); ++ui) {
CFeature* f = *ui;
// NOTE:
// if f is non-blocking, ProjectileHandler will not test
// for collisions with projectiles so we can skip it here
if (!f->HasCollidableStateBit(CSolidObject::CSTATE_BIT_QUADMAPRAYS))
continue;
if (CCollisionHandler::DetectHit(f, start, start + dir * length, &cq, true)) {
const float len = cq.GetHitPosDist(start, dir);
// we want the closest feature (intersection point) on the ray
if (len < length) {
length = len;
hitFeature = f;
*hitColQuery = cq;
}
}
}
}
}
// unit intersection
if (!ignoreUnits) {
for (int* quadPtr = begQuad; quadPtr != endQuad; ++quadPtr) {
const CQuadField::Quad& quad = quadField->GetQuad(*quadPtr);
for (std::list<CUnit*>::const_iterator ui = quad.units.begin(); ui != quad.units.end(); ++ui) {
CUnit* u = *ui;
if (u == owner)
continue;
if (!u->HasCollidableStateBit(CSolidObject::CSTATE_BIT_QUADMAPRAYS))
continue;
if (ignoreAllies && u->allyteam == owner->allyteam)
continue;
if (ignoreNeutrals && u->IsNeutral())
continue;
if (ignoreEnemies && u->allyteam != owner->allyteam)
continue;
if (CCollisionHandler::DetectHit(u, start, start + dir * length, &cq, true)) {
const float len = cq.GetHitPosDist(start, dir);
// we want the closest unit (intersection point) on the ray
if (len < length) {
length = len;
hitUnit = u;
*hitColQuery = cq;
}
}
}
}
if (hitUnit)
//.........这里部分代码省略.........
示例13: switch
int CAICallback::HandleCommand(int commandId, void* data)
{
switch (commandId) {
case AIHCQuerySubVersionId: {
return 1; // current version of Handle Command interface
} break;
case AIHCAddMapPointId: {
const AIHCAddMapPoint* cmdData = static_cast<AIHCAddMapPoint*>(data);
/*
TODO: gu->myPlayerNum makes the command to look like as it comes from the local player,
"team" should be used (but needs some major changes in other engine parts)
*/
clientNet->Send(CBaseNetProtocol::Get().SendMapDrawPoint(gu->myPlayerNum, (short)cmdData->pos.x, (short)cmdData->pos.z, std::string(cmdData->label), false));
return 1;
} break;
case AIHCAddMapLineId: {
const AIHCAddMapLine* cmdData = static_cast<AIHCAddMapLine*>(data);
// see TODO above
clientNet->Send(CBaseNetProtocol::Get().SendMapDrawLine(gu->myPlayerNum, (short)cmdData->posfrom.x, (short)cmdData->posfrom.z, (short)cmdData->posto.x, (short)cmdData->posto.z, false));
return 1;
} break;
case AIHCRemoveMapPointId: {
const AIHCRemoveMapPoint* cmdData = static_cast<AIHCRemoveMapPoint*>(data);
// see TODO above
clientNet->Send(CBaseNetProtocol::Get().SendMapErase(gu->myPlayerNum, (short)cmdData->pos.x, (short)cmdData->pos.z));
return 1;
} break;
case AIHCSendStartPosId:
case AIHCGetUnitDefByIdId:
case AIHCGetWeaponDefByIdId:
case AIHCGetFeatureDefByIdId:
case AIHCGetDataDirId:
{
// NOTE: these commands should never arrive, handled in SSkirmishAICallbackImpl
assert(false);
return 0;
} break;
case AIHCTraceRayId: {
AIHCTraceRay* cmdData = static_cast<AIHCTraceRay*>(data);
if (CHECK_UNITID(cmdData->srcUID)) {
const CUnit* srcUnit = unitHandler->GetUnit(cmdData->srcUID);
if (srcUnit != nullptr) {
CUnit* hitUnit = nullptr;
CFeature* hitFeature = nullptr;
//FIXME add COLLISION_NOFEATURE?
const float realLen = TraceRay::TraceRay(cmdData->rayPos, cmdData->rayDir, cmdData->rayLen, cmdData->flags, srcUnit, hitUnit, hitFeature);
if (hitUnit != nullptr) {
myAllyTeamId = teamHandler->AllyTeam(team);
if (unit_IsInLos(hitUnit)) {
cmdData->rayLen = realLen;
cmdData->hitUID = hitUnit->id;
}
}
}
}
return 1;
} break;
case AIHCFeatureTraceRayId: {
AIHCFeatureTraceRay* cmdData = static_cast<AIHCFeatureTraceRay*>(data);
if (CHECK_UNITID(cmdData->srcUID)) {
const CUnit* srcUnit = unitHandler->GetUnit(cmdData->srcUID);
if (srcUnit != nullptr) {
CUnit* hitUnit = nullptr;
CFeature* hitFeature = nullptr;
//FIXME add COLLISION_NOENEMIES || COLLISION_NOFRIENDLIES || COLLISION_NONEUTRALS?
const float realLen = TraceRay::TraceRay(cmdData->rayPos, cmdData->rayDir, cmdData->rayLen, cmdData->flags, srcUnit, hitUnit, hitFeature);
if (hitFeature != nullptr) {
if (hitFeature->IsInLosForAllyTeam(teamHandler->AllyTeam(team))) {
cmdData->rayLen = realLen;
cmdData->hitFID = hitFeature->id;
}
}
}
}
return 1;
} break;
case AIHCPauseId: {
AIHCPause* cmdData = static_cast<AIHCPause*>(data);
clientNet->Send(CBaseNetProtocol::Get().SendPause(gu->myPlayerNum, cmdData->enable));
LOG("Skirmish AI controlling team %i paused the game, reason: %s",
team,
cmdData->reason != NULL ? cmdData->reason : "UNSPECIFIED");
return 1;
} break;
//.........这里部分代码省略.........
示例14: SCOPED_TIMER
void CFeatureHandler::Update()
{
SCOPED_TIMER("FeatureHandler::Update");
if ((gs->frameNum & 31) == 0) {
// let all areareclaimers choose a target with a different id
bool dontClear = false;
for (list<int>::iterator it = toBeFreedIDs.begin(); it != toBeFreedIDs.end(); ++it) {
if (CBuilderCAI::IsFeatureBeingReclaimed(*it)) {
// postpone recycling
dontClear = true;
break;
}
}
if (!dontClear)
freeIDs.splice(freeIDs.end(), toBeFreedIDs, toBeFreedIDs.begin(), toBeFreedIDs.end());
}
{
GML_STDMUTEX_LOCK(rfeat); // Update
if(!toBeRemoved.empty()) {
GML_RECMUTEX_LOCK(obj); // Update
eventHandler.DeleteSyncedObjects();
GML_RECMUTEX_LOCK(feat); // Update
eventHandler.DeleteSyncedFeatures();
GML_RECMUTEX_LOCK(quad); // Update
while (!toBeRemoved.empty()) {
CFeature* feature = GetFeature(toBeRemoved.back());
toBeRemoved.pop_back();
if (feature) {
int delID = feature->id;
toBeFreedIDs.push_back(delID);
activeFeatures.erase(feature);
features[delID] = 0;
if (feature->inUpdateQue) {
updateFeatures.erase(feature);
}
CSolidObject::SetDeletingRefID(delID + uh->MaxUnits());
delete feature;
CSolidObject::SetDeletingRefID(-1);
}
}
}
eventHandler.UpdateFeatures();
}
CFeatureSet::iterator fi = updateFeatures.begin();
while (fi != updateFeatures.end()) {
CFeature* feature = *fi;
++fi;
if (!feature->Update()) {
// remove it
feature->inUpdateQue = false;
updateFeatures.erase(feature);
}
}
}
示例15: DrawQuad
void CFeatureQuadDrawer::DrawQuad(int x, int y)
{
CFeatureDrawer::DrawQuad* dq = &(*drawQuads)[y * drawQuadsX + x];
for (set<CFeature*>::iterator fi = dq->features.begin(); fi != dq->features.end(); ++fi) {
CFeature* f = (*fi);
const FeatureDef* def = f->def;
if (def->drawType == DRAWTYPE_MODEL
&& (gu->spectatingFullView || f->IsInLosForAllyTeam(gu->myAllyTeam))) {
if (drawReflection) {
float3 zeroPos;
if (f->midPos.y < 0) {
zeroPos = f->midPos;
} else {
float dif = f->midPos.y - camera->pos.y;
zeroPos = camera->pos * (f->midPos.y / dif) + f->midPos * (-camera->pos.y / dif);
}
if (ground->GetApproximateHeight(zeroPos.x, zeroPos.z) > f->radius) {
continue;
}
}
if (drawRefraction) {
if (f->pos.y > 0)
continue;
}
float sqDist = (f->pos - camera->pos).SqLength2D();
float farLength = f->sqRadius * unitDrawDist * unitDrawDist;
if(statFeatures && (f->reclaimLeft < 1.0f || f->resurrectProgress > 0.0f))
statFeatures->push_back(f);
if (sqDist < farLength) {
float sqFadeDistE;
float sqFadeDistB;
if(farLength < sqFadeDistEnd) {
sqFadeDistE = farLength;
sqFadeDistB = farLength * 0.75f * 0.75f;
} else {
sqFadeDistE = sqFadeDistEnd;
sqFadeDistB = sqFadeDistBegin;
}
if(sqDist < sqFadeDistB) {
f->tempalpha = 0.99f;
if (f->model->type == MODELTYPE_3DO) {
unitDrawer->DrawFeatureStatic(f);
} else {
unitDrawer->QueS3ODraw(f, f->model->textureType);
}
} else if(sqDist < sqFadeDistE) {
f->tempalpha = 1.0f - (sqDist - sqFadeDistB) / (sqFadeDistE - sqFadeDistB);
if (f->model->type == MODELTYPE_3DO) {
featureDrawer->fadeFeatures.insert(f);
} else {
featureDrawer->fadeFeaturesS3O.insert(f);
}
}
} else {
if (farFeatures)
farFeatures->push_back(f);
}
}
}
}