UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ui_node_radar.cpp
Go to the documentation of this file.
1 
5 /*
6 Copyright (C) 2002-2020 UFO: Alien Invasion.
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17 See the GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 
23 */
24 
25 #include "ui_node_radar.h"
26 #include "ui_node_abstractnode.h"
27 #include "../ui_render.h"
28 #include "../ui_main.h"
29 #include "../ui_behaviour.h"
30 #include "../ui_input.h"
31 
32 #include "../../client.h"
33 #include "../../battlescape/cl_hud.h" /* cl_worldlevel cvar */
34 #include "../../renderer/r_draw.h"
35 #include "../../../shared/parse.h"
36 
37 #include "../../../common/scripts_lua.h"
38 
40 typedef struct hudRadarImage_s {
41  /* image */
42  char* name;
44  int x, y;
45  int width, height;
47  /* position of this piece into the map */
48  float mapX;
49  float mapY;
50  float mapWidth;
51  float mapHeight;
52 
53  bool isTile;
54  int gridX, gridY;
56  int gridWidth;
57  int maxlevel;
59 
60 typedef struct hudRadar_s {
64  char base[MAX_QPATH];
65  int numImages;
66  hudRadarImage_t images[MAX_MAPTILES];
74  vec3_t a, b, c;
76  int x, y;
78  int w, h;
79 } hudRadar_t;
80 
82 
83 static void UI_FreeRadarImages (void)
84 {
85  for (int i = 0; i < radar.numImages; i++) {
86  hudRadarImage_t* image = &radar.images[i];
87  Mem_Free(image->name);
88  for (int j = 0; j < image->maxlevel; j++)
89  Mem_Free(image->path[j]);
90  }
91  OBJZERO(radar);
92 }
93 
103 static void UI_BuildRadarImageList (const char* tiles, const char* pos)
104 {
105  const float mapMidX = cl.mapData->mapBox.getWidthX() * 0.5;
106  const float mapMidY = cl.mapData->mapBox.getWidthY() * 0.5;
107 
108  /* load tiles */
109  while (tiles) {
110  vec3_t sh;
111  char name[MAX_VAR];
112  /* get tile name */
113  const char* token = Com_Parse(&tiles);
114  if (!tiles) {
115  /* finish */
116  return;
117  }
118 
119  /* get base path */
120  if (token[0] == '-') {
121  Q_strncpyz(radar.base, token + 1, sizeof(radar.base));
122  continue;
123  }
124 
125  /* get tile name */
126  if (token[0] == '+')
127  token++;
128  Com_sprintf(name, sizeof(name), "%s%s", radar.base, token);
129 
130  hudRadarImage_t* image = &radar.images[radar.numImages++];
131  image->name = Mem_StrDup(name);
132 
133  image->isTile = pos && pos[0];
134  if (!image->isTile)
135  /* it is a single background image*/
136  return;
137 
138  /* get grid position and add a tile */
139  for (int i = 0; i < 3; i++) {
140  token = Com_Parse(&pos);
141  if (!pos)
142  Com_Error(ERR_DROP, "UI_BuildRadarImageList: invalid positions\n");
143  sh[i] = atoi(token);
144  }
145  image->gridX = sh[0];
146  image->gridY = sh[1];
147  image->mapX = mapMidX + sh[0] * UNIT_SIZE;
148  image->mapY = mapMidY + sh[1] * UNIT_SIZE;
149  Com_Printf("radar %s %dx%d\n", name, image->gridX, image->gridY);
150 
151  if (radar.gridMin[0] > sh[0])
152  radar.gridMin[0] = sh[0];
153  if (radar.gridMin[1] > sh[1])
154  radar.gridMin[1] = sh[1];
155  }
156 }
157 
164 static void UI_GetRadarWidth (const uiNode_t* node, vec2_t gridSize)
165 {
166  int tileWidth[2];
167  int tileHeight[2];
168  int secondTileGridX;
169  int secondTileGridY;
170  float ratioConversion;
171  const int ROUNDING_PIXEL = 1;
175  /* Set radar.gridMax */
176  radar.gridMax[0] = radar.gridMin[0];
177  radar.gridMax[1] = radar.gridMin[1];
178 
179  /* Initialize secondTileGridX to value higher that real value */
180  secondTileGridX = radar.gridMin[0] + 1000;
181  secondTileGridY = radar.gridMin[1] + 1000;
182 
183  /* Initialize screen size of last tile (will be used only if there is 1 tile in a line or in a row) */
184  Vector2Set(tileWidth, 0, 0);
185  Vector2Set(tileHeight, 0, 0);
186 
187  for (int j = 0; j < radar.numImages; j++) {
188  const hudRadarImage_t* image = &radar.images[j];
189 
190  assert(image->gridX >= radar.gridMin[0]);
191  assert(image->gridY >= radar.gridMin[1]);
192 
193  /* we can assume this because every random map tile has it's origin in
194  * (0, 0) and therefore there are no intersections possible on the min
195  * x and the min y axis. We just have to add the image->w and image->h
196  * values of those images that are placed on the gridMin values.
197  * This also works for static maps, because they have a gridX and gridY
198  * value of zero */
199 
200  if (image->gridX == radar.gridMin[0]) {
201  /* radar.gridMax[1] is the maximum for FIRST column (maximum depends on column) */
202  if (image->gridY > radar.gridMax[1]) {
203  tileHeight[1] = image->height;
204  radar.gridMax[1] = image->gridY;
205  }
206  if (image->gridY == radar.gridMin[1]) {
207  /* This is the tile of the map in the lower left: */
208  tileHeight[0] = image->height;
209  tileWidth[0] = image->width;
210  } else if (image->gridY < secondTileGridY)
211  secondTileGridY = image->gridY;
212  }
213  if (image->gridY == radar.gridMin[1]) {
214  /* radar.gridMax[1] is the maximum for FIRST line (maximum depends on line) */
215  if (image->gridX > radar.gridMax[0]) {
216  tileWidth[1] = image->width;
217  radar.gridMax[0] = image->gridX;
218  } else if (image->gridX < secondTileGridX)
219  secondTileGridX = image->gridX;
220  }
221  }
222 
223  /* Maybe there was only one tile in a line or in a column? */
224  if (!tileHeight[1])
225  tileHeight[1] = tileHeight[0];
226  if (!tileWidth[1])
227  tileWidth[1] = tileWidth[0];
228 
229  /* Now we get the ratio conversion between screen coordinates and grid coordinates.
230  * The problem is that some tiles may have L or T shape.
231  * But we now that the tile in the lower left follows for sure the side of the map on it's whole length
232  * at least either on its height or on its width.*/
233  ratioConversion = std::max((secondTileGridX - radar.gridMin[0]) / (tileWidth[0] - ROUNDING_PIXEL),
234  (secondTileGridY - radar.gridMin[1]) / (tileHeight[0] - ROUNDING_PIXEL));
235 
236  /* And now we fill radar.w and radar.h */
237  radar.w = floor((radar.gridMax[0] - radar.gridMin[0]) / ratioConversion) + tileWidth[1];
238  radar.h = floor((radar.gridMax[1] - radar.gridMin[1]) / ratioConversion) + tileHeight[1];
239 
240  Vector2Set(gridSize, round(radar.w * ratioConversion), round(radar.h * ratioConversion));
241 }
242 
243 static char const* const imageExtensions[] = {
244  "jpg", "png", nullptr
245 };
246 
247 static bool UI_CheckRadarImage (const char* imageName, const int level)
248 {
249  char const* const* ext = imageExtensions;
250 
251  while (*ext) {
252  if (FS_CheckFile("pics/radars/%s_%i.%s", imageName, level, *ext) > 0)
253  return true;
254  ext++;
255  }
256  /* none found */
257  return false;
258 }
259 
265 static void UI_InitRadar (const uiNode_t* node)
266 {
267  int i, j;
268  const vec3_t offset = {MAP_SIZE_OFFSET, MAP_SIZE_OFFSET, MAP_SIZE_OFFSET};
269  float distAB, distBC;
270  vec2_t gridSize;
271  vec2_t nodepos;
272  vec2_t min;
273  vec2_t max;
274 
277 
278  UI_GetNodeAbsPos(node, nodepos);
279  radar.x = nodepos[0] + node->box.size[0] / 2;
280  radar.y = nodepos[1] + node->box.size[1] / 2;
281 
282  /* only check once per map whether all the needed images exist */
283  for (j = 0; j < radar.numImages; j++) {
284  hudRadarImage_t* tile = &radar.images[j];
285  /* map_mins, map_maxs */
286  for (i = 0; i < PATHFINDING_HEIGHT; i++) {
287  char imagePath[MAX_QPATH];
288  const image_t* image;
289  if (!UI_CheckRadarImage(tile->name, i + 1)) {
290  if (i == 0) {
291  /* there should be at least one level */
292  Com_Printf("No radar images for map: '%s'\n", tile->name);
293  radar.numImages = 0;
294  return;
295  }
296  continue;
297  }
298 
299  Com_sprintf(imagePath, sizeof(imagePath), "radars/%s_%i", tile->name, i + 1);
300  tile->path[i] = Mem_StrDup(imagePath);
301  tile->maxlevel++;
302 
303  image = R_FindImage(va("pics/%s", tile->path[i]), it_pic);
304  tile->width = image->width;
305  tile->height = image->height;
306  if (tile->isTile) {
307  tile->gridWidth = round(image->width / 94.0f);
308  tile->gridHeight = round(image->height / 94.0f);
309  tile->mapWidth = tile->gridWidth * 8 * UNIT_SIZE;
310  tile->mapHeight = tile->gridHeight * 8 * UNIT_SIZE;
311  } else {
312  tile->mapX = cl.mapData->mapBox.getMinX();
313  tile->mapY = cl.mapData->mapBox.getMinY();
314  tile->mapWidth = cl.mapData->mapBox.getWidthX();
315  tile->mapHeight = cl.mapData->mapBox.getWidthY();
316  }
317  }
318  if (tile->isTile) {
319  tile->mapY = cl.mapData->mapBox.getMaxY() - tile->mapY - tile->mapHeight;
320  }
321  }
322 
323  /* center tiles into the minMap/maxMap */
326  for (j = 0; j < radar.numImages; j++) {
327  hudRadarImage_t* tile = &radar.images[j];
328  if (tile->mapX < min[0])
329  min[0] = tile->mapX;
330  if (tile->mapY < min[1])
331  min[1] = tile->mapY;
332  if (tile->mapX + tile->mapWidth > max[0])
333  max[0] = tile->mapX + tile->mapWidth;
334  if (tile->mapY + tile->mapHeight > max[1])
335  max[1] = tile->mapY + tile->mapHeight;
336  }
337  /* compute translation */
338  min[0] = cl.mapData->mapBox.getMinX() + (cl.mapData->mapBox.getWidthX() - (max[0] - min[0])) * 0.5 - min[0];
339  min[1] = cl.mapData->mapBox.getMinY() + (cl.mapData->mapBox.getWidthY() - (max[1] - min[1])) * 0.5 - min[1];
340  for (j = 0; j < radar.numImages; j++) {
341  hudRadarImage_t* tile = &radar.images[j];
342  tile->mapX += min[0];
343  tile->mapY += min[1];
344  }
345 
346  /* get the three points of the triangle */
347  VectorSubtract(cl.mapData->mapBox.mins, offset, radar.a);
348  VectorAdd(cl.mapData->mapBox.maxs, offset, radar.c);
349  VectorSet(radar.b, radar.c[0], radar.a[1], 0);
350 
351  distAB = (Vector2Dist(radar.a, radar.b) / UNIT_SIZE);
352  distBC = (Vector2Dist(radar.b, radar.c) / UNIT_SIZE);
353 
354  UI_GetRadarWidth(node, gridSize);
355 
356  /* get the dimensions for one grid field on the radar map */
357  radar.gridWidth = radar.w / distAB;
358  radar.gridHeight = radar.h / distBC;
359 
360  /* shift the x and y values according to their grid width/height and
361  * their gridX and gridY position */
362  {
363  const float radarLength = std::max(1.0f, fabsf(gridSize[0]));
364  const float radarHeight = std::max(1.0f, fabsf(gridSize[1]));
365  /* image grid relations */
366  const float gridFactorX = radar.w / radarLength;
367  const float gridFactorY = radar.h / radarHeight;
368  for (j = 0; j < radar.numImages; j++) {
369  hudRadarImage_t* image = &radar.images[j];
370 
371  image->x = (image->gridX - radar.gridMin[0]) * gridFactorX;
372  image->y = radar.h - (image->gridY - radar.gridMin[1]) * gridFactorY - image->height;
373  }
374  }
375 
376  /* now align the screen coordinates like it's given by the node */
377  radar.x -= (radar.w / 2);
378  radar.y -= (radar.h / 2);
379 }
380 
381 /*=========================================
382  DRAW FUNCTIONS
383 =========================================*/
384 
385 static void UI_RadarNodeGetActorColor (const le_t* le, vec4_t color)
386 {
387  const int actorLevel = le->pos[2];
388  Vector4Set(color, 0, 1, 0, 1);
389 
390  /* use different alpha values for different levels */
391  if (actorLevel < cl_worldlevel->integer)
392  color[3] = 0.5;
393  else if (actorLevel > cl_worldlevel->integer)
394  color[3] = 0.3;
395 
396  /* use different colors for different teams */
397  if (LE_IsCivilian(le)) {
398  color[0] = 1;
399  } else if (le->team != cls.team) {
400  color[1] = 0;
401  color[0] = 1;
402  }
403 
404  /* show dead actors in full black */
405  if (LE_IsDead(le)) {
406  Vector4Set(color, 0, 0, 0, 0.3);
407  }
408 }
409 
410 static void UI_RadarNodeDrawArrays (const vec4_t color, vec2_t coords[4], vec2_t vertices[4], const image_t* image)
411 {
412  R_Color(color);
413  R_DrawImageArray((const vec2_t*)coords, (const vec2_t*)vertices, image);
414  R_Color(nullptr);
415 }
416 
417 static void UI_RadarNodeDrawItem (const le_t* le, const vec3_t pos)
418 {
419 }
420 
421 static void UI_RadarNodeDrawActor (const le_t* le, const vec3_t pos)
422 {
423  vec2_t coords[4];
424  vec2_t vertices[4];
425  int i;
426  const float size = 10;
427  const int tileSize = 28;
428  int tilePos = 4;
429  const image_t* image;
430  vec4_t color;
431  const float pov = directionAngles[le->angle] * torad + M_PI;
432 
433  image = UI_LoadImage("ui/radar");
434  if (image == nullptr)
435  return;
436 
437  /* draw FOV */
438  if (!LE_IsDead(le)) {
439  vertices[0][0] = - size * 4;
440  vertices[0][1] = + 0;
441  vertices[1][0] = + size * 4;
442  vertices[1][1] = + 0;
443  vertices[2][0] = + size * 4;
444  vertices[2][1] = - size * 4;
445  vertices[3][0] = - size * 4;
446  vertices[3][1] = - size * 4;
447  coords[0][0] = (7) / 128.0f;
448  coords[0][1] = (37 + 63) / 128.0f;
449  coords[1][0] = (7 + 114) / 128.0f;
450  coords[1][1] = (37 + 63) / 128.0f;
451  coords[2][0] = (7 + 114) / 128.0f;
452  coords[2][1] = (37) / 128.0f;
453  coords[3][0] = (7) / 128.0f;
454  coords[3][1] = (37) / 128.0f;
455 
456  /* affine transformation */
457  for (i = 0; i < 4; i++) {
458  const float dx = vertices[i][0];
459  const float dy = vertices[i][1];
460  vertices[i][0] = pos[0] + dx * sin(pov) + dy * cos(pov);
461  vertices[i][1] = pos[1] + dx * cos(pov) - dy * sin(pov);
462  }
463 
464  UI_RadarNodeGetActorColor(le, color);
465  if (LE_IsSelected(le)) {
466  color[3] *= 0.75;
467  } else {
468  color[3] = 0.1f;
469  }
470  UI_RadarNodeDrawArrays(color, coords, vertices, image);
471  }
472 
473  if (LE_IsDead(le))
474  tilePos = 4;
475  else if (LE_IsSelected(le))
476  tilePos = 66;
477  else
478  tilePos = 36;
479 
480  /* a 0,0 centered square */
481  vertices[0][0] = - size;
482  vertices[0][1] = + size;
483  vertices[1][0] = + size;
484  vertices[1][1] = + size;
485  vertices[2][0] = + size;
486  vertices[2][1] = - size;
487  vertices[3][0] = - size;
488  vertices[3][1] = - size;
489  coords[0][0] = (tilePos) / 128.0f;
490  coords[0][1] = (5 + tileSize) / 128.0f;
491  coords[1][0] = (tilePos + tileSize) / 128.0f;
492  coords[1][1] = (5 + tileSize) / 128.0f;
493  coords[2][0] = (tilePos + tileSize) / 128.0f;
494  coords[2][1] = (5) / 128.0f;
495  coords[3][0] = (tilePos) / 128.0f;
496  coords[3][1] = (5) / 128.0f;
497 
498  /* affine transformation */
499  for (i = 0; i < 4; i++) {
500  const float dx = vertices[i][0];
501  const float dy = vertices[i][1];
502  vertices[i][0] = pos[0] + dx * sin(pov) + dy * cos(pov);
503  vertices[i][1] = pos[1] + dx * cos(pov) - dy * sin(pov);
504  }
505 
506  UI_RadarNodeGetActorColor(le, color);
507  UI_RadarNodeDrawArrays(color, coords, vertices, image);
508 }
509 
510 /*#define RADARSIZE_DEBUG*/
511 
518 {
519  vec2_t pos;
520  vec2_t screenPos;
521 #ifdef RADARSIZE_DEBUG
522  int textposy = 40;
523  static const vec4_t red = {1, 0, 0, 0.5};
524 #endif
525 
526  static const vec4_t backgroundColor = {0.0, 0.0, 0.0, 1};
527  const float mapWidth = cl.mapData->mapBox.getWidthX();
528  const float mapHeight = cl.mapData->mapBox.getWidthY();
529 
531  const float mapCoefX = (float) node->box.size[0] / (float) mapWidth;
532  const float mapCoefY = (float) node->box.size[1] / (float) mapHeight;
533 
534  if (cls.state != ca_active)
535  return;
536 
537  UI_GetNodeAbsPos(node, pos);
538  UI_GetNodeScreenPos(node, screenPos);
539  R_CleanupDepthBuffer(pos[0], pos[1], node->box.size[0], node->box.size[1]);
540  UI_DrawFill(pos[0], pos[1], mapWidth * mapCoefX, mapHeight * mapCoefY, backgroundColor);
541 #ifndef RADARSIZE_DEBUG
542  UI_PushClipRect(screenPos[0], screenPos[1], node->box.size[0], node->box.size[1]);
543 #endif
544 
545  /* the cl struct is wiped with every new map */
546  if (!cl.radarInitialized) {
547  UI_InitRadar(node);
548  cl.radarInitialized = true;
549  }
550 
551  /* update context */
552  radar.x = pos[0];
553  radar.y = pos[1];
554  radar.w = node->box.size[0];
555  radar.h = node->box.size[1];
556  if (radar.gridWidth < 6)
557  radar.gridWidth = 6;
558  if (radar.gridHeight < 6)
559  radar.gridHeight = 6;
560 
561 #ifdef RADARSIZE_DEBUG
562  UI_DrawStringInBox("f_small", ALIGN_UL, 50, textposy, 500, 25, va("%fx%f %fx%f map", cl.mapData->mapBox.getMinX(), cl.mapData->mapBox.getMinY(), cl.mapData->getMaxX(), cl.mapData->getMaxY()));
563  textposy += 25;
564  UI_DrawStringInBox("f_small", ALIGN_UL, 50, textposy, 500, 25, va("%fx%f map", mapWidth, mapHeight));
565  textposy += 25;
566 #endif
567 
568  /* draw background */
569  for (int i = 0; i < radar.numImages; i++) {
570  vec2_t imagePos;
571  hudRadarImage_t* tile = &radar.images[i];
572  int maxlevel = cl_worldlevel->integer;
573 
574  /* check the max level value for this map tile */
575  if (maxlevel >= tile->maxlevel)
576  maxlevel = tile->maxlevel - 1;
577  assert(tile->path[maxlevel]);
578  imagePos[0] = radar.x + mapCoefX * (tile->mapX - cl.mapData->mapBox.getMinX());
579  imagePos[1] = radar.y + mapCoefY * (tile->mapY - cl.mapData->mapBox.getMinY());
580 
581  UI_DrawNormImageByName(false, imagePos[0], imagePos[1],
582  mapCoefX * tile->mapWidth, mapCoefY * tile->mapHeight,
583  0, 0, 0, 0, tile->path[maxlevel]);
584 #ifdef RADARSIZE_DEBUG
585  UI_DrawStringInBox("f_small", ALIGN_UL, 50, textposy, 500, 25, va("%dx%d %dx%d %s", tile->x, tile->y, tile->width, tile->height, tile->path[maxlevel]));
586  textposy += 25;
587  UI_DrawStringInBox("f_small", ALIGN_UL, imagePos[0], imagePos[1], 500, 25, va("%dx%d", tile->gridX, tile->gridY));
588 #endif
589  }
590 
591 #ifdef RADARSIZE_DEBUG
592  UI_DrawFill(pos[0], pos[1], 100.0f * mapCoefX, 100.0f * mapCoefY, red);
593  UI_DrawFill(pos[0], pos[1], UNIT_SIZE * mapCoefX, UNIT_SIZE * mapCoefY, red);
594 #endif
595 
596  le_t* le = nullptr;
597  while ((le = LE_GetNextInUse(le))) {
598  vec3_t itempos;
599  if (LE_IsInvisible(le))
600  continue;
601 
602  /* convert to radar area coordinates */
603  itempos[0] = pos[0] + (le->origin[0] - cl.mapData->mapBox.getMinX()) * mapCoefX;
604  itempos[1] = pos[1] + (mapHeight - (le->origin[1] - cl.mapData->mapBox.getMinY())) * mapCoefY;
605 
606  switch (le->type) {
607  case ET_ACTOR:
608  case ET_ACTOR2x2:
609  UI_RadarNodeDrawActor(le, itempos);
610  break;
611  case ET_ITEM:
612  UI_RadarNodeDrawItem(le, itempos);
613  break;
614  default:
615  break;
616  }
617 #ifdef RADARSIZE_DEBUG
618  UI_DrawStringInBox("f_small", ALIGN_UL, 50, textposy, 500, 25, va("%fx%f %dx%d actor", le->origin[0], le->origin[1], le->pos[0], le->pos[1]));
619  textposy += 25;
620  UI_DrawFill(itempos[0], itempos[1], UNIT_SIZE * mapCoefX, 1, red);
621  UI_DrawFill(itempos[0], itempos[1], 1, UNIT_SIZE * mapCoefY, red);
622 #endif
623  }
624 
625 #ifndef RADARSIZE_DEBUG
626  UI_PopClipRect();
627 #endif
628 }
629 
633 void uiRadarNode::onCapturedMouseMove (uiNode_t* node, int x, int y)
634 {
635  const float mapWidth = cl.mapData->mapBox.getWidthX();
636  const float mapHeight = cl.mapData->mapBox.getWidthY();
637  const float mapCoefX = node->box.size[0] / mapWidth;
638  const float mapCoefY = node->box.size[1] / mapHeight;
639  vec3_t pos;
640 
641  /* from absolute to relative to node */
642  UI_NodeAbsoluteToRelativePos(node, &x, &y);
643 
644  /* from node to map */
645  pos[0] = cl.mapData->mapBox.getMinX() + x / mapCoefX;
646  pos[1] = cl.mapData->mapBox.getMaxY() - y / mapCoefY;
647  pos[2] = 0;
648 
649  VectorCopy(pos, cl.cam.origin);
650 }
651 
652 void uiRadarNode::onMouseDown (uiNode_t* node, int x, int y, int button)
653 {
654  if (node->disabled)
655  return;
656 
657  if (button == K_MOUSE1) {
658  UI_SetMouseCapture(node);
659  onCapturedMouseMove(node, x, y);
660  }
661 }
662 
663 void uiRadarNode::onMouseUp (uiNode_t* node, int x, int y, int button)
664 {
665  if (button == K_MOUSE1)
666  UI_MouseRelease();
667 }
668 
670 {
671 }
672 
674 {
675 }
676 
678 {
679  behaviour->name = "radar";
680  behaviour->manager = UINodePtr(new uiRadarNode());
681  behaviour->lua_SWIG_typeinfo = UI_SWIG_TypeQuery("uiRadarNode_t *");
682 }
vec2_t size
Definition: ui_nodes.h:52
#define VectorCopy(src, dest)
Definition: vector.h:51
int UI_DrawStringInBox(const char *fontID, align_t align, int x, int y, int width, int height, const char *text, longlines_t method)
draw a line into a bounding box
Definition: ui_render.cpp:359
void UI_PopClipRect(void)
Definition: ui_render.cpp:52
void onMouseUp(uiNode_t *node, int x, int y, int button) override
#define VectorSet(v, x, y, z)
Definition: vector.h:59
int FS_CheckFile(const char *fmt,...)
Just returns the filelength and -1 if the file wasn't found.
Definition: files.cpp:298
const image_t * R_DrawImageArray(const vec2_t texcoords[4], const vec2_t verts[4], const image_t *image)
Definition: r_draw.cpp:357
static void UI_RadarNodeGetActorColor(const le_t *le, vec4_t color)
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
Definition: shared.cpp:410
const char * name
Definition: ui_behaviour.h:41
pos3_t pos
char * CL_GetConfigString(int index)
hudRadarImage_t images[MAX_MAPTILES]
float gridHeight
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition: shared.cpp:494
static void UI_BuildRadarImageList(const char *tiles, const char *pos)
Reads the tiles and position config strings and convert them into a linked list that holds the imagen...
#define LE_IsInvisible(le)
#define LE_IsCivilian(le)
UINodePtr manager
Definition: ui_behaviour.h:43
struct hudRadar_s hudRadar_t
int angle
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
vec3_t origin
vec3_t maxs
Definition: aabb.h:258
Definition: r_image.h:45
#define Mem_StrDup(in)
Definition: mem.h:48
char * path[PATHFINDING_HEIGHT]
int width
Definition: r_image.h:64
#define CS_POSITIONS
Definition: q_shared.h:326
int integer
Definition: cvar.h:81
void UI_MouseRelease(void)
Release the captured node.
Definition: ui_input.cpp:526
void onWindowClosed(uiNode_t *node) override
Each maptile must have an entry in the images array.
vec2_t gridMax
#define MAP_SIZE_OFFSET
Definition: defines.h:388
void R_Color(const vec4_t rgba)
Change the color to given value.
Definition: r_state.cpp:1011
void Com_Error(int code, const char *fmt,...)
Definition: common.cpp:417
image_t * R_FindImage(const char *pname, imagetype_t type)
Finds or loads the given image.
Definition: r_image.cpp:603
static void UI_FreeRadarImages(void)
client_static_t cls
Definition: cl_main.cpp:83
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition: shared.cpp:457
cvar_t * cl_worldlevel
Definition: cl_hud.cpp:46
#define ERR_DROP
Definition: common.h:211
vec3_t origin
Definition: cl_camera.h:31
const image_t * UI_DrawNormImageByName(bool flip, float x, float y, float w, float h, float sh, float th, float sl, float tl, const char *name)
Draws an image or parts of it.
Definition: ui_render.cpp:203
GLsizei size
Definition: r_gl.h:152
#define OBJZERO(obj)
Definition: shared.h:178
#define MAX_VAR
Definition: shared.h:36
#define Vector4Set(v, r, g, b, a)
Definition: vector.h:62
#define Vector2Set(v, x, y)
Definition: vector.h:61
#define M_PI
Definition: mathlib.h:34
#define LE_IsSelected(le)
SharedPtr< uiNode > UINodePtr
const struct image_s * UI_LoadImage(const char *name)
Searches for an image in the image array.
Definition: ui_render.cpp:91
float getWidthY() const
Definition: aabb.h:144
clientBattleScape_t cl
void * lua_SWIG_typeinfo
Definition: ui_behaviour.h:57
void UI_SetMouseCapture(uiNode_t *node)
Captured the mouse into a node.
Definition: ui_input.cpp:516
static bool UI_CheckRadarImage(const char *imageName, const int level)
float getMaxY() const
Definition: aabb.h:134
Atomic structure used to define most of the UI.
Definition: ui_nodes.h:80
void * UI_SWIG_TypeQuery(const char *name)
This function queries the SWIG type table for a type information structure. It is used in combination...
bool disabled
Definition: ui_nodes.h:102
void UI_GetNodeAbsPos(const uiNode_t *node, vec2_t pos)
Returns the absolute position of a node.
Definition: ui_node.cpp:514
static void UI_GetRadarWidth(const uiNode_t *node, vec2_t gridSize)
Get the width of radar.
#define UNIT_SIZE
Definition: defines.h:121
a local entity
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
le_t * LE_GetNextInUse(le_t *lastLE)
Iterate through the entities that are in use.
#define Vector2Dist(a, b)
Definition: vector.h:70
#define PATHFINDING_HEIGHT
15 max, adjusting above 8 will require a rewrite to the DV code
Definition: defines.h:294
#define VectorAdd(a, b, dest)
Definition: vector.h:47
entity_type_t type
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
Definition: parse.cpp:107
float getWidthX() const
Definition: aabb.h:141
static const vec4_t red
Definition: cp_geoscape.cpp:57
float getMinY() const
Definition: aabb.h:122
void onWindowOpened(uiNode_t *node, linkedList_t *params) override
#define MAX_QPATH
Definition: filesys.h:40
QGL_EXTERN GLint i
Definition: r_gl.h:113
static hudRadar_t radar
#define LE_IsDead(le)
void UI_NodeAbsoluteToRelativePos(const uiNode_t *node, int *x, int *y)
Update an absolute position to a relative one.
Definition: ui_node.cpp:592
node behaviour, how a node work
Definition: ui_behaviour.h:39
static void UI_RadarNodeDrawArrays(const vec4_t color, vec2_t coords[4], vec2_t vertices[4], const image_t *image)
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition: r_gl.h:110
#define CS_TILES
Definition: q_shared.h:325
int height
Definition: r_image.h:64
vec2_t gridMin
#define Mem_Free(ptr)
Definition: mem.h:35
float getMinX() const
Definition: aabb.h:119
vec_t vec3_t[3]
Definition: ufotypes.h:39
static void UI_RadarNodeDrawItem(const le_t *le, const vec3_t pos)
#define torad
Definition: mathlib.h:50
#define Vector2Copy(src, dest)
Definition: vector.h:52
vec_t vec2_t[2]
Definition: ufotypes.h:38
void UI_PushClipRect(int x, int y, int width, int height)
Definition: ui_render.cpp:47
vec3_t mins
Definition: aabb.h:257
AABB mapBox
Definition: typedefs.h:351
const float directionAngles[CORE_DIRECTIONS]
Definition: mathlib.cpp:105
connstate_t state
Definition: client.h:55
void draw(uiNode_t *node) override
void onCapturedMouseMove(uiNode_t *node, int x, int y) override
Called when the node is captured by the mouse.
uiBox_t box
Definition: ui_nodes.h:96
void UI_DrawFill(int x, int y, int w, int h, const vec4_t color)
Fills a box of pixels with a single color.
Definition: ui_render.cpp:37
char base[MAX_QPATH]
int team
voidpf uLong offset
Definition: ioapi.h:45
static char const *const imageExtensions[]
static void UI_RadarNodeDrawActor(const le_t *le, const vec3_t pos)
#define VectorSubtract(a, b, dest)
Definition: vector.h:45
void R_CleanupDepthBuffer(int x, int y, int width, int height)
"Clean up" the depth buffer into a rect
Definition: r_draw.cpp:596
void onMouseDown(uiNode_t *node, int x, int y, int button) override
static void UI_InitRadar(const uiNode_t *node)
Calculate some radar values that won't change during a mission.
void UI_RegisterRadarNode(uiBehaviour_t *behaviour)
struct hudRadarImage_s hudRadarImage_t
Each maptile must have an entry in the images array.
level_locals_t level
Definition: g_main.cpp:38
void UI_GetNodeScreenPos(const uiNode_t *node, vec2_t pos)
Returns the absolute position of a node in the screen. Screen position is not used for the node rende...
Definition: ui_node.cpp:542
vec_t vec4_t[4]
Definition: ufotypes.h:40