123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275 |
- #include "pch.h"
- const char* c_szRadarLODs[] = {
- "Radar mode: All",
- "Radar mode: Default",
- "Radar mode: Target",
- "Radar mode: None"
- };
- /*
- "Radar mode: Ships",
- "Radar mode: Stations",
- "Radar mode: Treasure",
- "Radar mode: Asteroids",
- };
- */
- static const char* c_pszEmpty = "";
- const float rangeClipLabels = 1000.0f;
- const int c_iNotUseful = 0;
- const int c_iUsefulPart = 1;
- const int c_iUsefulTech = 2;
- //////////////////////////////////////////////////////////////////////////////
- //
- // Peripheral Radar Image
- //
- //////////////////////////////////////////////////////////////////////////////
- const int c_maskOrder = 0x01;
- const int c_maskTarget = c_maskOrder << c_cmdCurrent;
- const int c_maskAccepted = c_maskOrder << c_cmdAccepted;
- const int c_maskQueued = c_maskOrder << c_cmdQueued;
- const int c_maskEnemy = 0x08;
- const int c_maskThreat = 0x10;
- const int c_maskFlash = 0x20;
- const int c_maskMe = 0x80;
- const int c_maskSubject = 0x100;
- const int c_maskFlag = 0x200;
- const int c_maskArtifact = 0x400;
- const int c_maskHighlight = 0x800;
- class RadarImageImpl : public RadarImage {
- //////////////////////////////////////////////////////////////////////////////
- //
- // Types
- //
- //////////////////////////////////////////////////////////////////////////////
- class TextData
- {
- public:
- const char* m_pszName;
- int m_range;
- float m_shield;
- float m_hull;
- float m_fill;
- Command m_cmd;
- CommandID m_cid;
- Point m_position;
- Point m_direction;
- Color m_color;
- TextData(const char* pszName,
- int range,
- float shield,
- float hull,
- float fill,
- Command cmd,
- CommandID cid,
- const Point& position,
- const Point& direction,
- const Color& color)
- :
- m_pszName(pszName),
- m_range(range),
- m_shield(shield),
- m_hull(hull),
- m_fill (fill),
- m_cmd(cmd),
- m_cid(cid),
- m_position(position),
- m_direction(direction),
- m_color(color)
- {
- }
- TextData(const TextData& data)
- :
- m_pszName(data.m_pszName),
- m_range(data.m_range),
- m_shield(data.m_shield),
- m_hull(data.m_hull),
- m_fill(data.m_fill),
- m_cmd(data.m_cmd),
- m_cid(data.m_cid),
- m_position(data.m_position),
- m_direction(data.m_direction),
- m_color(data.m_color)
- {
- }
- };
- typedef TList<TextData> TextDataList;
- //////////////////////////////////////////////////////////////////////////////
- //
- // Members
- //
- //////////////////////////////////////////////////////////////////////////////
- TextDataList m_listTextData;
- TRef<Surface> m_psurfaceLastFired;
- TRef<Surface> m_psurfaceTargeted;
- TRef<Surface> m_psurfaceLocked;
- TRef<Surface> m_psurfacePartialLock;
- TRef<Surface> m_psurfaceEnemy;
- TRef<Surface> m_psurfaceMe;
- TRef<Surface> m_psurfaceSubject;
- TRef<Surface> m_psurfaceFlag;
- TRef<Surface> m_psurfaceArtifact;
- TRef<Surface> m_psurfaceTechIcon;
- TRef<Surface> m_psurfaceAccepted[c_cidMax];
- TRef<Surface> m_psurfaceQueued[c_cidMax];
- RadarLOD m_radarLOD;
- TVector<VertexL> m_vertices;
- TVector<WORD> m_indices;
- float m_fRoundRadarRadius;
- static Color s_colorNeutral;
- //////////////////////////////////////////////////////////////////////////////
- //
- // Evaluate gets called when the view size changes
- //
- //////////////////////////////////////////////////////////////////////////////
- void Evaluate (void)
- {
- Color color (0.5f, 0.5f, 0.5f, 0.25f);
- Rect rectImage = GetViewRect()->GetValue();
- {
- Point pointCenter = rectImage.Center();
- rectImage.Offset(-pointCenter);
- rectImage.Expand(-c_flBorderSide);
- }
- // establish the vertex and index array for the round radar circle, and set the indices
- const int cCount = 60;
- const float fAngleStep = RadiansFromDegrees (360.0f / cCount);
- m_vertices.SetCount (cCount);
- m_indices.SetCount (cCount * 2);
- for (int j = 0; j < cCount; j++)
- {
- m_indices.Set (j * 2, j);
- m_indices.Set ((j * 2) + 1, (j + 1) % m_vertices.GetCount ());
- }
- {
- m_fRoundRadarRadius = ((rectImage.YMax () - rectImage.YMin ()) * 0.48f);
- // this recalculates the vertices of the round radar circle
- for (int i = 0; i < m_vertices.GetCount (); i++)
- {
- float fTheta = fAngleStep * static_cast<float> (i),
- fCosTheta = cosf (fTheta),
- fSinTheta = sinf (fTheta);
- m_vertices.Set (i, VertexL (Vector (fCosTheta * m_fRoundRadarRadius, fSinTheta * m_fRoundRadarRadius, 0.0f), color));
- }
- }
- /*
- {
- m_vertices.Set (0, VertexL (Vector (rectImage.XMin(), rectImage.YMin(), 0.0f), color));
- m_vertices.Set (1, VertexL (Vector (rectImage.XMin(), rectImage.YMax(), 0.0f), color));
- m_vertices.Set (2, VertexL (Vector (rectImage.XMax(), rectImage.YMax(), 0.0f), color));
- m_vertices.Set (3, VertexL (Vector (rectImage.XMax(), rectImage.YMin(), 0.0f), color));
- }
- */
- }
- public:
- //////////////////////////////////////////////////////////////////////////////
- //
- // Constructor
- //
- //////////////////////////////////////////////////////////////////////////////
- RadarImageImpl(Modeler* pmodeler, Viewport* pviewport) :
- RadarImage(pviewport),
- m_radarLOD(c_rlDefault)
- {
- m_psurfaceEnemy = pmodeler->LoadSurface(AWF_FLIGHT_ENEMY_ICON, true);
- m_psurfaceMe = pmodeler->LoadSurface(AWF_FLIGHT_ME_ICON, true);
- m_psurfaceTargeted = pmodeler->LoadSurface(AWF_FLIGHT_TARGETED_ICON, true);
- m_psurfaceLocked = pmodeler->LoadSurface(AWF_FLIGHT_MISSILE_LOCKED_ICON, true);
- m_psurfacePartialLock = pmodeler->LoadSurface(AWF_FLIGHT_PARTIAL_MISSILE_LOCK_ICON, true);
- m_psurfaceSubject = pmodeler->LoadSurface(AWF_FLIGHT_SUBJECT_ICON, true);
- m_psurfaceFlag = pmodeler->LoadSurface(AWF_FLIGHT_FLAG_ICON, true);
- m_psurfaceArtifact = pmodeler->LoadSurface(AWF_FLIGHT_ARTIFACT_ICON, true);
- m_psurfaceTechIcon = pmodeler->LoadSurface("icontechbmp", true);
- for (CommandID i = c_cidAttack; (i < c_cidMax); i++)
- {
- if (c_cdAllCommands[i].szAccepted[0] != '\0')
- m_psurfaceAccepted[i] = pmodeler->LoadSurface(c_cdAllCommands[i].szAccepted, true);
- if (c_cdAllCommands[i].szQueued[0] != '\0')
- m_psurfaceQueued[i] = pmodeler->LoadSurface(c_cdAllCommands[i].szQueued, true);
- }
- m_psurfaceLastFired = pmodeler->LoadSurface(AWF_FLIGHT_LASTFIRED_ICON, true);
- }
- void SetRadarLOD(RadarLOD radarLOD)
- {
- m_radarLOD = radarLOD;
- }
- RadarLOD GetRadarLOD(void) const
- {
- return m_radarLOD;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Draw a blip expanded to fit around the object
- //
- //////////////////////////////////////////////////////////////////////////////
- void DrawExpandedBlip(Context* pcontext, float radius, Surface* psurface, const Color& color)
- {
- Point size = Point::Cast(psurface->GetSize());
- float xsize = size.X();
- float ysize = size.Y();
- float xsizeMid = xsize / 2;
- float ysizeMid = ysize / 2;
- float delta = radius / sqrt2;
- {
- float m = xsizeMid / 2;
- if (delta < m)
- delta = m;
- }
- pcontext->DrawImage3D(psurface, Rect( 0, 0, xsizeMid, ysizeMid), color, true, Point(-delta, -delta));
- pcontext->DrawImage3D(psurface, Rect(xsizeMid, 0, xsize, ysizeMid), color, true, Point( delta, -delta));
- pcontext->DrawImage3D(psurface, Rect(xsizeMid, ysizeMid, xsize, ysize), color, true, Point( delta, delta));
- pcontext->DrawImage3D(psurface, Rect( 0, ysizeMid, xsizeMid, ysize), color, true, Point(-delta, delta));
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Draw a blip based on passed parameters
- //
- //////////////////////////////////////////////////////////////////////////////
-
- void DrawBlip(Context* pcontext,
- const Rect& rectImage,
- const Color& colorIcon,
- const Color& colorOther,
- unsigned char ucRadarState,
- ThingSite* pts,
- Surface* psurfaceIcon,
- const char* pszName,
- int range,
- float shield,
- float hull,
- float fill,
- Command cmd,
- CommandID cid,
- int maskBrackets,
- float lock,
- bool bIcon,
- bool bStats)
- {
- float radiusObject = pts->GetScreenRadius();
- {
- static const float maxRadius = sqrt2 * 80.0f;
- if (radiusObject > maxRadius)
- radiusObject = maxRadius;
- }
- float radiusBracket = 1.05f * radiusObject;
- float distanceToEdge = pts->GetDistanceToEdge();
- //Clip the brackets so that they are always entirely on screen
- if (radiusBracket > distanceToEdge + c_flBorderSide)
- radiusBracket = distanceToEdge + c_flBorderSide;
- const Point& positionObject = pts->GetScreenPosition();
- {
- //Draw the brackets around the "object"
- pcontext->Translate(positionObject);
- if (lock != 0.0f)
- {
- if (lock == 1.0f)
- DrawExpandedBlip(pcontext, radiusBracket, m_psurfaceLocked, Color::White());
- else
- DrawExpandedBlip(pcontext, radiusBracket + 40.0f * (1.0f - lock), m_psurfacePartialLock, Color::White());
- }
- if (maskBrackets & c_maskEnemy)
- DrawExpandedBlip(pcontext, radiusBracket, m_psurfaceEnemy, colorOther);
- if (maskBrackets & c_maskMe)
- DrawExpandedBlip(pcontext, radiusBracket, m_psurfaceMe, colorOther);
- if (maskBrackets & c_maskSubject)
- DrawExpandedBlip(pcontext, radiusBracket, m_psurfaceSubject, colorOther);
- if (maskBrackets & c_maskFlag)
- DrawExpandedBlip(pcontext, radiusBracket, m_psurfaceFlag, colorOther);
- else if (maskBrackets & c_maskArtifact)
- DrawExpandedBlip(pcontext, radiusBracket, m_psurfaceArtifact, colorOther);
- if (maskBrackets & c_maskTarget)
- DrawExpandedBlip(pcontext, radiusBracket, m_psurfaceTargeted, colorOther);
- if (maskBrackets & c_maskThreat)
- DrawExpandedBlip(pcontext, radiusBracket, m_psurfaceLastFired, colorOther);
- }
- Point directionCenter;
- {
- directionCenter.SetX(positionObject.X());
- directionCenter.SetY(GetWindow ()->GetRoundRadarMode()
- ? positionObject.Y()
- : (positionObject.Y() - rectImage.Size().Y() / 5.0f));
- float fLengthSquared = directionCenter.X() * directionCenter.X() + directionCenter.Y() * directionCenter.Y();
- if (fLengthSquared < 1.0f)
- {
- directionCenter.SetX(0.0f);
- directionCenter.SetY(-1.0f);
- }
- else
- {
- float f = float(-1.0 / sqrt(fLengthSquared));
- directionCenter.SetX(directionCenter.X() * f);
- directionCenter.SetY(directionCenter.Y() * f);
- }
- }
-
- Point positionIcon;
- if (ucRadarState != c_ucRadarOnScreenLarge)
- {
- positionIcon.SetX(0.0f);
- positionIcon.SetY(0.0f);
- }
- else
- {
- // the radius bracket is big, and the icon should appear near
- // the object instead of off it. Shrinking the radius bracket
- // accomplishes this.
- // XXX difficult to assess for now, Rob is inclined to leave the icon
- // XXX further away to avoid obscuring ships, so we agreed that I could
- // XXX check it in commented out.
- // radiusBracket *= 0.5f;
- //Get the vector from the object to the center of the screen
- //where this direction for something close to the center of the
- //screen is always straight down.
- {
- float f = (distanceToEdge < radiusBracket) ? distanceToEdge : radiusBracket;
- positionIcon.SetX(directionCenter.X() * f);
- positionIcon.SetY(directionCenter.Y() * f);
- }
- }
- if (bIcon)
- {
- pcontext->Translate(positionIcon);
- pcontext->SetBlendMode(BlendModeAdd);
- pcontext->DrawImage3D(psurfaceIcon, colorIcon, true);
- }
- if ((pszName[0] != '\0') || (range > 0) || bStats)
- {
- Point positionLabel = positionObject + positionIcon;
- if (maskBrackets & (c_maskTarget | c_maskAccepted | c_maskThreat))
- m_listTextData.PushEnd(TextData(pszName, range, shield, hull, fill, cmd, cid, positionLabel, directionCenter, colorOther));
- else
- m_listTextData.PushFront(TextData(pszName, range, shield, hull, fill, cmd, cid, positionLabel, directionCenter, colorOther));
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Render one blip for each object in the cluster
- //
- //////////////////////////////////////////////////////////////////////////////
- static int UsefulTreasure(IshipIGC* pship, ItreasureIGC* pt)
- {
- TreasureCode tc = pt->GetTreasureCode();
- switch (tc)
- {
- case c_tcPowerup:
- {
- if (!pship->GetCluster())
- return c_iNotUseful;
- }
- //no break
- case c_tcCash:
- case c_tcFlag:
- {
- return c_iUsefulPart;
- }
- break;
- case c_tcDevelopment:
- {
- IdevelopmentIGC* pd = trekClient.m_pCoreIGC->GetDevelopment(pt->GetTreasureID());
- assert (pd);
- return pd->IsObsolete(trekClient.GetSide()->GetDevelopmentTechs())
- ? c_iNotUseful
- : c_iUsefulPart; //It really is a tech, but use its icon instead of the special icon
- }
- break;
- default:
- {
- assert (tc == c_tcPart);
- IpartTypeIGC* ppt = trekClient.m_pCoreIGC->GetPartType(pt->GetTreasureID());
- assert (ppt);
- EquipmentType et = ppt->GetEquipmentType();
- if (et == ET_Pack)
- {
- if (pship->GetCluster() != NULL)
- {
- const DataPackTypeIGC* pdata = (const DataPackTypeIGC*)(ppt->GetData());
- if (pdata->packType == c_packFuel)
- {
- //Fuel is useful only if we have an afterburner
- return (pship->GetMountedPart(ET_Afterburner, 0) != NULL)
- ? c_iUsefulPart
- : c_iNotUseful;
- }
- else
- {
- assert (pdata->packType == c_packAmmo);
- Mount m = pship->GetHullType()->GetMaxWeapons();
- for (Mount i = 0; (i < m); i++)
- {
- IweaponIGC* pw = (IweaponIGC*)(pship->GetMountedPart(ET_Weapon, i));
- if (pw && (pw->GetAmmoPerShot() != 0))
- return c_iUsefulPart;
- }
- }
- }
- return c_iNotUseful;
- }
- else
- {
- if (!(ppt->GetEffectTechs() <= trekClient.GetSide()->GetDevelopmentTechs()))
- return c_iUsefulTech;
- if (IlauncherTypeIGC::IsLauncherType(et) && pship->GetCluster() && pship->GetHullType()->CanMount(ppt, 0))
- return c_iUsefulPart;
- return c_iNotUseful;
- }
- }
- break;
- }
- }
- void RenderBlips(Context* pcontext, const Rect& rectImage)
- {
- IclusterIGC* pcluster = trekClient.GetCluster();
- if (pcluster == NULL)
- return;
- const ModelListIGC* models = pcluster->GetPickableModels();
- ZAssert(models != NULL);
- bool bRangeLabels = !TrekWindow::CommandCamera(GetWindow()->GetCameraMode());
- assert (trekClient.GetShip()->GetCluster() || !bRangeLabels);
- //
- // Draw a blip for every model in the cluster
- //
- IshipIGC* pshipSource = trekClient.GetShip()->GetSourceShip();
- const Vector& vecPositionPlayer = pshipSource->GetPosition();
- float radiusSource = pshipSource->GetRadius();
- ImodelIGC* pmodelOrders[c_cmdMax];
- {
- // For command targets not in the current sector ... show the user how to get there.
- for (Command i = 0; (i <= c_cmdCurrent); i++) //Explicitly do not handle the case of planned
- {
- pmodelOrders[i] = trekClient.GetShip()->GetCommandTarget(i);
- if (pmodelOrders[i])
- {
- IclusterIGC* c = pmodelOrders[i]->GetCluster();
- if (pmodelOrders[i]->GetObjectType() == OT_ship)
- {
- pmodelOrders[i] = ((IshipIGC*)pmodelOrders[i])->GetSourceShip();
- if (c == NULL)
- c = trekClient.GetCluster(trekClient.GetShip(), pmodelOrders[i]);
- }
- if (c == NULL)
- pmodelOrders[i] = NULL;
- else
- {
- IclusterIGC* pcluster = trekClient.GetShip()->GetCluster();
- if (pcluster && (c != pcluster))
- {
- // The target is not in the sector ... find out how to get to the target
- pmodelOrders[i] = FindPath(trekClient.GetShip(), pmodelOrders[i], false);
- }
- }
- }
- }
- }
- const ShipListIGC* psubjects;
- if (bRangeLabels)
- psubjects = NULL;
- else
- psubjects = GetWindow()->GetConsoleImage()->GetSubjects();
- IsideIGC* psideMine = trekClient.GetShip()->GetSide();
- float capacity = trekClient.m_pCoreIGC->GetFloatConstant(c_fcidCapacityHe3) *
- psideMine->GetGlobalAttributeSet().GetAttribute(c_gaMiningCapacity);
- Time now = Time::Now();
- ImodelIGC* pmodelEnemy = bRangeLabels
- ? FindTarget(pshipSource, c_ttShip | c_ttEnemy | c_ttNearest)
- : NULL;
- for (ModelLinkIGC* l = models->first();
- (l != NULL); l = l->next())
- {
- ImodelIGC* pmodel = l->data();
- if (pmodel->GetVisibleF() && pshipSource->CanSee(pmodel))
- {
- ObjectType type = pmodel->GetObjectType();
- Surface* psurfaceIcon = (Surface*)(pmodel->GetIcon());
- if (psurfaceIcon)
- {
- int maskBrackets = 0x00;
- const char* pszName = pmodel->GetName();
- Command cmd;
- CommandID cidOrder = c_cidNone;
- {
- for (Command i = 0; (i < c_cmdMax); i++)
- {
- if (pmodel == pmodelOrders[i])
- {
- maskBrackets |= (c_maskOrder << i);
- CommandID cid = trekClient.GetShip()->GetCommandID(i);
- if (cid != c_cidNone)
- {
- cmd = i;
- cidOrder = cid;
- }
- }
- }
- }
- float lock = 0.0f;
- if (maskBrackets & c_maskTarget)
- {
- ImagazineIGC* magazine = (ImagazineIGC*)(trekClient.GetShip()->GetMountedPart(ET_Magazine, 0));
- if (magazine)
- lock = magazine->GetLock();
- }
- float separation = (pmodel->GetPosition() - vecPositionPlayer).Length();
- int range;
- {
- if ((pmodel == pshipSource) || !bRangeLabels)
- range = 0;
- else
- range = int(separation + 0.5f);
- }
- separation -= radiusSource + pmodel->GetRadius();
- if (type == OT_treasure)
- {
- if (((ItreasureIGC*)pmodel)->GetTreasureCode() == c_tcFlag)
- maskBrackets |= c_maskHighlight;
- }
- else
- {
- SideID sidFlag = pmodel->GetFlag();
- if (sidFlag != NA)
- maskBrackets |= (sidFlag == SIDE_TEAMLOBBY) ? c_maskArtifact : c_maskFlag;
- }
- ThingSite* pts = pmodel->GetThingSite();
- unsigned char ucRadarState = pts->GetRadarState();
- if (psubjects && (type == OT_ship) && psubjects->find((IshipIGC*)pmodel))
- maskBrackets |= c_maskSubject;
- if (pmodel == pmodelEnemy)
- maskBrackets |= c_maskEnemy;
- {
- const DamageBucketList* b = pmodel->GetDamageBuckets();
- if (b->n() != 0)
- {
- assert (b->n() == 1);
- DamageBucket* db = b->first()->data();
- maskBrackets |= (db->flash(now))
- ? (c_maskThreat | c_maskFlash)
- : c_maskThreat;
- }
- }
- //
- // Color for the side
- //
- IsideIGC* pside = pmodel->GetSide();
- if (pmodel == pshipSource)
- maskBrackets |= c_maskMe;
- Color color = pside
- ? ((maskBrackets & c_maskFlash) ? Color::Red() : pside->GetColor())
- : s_colorNeutral;
- /*
- static const int closeRange = 100;
- static const int farRange = 1000;
- static const float closeAlpha = 0.75f;
- static const float farAlpha = 0.25f;
- color.SetAlpha((range < closeRange)
- ? closeAlpha
- : ((range > farRange)
- ? farAlpha
- : (farAlpha +
- (float(range - farRange) * (closeAlpha - farAlpha) / float(closeRange - farRange)))));
- */
- bool bIcon = true;
- bool bLabel = ((maskBrackets & (c_maskTarget |
- c_maskAccepted |
- c_maskQueued |
- c_maskHighlight |
- c_maskThreat |
- c_maskFlag |
- c_maskArtifact)) != 0);
- bool bStats = bLabel;
- if (bLabel)
- {
- if ((type == OT_treasure) &&
- (UsefulTreasure(pshipSource, (ItreasureIGC*)pmodel) == c_iUsefulTech))
- {
- psurfaceIcon = m_psurfaceTechIcon;
- }
- }
- else
- {
- if (m_radarLOD == c_rlMinimal)
- {
- if (pmodel != pshipSource)
- {
- bIcon = false;
- range = 0;
- }
- }
- else
- {
- switch (type)
- {
- case OT_ship:
- {
- switch (m_radarLOD)
- {
- case c_rlAll:
- {
- bLabel = bStats = true;
- if ((ucRadarState == c_ucRadarOffScreen) && (pside == psideMine))
- range = 0;
- }
- break;
- case c_rlDefault:
- {
- if ((ucRadarState != c_ucRadarOffScreen) || (separation < rangeClipLabels))
- bLabel = true;
- if (pside == psideMine)
- range = 0;
- else
- bStats = true;
- }
- break;
- case c_rlTarget:
- {
- if (pside == psideMine)
- {
- if (pmodel != pshipSource)
- {
- bIcon = false;
- range = 0;
- }
- }
- else
- {
- if (ucRadarState != c_ucRadarOffScreen)
- bStats = true;
- if (separation < rangeClipLabels)
- bLabel = true;
- }
- }
- break;
- }
- }
- break;
- case OT_station:
- {
- if (((IstationIGC*)pmodel)->GetBaseStationType()->HasCapability(c_sabmPedestal))
- {
- if (separation >= rangeClipLabels)
- {
- bIcon = bLabel = bStats = false;
- range = 0;
- }
- }
- else
- {
- switch (m_radarLOD)
- {
- case c_rlAll:
- {
- bLabel = bStats = true;
- }
- break;
- case c_rlDefault:
- {
- if ((separation >= rangeClipLabels) || (ucRadarState == c_ucRadarOffScreen))
- range = 0;
- }
- break;
- case c_rlTarget:
- {
- range = 0;
- if ((pside == psideMine) && (ucRadarState == c_ucRadarOffScreen))
- bIcon = false;
- }
- break;
- }
- }
- }
- break;
- case OT_missile:
- {
- if (m_radarLOD != c_rlAll)
- {
- ImodelIGC* pmodelTarget = ((ImissileIGC*)pmodel)->GetTarget();
- if ((pmodelTarget == NULL) || (pmodelTarget->GetSide() != psideMine))
- {
- bIcon = false;
- range = 0;
- }
- }
- }
- break;
- case OT_probe:
- case OT_mine:
- {
- switch (m_radarLOD)
- {
- case c_rlAll:
- {
- if (pside == psideMine)
- {
- if ((ucRadarState == c_ucRadarOffScreen) && (separation >= rangeClipLabels))
- range = 0;
- }
- else
- {
- if (ucRadarState != c_ucRadarOffScreen)
- bLabel = true;
- }
- bStats = true;
- }
- break;
- case c_rlDefault:
- {
- if (pside == psideMine)
- {
- if (separation >= rangeClipLabels)
- range = 0;
- }
- }
- break;
- case c_rlTarget:
- {
- if ((pside == psideMine) || (separation >= rangeClipLabels))
- {
- bIcon = false;
- range = 0;
- }
- }
- break;
- }
- }
- break;
- case OT_treasure:
- {
- int iUseful = UsefulTreasure(pshipSource, (ItreasureIGC*)pmodel);
- if (iUseful != c_iNotUseful)
- {
- bLabel = (m_radarLOD == c_rlAll);
- if ((m_radarLOD == c_rlTarget) && (separation >= rangeClipLabels))
- {
- bIcon = false;
- range = 0;
- }
- else if (iUseful == c_iUsefulTech)
- {
- psurfaceIcon = m_psurfaceTechIcon;
- }
- }
- else if (m_radarLOD != c_rlAll)
- {
- bIcon = false;
- range = 0;
- }
- }
- break;
- case OT_asteroid:
- {
- switch (m_radarLOD)
- {
- case c_rlAll:
- {
- if ((pszName[0] == '\0') || (pszName[0] == 'A'))
- {
- if (separation >= rangeClipLabels)
- {
- bIcon = false;
- range = 0;
- }
- else if (range == 0)
- bIcon = false;
- }
- else
- bLabel = bStats = true;
- }
- break;
- case c_rlDefault:
- {
- if ((pszName[0] == '\0') || (pszName[0] == 'A'))
- {
- if (separation >= rangeClipLabels)
- {
- bIcon = false;
- range = 0;
- }
- else if (range == 0)
- bIcon = false;
- }
- }
- break;
- case c_rlTarget:
- {
- if (separation >= rangeClipLabels)
- {
- bIcon = false;
- range = 0;
- }
- else if (range == 0)
- bIcon = false;
- }
- break;
- }
- }
- break;
- case OT_warp:
- {
- bLabel = (m_radarLOD <= c_rlDefault);
- if ((m_radarLOD == c_rlTarget) && (separation >= rangeClipLabels))
- range = 0;
- }
- break;
- }
- }
- }
- float shield = 2.0f;
- float hull = 2.0f;
- float fill = 2.0f;
- if (!bLabel)
- {
- pszName = c_pszEmpty;
- }
- else if (pszName[0] == '\0')
- {
- pszName = GetModelName(pmodel);
- }
- if (bStats)
- {
- switch(type)
- {
- case OT_ship:
- {
- IshipIGC* pship = static_cast<IshipIGC*> (pmodel);
- IshieldIGC* pshield = static_cast<IshieldIGC*> (pship->GetMountedPart(ET_Shield, 0));
- shield = pshield ? pshield->GetFraction() : 2.0f;
- hull = ((IdamageIGC*)pmodel)->GetFraction();
- // this really only works if the server updates the client with
- // the information. We would have to add a new message type
- // for that to happen, so for now I'm just commenting it out and
- // moving on.
- /*
- if (pship->GetPilotType () == c_ptMiner)
- {
- fill = pship->GetOre () / capacity;
- if (fill > 1.0f)
- fill = 1.0f;
- }
- */
- }
- break;
- case OT_station:
- {
- shield = ((IstationIGC*)pmodel)->GetShieldFraction();
- hull = ((IdamageIGC*)pmodel)->GetFraction();
- }
- break;
- case OT_asteroid:
- {
- hull = ((IdamageIGC*)pmodel)->GetFraction();
- float ore = ((IasteroidIGC*)pmodel)->GetOre();
- if (ore != 0.0f)
- {
- // this is displaying how many shiploads of ore are on the asteroid.
- // more than two is shown as full.
- fill = ore / (2.0f * capacity);
- if (fill > 1.0f)
- fill = 1.0f;
- }
- }
- break;
- case OT_mine:
- {
- fill = ((ImineIGC*)pmodel)->GetTimeFraction();
- }
- break;
- case OT_probe:
- {
- fill = ((IprobeIGC*)pmodel)->GetTimeFraction();
- hull = ((IprobeIGC*)pmodel)->GetFraction();
- }
- break;
- }
- }
- //
- // Draw the Blip
- //
- Color colorOther(color);
- if ((maskBrackets & (c_maskTarget | c_maskAccepted | c_maskThreat | c_maskHighlight | c_maskFlag | c_maskArtifact)) == 0)
- colorOther = (maskBrackets & c_maskQueued)
- ? (colorOther * 0.75f)
- : (colorOther * 0.5f);
- pcontext->PushState();
- DrawBlip(pcontext,
- rectImage,
- color,
- colorOther,
- ucRadarState,
- pts,
- psurfaceIcon,
- pszName,
- range,
- shield,
- hull,
- fill,
- cmd,
- cidOrder,
- maskBrackets,
- lock,
- bIcon,
- bStats);
- pcontext->PopState();
- }
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Draw a circle bordering the round radar
- //
- //////////////////////////////////////////////////////////////////////////////
- void RenderRoundBorder (Context* pcontext, const Rect& rectImage)
- {
- pcontext->PushState ();
- pcontext->SetClipping (false);
- pcontext->SetBlendMode (BlendModeSourceAlpha);
- pcontext->DrawLines(m_vertices, m_indices);
- pcontext->PopState ();
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Render the image
- //
- //////////////////////////////////////////////////////////////////////////////
- void Render(Context* pcontext)
- {
- if (m_radarLOD != c_rlNone)
- {
- //
- // Use flat shading
- //
- pcontext->SetShadeMode(ShadeModeFlat);
- pcontext->SetLinearFilter(false, true);
- //
- // Shrink the rect size by half the size of the gauge bitmap
- // and center the rect around the origin
- //
- Rect rectImage = GetViewRect()->GetValue();
- {
- Point pointCenter = rectImage.Center();
- pcontext->Translate(pointCenter);
- }
- //
- // Draw the round border if appropriate
- //
- if (GetWindow ()->GetRoundRadarMode ())
- RenderRoundBorder (pcontext, rectImage);
- //
- // Draw some Blips
- //
- RenderBlips(pcontext, rectImage);
- //
- // Draw the text
- //
- TRef<IEngineFont> pfont = TrekResources::SmallFont();
- float heightFont = float(pfont->GetHeight());
- TextDataList::Iterator iter(m_listTextData);
- while (!iter.End())
- {
- const TextData& data = iter.Value();
- float lines = 0.0f;
- float width = 0.0f;
- if (data.m_pszName[0] != '\0')
- {
- float w = (float)(pfont->GetTextExtent(data.m_pszName).X());
- if (w > width)
- width = w;
- lines += 1.0f;
- }
- char szRange[20];
- if (data.m_range > 0)
- {
- _itoa(data.m_range, szRange, 10);
- float w = (float)(pfont->GetTextExtent(szRange).X());
- if (w > width)
- width = w;
- lines += 1.0f;
- }
- if (data.m_shield <= 1.0f)
- {
- lines += 0.5f;
- }
- if (data.m_hull <= 1.0f)
- {
- lines += 0.5f;
- }
- if (data.m_fill <= 1.0f)
- {
- lines += 0.5f;
- }
- Surface* psurfaceIcon = NULL;
- float xshift;
- if (data.m_cid != c_cidNone)
- {
- assert (data.m_cid >= 0);
- assert (data.m_cid < c_cidMax);
- psurfaceIcon = (data.m_cmd != c_cmdQueued) ? m_psurfaceAccepted[data.m_cid] : m_psurfaceQueued[data.m_cid];
- if (psurfaceIcon)
- {
- Point size = Point::Cast(psurfaceIcon->GetSize());
- xshift = size.X();
- width += xshift;
- }
- }
- //Find the offset to center the text at position + offset
- Point offset(data.m_position.X() - 0.5f * width, data.m_position.Y() + heightFont * 0.5f * (lines - 2.0f));
- //Adjust the offset by the amount required to move a point from the center to the edge
- //in the specified direction
- {
- float w = width + 15.0f;
- float h = heightFont * lines + 15.0f;
- float x = data.m_direction.X();
- float y = data.m_direction.Y();
-
- if (x == 0.0f)
- y = (y < 0.0f) ? -h : h;
- else if (y == 0.0f)
- x = (x <= 0.0f) ? -w : w;
- else
- {
- float tX = w / float(fabs(x));
- float tY = h / float(fabs(y));
- float tMin = (tX < tY) ? tX : tY;
- x *= tMin;
- y *= tMin;
- }
- offset.SetX(offset.X() + x * 0.5f);
- offset.SetY(offset.Y() + y * 0.5f);
- if (psurfaceIcon)
- {
- offset.SetX(offset.X() + xshift * 0.5f);
- pcontext->DrawImage3D(psurfaceIcon, data.m_color, true, offset);
- offset.SetX(offset.X() + xshift * 0.5f);
- }
- }
- if (data.m_pszName[0] != '\0')
- {
- pcontext->DrawString(pfont, data.m_color, offset, ZString(data.m_pszName));
- offset.SetY(offset.Y() - heightFont);
- }
- if (data.m_range > 0)
- {
- pcontext->DrawString(pfont, data.m_color, offset, ZString(szRange));
- offset.SetY(offset.Y() - heightFont);
- }
- if ((data.m_hull <= 1.0f) || (data.m_fill <= 1.0f))
- {
- const float c_width = 16.0f;
- float xOffset = float(floor(offset.X()));
- float yOffset = float(floor(offset.Y() + heightFont - 4.0f));
- // draw the ore fill state if needed
- if (data.m_fill <= 1.0f)
- {
- Rect rectFill (xOffset, yOffset, xOffset + (c_width * data.m_fill), yOffset + 2.0f);
- pcontext->FillRect (rectFill, data.m_color);
- // if the value isn't 1.0f, the bar has two parts, here we draw the "empty" part
- if (data.m_fill < 1.0f)
- {
- rectFill.SetXMin(rectFill.XMax());
- rectFill.SetXMax(xOffset + c_width);
- pcontext->FillRect(rectFill, Color(0.333f, 0.0f, 0.0f));
- }
- yOffset -= 4.0f;
- }
- // if shield is valid, draw it and update the hull bar location
- if (data.m_shield <= 1.0f)
- {
- Rect rectShield (xOffset, yOffset, xOffset + c_width * data.m_shield, yOffset + 2.0f);
- pcontext->FillRect (rectShield, data.m_color);
- // if the value isn't 1.0f, the bar has two parts, here we draw the "empty" part
- if (data.m_shield < 1.0f)
- {
- rectShield.SetXMin(rectShield.XMax());
- rectShield.SetXMax(xOffset + c_width);
- pcontext->FillRect(rectShield, Color(1.0f, 0.0f, 0.0f));
- }
- yOffset -= 4.0f;
- }
- // if hull is valid, so draw it and update the hull bar location
- if (data.m_hull <= 1.0f)
- {
- Rect rectHull (xOffset, yOffset, xOffset + c_width * data.m_hull, yOffset + 2.0f);
- pcontext->FillRect(rectHull, data.m_color);
- // if the value isn't 1.0f, the bar has two parts, here we draw the "empty" part
- if (data.m_hull < 1.0f)
- {
- rectHull.SetXMin(rectHull.XMax());
- rectHull.SetXMax(xOffset + c_width);
- pcontext->FillRect(rectHull, Color(1.0f, 0.0f, 0.0f));
- }
- }
- }
- iter.Next();
- }
- m_listTextData.SetEmpty();
- }
- }
- };
- Color RadarImageImpl::s_colorNeutral(1, 1, 1);
- //////////////////////////////////////////////////////////////////////////////
- //
- // RadarImage Constructor
- //
- //////////////////////////////////////////////////////////////////////////////
- TRef<RadarImage> RadarImage::Create(Modeler* pmodeler, Viewport* pviewport)
- {
- return new RadarImageImpl(pmodeler, pviewport);
- }
|