1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
#ifndef LOSHANDLER_H
#define LOSHANDLER_H
// LosHandler.h: interface for the CLosHandler class.
//
//////////////////////////////////////////////////////////////////////
#include <vector>
#include <list>
#include <deque>
#include <boost/noncopyable.hpp>
#include "MemPool.h"
#include "Map/Ground.h"
#include "Sim/Objects/WorldObject.h"
#include "Sim/Units/Unit.h"
#include "Sim/Misc/RadarHandler.h"
#include <assert.h>
struct LosInstance : public boost::noncopyable
{
CR_DECLARE_STRUCT(LosInstance);
std::vector<int> losSquares;
LosInstance() {} // default constructor for creg
LosInstance(int lossize, int airLosSize, int allyteam, int2 basePos,
int baseSquare, int2 baseAirPos, int hashNum, float baseHeight)
: losSize(lossize),
airLosSize(airLosSize),
refCount(1),
allyteam(allyteam),
basePos(basePos),
baseSquare(baseSquare),
baseAirPos(baseAirPos),
hashNum(hashNum),
baseHeight(baseHeight),
toBeDeleted(false) {}
int losSize;
int airLosSize;
int refCount;
int allyteam;
int2 basePos;
int baseSquare;
int2 baseAirPos;
int hashNum;
float baseHeight;
bool toBeDeleted;
};
class CLosHandler : public boost::noncopyable
{
CR_DECLARE(CLosHandler);
// CR_DECLARE_SUB(CPoint);
CR_DECLARE_SUB(DelayedInstance);
public:
void MoveUnit(CUnit* unit, bool redoCurrent);
void FreeInstance(LosInstance* instance);
bool InLos(const CWorldObject* object, int allyTeam) {
if (object->alwaysVisible || gs->globalLOS) {
return true;
}
else if (object->useAirLos) {
const int gx = (int)(object->pos.x * invAirDiv);
const int gz = (int)(object->pos.z * invAirDiv);
return !!airLosMap[allyTeam].At(gx, gz);
}
else {
const int gx = (int)(object->pos.x * invLosDiv);
const int gz = (int)(object->pos.z * invLosDiv);
return !!losMap[allyTeam].At(gx, gz);
}
}
bool InLos(const CUnit* unit, int allyTeam) {
// NOTE: units are treated differently than world objects in 2 ways:
// 1. they can be cloaked
// 2. when underwater, they only get LOS if they also have sonar
// (when the requireSonarUnderWater variable is enabled)
if (unit->alwaysVisible || gs->globalLOS) {
return true;
}
else if (unit->isCloaked) {
return false;
}
else if (unit->useAirLos) {
const int gx = (int)(unit->pos.x * invAirDiv);
const int gz = (int)(unit->pos.z * invAirDiv);
return !!airLosMap[allyTeam].At(gx, gz);
}
else {
if (unit->isUnderWater && requireSonarUnderWater &&
!radarhandler->InRadar(unit, allyTeam)) {
return false;
}
const int gx = (int)(unit->pos.x * invLosDiv);
const int gz = (int)(unit->pos.z * invLosDiv);
return !!losMap[allyTeam].At(gx, gz);
}
}
bool InLos(float3 pos, int allyTeam) {
if (gs->globalLOS) {
return true;
}
const int gx = (int)(pos.x * invLosDiv);
const int gz = (int)(pos.z * invLosDiv);
return !!losMap[allyTeam].At(gx, gz);
}
bool InAirLos(float3 pos, int allyTeam) {
if (gs->globalLOS) {
return true;
}
const int gx = (int)(pos.x * invAirDiv);
const int gz = (int)(pos.z * invAirDiv);
return !!airLosMap[allyTeam].At(gx, gz);
}
CLosHandler();
~CLosHandler();
std::vector<CLosMap> losMap;
std::vector<CLosMap> airLosMap;
const int losMipLevel;
const int airMipLevel;
const int losDiv;
const int airDiv;
const float invLosDiv;
const float invAirDiv;
const int airSizeX;
const int airSizeY;
const int losSizeX;
const int losSizeY;
const bool requireSonarUnderWater;
private:
void PostLoad();
void LosAdd(LosInstance* instance);
int GetHashNum(CUnit* unit);
void AllocInstance(LosInstance* instance);
void CleanupInstance(LosInstance* instance);
CLosAlgorithm losAlgo;
std::list<LosInstance*> instanceHash[2309+1];
std::deque<LosInstance*> toBeDeleted;
struct DelayedInstance {
CR_DECLARE_STRUCT(DelayedInstance);
LosInstance* instance;
int timeoutTime;
};
std::deque<DelayedInstance> delayQue;
public:
void Update(void);
void DelayedFreeInstance(LosInstance* instance);
};
extern CLosHandler* loshandler;
#endif /* LOSHANDLER_H */
|