/*
===========================================================================
ARX FATALIS GPL Source Code
Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code. If not, see
.
In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//////////////////////////////////////////////////////////////////////////////////////
// @@ @@@ @@@ @@ @@@@@ //
// @@@ @@@@@@ @@@ @@ @@@@ @@@ @@@ //
// @@@ @@@@@@@ @@@ @@@@ @@@@ @@ @@@@ //
// @@@ @@ @@@@ @@@ @@@@@ @@@@@@ @@@ @@@ //
// @@@@@ @@ @@@@ @@@ @@@@@ @@@@@@@ @@@ @ @@@ //
// @@@@@ @@ @@@@ @@@@@@@@ @@@@ @@@ @@@@@ @@ @@@@@@@ //
// @@ @@@ @@ @@@@ @@@@@@@ @@@ @@@ @@@@@@ @@ @@@@ //
// @@@ @@@ @@@ @@@@ @@@@@ @@@@@@@@@ @@@@@@@ @@@ @@@@ //
// @@@ @@@@ @@@@@@@ @@@@@@ @@@ @@@@ @@@ @@@ @@@ @@@@ //
// @@@@@@@@ @@@@@ @@@@@@@@@@ @@@ @@@ @@@ @@@ @@@ @@@@@ //
// @@@ @@@@ @@@@ @@@ @@@@@@@ @@@ @@@ @@@@ @@@ @@@@ @@@@@ //
//@@@ @@@@ @@@@@ @@@ @@@@@@ @@ @@@ @@@@ @@@@@@@ @@@@@ @@@@@ //
//@@@ @@@@@ @@@@@ @@@@ @@@ @@ @@ @@@@ @@@@@@@ @@@@@@@@@ //
//@@@ @@@@ @@@@@@@ @@@@ @@ @@ @@@@ @@@@@ @@@@@ //
//@@@ @@@@ @@@@@@@ @@@@ @@ @@ @@@@ @@@@@ @@ //
//@@@ @@@ @@@ @@@@@ @@ @@@ //
// @@@ @@@ @@ @@ STUDIOS //
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
// ARX_NPC
//////////////////////////////////////////////////////////////////////////////////////
//
// Description:
// ARX Minimap Management
//
// Updates: (date) (person) (update)
//
// Code: Cyril Meynier
//
// Copyright (c) 1999-2001 ARKANE Studios SA. All rights reserved
//////////////////////////////////////////////////////////////////////////////////////
#include "ARX_Levels.h"
#include "ARX_Minimap.h"
#include "ARX_Text.h"
#include "EERIELight.h"
#include "EERIEPhysicsBox.h"
#include "EERIEDRAW.h"
#include "EERIEObject.h"
#include "Hermesmain.h"
#include "danae.h"
#include
#define _CRTDBG_MAP_ALLOC
#include
MINI_MAP_DATA minimap[MAX_MINIMAPS];
float mini_offset_x[MAX_MINIMAPS];
float mini_offset_y[MAX_MINIMAPS];
float mapmaxy[32];
TextureContainer * pTexDetect = NULL;
extern long FOR_EXTERNAL_PEOPLE;
MAPMARKER_DATA * Mapmarkers = NULL;
long Nb_Mapmarkers = 0;
//-----------------------------------------------------------------------------
void ARX_MINIMAP_GetData(long SHOWLEVEL)
{
if (minimap[SHOWLEVEL].tc == NULL)
{
char name[256];
char LevelMap[256];
GetLevelNameByNum(SHOWLEVEL, name);
sprintf(LevelMap, "Graph\\Levels\\Level%s\\map.bmp", name);
minimap[SHOWLEVEL].tc = MakeTCFromFile(LevelMap);
if (minimap[SHOWLEVEL].tc) // 4 pix/meter
{
minimap[SHOWLEVEL].tc->Restore(GDevice);
SpecialBorderSurface(minimap[SHOWLEVEL].tc, minimap[SHOWLEVEL].tc->m_dwOriginalWidth, minimap[SHOWLEVEL].tc->m_dwOriginalHeight);
minimap[SHOWLEVEL].height = ARX_CLEAN_WARN_CAST_FLOAT(minimap[SHOWLEVEL].tc->m_dwHeight);
minimap[SHOWLEVEL].width = ARX_CLEAN_WARN_CAST_FLOAT(minimap[SHOWLEVEL].tc->m_dwWidth);
float minx = FLT_MAX;
float maxx = FLT_MIN;
float miny = FLT_MAX;
float maxy = FLT_MIN;
EERIEPOLY * ep;
EERIE_BKG_INFO * eg;
for (long j = 0; j < ACTIVEBKG->Zsize; j++)
{
for (long i = 0; i < ACTIVEBKG->Xsize; i++)
{
eg = &ACTIVEBKG->Backg[i+j*ACTIVEBKG->Xsize];
for (long k = 0; k < eg->nbpoly; k++)
{
ep = &eg->polydata[k];
if (ep)
{
minx = __min(minx, ep->min.x);
maxx = __max(maxx, ep->max.x);
miny = __min(miny, ep->min.z);
maxy = __max(maxy, ep->max.z);
}
}
}
mapmaxy[SHOWLEVEL] = maxy;
minimap[SHOWLEVEL].xratio = minx;
minimap[SHOWLEVEL].yratio = miny;
for (long iii = 0; iii < 32; iii++)
{
minimap[iii].offsetx = 0;
minimap[iii].offsety = 0;
}
}
}
}
}
extern long Book_MapPage;
//-----------------------------------------------------------------------------
void ARX_MINIMAP_ValidatePos(EERIE_3D * pos)
{
long SHOWLEVEL = ARX_LEVELS_GetRealNum(CURRENTLEVEL);
if ((SHOWLEVEL >= 0) && (SHOWLEVEL < 32))
{
if (minimap[SHOWLEVEL].tc == NULL)
{
ARX_MINIMAP_GetData(SHOWLEVEL);
}
if (minimap[CURRENTLEVEL].tc == NULL)
{
ARX_MINIMAP_GetData(CURRENTLEVEL);
}
if ((minimap[SHOWLEVEL].tc) && (minimap[SHOWLEVEL].tc->m_pddsSurface))
{
ARX_MINIMAP_Show(GDevice, ARX_LEVELS_GetRealNum(CURRENTLEVEL), 2);
}
}
}
float AM_LASTPOS_x = -999999.f;
float AM_LASTPOS_z = -999999.f;
void ARX_MINIMAP_ValidatePlayerPos()
{
if (BLOCK_PLAYER_CONTROLS) return;
float dist = Distance2D(AM_LASTPOS_x, AM_LASTPOS_z, player.pos.x, player.pos.z);
float req;
if ((player.Interface & INTER_MAP) && (!(player.Interface & INTER_COMBATMODE)) && (Book_Mode == 2))
req = 20.f;
else req = 80.f;
if (dist > req)
{
AM_LASTPOS_x = player.pos.x;
AM_LASTPOS_z = player.pos.z;
ARX_MINIMAP_ValidatePos(&player.pos);
}
}
//-----------------------------------------------------------------------------
// MINIMAP
//-----------------------------------------------------------------------------
void ARX_MINIMAP_Load_Offsets()
{
char fic[256];
sprintf(fic, "%s\\Graph\\Levels\\mini_offsets.ini", Project.workingdir);
if (PAK_FileExist(fic))
{
long siz = 0;
char * dat = (char *)PAK_FileLoadMalloc(fic, &siz);
long pos = 0;
if (dat)
{
for (long i = 0; i < 29; i++)
{
char t[512];
sscanf(dat + pos, "%s %f %f", t, &mini_offset_x[i], &mini_offset_y[i]);
while ((pos < siz) && (dat[pos] != 10)) pos++;
pos++;
if (pos >= siz) i = 100;
}
free(dat);
}
}
mini_offset_x[0] = 0;
mini_offset_y[0] = -0.5;
mini_offset_x[1] = 0;
mini_offset_y[1] = 0;
mini_offset_x[14] = 130;
mini_offset_y[14] = 0;
mini_offset_x[15] = 31;
mini_offset_y[15] = -3.5;
}
void ARX_MINIMAP_Reveal()
{
for (long ii = 0; ii < MAX_MINIMAPS; ii++)
{
for (long j = 0; j < MINIMAP_MAX_Z; j++)
for (long i = 0; i < MINIMAP_MAX_X; i++)
{
minimap[ii].revealed[i][j] = 255;
}
}
}
//-----------------------------------------------------------------------------
void ARX_MINIMAP_FirstInit()
{
memset(minimap, 0, sizeof(MINI_MAP_DATA)*MAX_MINIMAPS);
for (long i = 0; i < MAX_MINIMAPS; i++)
{
mini_offset_x[i] = 0;
mini_offset_y[i] = 0;
}
ARX_MINIMAP_Load_Offsets();
}
//-----------------------------------------------------------------------------
void ARX_MINIMAP_Reset()
{
for (long i = 0; i < MAX_MINIMAPS; i++)
{
if (minimap[i].tc)
{
D3DTextr_KillTexture(minimap[i].tc);
minimap[i].tc = NULL;
}
}
memset(minimap, 0, sizeof(MINI_MAP_DATA)*MAX_MINIMAPS);
}
//-----------------------------------------------------------------------------
void ARX_MINIMAP_PurgeTC()
{
for (long i = 0; i < MAX_MINIMAPS; i++)
{
if (minimap[i].tc)
{
D3DTextr_KillTexture(minimap[i].tc);
minimap[i].tc = NULL;
}
}
}
//-----------------------------------------------------------------------------
TextureContainer * MapMarkerTc = NULL;
float DECALY = -150;
float DECALX = +40;
//-----------------------------------------------------------------------------
void ARX_MINIMAP_Show(LPDIRECT3DDEVICE7 m_pd3dDevice, long SHOWLEVEL, long flag, long fl2)
{
float sstartx, sstarty;
if (!pTexDetect)
{
GetTextureFile("Graph\\particles\\flare.bmp");
char temp[256];
MakeDir(temp, "Graph\\particles\\flare.bmp");
pTexDetect = D3DTextr_GetSurfaceContainer(temp);
}
// SHOWLEVEL=8;
// First Load Minimap TC & DATA if needed
if (minimap[SHOWLEVEL].tc == NULL)
{
ARX_MINIMAP_GetData(SHOWLEVEL);
}
if ((minimap[SHOWLEVEL].tc) && (minimap[SHOWLEVEL].tc->m_pddsSurface))
{
float startx, starty, casex, casey, ratiooo;
float mod_x = (float)MAX_BKGX / (float)MINIMAP_MAX_X;
float mod_z = (float)MAX_BKGZ / (float)MINIMAP_MAX_Z;
if (flag == 1)
{
startx = 0;
starty = 0;
casex = (900) / ((float)MINIMAP_MAX_X);
casey = (900) / ((float)MINIMAP_MAX_Z);
ratiooo = 900.f / 250.f;
if (fl2)
{
casex = (600) / ((float)MINIMAP_MAX_X);
casey = (600) / ((float)MINIMAP_MAX_Z);
ratiooo = 600.f / 250.f;
}
}
else
{
startx = (140);
starty = (120);
casex = (250) / ((float)MINIMAP_MAX_X);
casey = (250) / ((float)MINIMAP_MAX_Z);
ratiooo = 1.f;
}
sstartx = startx;
sstarty = starty;
float ofx, ofx2, ofy, ofy2, px, py;
px = py = 0.f;
ofx = mini_offset_x[CURRENTLEVEL];
ofx2 = minimap[SHOWLEVEL].xratio;
ofy = mini_offset_y[CURRENTLEVEL];
ofy2 = minimap[SHOWLEVEL].yratio;
if ((SHOWLEVEL == ARX_LEVELS_GetRealNum(CURRENTLEVEL)) || (flag == 2))
{
// Computes playerpos
ofx = mini_offset_x[CURRENTLEVEL];
ofx2 = minimap[SHOWLEVEL].xratio;
ofy = mini_offset_y[CURRENTLEVEL];
ofy2 = minimap[SHOWLEVEL].yratio;
px = startx + ((player.pos.x + ofx - ofx2) * DIV100 * casex
+ mini_offset_x[CURRENTLEVEL] * ratiooo * mod_x) / mod_x ; //DIV100*2;
py = starty + ((mapmaxy[SHOWLEVEL] - ofy - ofy2) * DIV100 * casey
- (player.pos.z + ofy - ofy2) * DIV100 * casey + mini_offset_y[CURRENTLEVEL] * ratiooo * mod_z) / mod_z ; //DIV100*2;
if (flag == 1)
{
sstartx = startx;
sstarty = starty;
startx = 490.f - px;
starty = 220.f - py;
px += startx;
py += starty;
}
}
D3DTLVERTEX verts[4];
SETTC(m_pd3dDevice, minimap[SHOWLEVEL].tc);
for (long k = 0; k < 4; k++)
{
verts[k].color = 0xFFFFFFFF;
verts[k].rhw = 1;
verts[k].sz = 0.00001f;
}
float div = DIV25;
TextureContainer * tc = minimap[SHOWLEVEL].tc;
float dw = 1.f / (float)max(tc->m_dwDeviceWidth, tc->m_dwOriginalWidth);
float dh = 1.f / (float)max(tc->m_dwDeviceHeight, tc->m_dwOriginalHeight);
float vx2 = 4.f * dw * mod_x;
float vy2 = 4.f * dh * mod_z;
float _px;
RECT boundaries;
float MOD20, MOD20DIV, divXratio, divYratio;
boundaries.bottom = boundaries.left = boundaries.right = boundaries.top = 0;
MOD20 = MOD20DIV = divXratio = divYratio = 0.f;
if (flag != 2)
{
if (flag == 1)
{
MOD20 = 20.f * Xratio;
MOD20DIV = 1.f / (MOD20);
//@PERF do if(fl2){}else{} to make 4 and not 8 flot op if fl2.
ARX_CHECK_LONG((360 + MOD20)*Xratio);
ARX_CHECK_LONG((555 - MOD20)*Xratio);
ARX_CHECK_LONG((85 + MOD20)*Yratio);
ARX_CHECK_LONG((355 - MOD20)*Yratio);
//CAST
boundaries.left = ARX_CLEAN_WARN_CAST_LONG((360 + MOD20) * Xratio);
boundaries.right = ARX_CLEAN_WARN_CAST_LONG((555 - MOD20) * Xratio);
boundaries.top = ARX_CLEAN_WARN_CAST_LONG((85 + MOD20) * Yratio);
boundaries.bottom = ARX_CLEAN_WARN_CAST_LONG((355 - MOD20) * Yratio);
if (fl2)
{
//CHECK (DEBUG)
ARX_CHECK_LONG((390 + MOD20)*Xratio);
ARX_CHECK_LONG((590 - MOD20)*Xratio);
ARX_CHECK_LONG((135 + MOD20)*Yratio);
ARX_CHECK_LONG((295 - MOD20)*Yratio);
//CAST
boundaries.left = ARX_CLEAN_WARN_CAST_LONG((390 + MOD20) * Xratio);
boundaries.right = ARX_CLEAN_WARN_CAST_LONG((590 - MOD20) * Xratio);
boundaries.top = ARX_CLEAN_WARN_CAST_LONG((135 + MOD20) * Yratio);
boundaries.bottom = ARX_CLEAN_WARN_CAST_LONG((295 - MOD20) * Yratio);
}
}
SETALPHABLEND(m_pd3dDevice, TRUE);
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO);
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR);
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS);
SETTEXTUREWRAPMODE(m_pd3dDevice, D3DTADDRESS_CLAMP);
if (fl2)
{
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE);
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR);
}
}
else
{
divXratio = 1.f / Xratio;
divYratio = 1.f / Yratio;
}
for (long j = -2; j < MINIMAP_MAX_Z + 2; j++)
{
for (long i = -2; i < MINIMAP_MAX_X + 2; i++)
{
float vx, vy, vxx, vyy;
vxx = ((float)i * (float)ACTIVEBKG->Xdiv * mod_x);
vyy = ((float)j * (float)ACTIVEBKG->Zdiv * mod_z);
vx = (vxx * div) * dw;
vy = (vyy * div) * dh;
long okay = 1;
float posx = (startx + i * casex) * Xratio;
float posy = (starty + j * casey) * Yratio;
if (flag == 1)
{
if ((posx < 360 * Xratio)
|| (posx > 555 * Xratio)
|| (posy < 85 * Yratio)
|| (posy > 355 * Yratio))
okay = 0;
if (fl2)
{
okay = 1;
if ((posx < 390 * Xratio)
|| (posx > 590 * Xratio)
|| (posy < 135 * Yratio)
|| (posy > 295 * Yratio))
okay = 0;
}
}
else
{
if ((posx > 345 * Xratio)
|| (posy > 290 * Yratio))
okay = 0;
}
if (okay)
{
if ((flag == 2)
&& (i >= 0) && (i < MINIMAP_MAX_X)
&& (j >= 0) && (j < MINIMAP_MAX_Z))
{
float d = Distance2D(posx * divXratio + casex * DIV2, posy * divYratio /*-casey * 2 * Yratio*/, px, py);
if (d <= 6.f)
{
long r;
float vv = (6 - d) * DIV6;
if (vv >= 0.5f)
vv = 1.f;
else if (vv > 0.f)
vv = vv * 2.f;
else
vv = 0.f;
F2L((float)(vv * 255.f), &r);
long ucLevel = __max(r, minimap[SHOWLEVEL].revealed[i][j]);
ARX_CHECK_UCHAR(ucLevel);
minimap[SHOWLEVEL].revealed[i][j] = ARX_CLEAN_WARN_CAST_UCHAR(ucLevel);
}
}
if (!FOR_EXTERNAL_PEOPLE)
{
if ((i >= 0) && (i < MINIMAP_MAX_X)
&& (j >= 0) && (j < MINIMAP_MAX_Z))
{
minimap[SHOWLEVEL].revealed[i][j] = 255;
}
}
verts[3].sx = verts[0].sx = (posx);
verts[1].sy = verts[0].sy = (posy);
verts[2].sx = verts[1].sx = posx + (casex * Xratio);
verts[3].sy = verts[2].sy = posy + (casey * Yratio);
verts[3].tu = verts[0].tu = vx;
verts[1].tv = verts[0].tv = vy;
verts[2].tu = verts[1].tu = vx + vx2;
verts[3].tv = verts[2].tv = vy + vy2;
if (flag != 2)
{
float v;
float oo = 0.f;
if ((i < 0) || (i >= MINIMAP_MAX_X) || (j < 0) || (j >= MINIMAP_MAX_Z)) v = 0;
else v = ((float)minimap[SHOWLEVEL].revealed[i][j]) * DIV255;
if (flag == 1)
{
long vert = 0;
_px = verts[vert].sx - boundaries.left;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
_px = boundaries.right - verts[vert].sx;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
_px = verts[vert].sy - boundaries.top;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
_px = boundaries.bottom - verts[vert].sy;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
}
if (fl2) verts[0].color = D3DRGB(v * DIV2, v * DIV2, v * DIV2);
else
verts[0].color = D3DRGB(v, v, v);
oo += v;
if ((i + 1 < 0) || (i + 1 >= MINIMAP_MAX_X) || (j < 0) || (j >= MINIMAP_MAX_Z)) v = 0;
else v = ((float)minimap[SHOWLEVEL].revealed[__min(i+1, MINIMAP_MAX_X-1)][j]) * DIV255;
if (flag == 1)
{
long vert = 1;
_px = verts[vert].sx - boundaries.left;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
_px = boundaries.right - verts[vert].sx;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
_px = verts[vert].sy - boundaries.top;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
_px = boundaries.bottom - verts[vert].sy;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
}
if (fl2) verts[1].color = D3DRGB(v * DIV2, v * DIV2, v * DIV2);
else
verts[1].color = D3DRGB(v, v, v);
oo += v;
if ((i + 1 < 0) || (i + 1 >= MINIMAP_MAX_X) || (j + 1 < 0) || (j + 1 >= MINIMAP_MAX_Z)) v = 0;
else v = ((float)minimap[SHOWLEVEL].revealed[__min(i+1, MINIMAP_MAX_X-1)][__min(j+1, MINIMAP_MAX_Z-1)]) * DIV255;
if (flag == 1)
{
long vert = 2;
_px = verts[vert].sx - boundaries.left;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
_px = boundaries.right - verts[vert].sx;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
_px = verts[vert].sy - boundaries.top;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
_px = boundaries.bottom - verts[vert].sy;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
}
if (fl2) verts[2].color = D3DRGB(v * DIV2, v * DIV2, v * DIV2);
else
verts[2].color = D3DRGB(v, v, v);
oo += v;
if ((i < 0) || (i >= MINIMAP_MAX_X) || (j + 1 < 0) || (j + 1 >= MINIMAP_MAX_Z)) v = 0;
else v = ((float)minimap[SHOWLEVEL].revealed[i][__min(j+1, MINIMAP_MAX_Z-1)]) * DIV255;
if (flag == 1)
{
long vert = 3;
_px = verts[vert].sx - boundaries.left;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
_px = boundaries.right - verts[vert].sx;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
_px = verts[vert].sy - boundaries.top;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
_px = boundaries.bottom - verts[vert].sy;
if (_px < 0.f) v = 0.f;
else if (_px < MOD20) v *= _px * MOD20DIV;
}
if (fl2) verts[3].color = D3DRGB(v * DIV2, v * DIV2, v * DIV2);
else
verts[3].color = D3DRGB(v, v, v);
oo += v;
if (oo > 0.f)
{
if (fl2)
{
verts[0].sx += DECALX * Xratio;
verts[0].sy += DECALY * Yratio;
verts[1].sx += DECALX * Xratio;
verts[1].sy += DECALY * Yratio;
verts[2].sx += DECALX * Xratio;
verts[2].sy += DECALY * Yratio;
verts[3].sx += DECALX * Xratio;
verts[3].sy += DECALY * Yratio;
}
EERIEDRAWPRIM(GDevice, D3DPT_TRIANGLEFAN, D3DFVF_TLVERTEX | D3DFVF_DIFFUSE, verts, 4, 0);
}
}
}
}
}
if (flag != 2)
{
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ADDRESS , D3DTADDRESS_WRAP);
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
SETALPHABLEND(m_pd3dDevice, FALSE);
if ((SHOWLEVEL == ARX_LEVELS_GetRealNum(CURRENTLEVEL)))
{
// Now Draws Playerpos/angle
verts[0].color = 0xFFFF0000;
verts[1].color = 0xFFFF0000;
verts[2].color = 0xFFFF0000;
float val;
if (flag == 1) val = 6.f;
else val = 3.f;
float rx = 0.f;
float ry = -val * 1.8f;
float rx2 = -val * DIV2;
float ry2 = val;
float rx3 = val * DIV2;
float ry3 = val;
float angle = DEG2RAD(player.angle.b);
float ca = EEcos(angle);
float sa = EEsin(angle);
verts[0].sx = (px + rx2 * ca + ry2 * sa) * Xratio;
verts[0].sy = (py + ry2 * ca - rx2 * sa) * Yratio;
verts[1].sx = (px + rx * ca + ry * sa) * Xratio;
verts[1].sy = (py + ry * ca - rx * sa) * Yratio;
verts[2].sx = (px + rx3 * ca + ry3 * sa) * Xratio;
verts[2].sy = (py + ry3 * ca - rx3 * sa) * Yratio;
SETTC(GDevice, NULL);
if (fl2)
{
SETALPHABLEND(m_pd3dDevice, TRUE);
verts[0].sx += DECALX * Xratio;
verts[0].sy += DECALY * Yratio;
verts[1].sx += DECALX * Xratio;
verts[1].sy += DECALY * Yratio;
verts[2].sx += DECALX * Xratio;
verts[2].sy += DECALY * Yratio;
}
EERIEDRAWPRIM(GDevice, D3DPT_TRIANGLEFAN, D3DFVF_TLVERTEX | D3DFVF_DIFFUSE, verts, 3, 0);
if (fl2) SETALPHABLEND(m_pd3dDevice, FALSE);
}
}
// tsu
for (long lnpc = 1; lnpc < inter.nbmax; lnpc++)
{
if ((inter.iobj[lnpc] != NULL) && (inter.iobj[lnpc]->ioflags & IO_NPC))
{
if (inter.iobj[lnpc]->_npcdata->life > 0.f)
if (!((inter.iobj[lnpc]->GameFlags & GFLAG_MEGAHIDE) ||
(inter.iobj[lnpc]->show == SHOW_FLAG_MEGAHIDE))
&& (inter.iobj[lnpc]->show == SHOW_FLAG_IN_SCENE))
if (!(inter.iobj[lnpc]->show == SHOW_FLAG_HIDDEN))
if (inter.iobj[lnpc]->_npcdata->fDetect >= 0)
{
if (player.Full_Skill_Etheral_Link >= inter.iobj[lnpc]->_npcdata->fDetect)
{
float fpx;
float fpy;
fpx = sstartx + ((inter.iobj[lnpc]->pos.x - 100 + ofx - ofx2) * DIV100 * casex
+ mini_offset_x[CURRENTLEVEL] * ratiooo * mod_x) / mod_x;
fpy = sstarty + ((mapmaxy[SHOWLEVEL] - ofy - ofy2) * DIV100 * casey
- (inter.iobj[lnpc]->pos.z + 200 + ofy - ofy2) * DIV100 * casey + mini_offset_y[CURRENTLEVEL] * ratiooo * mod_z) / mod_z;
if (flag == 1)
{
fpx = startx + ((inter.iobj[lnpc]->pos.x - 100 + ofx - ofx2) * DIV100 * casex
+ mini_offset_x[CURRENTLEVEL] * ratiooo * mod_x) / mod_x;
fpy = starty + ((mapmaxy[SHOWLEVEL] - ofy - ofy2) * DIV100 * casey
- (inter.iobj[lnpc]->pos.z + 200 + ofy - ofy2) * DIV100 * casey + mini_offset_y[CURRENTLEVEL] * ratiooo * mod_z) / mod_z;
}
float d = Distance2D(player.pos.x, player.pos.z, inter.iobj[lnpc]->pos.x, inter.iobj[lnpc]->pos.z);
if ((d <= 800) && (fabs(inter.iobj[0]->pos.y - inter.iobj[lnpc]->pos.y) < 250.f))
{
float col = 1.f;
if (d > 600.f)
{
col = 1.f - (d - 600.f) * DIV200;
}
if (!fl2)
{
SETALPHABLEND(m_pd3dDevice, true);
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE);
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE);
}
else
SETALPHABLEND(m_pd3dDevice, true);
if (fl2)
{
fpx += DECALX * Xratio;
fpy += (DECALY + 15) * Yratio;
}
fpx *= Xratio;
fpy *= Yratio;
EERIEDrawBitmap(GDevice, fpx, fpy,
5.f * ratiooo, 5.f * ratiooo, 0, pTexDetect, D3DRGB(col, 0, 0));
if (!fl2)
SETALPHABLEND(m_pd3dDevice, false);
}
}
}
}
}
if (flag == 0)
for (long i = 0; i < Nb_Mapmarkers; i++)
{
if (Mapmarkers[i].lvl == SHOWLEVEL + 1)
{
float pos_x = Mapmarkers[i].x * 8 * ratiooo * ACTIVEBKG->Xmul * casex + startx;
float pos_y = Mapmarkers[i].y * 8 * ratiooo * ACTIVEBKG->Zmul * casey + starty;
float size = 5.f * ratiooo;
verts[0].color = 0xFFFF0000;
verts[1].color = 0xFFFF0000;
verts[2].color = 0xFFFF0000;
verts[3].color = 0xFFFF0000;
verts[0].sx = (pos_x - size) * Xratio;
verts[0].sy = (pos_y - size) * Yratio;
verts[1].sx = (pos_x + size) * Xratio;
verts[1].sy = (pos_y - size) * Yratio;
verts[2].sx = (pos_x + size) * Xratio;
verts[2].sy = (pos_y + size) * Yratio;
verts[3].sx = (pos_x - size) * Xratio;
verts[3].sy = (pos_y + size) * Yratio;
verts[0].tu = 0.f;
verts[0].tv = 0.f;
verts[1].tu = 1.f;
verts[1].tv = 0.f;
verts[2].tu = 1.f;
verts[2].tv = 1.f;
verts[3].tu = 0.f;
verts[3].tv = 1.f;
if ((!fl2)
&& (MouseInRect(verts[0].sx, verts[0].sy, verts[2].sx, verts[2].sy)))
{
if (!Mapmarkers[i].tstring)
{
_TCHAR output[4096];
MakeLocalised(Mapmarkers[i].string, output, 4096, 0);
Mapmarkers[i].tstring = (_TCHAR *)malloc((_tcslen(output) + 1) * sizeof(_TCHAR));
ZeroMemory(Mapmarkers[i].tstring, (_tcslen(output) + 1)*sizeof(_TCHAR));
_tcscpy(Mapmarkers[i].tstring, output);
}
if (Mapmarkers[i].tstring)
{
RECT rRect, bRect;
SetRect(&bRect , (140), (290)
, (140 + 205), (358));
float fLeft = (bRect.left) * Xratio ;
float fRight = (bRect.right) * Xratio ;
float fTop = (bRect.top) * Yratio ;
float fBottom = (bRect.bottom) * Yratio ;
ARX_CHECK_INT(fLeft);
ARX_CHECK_INT(fRight);
ARX_CHECK_INT(fTop);
ARX_CHECK_INT(fBottom);
SetRect(&rRect
, ARX_CLEAN_WARN_CAST_INT(fLeft)
, ARX_CLEAN_WARN_CAST_INT(fTop)
, ARX_CLEAN_WARN_CAST_INT(fRight)
, ARX_CLEAN_WARN_CAST_INT(fBottom));
long lLengthDraw = ARX_UNICODE_ForceFormattingInRect(
hFontInGameNote, Mapmarkers[i].tstring, 0, rRect);
danaeApp.DANAEEndRender();
_TCHAR Page_Buffer[256];
_tcsncpy(Page_Buffer, Mapmarkers[i].tstring, lLengthDraw);
Page_Buffer[lLengthDraw] = _T('\0');
DrawBookTextInRect(ARX_CLEAN_WARN_CAST_FLOAT(bRect.left), ARX_CLEAN_WARN_CAST_FLOAT(bRect.top),
ARX_CLEAN_WARN_CAST_FLOAT(bRect.right), ARX_CLEAN_WARN_CAST_FLOAT(bRect.bottom),
Page_Buffer, 0, 0x00FF00FF,
hFontInGameNote);
danaeApp.DANAEStartRender();
}
}
if (MapMarkerTc == NULL)
{
MapMarkerTc = MakeTCFromFile("Graph\\interface\\icons\\mapmarker.bmp");
}
SETTC(GDevice, MapMarkerTc);
if (fl2)
{
verts[0].sx += DECALX * Xratio;
verts[0].sy += DECALY * Yratio;
verts[1].sx += DECALX * Xratio;
verts[1].sy += DECALY * Yratio;
verts[2].sx += DECALX * Xratio;
verts[2].sy += DECALY * Yratio;
verts[3].sx += DECALX * Xratio;
verts[3].sy += DECALY * Yratio;
}
EERIEDRAWPRIM(GDevice, D3DPT_TRIANGLEFAN, D3DFVF_TLVERTEX | D3DFVF_DIFFUSE, verts, 4, 0);
}
}
}
}
void ARX_MAPMARKER_Init()
{
if (Mapmarkers)
{
for (long i = 0; i < Nb_Mapmarkers; i++)
{
if (Mapmarkers[i].tstring)
free(Mapmarkers[i].tstring);
Mapmarkers[i].tstring = NULL;
}
free(Mapmarkers);
}
Mapmarkers = NULL;
Nb_Mapmarkers = 0;
}
long ARX_MAPMARKER_Get(char * str)
{
for (long i = 0; i < Nb_Mapmarkers; i++)
{
if (!stricmp(Mapmarkers[i].string, str))
return i;
}
return -1;
}
void ARX_MAPMARKER_Add(float x, float y, long lvl, char * temp)
{
long num = ARX_MAPMARKER_Get(temp);
if (num >= 0) // already exists
{
Mapmarkers[num].lvl = lvl;
Mapmarkers[num].x = x;
Mapmarkers[num].y = y;
if (Mapmarkers[num].tstring)
free(Mapmarkers[num].tstring);
Mapmarkers[num].tstring = NULL;
strcpy(Mapmarkers[num].string, temp);
return;
}
Mapmarkers = (MAPMARKER_DATA *)realloc(Mapmarkers, sizeof(MAPMARKER_DATA) * (Nb_Mapmarkers + 1));
// Memory Error Handling
if (!Mapmarkers)
{
Nb_Mapmarkers = 0;
return;
}
Mapmarkers[Nb_Mapmarkers].lvl = lvl;
Mapmarkers[Nb_Mapmarkers].x = x;
Mapmarkers[Nb_Mapmarkers].y = y;
Mapmarkers[Nb_Mapmarkers].tstring = NULL;
strcpy(Mapmarkers[Nb_Mapmarkers].string, temp);
Nb_Mapmarkers++;
}
void ARX_MAPMARKER_Remove(char * temp)
{
long num = ARX_MAPMARKER_Get(temp);
if (num < 0) return; // Doesn't exists
if (Nb_Mapmarkers <= 1)
{
ARX_MAPMARKER_Init();
return;
}
if (Mapmarkers[num].tstring)
free(Mapmarkers[num].tstring);
Mapmarkers[num].tstring = NULL;
for (long i = num; i < Nb_Mapmarkers - 1; i++)
{
memcpy(&Mapmarkers[i], &Mapmarkers[i+1], sizeof(MAPMARKER_DATA));
}
Mapmarkers = (MAPMARKER_DATA *)realloc(Mapmarkers, sizeof(MAPMARKER_DATA) * (Nb_Mapmarkers - 1));
Nb_Mapmarkers--;
}