本文整理汇总了C++中CFeature::IsInLosForAllyTeam方法的典型用法代码示例。如果您正苦于以下问题:C++ CFeature::IsInLosForAllyTeam方法的具体用法?C++ CFeature::IsInLosForAllyTeam怎么用?C++ CFeature::IsInLosForAllyTeam使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CFeature
的用法示例。
在下文中一共展示了CFeature::IsInLosForAllyTeam方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: TestBuildSquare
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;
}
示例2: GuiTraceRayFeature
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;
}
示例3: TestBuildSquare
CGameHelper::BuildSquareStatus CGameHelper::TestBuildSquare(const float3& pos, const float buildHeight, const UnitDef* unitdef, const MoveDef* moveDef, CFeature*& feature, int allyteam, bool synced)
{
if (!pos.IsInMap()) {
return BUILDSQUARE_BLOCKED;
}
BuildSquareStatus ret = BUILDSQUARE_OPEN;
const int yardxpos = int(pos.x + 4) / SQUARE_SIZE;
const int yardypos = int(pos.z + 4) / SQUARE_SIZE;
CSolidObject* s = groundBlockingObjectMap->GroundBlocked(yardxpos, yardypos);
if (s != NULL) {
CFeature* f = dynamic_cast<CFeature*>(s);
if (f != NULL) {
if ((allyteam < 0) || f->IsInLosForAllyTeam(allyteam)) {
if (!f->def->reclaimable) {
ret = BUILDSQUARE_BLOCKED;
} else {
ret = BUILDSQUARE_RECLAIMABLE;
feature = f;
}
}
} else if (!dynamic_cast<CUnit*>(s) || (allyteam < 0) ||
(static_cast<CUnit*>(s)->losStatus[allyteam] & LOS_INLOS)) {
if (s->immobile) {
ret = BUILDSQUARE_BLOCKED;
} else {
ret = BUILDSQUARE_OCCUPIED;
}
}
if ((ret == BUILDSQUARE_BLOCKED) || (ret == BUILDSQUARE_OCCUPIED)) {
if (CMoveMath::IsNonBlocking(s, moveDef, pos, buildHeight)) {
ret = BUILDSQUARE_OPEN;
}
}
if (ret == BUILDSQUARE_BLOCKED) {
return ret;
}
}
const float groundHeight = ground->GetHeightReal(pos.x, pos.z, synced);
if (!unitdef->floatOnWater || groundHeight > 0.0f) {
// if we are capable of floating, only test local
// height difference IF terrain is above sea-level
const float* orgHeightMap = readmap->GetOriginalHeightMapSynced();
const float* curHeightMap = readmap->GetCornerHeightMapSynced();
#ifdef USE_UNSYNCED_HEIGHTMAP
if (!synced) {
orgHeightMap = readmap->GetCornerHeightMapUnsynced();
curHeightMap = readmap->GetCornerHeightMapUnsynced();
}
#endif
const int sqx = pos.x / SQUARE_SIZE;
const int sqz = pos.z / SQUARE_SIZE;
const float orgHgt = orgHeightMap[sqz * gs->mapxp1 + sqx];
const float curHgt = curHeightMap[sqz * gs->mapxp1 + sqx];
const float difHgt = unitdef->maxHeightDif;
if (pos.y > std::max(orgHgt + difHgt, curHgt + difHgt)) { return BUILDSQUARE_BLOCKED; }
if (pos.y < std::min(orgHgt - difHgt, curHgt - difHgt)) { return BUILDSQUARE_BLOCKED; }
}
if (!unitdef->IsAllowedTerrainHeight(moveDef, groundHeight))
ret = BUILDSQUARE_BLOCKED;
return ret;
}
示例4: DrawQuad
void DrawQuad(int x, int y)
{
std::vector<IWorldObjectModelRenderer*>& opaqueModelRenderers = featureDrawer->opaqueModelRenderers;
std::vector<IWorldObjectModelRenderer*>& cloakedModelRenderers = featureDrawer->cloakedModelRenderers;
const CFeatureDrawer::DrawQuad* dq = &(*drawQuads)[y * drawQuadsX + x];
for (std::set<CFeature*>::const_iterator fi = dq->features.begin(); fi != dq->features.end(); ++fi) {
CFeature* f = (*fi);
if (f->IsInVoid())
continue;
assert(f->def->drawType == DRAWTYPE_MODEL);
if (gu->spectatingFullView || f->IsInLosForAllyTeam(gu->myAllyTeam)) {
if (drawReflection) {
float3 zeroPos;
if (f->midPos.y < 0.0f) {
zeroPos = f->midPos;
} else {
const float dif = f->midPos.y - camera->GetPos().y;
zeroPos =
camera->GetPos() * (f->midPos.y / dif) +
f->midPos * (-camera->GetPos().y / dif);
}
if (ground->GetApproximateHeight(zeroPos.x, zeroPos.z, false) > f->drawRadius) {
continue;
}
}
if (drawRefraction) {
if (f->pos.y > 0.0f)
continue;
}
const float sqDist = (f->pos - camera->GetPos()).SqLength();
const float farLength = f->sqRadius * unitDrawer->unitDrawDistSqr;
#ifdef USE_GML
if (statFeatures && (f->reclaimLeft < 1.0f || f->resurrectProgress > 0.0f))
statFeatures->push_back(f);
#endif
if (sqDist < farLength) {
float sqFadeDistE;
float sqFadeDistB;
if (farLength < sqFadeDistEnd) {
sqFadeDistE = farLength;
sqFadeDistB = farLength * sqFadeDistBegin / sqFadeDistEnd;
} else {
sqFadeDistE = sqFadeDistEnd;
sqFadeDistB = sqFadeDistBegin;
}
if (sqDist < sqFadeDistB) {
cloakedModelRenderers[MDL_TYPE(f)]->DelFeature(f);
if (camera->InView(f->drawMidPos, f->drawRadius))
opaqueModelRenderers[MDL_TYPE(f)]->AddFeature(f);
} else if (sqDist < sqFadeDistE) {
const float falpha = 1.0f - (sqDist - sqFadeDistB) / (sqFadeDistE - sqFadeDistB);
opaqueModelRenderers[MDL_TYPE(f)]->DelFeature(f);
if (camera->InView(f->drawMidPos, f->drawRadius))
cloakedModelRenderers[MDL_TYPE(f)]->AddFeature(f, falpha);
}
} else {
if (farFeatures) {
farTextureHandler->Queue(f);
}
}
}
}
}
示例5: HandleCommand
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);
net->Send(CBaseNetProtocol::Get().SendMapDrawPoint(team, (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);
net->Send(CBaseNetProtocol::Get().SendMapDrawLine(team, (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);
net->Send(CBaseNetProtocol::Get().SendMapErase(team, (short)cmdData->pos.x, (short)cmdData->pos.z));
return 1;
} break;
case AIHCSendStartPosId: {
const AIHCSendStartPos* cmdData = static_cast<AIHCSendStartPos*>(data);
SendStartPos(cmdData->ready, cmdData->pos);
return 1;
} break;
case AIHCGetUnitDefByIdId: {
// NOTE: this command should never arrive, handled in SSkirmishAICallbackImpl
return 0;
} break;
case AIHCGetWeaponDefByIdId: {
// NOTE: this command should never arrive, handled in SSkirmishAICallbackImpl
return 0;
} break;
case AIHCGetFeatureDefByIdId: {
// NOTE: this command should never arrive, handled in SSkirmishAICallbackImpl
return 0;
} break;
case AIHCTraceRayId: {
AIHCTraceRay* cmdData = static_cast<AIHCTraceRay*>(data);
if (CHECK_UNITID(cmdData->srcUID)) {
const CUnit* srcUnit = unitHandler->units[cmdData->srcUID];
if (srcUnit != NULL) {
CUnit* hitUnit = NULL;
CFeature* hitFeature = NULL;
//FIXME add COLLISION_NOFEATURE?
const float realLen = TraceRay::TraceRay(cmdData->rayPos, cmdData->rayDir, cmdData->rayLen, cmdData->flags, srcUnit, hitUnit, hitFeature);
if (hitUnit != NULL) {
myAllyTeamId = teamHandler->AllyTeam(team);
const bool isUnitVisible = unit_IsInLos(hitUnit);
if (isUnitVisible) {
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->units[cmdData->srcUID];
if (srcUnit != NULL) {
CUnit* hitUnit = NULL;
CFeature* hitFeature = NULL;
//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 != NULL) {
const bool isFeatureVisible = hitFeature->IsInLosForAllyTeam(teamHandler->AllyTeam(team));
if (isFeatureVisible) {
cmdData->rayLen = realLen;
cmdData->hitFID = hitFeature->id;
}
}
}
}
return 1;
} break;
case AIHCPauseId: {
AIHCPause* cmdData = static_cast<AIHCPause*>(data);
net->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;
//.........这里部分代码省略.........
示例6: GuiTraceRay
float GuiTraceRay(
const float3& start,
const float3& dir,
float length,
bool useRadar,
const CUnit* exclude,
CUnit*& hitUnit,
CFeature*& hitFeature,
bool groundOnly
) {
hitUnit = NULL;
hitFeature = NULL;
if (dir == ZeroVector)
return -1.0f;
// ground intersection
const float origlength = length;
const float groundLength = ground->LineGroundCol(start, start + dir * origlength, false);
float length2 = length;
if (groundOnly)
return groundLength;
GML_RECMUTEX_LOCK(quad); // GuiTraceRay
int* begQuad = NULL;
int* endQuad = NULL;
bool hitFactory = false;
CollisionQuery cq;
qf->GetQuadsOnRay(start, dir, length, begQuad, endQuad);
std::list<CUnit*>::const_iterator ui;
std::list<CFeature*>::const_iterator fi;
for (int* quadPtr = begQuad; quadPtr != endQuad; ++quadPtr) {
const CQuadField::Quad& quad = qf->GetQuad(*quadPtr);
// Unit Intersection
for (ui = quad.units.begin(); ui != quad.units.end(); ++ui) {
CUnit* unit = *ui;
if (unit == exclude)
continue;
if ((unit->allyteam == gu->myAllyTeam) || gu->spectatingFullView ||
(unit->losStatus[gu->myAllyTeam] & (LOS_INLOS | LOS_CONTRADAR)) ||
(useRadar && radarhandler->InRadar(unit, gu->myAllyTeam)))
{
CollisionVolume cv(unit->collisionVolume);
if (unit->isIcon) {
// for iconified units, just pretend the collision
// volume is a sphere of radius <unit->IconRadius>
// randomize it (by scaling up to a factor of 4) so
// unit size cannot be determined by hovering mouse
// over radar blips
cv.Init(unit->iconRadius * (1.0f + (gu->usRandFloat() * 3.0f)));
}
if (CCollisionHandler::MouseHit(unit, start, start + dir * origlength, &cv, &cq)) {
// get the distance to the ray-volume ingress point
const float3& ingressPos = (cq.b0)? cq.p0 : cq.p1;
const float3& egressPos = (cq.b1)? cq.p1 : cq.p0;
const float ingressDist = (ingressPos - start).dot(dir); // same as (intPos - start).Length()
const float egressDist = ( egressPos - start).dot(dir); // same as (intPos2 - start).Length()
const bool isFactory = unit->unitDef->IsFactoryUnit();
// give units in a factory higher priority than the factory itself
if (!hitUnit ||
(isFactory && ((hitFactory && ingressDist < length) || (!hitFactory && egressDist < length))) ||
(!isFactory && ((hitFactory && ingressDist < length2) || (!hitFactory && ingressDist < length)))) {
hitFactory = isFactory;
length = ingressDist;
length2 = egressDist;
hitUnit = unit;
hitFeature = NULL;
}
}
}
}
// Feature Intersection
// NOTE: switch this to custom volumes fully?
// (not used for any LOF checks, maybe wasteful)
for (fi = quad.features.begin(); fi != quad.features.end(); ++fi) {
CFeature* f = *fi;
// FIXME add useradar?
if (!gu->spectatingFullView && !f->IsInLosForAllyTeam(gu->myAllyTeam))
continue;
if (f->noSelect)
continue;
if (CCollisionHandler::DetectHit(f, start, start + dir * origlength, &cq, true)) {
const float3& ingressPos = (cq.b0)? cq.p0 : cq.p1;
const float ingressDist = (ingressPos - start).dot(dir); // same as (intPos - start).Length()
//.........这里部分代码省略.........
示例7: GuiTraceRay
float GuiTraceRay(const float3 &start, const float3 &dir, float length, bool useRadar, const CUnit* exclude, CUnit*& hitUnit, CFeature*& hitFeature)
{
hitUnit = NULL;
hitFeature = NULL;
if (dir == ZeroVector) {
return -1.0f;
}
bool hover_factory = false;
CollisionQuery cq;
{
GML_RECMUTEX_LOCK(quad); //! GuiTraceRay
const vector<int> &quads = qf->GetQuadsOnRay(start, dir, length);
std::list<CUnit*>::const_iterator ui;
std::list<CFeature*>::const_iterator fi;
for (vector<int>::const_iterator qi = quads.begin(); qi != quads.end(); ++qi) {
const CQuadField::Quad& quad = qf->GetQuad(*qi);
//! Unit Intersection
for (ui = quad.units.begin(); ui != quad.units.end(); ++ui) {
CUnit* unit = *ui;
if (unit == exclude) {
continue;
}
if ((unit->allyteam == gu->myAllyTeam) || gu->spectatingFullView ||
(unit->losStatus[gu->myAllyTeam] & (LOS_INLOS | LOS_CONTRADAR)) ||
(useRadar && radarhandler->InRadar(unit, gu->myAllyTeam)))
{
CollisionVolume cv(unit->collisionVolume);
if (unit->isIcon) {
//! for iconified units, just pretend the collision
//! volume is a sphere of radius <unit->IconRadius>
cv.Init(unit->iconRadius);
}
if (CCollisionHandler::MouseHit(unit, start, start + dir * length, &cv, &cq)) {
//! get the distance to the ray-volume ingress point
const float3& intPos = (cq.b0)? cq.p0 : cq.p1;
const float len = (intPos - start).dot(dir); //! same as (intPos - start).Length()
const bool isfactory = dynamic_cast<CFactory*>(unit);
if (len < length) {
if (!isfactory || !hitUnit || hover_factory) {
hover_factory = isfactory;
length = len;
hitUnit = unit;
hitFeature = NULL;
}
} else if (!isfactory && hover_factory) { //FIXME still check if the unit is BEHIND (and not IN) the factory!
//! give an unit in a factory a higher priority than the factory itself
hover_factory = isfactory;
length = len;
hitUnit = unit;
hitFeature = NULL;
}
}
}
}
//! Feature Intersection
// NOTE: switch this to custom volumes fully?
// (not used for any LOF checks, maybe wasteful)
for (fi = quad.features.begin(); fi != quad.features.end(); ++fi) {
CFeature* f = *fi;
if (!f->collisionVolume) {
continue;
}
//FIXME add useradar?
if (!gu->spectatingFullView && !f->IsInLosForAllyTeam(gu->myAllyTeam)) {
continue;
}
if (f->noSelect) {
continue;
}
if (CCollisionHandler::Intersect(f, start, start + dir * length, &cq)) {
const float3& intPos = (cq.b0)? cq.p0 : cq.p1;
const float len = (intPos - start).dot(dir); //! same as (intPos - start).Length()
//! we want the closest feature (intersection point) on the ray
if (len < length) {
hover_factory = false;
length = len;
hitFeature = f;
hitUnit = NULL;
} else if (hover_factory) { //FIXME still check if the unit is BEHIND (and not IN) the factory!
//! give features in a factory a higher priority than the factory itself
hover_factory = false;
length = len;
hitFeature = f;
hitUnit = NULL;
}
//.........这里部分代码省略.........
示例8: 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);
}
}
}
}
示例9: GuiTraceRay
float GuiTraceRay(
const float3& start,
const float3& dir,
const float length,
const CUnit* exclude,
CUnit*& hitUnit,
CFeature*& hitFeature,
bool useRadar,
bool groundOnly,
bool ignoreWater
) {
hitUnit = NULL;
hitFeature = NULL;
if (dir == ZeroVector)
return -1.0f;
// ground intersection
const float guiRayLength = length;
const float groundRayLength = ground->LineGroundCol(start, start + dir * guiRayLength, false);
const float waterRayLength = math::floor(math::fabs(start.y / std::min(dir.y, -0.00001f)));
float minRayLength = groundRayLength;
float minIngressDist = length;
float minEgressDist = length;
if (!ignoreWater)
minRayLength = std::min(groundRayLength, waterRayLength);
if (groundOnly)
return minRayLength;
GML_RECMUTEX_LOCK(quad); // GuiTraceRay
int* begQuad = NULL;
int* endQuad = NULL;
bool hitFactory = false;
CollisionQuery cq;
quadField->GetQuadsOnRay(start, dir, length, begQuad, endQuad);
std::list<CUnit*>::const_iterator ui;
std::list<CFeature*>::const_iterator fi;
for (int* quadPtr = begQuad; quadPtr != endQuad; ++quadPtr) {
const CQuadField::Quad& quad = quadField->GetQuad(*quadPtr);
// Unit Intersection
for (ui = quad.units.begin(); ui != quad.units.end(); ++ui) {
CUnit* unit = *ui;
const bool unitIsEnemy = !teamHandler->Ally(unit->allyteam, gu->myAllyTeam);
const bool unitOnRadar = (useRadar && radarhandler->InRadar(unit, gu->myAllyTeam));
const bool unitInSight = (unit->losStatus[gu->myAllyTeam] & (LOS_INLOS | LOS_CONTRADAR));
const bool unitVisible = !unitIsEnemy || unitOnRadar || unitInSight || gu->spectatingFullView;
if (unit == exclude)
continue;
if (!unitVisible)
continue;
CollisionVolume cv(unit->collisionVolume);
if (unit->isIcon || (!unitInSight && unitOnRadar && unitIsEnemy)) {
// for iconified units, just pretend the collision
// volume is a sphere of radius <unit->IconRadius>
// (count radar blips as such too)
cv.InitSphere(unit->iconRadius);
}
if (CCollisionHandler::MouseHit(unit, start, start + dir * guiRayLength, &cv, &cq)) {
// get the distance to the ray-volume ingress point
// (not likely to generate inside-hit special cases)
const float ingressDist = cq.GetIngressPosDist(start, dir);
const float egressDist = cq.GetEgressPosDist(start, dir);
const bool isFactory = unit->unitDef->IsFactoryUnit();
const bool factoryHitBeforeUnit = ((hitFactory && ingressDist < minIngressDist) || (!hitFactory && egressDist < minIngressDist));
const bool unitHitInsideFactory = ((hitFactory && ingressDist < minEgressDist) || (!hitFactory && ingressDist < minIngressDist));
// give units in a factory higher priority than the factory itself
if (hitUnit == NULL || (isFactory && factoryHitBeforeUnit) || (!isFactory && unitHitInsideFactory)) {
hitFactory = isFactory;
minIngressDist = ingressDist;
minEgressDist = egressDist;
hitUnit = unit;
hitFeature = NULL;
}
}
}
// Feature Intersection
// NOTE: switch this to custom volumes fully?
// (not used for any LOF checks, maybe wasteful)
for (fi = quad.features.begin(); fi != quad.features.end(); ++fi) {
CFeature* f = *fi;
// FIXME add useradar?
if (!gu->spectatingFullView && !f->IsInLosForAllyTeam(gu->myAllyTeam))
continue;
//.........这里部分代码省略.........
示例10: HandleCommand
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;
//.........这里部分代码省略.........