1 /*
2 * This file is part of the Colobot: Gold Edition source code
3 * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
4 * http://epsitec.ch; http://colobot.info; http://github.com/colobot
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see http://gnu.org/licenses
18 */
19
20
21 #include "ui/controls/map.h"
22
23 #include "common/image.h"
24
25 #include "graphics/core/device.h"
26
27 #include "graphics/engine/terrain.h"
28 #include "graphics/engine/water.h"
29
30 #include "level/robotmain.h"
31
32 #include "math/geometry.h"
33
34 #include "object/interface/controllable_object.h"
35 #include "object/interface/transportable_object.h"
36
37 #include <cstring>
38
39
40 namespace Ui
41 {
42
43 // Object's constructor.
44
CMap()45 CMap::CMap() : CControl()
46 {
47 m_main = CRobotMain::GetInstancePointer();
48 m_terrain = m_main->GetTerrain();
49 m_water = Gfx::CEngine::GetInstancePointer()->GetWater();
50
51 m_bEnable = true;
52 m_time = 0.0f;
53 m_zoom = 2.0f;
54 m_offset.x = 0.0f;
55 m_offset.y = 0.0f;
56 m_angle = 0.0f;
57
58 m_floorColor.r = 1.00f;
59 m_floorColor.g = 0.50f;
60 m_floorColor.b = 0.00f; // orange
61
62 m_waterColor.r = 0.00f;
63 m_waterColor.g = 0.80f;
64 m_waterColor.b = 1.00f; // blue
65
66 m_half = m_terrain->GetMosaicCount() * m_terrain->GetBrickCount() * m_terrain->GetBrickSize() / 2.0f;
67
68 m_highlightRank = -1;
69 m_totalFix = 0;
70 m_totalMove = 0;
71 m_bRadar = false;
72
73 FlushObject();
74
75 m_mode = 0;
76 m_bToy = false;
77 m_bDebug = false;
78 }
79
80 // Object's destructor.
81
~CMap()82 CMap::~CMap()
83 {
84 }
85
86
87 // Creates a new button.
88
Create(Math::Point pos,Math::Point dim,int icon,EventType eventMsg)89 bool CMap::Create(Math::Point pos, Math::Point dim, int icon, EventType eventMsg)
90 {
91 if (eventMsg == EVENT_NULL)
92 eventMsg = GetUniqueEventType();
93
94 CControl::Create(pos, dim, icon, eventMsg);
95 return true;
96 }
97
98
99 // Choice of the offset, when image is displayed.
100
SetOffset(float ox,float oy)101 void CMap::SetOffset(float ox, float oy)
102 {
103 m_offset.x = ox;
104 m_offset.y = oy;
105 m_half = m_terrain->GetMosaicCount() * m_terrain->GetBrickCount() * m_terrain->GetBrickSize() / 2.0f;
106 }
107
108 // Choice of the global angle of rotation.
109
SetAngle(float angle)110 void CMap::SetAngle(float angle)
111 {
112 m_angle = angle;
113 }
114
115 // Specifies the alternate mode.
116
SetMode(int mode)117 void CMap::SetMode(int mode)
118 {
119 m_mode = mode;
120 }
121
122 // Specifies the type of icon for the selected object.
123
SetToy(bool bToy)124 void CMap::SetToy(bool bToy)
125 {
126 m_bToy = bToy;
127 }
128
SetDebug(bool bDebug)129 void CMap::SetDebug(bool bDebug)
130 {
131 m_bDebug = bDebug;
132 }
133
134
135 //Choice of magnification of the map.
136
SetZoom(float value)137 void CMap::SetZoom(float value)
138 {
139 m_zoom = value;
140 m_half = m_terrain->GetMosaicCount() * m_terrain->GetBrickCount() * m_terrain->GetBrickSize() / 2.0f;
141 }
142
GetZoom()143 float CMap::GetZoom()
144 {
145 return m_zoom;
146 }
147
148 // Choosing a fixed offset.
149
150 // Enables or disables the card.
151
SetEnable(bool bEnable)152 void CMap::SetEnable(bool bEnable)
153 {
154 m_bEnable = bEnable;
155 SetState(STATE_DEAD, !bEnable);
156 }
157
GetEnable()158 bool CMap::GetEnable()
159 {
160 return m_bEnable;
161 }
162
163
164 // Choosing the color of the soil.
165
SetFloorColor(Gfx::Color color)166 void CMap::SetFloorColor(Gfx::Color color)
167 {
168 m_floorColor = color;
169 }
170
171 // Choosing the color of the water.
172
SetWaterColor(Gfx::Color color)173 void CMap::SetWaterColor(Gfx::Color color)
174 {
175 m_waterColor = color;
176 }
177
178
179 // Specifies a fixed image in place of the drawing of the relief.
180
SetFixImage(const std::string & filename)181 void CMap::SetFixImage(const std::string& filename)
182 {
183 m_fixImage = filename;
184 }
185
186 // Whether to use a still image.
187
GetFixImage()188 bool CMap::GetFixImage()
189 {
190 return ! m_fixImage.empty();
191 }
192
193
194 // Management of an event.
195
EventProcess(const Event & event)196 bool CMap::EventProcess(const Event &event)
197 {
198 if ( (m_state & STATE_VISIBLE) == 0 )
199 return true;
200
201 CControl::EventProcess(event);
202
203 if ( event.type == EVENT_FRAME )
204 m_time += event.rTime;
205
206 if ( event.type == EVENT_MOUSE_MOVE || event.type == EVENT_MOUSE_BUTTON_DOWN || event.type == EVENT_MOUSE_BUTTON_UP )
207 {
208 if (Detect(event.mousePos))
209 {
210 m_engine->SetMouseType(Gfx::ENG_MOUSE_NORM);
211 bool inMap = false;
212 if (DetectObject(event.mousePos, inMap) != nullptr)
213 m_engine->SetMouseType(Gfx::ENG_MOUSE_HAND);
214 }
215 }
216
217 if (event.type == EVENT_MOUSE_BUTTON_DOWN &&
218 event.GetData<MouseButtonEventData>()->button == MOUSE_BUTTON_LEFT)
219 {
220 if ( CControl::Detect(event.mousePos) )
221 {
222 SelectObject(event.mousePos);
223 return false;
224 }
225 }
226
227 return true;
228 }
229
230 // Adjusts the offset to not exceed the card.
231
AdjustOffset(Math::Point offset)232 Math::Point CMap::AdjustOffset(Math::Point offset)
233 {
234 float limit;
235
236 limit = m_half - m_half / m_zoom;
237 if ( offset.x < -limit ) offset.x = -limit;
238 if ( offset.x > limit ) offset.x = limit;
239 if ( offset.y < -limit ) offset.y = -limit;
240 if ( offset.y > limit ) offset.y = limit;
241
242 return offset;
243 }
244
245 // Indicates the object with the mouse hovers over.
246
SetHighlight(CObject * pObj)247 void CMap::SetHighlight(CObject* pObj)
248 {
249 m_highlightRank = -1;
250 if ( m_bToy || !m_fixImage.empty())
251 return; // card with still image?
252 if ( pObj == nullptr )
253 return;
254
255 for (int i = 0; i < MAPMAXOBJECT; i++)
256 {
257 if ( !m_map[i].bUsed )
258 continue;
259
260 if ( m_map[i].object == pObj )
261 {
262 m_highlightRank = i;
263 break;
264 }
265 }
266 }
267
268 // Detects an object in the map.
269
DetectObject(Math::Point pos,bool & bInMap)270 CObject* CMap::DetectObject(Math::Point pos, bool &bInMap)
271 {
272 float dist, min;
273 int best;
274
275 bInMap = false;
276 if ( pos.x < m_pos.x ||
277 pos.y < m_pos.y ||
278 pos.x > m_pos.x + m_dim.x ||
279 pos.y > m_pos.y + m_dim.y )
280 return nullptr;
281
282 bInMap = true;
283
284 pos.x = (pos.x - m_pos.x) / m_dim.x * 256.0f;
285 pos.y = (pos.y - m_pos.y) / m_dim.y * 256.0f; // 0..256
286 pos.x = (pos.x - 128.0f) * m_half / (m_zoom * 128.0f) + m_offset.x;
287 pos.y = (pos.y - 128.0f) * m_half / (m_zoom * 128.0f) + m_offset.y;
288
289 min = 10000.0f;
290 best = -1;
291 for (int i = MAPMAXOBJECT - 1; i >= 0; i--)
292 {
293 if ( !m_map[i].bUsed )
294 continue;
295 if ( m_map[i].color == MAPCOLOR_BBOX && !m_bRadar )
296 continue;
297 if ( m_map[i].color == MAPCOLOR_ALIEN && !m_bRadar )
298 continue;
299
300 dist = Math::Point(m_map[i].pos.x - pos.x, m_map[i].pos.y - pos.y).Length();
301 if ( dist > m_half / m_zoom * 8.0f / 100.0f )
302 continue; // too far?
303 if ( dist < min )
304 {
305 min = dist;
306 best = i;
307 }
308 }
309 if ( best == -1 )
310 return nullptr;
311 return m_map[best].object;
312 }
313
314 // Selects an object.
315
SelectObject(Math::Point pos)316 void CMap::SelectObject(Math::Point pos)
317 {
318 CObject *pObj;
319 bool bInMap;
320
321 pObj = DetectObject(pos, bInMap);
322 if ( pObj != nullptr )
323 m_main->SelectObject(pObj);
324 }
325
326
327 // Draw the map.
328
Draw()329 void CMap::Draw()
330 {
331 Math::Point uv1, uv2;
332 int i;
333
334 if ( (m_state & STATE_VISIBLE) == 0 )
335 return;
336
337 CControl::Draw(); // draws the bottom (button)
338
339 if ( !m_bEnable )
340 return;
341
342 if (m_fixImage.empty() && m_map[MAPMAXOBJECT - 1].bUsed)
343 m_offset = AdjustOffset(m_map[MAPMAXOBJECT - 1].pos);
344
345 if (m_fixImage.empty()) // drawing of the relief?
346 {
347 m_engine->SetTexture("textures/interface/map.png");
348 m_engine->SetState(Gfx::ENG_RSTATE_NORMAL);
349 uv1.x = 0.5f + (m_offset.x - (m_half / m_zoom)) / (m_half * 2.0f);
350 uv1.y = 0.5f - (m_offset.y + (m_half / m_zoom)) / (m_half * 2.0f);
351 uv2.x = 0.5f + (m_offset.x + (m_half / m_zoom)) / (m_half * 2.0f);
352 uv2.y = 0.5f - (m_offset.y - (m_half / m_zoom)) / (m_half * 2.0f);
353 DrawVertex(uv1, uv2, 0.97f); // drawing the map
354 }
355 else // still image?
356 {
357 m_engine->LoadTexture(m_fixImage);
358 m_engine->SetTexture(m_fixImage);
359 m_engine->SetState(Gfx::ENG_RSTATE_NORMAL);
360 uv1.x = 0.0f;
361 uv1.y = 0.0f;
362 uv2.x = 1.0f;
363 uv2.y = 1.0f;
364 DrawVertex(uv1, uv2, 0.97f); // drawing the map
365 }
366
367 i = MAPMAXOBJECT-1;
368 if ( m_map[i].bUsed ) // selection:
369 DrawFocus(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color);
370
371 for ( i=0 ; i<m_totalFix ; i++ ) // fixed objects:
372 {
373 if ( i == m_highlightRank )
374 continue;
375 DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, false, false);
376 }
377
378 for ( i=MAPMAXOBJECT-2 ; i>m_totalMove ; i-- ) // moving objects:
379 {
380 if ( i == m_highlightRank )
381 continue;
382 DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, false, false);
383 }
384
385 i = MAPMAXOBJECT-1;
386 if ( m_map[i].bUsed && i != m_highlightRank ) // selection:
387 DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, true, false);
388
389 if ( m_highlightRank != -1 && m_map[m_highlightRank].bUsed )
390 {
391 i = m_highlightRank;
392 DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, false, true);
393 DrawHighlight(m_map[i].pos);
394 }
395 }
396
397 // Computing a point for drawFocus.
398
MapInter(Math::Point pos,float dir)399 Math::Point CMap::MapInter(Math::Point pos, float dir)
400 {
401 Math::Point p1;
402 float limit;
403
404 p1.x = pos.x + 1.0f;
405 p1.y = pos.y;
406 p1 = Math::RotatePoint(pos, dir, p1);
407
408 p1.x -= pos.x;
409 p1.y -= pos.y;
410
411 limit = m_mapPos.x + m_mapDim.x - pos.x;
412 if ( p1.x > limit ) // exceeds the right?
413 {
414 p1.y = limit*p1.y/p1.x;
415 p1.x = limit;
416 }
417 limit = m_mapPos.y * 0.75f + m_mapDim.y * 0.75f - pos.y;
418 if ( p1.y > limit ) // exceeds the top?
419 {
420 p1.x = limit * p1.x / p1.y;
421 p1.y = limit;
422 }
423 limit = m_mapPos.x - pos.x;
424 if ( p1.x < limit ) // exceeds the left?
425 {
426 p1.y = limit * p1.y / p1.x;
427 p1.x = limit;
428 }
429
430 limit = m_mapPos.y * 0.75f - pos.y;
431 if ( p1.y < limit ) // exceeds the bottom?
432 {
433 p1.x = limit * p1.x / p1.y;
434 p1.y = limit;
435 }
436
437 p1.x += pos.x;
438 p1.y += pos.y;
439 return p1;
440 }
441
442 // Draw the field of vision of the selected object.
443
DrawFocus(Math::Point pos,float dir,ObjectType type,MapColor color)444 void CMap::DrawFocus(Math::Point pos, float dir, ObjectType type, MapColor color)
445 {
446 Math::Point p0, p1, p2, uv1, uv2, rel;
447 float aMin, aMax, aOct, focus, a;
448 float limit[5];
449 bool bEnding;
450 int quart;
451
452 if (m_bToy || !m_fixImage.empty()) return; // map with still image?
453 if ( color != MAPCOLOR_MOVE ) return;
454
455 pos.x = (pos.x-m_offset.x)*(m_zoom*0.5f)/m_half+0.5f;
456 pos.y = (pos.y-m_offset.y)*(m_zoom*0.5f)/m_half+0.5f;
457
458 if ( pos.x < 0.0f || pos.x > 1.0f ||
459 pos.y < 0.0f || pos.y > 1.0f ) return;
460
461 rel.x = pos.x*2.0f-1.0f;
462 rel.y = pos.y*2.0f-1.0f; // rel [-1..1]
463
464 pos.x = m_mapPos.x+m_mapDim.x*pos.x;
465 pos.y = m_mapPos.y*0.75f+m_mapDim.y*pos.y*0.75f;
466
467 focus = m_engine->GetFocus();
468 dir += Math::PI/2.0f;
469 aMin = Math::NormAngle(dir-Math::PI/4.0f*focus);
470 aMax = Math::NormAngle(dir+Math::PI/4.0f*focus);
471
472 if ( aMin > aMax )
473 {
474 aMax += Math::PI*2.0f; // aMax always after aMin
475 }
476
477 limit[0] = Math::RotateAngle( 1.0f-rel.x, 1.0f-rel.y); // upper/right
478 limit[1] = Math::RotateAngle(-1.0f-rel.x, 1.0f-rel.y); // upper/left
479 limit[2] = Math::RotateAngle(-1.0f-rel.x, -1.0f-rel.y); // lower/left
480 limit[3] = Math::RotateAngle( 1.0f-rel.x, -1.0f-rel.y); // lower/right
481 limit[4] = limit[0]+Math::PI*2.0f;
482
483 a = Math::NormAngle(aMin);
484 for ( quart=0 ; quart<4 ; quart++ )
485 {
486 if ( a >= limit[quart+0] &&
487 a <= limit[quart+1] ) break;
488 }
489 if ( quart == 4 ) quart = -1;
490
491 uv1.x = 113.0f/256.0f; // degrade green
492 uv1.y = 240.5f/256.0f;
493 uv2.x = 126.0f/256.0f;
494 uv2.y = 255.0f/256.0f;
495
496 m_engine->SetTexture("textures/interface/button2.png");
497 m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_WHITE);
498
499 bEnding = false;
500 do
501 {
502 quart ++;
503 aOct = limit[quart%4];
504 if ( quart >= 4 ) aOct += Math::PI*2.0f;
505 if ( aOct >= aMax - Math::VERY_SMALL_NUM )
506 {
507 aOct = aMax;
508 bEnding = true;
509 }
510
511 p0 = pos;
512 p1 = MapInter(pos, aMin);
513 p2 = MapInter(pos, aOct);
514 p0.y /= 0.75f;
515 p1.y /= 0.75f;
516 p2.y /= 0.75f;
517 DrawTriangle(p0, p2, p1, uv1, uv2);
518
519 aMin = aOct;
520 }
521 while ( !bEnding );
522 }
523
524 // Draw an object.
525
DrawObject(Math::Point pos,float dir,ObjectType type,MapColor color,bool bSelect,bool bHilite)526 void CMap::DrawObject(Math::Point pos, float dir, ObjectType type, MapColor color,
527 bool bSelect, bool bHilite)
528 {
529 Math::Point p1, p2, p3, p4, p5, dim, uv1, uv2;
530 bool bOut, bUp, bDown, bLeft, bRight;
531
532 pos.x = (pos.x-m_offset.x)*(m_zoom*0.5f)/m_half+0.5f;
533 pos.y = (pos.y-m_offset.y)*(m_zoom*0.5f)/m_half+0.5f;
534
535 bOut = bUp = bDown = bLeft = bRight = false;
536 if ( pos.x < 0.06f ) { pos.x = 0.02f; bOut = bLeft = true; }
537 if ( pos.y < 0.06f ) { pos.y = 0.02f; bOut = bDown = true; }
538 if ( pos.x > 0.94f ) { pos.x = 0.98f; bOut = bRight = true; }
539 if ( pos.y > 0.94f ) { pos.y = 0.98f; bOut = bUp = true; }
540
541 pos.x = m_mapPos.x+m_mapDim.x*pos.x;
542 pos.y = m_mapPos.y+m_mapDim.y*pos.y;
543 dim.x = 2.0f/128.0f*0.75f;
544 dim.y = 2.0f/128.0f;
545
546 if ( bOut ) // outside the map?
547 {
548 if ( color == MAPCOLOR_BBOX && !m_bRadar ) return;
549 if ( color == MAPCOLOR_ALIEN && !m_bRadar ) return;
550
551 if ( Math::Mod(m_time+(pos.x+pos.y)*4.0f, 0.6f) > 0.2f )
552 {
553 return; // flashes
554 }
555
556 m_engine->SetTexture("textures/interface/button2.png");
557 m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK);
558 if ( bUp )
559 {
560 uv1.x = 160.5f/256.0f; // yellow triangle ^
561 uv1.y = 240.5f/256.0f;
562 uv2.x = 175.0f/256.0f;
563 uv2.y = 255.0f/256.0f;
564 }
565 if ( bDown )
566 {
567 uv1.x = 160.5f/256.0f; // yellow triangle v
568 uv1.y = 255.0f/256.0f;
569 uv2.x = 175.0f/256.0f;
570 uv2.y = 240.5f/256.0f;
571 }
572 if ( bRight )
573 {
574 uv1.x = 176.5f/256.0f; // yellow triangle >
575 uv1.y = 240.5f/256.0f;
576 uv2.x = 191.0f/256.0f;
577 uv2.y = 255.0f/256.0f;
578 }
579 if ( bLeft )
580 {
581 uv1.x = 191.0f/256.0f; // yellow triangle <
582 uv1.y = 240.5f/256.0f;
583 uv2.x = 176.5f/256.0f;
584 uv2.y = 255.0f/256.0f;
585 }
586 pos.x -= dim.x/2.0f;
587 pos.y -= dim.y/2.0f;
588 DrawIcon(pos, dim, uv1, uv2);
589 return;
590 }
591
592 if ( bSelect )
593 {
594 if ( m_bToy )
595 {
596 dim.x *= 1.2f+sinf(m_time*8.0f)*0.1f;
597 dim.y *= 1.2f+sinf(m_time*8.0f)*0.1f;
598 }
599 else
600 {
601 dim.x *= 1.2f+sinf(m_time*8.0f)*0.3f;
602 dim.y *= 1.2f+sinf(m_time*8.0f)*0.3f;
603 }
604 }
605 if ( color == MAPCOLOR_BASE ||
606 color == MAPCOLOR_FIX ||
607 color == MAPCOLOR_MOVE )
608 {
609 if ( bHilite )
610 {
611 dim.x *= 2.2f;
612 dim.y *= 2.2f;
613 }
614 else
615 {
616 dim.x *= 0.6f;
617 dim.y *= 0.6f;
618 }
619 }
620 if ( color == MAPCOLOR_ALIEN )
621 {
622 dim.x *= 1.4f;
623 dim.y *= 1.4f;
624 }
625 if ( type == OBJECT_TEEN28 ) // bottle?
626 {
627 dim.x *= 3.0f;
628 dim.y *= 3.0f;
629 bHilite = true;
630 }
631 if ( type == OBJECT_TEEN34 ) // stone?
632 {
633 dim.x *= 2.0f;
634 dim.y *= 2.0f;
635 bHilite = true;
636 }
637
638 if ( color == MAPCOLOR_MOVE && bSelect )
639 {
640 if ( m_bToy )
641 {
642 p1.x = pos.x;
643 p1.y = pos.y+dim.y*1.4f;
644 p1 = Math::RotatePoint(pos, dir, p1);
645 p1.x = pos.x+(p1.x-pos.x)*0.75f;
646
647 p2.x = pos.x+dim.x*1.2f;
648 p2.y = pos.y+dim.y*0.8f;
649 p2 = Math::RotatePoint(pos, dir, p2);
650 p2.x = pos.x+(p2.x-pos.x)*0.75f;
651
652 p3.x = pos.x+dim.x*1.2f;
653 p3.y = pos.y-dim.y*1.0f;
654 p3 = Math::RotatePoint(pos, dir, p3);
655 p3.x = pos.x+(p3.x-pos.x)*0.75f;
656
657 p4.x = pos.x-dim.x*1.2f;
658 p4.y = pos.y-dim.y*1.0f;
659 p4 = Math::RotatePoint(pos, dir, p4);
660 p4.x = pos.x+(p4.x-pos.x)*0.75f;
661
662 p5.x = pos.x-dim.x*1.2f;
663 p5.y = pos.y+dim.y*0.8f;
664 p5 = Math::RotatePoint(pos, dir, p5);
665 p5.x = pos.x+(p5.x-pos.x)*0.75f;
666 }
667 else
668 {
669 p1.x = pos.x;
670 p1.y = pos.y+dim.y*2.4f;
671 p1 = Math::RotatePoint(pos, dir, p1);
672 p1.x = pos.x+(p1.x-pos.x)*0.75f;
673
674 p2.x = pos.x+dim.x*1.0f;
675 p2.y = pos.y-dim.y*1.6f;
676 p2 = Math::RotatePoint(pos, dir, p2);
677 p2.x = pos.x+(p2.x-pos.x)*0.75f;
678
679 p3.x = pos.x-dim.x*1.0f;
680 p3.y = pos.y-dim.y*1.6f;
681 p3 = Math::RotatePoint(pos, dir, p3);
682 p3.x = pos.x+(p3.x-pos.x)*0.75f;
683 }
684 }
685
686 pos.x -= dim.x/2.0f;
687 pos.y -= dim.y/2.0f;
688
689 if ( color == MAPCOLOR_BASE ||
690 color == MAPCOLOR_FIX )
691 {
692 DrawObjectIcon(pos, dim, color, type, bHilite);
693 }
694
695 if ( color == MAPCOLOR_MOVE )
696 {
697 if ( bSelect )
698 {
699 m_engine->SetTexture("textures/interface/button2.png");
700 m_engine->SetState(Gfx::ENG_RSTATE_NORMAL);
701 if ( m_bToy )
702 {
703 uv1.x = 164.5f/256.0f; // black pentagon
704 uv1.y = 228.5f/256.0f;
705 uv2.x = 172.0f/256.0f;
706 uv2.y = 236.0f/256.0f;
707 DrawPenta(p1, p2, p3, p4, p5, uv1, uv2);
708 }
709 else
710 {
711 uv1.x = 144.5f/256.0f; // red triangle
712 uv1.y = 240.5f/256.0f;
713 uv2.x = 159.0f/256.0f;
714 uv2.y = 255.0f/256.0f;
715 DrawTriangle(p1, p2, p3, uv1, uv2);
716 }
717 }
718 DrawObjectIcon(pos, dim, color, type, bHilite);
719 }
720
721 if ( color == MAPCOLOR_BBOX )
722 {
723 if ( m_bRadar )
724 {
725 m_engine->SetTexture("textures/interface/button2.png");
726 m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_WHITE);
727 uv1.x = 64.5f/256.0f; // blue triangle
728 uv1.y = 240.5f/256.0f;
729 uv2.x = 79.0f/256.0f;
730 uv2.y = 255.0f/256.0f;
731 DrawIcon(pos, dim, uv1, uv2);
732 }
733 }
734
735 if ( color == MAPCOLOR_ALIEN )
736 {
737 if ( m_bRadar )
738 {
739 DrawObjectIcon(pos, dim, color, type, true);
740 }
741 }
742
743 if ( color == MAPCOLOR_WAYPOINTb )
744 {
745 m_engine->SetTexture("textures/interface/button2.png");
746 m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK);
747 uv1.x = 192.5f/256.0f; // blue cross
748 uv1.y = 240.5f/256.0f;
749 uv2.x = 207.0f/256.0f;
750 uv2.y = 255.0f/256.0f;
751 DrawIcon(pos, dim, uv1, uv2);
752 }
753 if ( color == MAPCOLOR_WAYPOINTr )
754 {
755 m_engine->SetTexture("textures/interface/button2.png");
756 m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK);
757 uv1.x = 208.5f/256.0f; // red cross
758 uv1.y = 240.5f/256.0f;
759 uv2.x = 223.0f/256.0f;
760 uv2.y = 255.0f/256.0f;
761 DrawIcon(pos, dim, uv1, uv2);
762 }
763 if ( color == MAPCOLOR_WAYPOINTg )
764 {
765 m_engine->SetTexture("textures/interface/button2.png");
766 m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK);
767 uv1.x = 224.5f/256.0f; // green cross
768 uv1.y = 240.5f/256.0f;
769 uv2.x = 239.0f/256.0f;
770 uv2.y = 255.0f/256.0f;
771 DrawIcon(pos, dim, uv1, uv2);
772 }
773 if ( color == MAPCOLOR_WAYPOINTy )
774 {
775 m_engine->SetTexture("textures/interface/button2.png");
776 m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK);
777 uv1.x = 240.5f/256.0f; // yellow cross
778 uv1.y = 240.5f/256.0f;
779 uv2.x = 255.0f/256.0f;
780 uv2.y = 255.0f/256.0f;
781 DrawIcon(pos, dim, uv1, uv2);
782 }
783 if ( color == MAPCOLOR_WAYPOINTv )
784 {
785 m_engine->SetTexture("textures/interface/button2.png");
786 m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK);
787 uv1.x = 192.5f/256.0f; // violet cross
788 uv1.y = 224.5f/256.0f;
789 uv2.x = 207.0f/256.0f;
790 uv2.y = 239.0f/256.0f;
791 DrawIcon(pos, dim, uv1, uv2);
792 }
793 }
794
795 // Draws the icon of an object.
796
DrawObjectIcon(Math::Point pos,Math::Point dim,MapColor color,ObjectType type,bool bHilite)797 void CMap::DrawObjectIcon(Math::Point pos, Math::Point dim, MapColor color,
798 ObjectType type, bool bHilite)
799 {
800 Math::Point ppos, ddim, uv1, uv2;
801 float dp;
802 int icon;
803
804 dp = 0.5f/256.0f;
805
806 m_engine->SetTexture("textures/interface/button3.png");
807 m_engine->SetState(Gfx::ENG_RSTATE_NORMAL);
808 if ( color == MAPCOLOR_MOVE )
809 {
810 uv1.x = 160.0f/256.0f; // blue
811 uv1.y = 224.0f/256.0f;
812 }
813 else if ( color == MAPCOLOR_ALIEN )
814 {
815 uv1.x = 224.0f/256.0f; // green
816 uv1.y = 224.0f/256.0f;
817 }
818 else
819 {
820 uv1.x = 192.0f/256.0f; // yellow
821 uv1.y = 224.0f/256.0f;
822 }
823 uv2.x = uv1.x+32.0f/256.0f;
824 uv2.y = uv1.y+32.0f/256.0f;
825 uv1.x += dp;
826 uv1.y += dp;
827 uv2.x -= dp;
828 uv2.y -= dp;
829 DrawIcon(pos, dim, uv1, uv2); // background colors
830
831 if ( bHilite )
832 {
833 switch ( type )
834 {
835 case OBJECT_FACTORY: icon = 32; break;
836 case OBJECT_DERRICK: icon = 33; break;
837 case OBJECT_CONVERT: icon = 34; break;
838 case OBJECT_RESEARCH: icon = 35; break;
839 case OBJECT_STATION: icon = 36; break;
840 case OBJECT_TOWER: icon = 37; break;
841 case OBJECT_LABO: icon = 38; break;
842 case OBJECT_ENERGY: icon = 39; break;
843 case OBJECT_RADAR: icon = 40; break;
844 case OBJECT_INFO: icon = 44; break;
845 case OBJECT_REPAIR: icon = 41; break;
846 case OBJECT_DESTROYER: icon = 41; break;
847 case OBJECT_NUCLEAR: icon = 42; break;
848 case OBJECT_PARA: icon = 46; break;
849 case OBJECT_SAFE: icon = 47; break;
850 case OBJECT_HUSTON: icon = 48; break;
851 case OBJECT_TARGET1: icon = 45; break;
852 case OBJECT_BASE: icon = 43; break;
853 case OBJECT_HUMAN: icon = 8; break;
854 case OBJECT_MOBILEfa: icon = 11; break;
855 case OBJECT_MOBILEta: icon = 10; break;
856 case OBJECT_MOBILEwa: icon = 9; break;
857 case OBJECT_MOBILEia: icon = 22; break;
858 case OBJECT_MOBILEfb: icon = 2; break; // button4
859 case OBJECT_MOBILEtb: icon = 1; break;
860 case OBJECT_MOBILEwb: icon = 0; break;
861 case OBJECT_MOBILEib: icon = 3; break;
862 case OBJECT_MOBILEfc: icon = 17; break;
863 case OBJECT_MOBILEtc: icon = 16; break;
864 case OBJECT_MOBILEwc: icon = 15; break;
865 case OBJECT_MOBILEic: icon = 23; break;
866 case OBJECT_MOBILEfi: icon = 27; break;
867 case OBJECT_MOBILEti: icon = 26; break;
868 case OBJECT_MOBILEwi: icon = 25; break;
869 case OBJECT_MOBILEii: icon = 28; break;
870 case OBJECT_MOBILEfs: icon = 14; break;
871 case OBJECT_MOBILEts: icon = 13; break;
872 case OBJECT_MOBILEws: icon = 12; break;
873 case OBJECT_MOBILEis: icon = 24; break;
874 case OBJECT_MOBILErt: icon = 18; break;
875 case OBJECT_MOBILErc: icon = 19; break;
876 case OBJECT_MOBILErr: icon = 20; break;
877 case OBJECT_MOBILErs: icon = 29; break;
878 case OBJECT_MOBILEsa: icon = 21; break;
879 case OBJECT_MOBILEft: icon = 6; break;
880 case OBJECT_MOBILEtt: icon = 5; break;
881 case OBJECT_MOBILEwt: icon = 30; break;
882 case OBJECT_MOBILEit: icon = 7; break;
883 case OBJECT_MOBILErp: icon = 9; break;
884 case OBJECT_MOBILEst: icon = 10; break;
885 case OBJECT_MOBILEtg: icon = 45; break;
886 case OBJECT_MOBILEdr: icon = 48; break;
887 case OBJECT_APOLLO2: icon = 49; break;
888 case OBJECT_MOTHER: icon = 31; break;
889 case OBJECT_ANT: icon = 31; break;
890 case OBJECT_SPIDER: icon = 31; break;
891 case OBJECT_BEE: icon = 31; break;
892 case OBJECT_WORM: icon = 31; break;
893 case OBJECT_TEEN28: icon = 48; break; // bottle
894 case OBJECT_TEEN34: icon = 48; break; // stone
895 default: icon = -1;
896 }
897 if ( icon == -1 ) return;
898
899 switch ( type )
900 {
901 case OBJECT_MOBILEfb:
902 case OBJECT_MOBILEtb:
903 case OBJECT_MOBILEwb:
904 case OBJECT_MOBILEib:
905 case OBJECT_MOBILEft:
906 case OBJECT_MOBILEtt:
907 case OBJECT_MOBILEit:
908 case OBJECT_MOBILErp:
909 case OBJECT_MOBILEst:
910 m_engine->SetTexture("textures/interface/button4.png"); break;
911 default: ; // button3.png
912 }
913
914 m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_WHITE);
915 uv1.x = (32.0f/256.0f)*(icon%8);
916 uv1.y = (32.0f/256.0f)*(icon/8);
917 uv2.x = uv1.x+32.0f/256.0f;
918 uv2.y = uv1.y+32.0f/256.0f;
919 uv1.x += dp;
920 uv1.y += dp;
921 uv2.x -= dp;
922 uv2.y -= dp;
923 DrawIcon(pos, dim, uv1, uv2); // icon
924 }
925 }
926
927 // Draw the object with the mouse hovers over.
928
DrawHighlight(Math::Point pos)929 void CMap::DrawHighlight(Math::Point pos)
930 {
931 Math::Point dim, uv1, uv2;
932
933 if (m_bToy || !m_fixImage.empty()) return; // map with still image?
934
935 pos.x = (pos.x-m_offset.x)*(m_zoom*0.5f)/m_half+0.5f;
936 pos.y = (pos.y-m_offset.y)*(m_zoom*0.5f)/m_half+0.5f;
937
938 pos.x = m_mapPos.x+m_mapDim.x*pos.x;
939 pos.y = m_mapPos.y+m_mapDim.y*pos.y;
940 dim.x = 2.0f/128.0f*0.75f;
941 dim.y = 2.0f/128.0f;
942 dim.x *= 2.0f+cosf(m_time*8.0f)*0.5f;
943 dim.y *= 2.0f+cosf(m_time*8.0f)*0.5f;
944
945 m_engine->SetTexture("textures/interface/button2.png");
946 m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK);
947 uv1.x = 160.5f/256.0f; // hilite
948 uv1.y = 224.5f/256.0f;
949 uv2.x = 175.0f/256.0f;
950 uv2.y = 239.0f/256.0f;
951 pos.x -= dim.x/2.0f;
952 pos.y -= dim.y/2.0f;
953 DrawIcon(pos, dim, uv1, uv2);
954 }
955
956 // Draws a triangular icon.
957
DrawTriangle(Math::Point p1,Math::Point p2,Math::Point p3,Math::Point uv1,Math::Point uv2)958 void CMap::DrawTriangle(Math::Point p1, Math::Point p2, Math::Point p3, Math::Point uv1, Math::Point uv2)
959 {
960 Gfx::CDevice* device;
961 Gfx::VertexTex2 vertex[3]; // 1 triangle
962 Math::Vector n;
963
964 device = m_engine->GetDevice();
965
966 n = Math::Vector(0.0f, 0.0f, -1.0f); // normal
967
968 vertex[0] = Gfx::VertexTex2(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(uv1.x,uv1.y));
969 vertex[1] = Gfx::VertexTex2(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(uv1.x,uv2.y));
970 vertex[2] = Gfx::VertexTex2(Math::Vector(p3.x, p3.y, 0.0f), n, Math::Point(uv2.x,uv2.y));
971
972 device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, vertex, 3);
973 m_engine->AddStatisticTriangle(1);
974 }
975
976 // Draw a pentagon icon (a 5 rating, what!).
977
DrawPenta(Math::Point p1,Math::Point p2,Math::Point p3,Math::Point p4,Math::Point p5,Math::Point uv1,Math::Point uv2)978 void CMap::DrawPenta(Math::Point p1, Math::Point p2, Math::Point p3, Math::Point p4, Math::Point p5, Math::Point uv1, Math::Point uv2)
979 {
980 Gfx::CDevice* device;
981 Gfx::VertexTex2 vertex[5]; // 1 pentagon
982 Math::Vector n;
983
984 device = m_engine->GetDevice();
985
986 n = Math::Vector(0.0f, 0.0f, -1.0f); // normal
987
988 vertex[0] = Gfx::VertexTex2(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(uv1.x,uv1.y));
989 vertex[1] = Gfx::VertexTex2(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(uv1.x,uv2.y));
990 vertex[2] = Gfx::VertexTex2(Math::Vector(p5.x, p5.y, 0.0f), n, Math::Point(uv2.x,uv2.y));
991 vertex[3] = Gfx::VertexTex2(Math::Vector(p3.x, p3.y, 0.0f), n, Math::Point(uv2.x,uv2.y));
992 vertex[4] = Gfx::VertexTex2(Math::Vector(p4.x, p4.y, 0.0f), n, Math::Point(uv2.x,uv2.y));
993
994 device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, vertex, 5);
995 m_engine->AddStatisticTriangle(3);
996 }
997
998 // Draw the vertex array.
999
DrawVertex(Math::Point uv1,Math::Point uv2,float zoom)1000 void CMap::DrawVertex(Math::Point uv1, Math::Point uv2, float zoom)
1001 {
1002 Gfx::CDevice* device;
1003 Gfx::VertexTex2 vertex[4]; // 2 triangles
1004 Math::Point p1, p2, c;
1005 Math::Vector n;
1006
1007 device = m_engine->GetDevice();
1008
1009 p1.x = m_pos.x;
1010 p1.y = m_pos.y;
1011 p2.x = m_pos.x + m_dim.x;
1012 p2.y = m_pos.y + m_dim.y;
1013
1014 c.x = (p1.x+p2.x)/2.0f;
1015 c.y = (p1.y+p2.y)/2.0f; // center
1016
1017 p1.x = (p1.x-c.x)*zoom + c.x;
1018 p1.y = (p1.y-c.y)*zoom + c.y;
1019
1020 p2.x = (p2.x-c.x)*zoom + c.x;
1021 p2.y = (p2.y-c.y)*zoom + c.y;
1022
1023 m_mapPos = p1;
1024 m_mapDim.x = p2.x-p1.x;
1025 m_mapDim.y = p2.y-p1.y;
1026
1027 n = Math::Vector(0.0f, 0.0f, -1.0f); // normal
1028
1029 vertex[0] = Gfx::VertexTex2(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(uv1.x,uv2.y));
1030 vertex[1] = Gfx::VertexTex2(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(uv1.x,uv1.y));
1031 vertex[2] = Gfx::VertexTex2(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(uv2.x,uv2.y));
1032 vertex[3] = Gfx::VertexTex2(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(uv2.x,uv1.y));
1033
1034 device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
1035 m_engine->AddStatisticTriangle(2);
1036 }
1037
1038
1039 // Updates the field in the map.
1040
UpdateTerrain()1041 void CMap::UpdateTerrain()
1042 {
1043 if (! m_fixImage.empty()) return; // still image?
1044
1045 CImage img(Math::IntPoint(256, 256));
1046
1047 float scale = m_terrain->GetReliefScale();
1048 float water = m_water->GetLevel();
1049
1050 Gfx::Color color;
1051 color.a = 0.0f;
1052
1053 for (int y = 0; y < 256; y++)
1054 {
1055 for (int x = 0; x < 256; x++)
1056 {
1057 Math::Vector pos;
1058 pos.x = (static_cast<float>(x) - 128.0f) * m_half / 128.0f;
1059 pos.z = -(static_cast<float>(y) - 128.0f) * m_half / 128.0f;
1060 pos.y = 0.0f;
1061
1062 float level;
1063
1064 if ( pos.x >= -m_half && pos.x <= m_half &&
1065 pos.z >= -m_half && pos.z <= m_half )
1066 {
1067 level = m_terrain->GetFloorLevel(pos, true) / scale;
1068 }
1069 else
1070 {
1071 level = 1000.0f;
1072 }
1073
1074 float intensity = level / 256.0f;
1075 if (intensity < 0.0f) intensity = 0.0f;
1076 if (intensity > 1.0f) intensity = 1.0f;
1077
1078 if (level >= water) // on water?
1079 {
1080 color.r = Math::Norm(m_floorColor.r + (intensity - 0.5f));
1081 color.g = Math::Norm(m_floorColor.g + (intensity - 0.5f));
1082 color.b = Math::Norm(m_floorColor.b + (intensity - 0.5f));
1083 }
1084 else // underwater?
1085 {
1086 color.r = Math::Norm(m_waterColor.r + (intensity - 0.5f));
1087 color.g = Math::Norm(m_waterColor.g + (intensity - 0.5f));
1088 color.b = Math::Norm(m_waterColor.b + (intensity - 0.5f));
1089 }
1090
1091 img.SetPixel(Math::IntPoint(x, y), color);
1092 }
1093 }
1094
1095 m_engine->DeleteTexture("interface/map.png");
1096 m_engine->LoadTexture("textures/interface/map.png", &img);
1097 }
1098
1099 // Updates the field in the map.
1100
UpdateTerrain(int bx,int by,int ex,int ey)1101 void CMap::UpdateTerrain(int bx, int by, int ex, int ey)
1102 {
1103 Gfx::Color color;
1104 Math::Vector pos;
1105 float scale, water, level, intensity;
1106 int x, y;
1107
1108 if (! m_fixImage.empty()) return; // still image?
1109
1110 // TODO: map texture manipulation
1111 return;
1112
1113 //if ( !m_engine->OpenImage("map.png") ) return;
1114 //m_engine->LoadImage();
1115
1116 scale = m_terrain->GetReliefScale();
1117 water = m_water->GetLevel();
1118 color.a = 0.0f;
1119
1120 for ( y=by ; y<ey ; y++ )
1121 {
1122 for ( x=bx ; x<ex ; x++ )
1123 {
1124 pos.x = (static_cast<float>(x)-128.0f)*m_half/128.0f;
1125 pos.z = -(static_cast<float>(y)-128.0f)*m_half/128.0f;
1126 pos.y = 0.0f;
1127
1128 if ( pos.x >= -m_half && pos.x <= m_half &&
1129 pos.z >= -m_half && pos.z <= m_half )
1130 {
1131 level = m_terrain->GetFloorLevel(pos, true)/scale;
1132 }
1133 else
1134 {
1135 level = 1000.0f;
1136 }
1137
1138 intensity = level/256.0f;
1139 if ( intensity < 0.0f ) intensity = 0.0f;
1140 if ( intensity > 1.0f ) intensity = 1.0f;
1141
1142 if ( level > water ) // on water?
1143 {
1144 color.r = m_floorColor.r + (intensity-0.5f);
1145 color.g = m_floorColor.g + (intensity-0.5f);
1146 color.b = m_floorColor.b + (intensity-0.5f);
1147 }
1148 else // underwater?
1149 {
1150 color.r = m_waterColor.r + (intensity-0.5f);
1151 color.g = m_waterColor.g + (intensity-0.5f);
1152 color.b = m_waterColor.b + (intensity-0.5f);
1153 }
1154
1155 //m_engine->SetDot(x, y, color);
1156 }
1157 }
1158
1159 //m_engine->CopyImage(); // copy the ground drawing
1160 //m_engine->CloseImage();
1161 }
1162
1163
1164 // Empty all objects.
1165
FlushObject()1166 void CMap::FlushObject()
1167 {
1168 m_totalFix = 0; // object index fixed
1169 m_totalMove = MAPMAXOBJECT-2; // moving vehicles index
1170 m_bRadar = m_main->GetRadar();
1171
1172 for (int i = 0; i < MAPMAXOBJECT; i++)
1173 {
1174 m_map[i].bUsed = false;
1175 }
1176 }
1177
1178 // Updates an object in the map.
1179
UpdateObject(CObject * pObj)1180 void CMap::UpdateObject(CObject* pObj)
1181 {
1182 ObjectType type;
1183 MapColor color;
1184 Math::Vector pos;
1185 Math::Point ppos;
1186 float dir;
1187
1188 if ( !m_bEnable ) return;
1189 if ( m_totalFix >= m_totalMove ) return; // full table?
1190
1191 type = pObj->GetType();
1192 if ( !pObj->GetDetectable() ) return;
1193 if ( type != OBJECT_MOTHER &&
1194 type != OBJECT_ANT &&
1195 type != OBJECT_SPIDER &&
1196 type != OBJECT_BEE &&
1197 type != OBJECT_WORM &&
1198 type != OBJECT_MOBILEtg )
1199 {
1200 if (pObj->Implements(ObjectInterfaceType::Controllable) && !dynamic_cast<CControllableObject&>(*pObj).GetSelectable()) return;
1201 }
1202 if ( pObj->GetProxyActivate() ) return;
1203 if (IsObjectBeingTransported(pObj)) return;
1204
1205 pos = pObj->GetPosition();
1206 dir = -(pObj->GetRotationY()+Math::PI/2.0f);
1207
1208 if ( m_angle != 0.0f )
1209 {
1210 ppos = RotatePoint(m_angle, Math::Point(pos.x, pos.z));
1211 pos.x = ppos.x;
1212 pos.z = ppos.y;
1213 dir += m_angle;
1214 }
1215
1216 color = MAPCOLOR_NULL;
1217 if ( type == OBJECT_BASE )
1218 {
1219 color = MAPCOLOR_BASE;
1220 }
1221 if ( type == OBJECT_DERRICK ||
1222 type == OBJECT_FACTORY ||
1223 type == OBJECT_STATION ||
1224 type == OBJECT_CONVERT ||
1225 type == OBJECT_REPAIR ||
1226 type == OBJECT_DESTROYER||
1227 type == OBJECT_TOWER ||
1228 type == OBJECT_RESEARCH ||
1229 type == OBJECT_RADAR ||
1230 type == OBJECT_INFO ||
1231 type == OBJECT_ENERGY ||
1232 type == OBJECT_LABO ||
1233 type == OBJECT_NUCLEAR ||
1234 type == OBJECT_PARA ||
1235 type == OBJECT_SAFE ||
1236 type == OBJECT_HUSTON ||
1237 type == OBJECT_TARGET1 ||
1238 type == OBJECT_START ||
1239 type == OBJECT_END || // stationary object?
1240 type == OBJECT_TEEN28 || // bottle?
1241 type == OBJECT_TEEN34 ) // stone?
1242 {
1243 color = MAPCOLOR_FIX;
1244 }
1245 if ( type == OBJECT_BBOX ||
1246 type == OBJECT_KEYa ||
1247 type == OBJECT_KEYb ||
1248 type == OBJECT_KEYc ||
1249 type == OBJECT_KEYd )
1250 {
1251 color = MAPCOLOR_BBOX;
1252 }
1253 if ( type == OBJECT_HUMAN ||
1254 type == OBJECT_MOBILEwa ||
1255 type == OBJECT_MOBILEta ||
1256 type == OBJECT_MOBILEfa ||
1257 type == OBJECT_MOBILEia ||
1258 type == OBJECT_MOBILEwb ||
1259 type == OBJECT_MOBILEtb ||
1260 type == OBJECT_MOBILEfb ||
1261 type == OBJECT_MOBILEib ||
1262 type == OBJECT_MOBILEwc ||
1263 type == OBJECT_MOBILEtc ||
1264 type == OBJECT_MOBILEfc ||
1265 type == OBJECT_MOBILEic ||
1266 type == OBJECT_MOBILEwi ||
1267 type == OBJECT_MOBILEti ||
1268 type == OBJECT_MOBILEfi ||
1269 type == OBJECT_MOBILEii ||
1270 type == OBJECT_MOBILEws ||
1271 type == OBJECT_MOBILEts ||
1272 type == OBJECT_MOBILEfs ||
1273 type == OBJECT_MOBILEis ||
1274 type == OBJECT_MOBILErt ||
1275 type == OBJECT_MOBILErc ||
1276 type == OBJECT_MOBILErr ||
1277 type == OBJECT_MOBILErs ||
1278 type == OBJECT_MOBILEsa ||
1279 type == OBJECT_MOBILEtg ||
1280 type == OBJECT_MOBILEwt ||
1281 type == OBJECT_MOBILEtt ||
1282 type == OBJECT_MOBILEft ||
1283 type == OBJECT_MOBILEit ||
1284 type == OBJECT_MOBILErp ||
1285 type == OBJECT_MOBILEst ||
1286 type == OBJECT_MOBILEdr ||
1287 type == OBJECT_APOLLO2 ) // moving vehicle?
1288 {
1289 color = MAPCOLOR_MOVE;
1290 }
1291 if ( type == OBJECT_ANT ||
1292 type == OBJECT_BEE ||
1293 type == OBJECT_WORM ||
1294 type == OBJECT_SPIDER ) // mobile enemy?
1295 {
1296 color = MAPCOLOR_ALIEN;
1297 }
1298 if ( type == OBJECT_WAYPOINT ||
1299 type == OBJECT_FLAGb )
1300 {
1301 color = MAPCOLOR_WAYPOINTb;
1302 }
1303 if ( type == OBJECT_FLAGr )
1304 {
1305 color = MAPCOLOR_WAYPOINTr;
1306 }
1307 if ( type == OBJECT_FLAGg )
1308 {
1309 color = MAPCOLOR_WAYPOINTg;
1310 }
1311 if ( type == OBJECT_FLAGy )
1312 {
1313 color = MAPCOLOR_WAYPOINTy;
1314 }
1315 if ( type == OBJECT_FLAGv )
1316 {
1317 color = MAPCOLOR_WAYPOINTv;
1318 }
1319
1320 if ( color == MAPCOLOR_NULL ) return;
1321
1322 /*if (!m_fixImage.empty() && !m_bDebug) // map with still image?
1323 {
1324 if ( (type == OBJECT_TEEN28 ||
1325 type == OBJECT_TEEN34 ) &&
1326 m_mode == 0 ) return;
1327
1328 if ( type != OBJECT_TEEN28 &&
1329 type != OBJECT_TEEN34 &&
1330 color != MAPCOLOR_MOVE ) return;
1331 }*/
1332
1333 if ( pObj->Implements(ObjectInterfaceType::Controllable) && dynamic_cast<CControllableObject&>(*pObj).GetSelect() )
1334 {
1335 m_map[MAPMAXOBJECT-1].type = type;
1336 m_map[MAPMAXOBJECT-1].object = pObj;
1337 m_map[MAPMAXOBJECT-1].color = color;
1338 m_map[MAPMAXOBJECT-1].pos.x = pos.x;
1339 m_map[MAPMAXOBJECT-1].pos.y = pos.z;
1340 m_map[MAPMAXOBJECT-1].dir = dir;
1341 m_map[MAPMAXOBJECT-1].bUsed = true;
1342 }
1343 else
1344 {
1345 if ( color == MAPCOLOR_BASE ||
1346 color == MAPCOLOR_FIX )
1347 {
1348 m_map[m_totalFix].type = type;
1349 m_map[m_totalFix].object = pObj;
1350 m_map[m_totalFix].color = color;
1351 m_map[m_totalFix].pos.x = pos.x;
1352 m_map[m_totalFix].pos.y = pos.z;
1353 m_map[m_totalFix].dir = dir;
1354 m_map[m_totalFix].bUsed = true;
1355 m_totalFix ++;
1356 }
1357 else
1358 {
1359 m_map[m_totalMove].type = type;
1360 m_map[m_totalMove].object = pObj;
1361 m_map[m_totalMove].color = color;
1362 m_map[m_totalMove].pos.x = pos.x;
1363 m_map[m_totalMove].pos.y = pos.z;
1364 m_map[m_totalMove].dir = dir;
1365 m_map[m_totalMove].bUsed = true;
1366 m_totalMove --;
1367 }
1368 }
1369 }
1370
1371 }
1372