1
0
vice-city/filterscripts/vc_minimap.pwn
2021-03-17 00:49:58 +01:00

326 lines
12 KiB
C

#include <a_samp>
#include <streamer>
//Vice City Map Limits
#define VICE_CITY_MIN_X 4130.0
#define VICE_CITY_MIN_Y -930.0
#define VICE_CITY_MAX_X 6975.0
#define VICE_CITY_MAX_Y 2665.0
//Minimap Global definitions
#define MINIMAP_MODEL_ID -1500
#define AREA_TYPE_MINIMAP 1 //this must be an unique int in streamer arrayData, use 1 if you don't use streamer data manipulation
#define MINIMAP_UPDATE_INTERVAL 100
//Minimap Textdraws definitions
#define MINIMAP_TEXTDRAW_POS_X 25.0
#define MINIMAP_TEXTDRAW_POS_Y 325.0
#define MINIMAP_TEXTDRAW_SIZE_X 110.0
#define MINIMAP_TEXTDRAW_SIZE_Y 95.0
#define MINIMAP_TEXTDRAW_ICON_SIZE_X 6.4
#define MINIMAP_TEXTDRAW_ICON_SIZE_Y 8.0
#define MINIMAP_TEXTDRAW_BORDER_SIZE 2.0
//Area variables
new
vcArea = INVALID_STREAMER_ID, //whole map
minimapAreas[15] = {INVALID_STREAMER_ID, ...}, //each minimap section
Float:minimapAreas_Coords[15][4] = //minimap sections limits (minX, minY, maxX, maxY)
{
{4130.000000, -930.000000, 5078.333496, -211.000000}, //1
{5078.333496, -930.000000, 6026.666503, -211.000000}, //2
{6026.666503, -930.000000, 6975.000000, -211.000000}, //3
{4130.000000, -211.000000, 5078.333496, 508.000000}, //4
{5078.333496, -211.000000, 6026.666503, 508.000000}, //5
{6026.666503, -211.000000, 6975.000000, 508.000000}, //6
{4130.000000, 508.000000, 5078.333496, 1227.000000}, //7
{5078.333496, 508.000000, 6026.666503, 1227.000000}, //8
{6026.666503, 508.000000, 6975.000000, 1227.000000}, //9
{4130.000000, 1227.000000, 5078.333496, 1946.000000}, //10
{5078.333496, 1227.000000, 6026.666503, 1946.000000}, //11
{6026.666503, 1227.000000, 6975.000000, 1946.000000}, //12
{4130.000000, 1946.000000, 5078.333496, 2665.000000}, //13
{5078.333496, 1946.000000, 6026.666503, 2665.000000}, //14
{6026.666503, 1946.000000, 6975.000000, 2665.000000} //15
}
;
//Player variables
forward OnVcMinimapRequestUpdate(playerid);
new
bool:pVcMinimap[MAX_PLAYERS],
PlayerText:pVcMinimapTextdraws[MAX_PLAYERS][3] = {{PlayerText:INVALID_TEXT_DRAW, ...}, ...},
pVcMinimapCurrentArea[MAX_PLAYERS],
pVcMinimapTimer[MAX_PLAYERS] = {-1, ...};
public OnFilterScriptInit()
{
AddSimpleModel(-1, 19379, MINIMAP_MODEL_ID, "blank.dff", "minimap.txd");
new streamer_info[2];
streamer_info[0] = AREA_TYPE_MINIMAP;
streamer_info[1] = 0;
vcArea = CreateDynamicRectangle(VICE_CITY_MIN_X, VICE_CITY_MIN_Y, VICE_CITY_MAX_X, VICE_CITY_MAX_Y, -1, 0);
Streamer_SetArrayData(STREAMER_TYPE_AREA, vcArea, E_STREAMER_EXTRA_ID, streamer_info);
for(new i = 0, j = sizeof minimapAreas; i != j; i ++)
{
streamer_info[1] = i + 1;
minimapAreas[i] = CreateDynamicRectangle(minimapAreas_Coords[i][0], minimapAreas_Coords[i][1], minimapAreas_Coords[i][2], minimapAreas_Coords[i][3], -1, 0);
Streamer_SetArrayData(STREAMER_TYPE_AREA, minimapAreas[i], E_STREAMER_EXTRA_ID, streamer_info);
}
for(new i = 0; i < MAX_PLAYERS; i ++)
{
if(IsPlayerConnected(i))
CreatePlayerVcMinimap(i);
}
}
public OnFilterScriptExit()
{
for(new i = 0; i < MAX_PLAYERS; i ++)
{
if(IsPlayerConnected(i) && pVcMinimap[i])
DestroyPlayerVcMinimap(i);
}
}
public OnPlayerSpawn(playerid)
{
if(!pVcMinimap[playerid])
CreatePlayerVcMinimap(playerid);
}
public OnPlayerDisconnect(playerid, reason)
{
if(pVcMinimap[playerid])
DestroyPlayerVcMinimap(playerid);
}
public OnPlayerEnterDynamicArea(playerid, areaid)
{
if(pVcMinimap[playerid])
{
new streamer_info[2];
Streamer_GetArrayData(STREAMER_TYPE_AREA, areaid, E_STREAMER_EXTRA_ID, streamer_info);
if(streamer_info[0] == AREA_TYPE_MINIMAP && streamer_info[1] > 0)
{
pVcMinimapCurrentArea[playerid] = streamer_info[1];
new td_str[64];
format(td_str, sizeof td_str, "mdl"#MINIMAP_MODEL_ID":%d", pVcMinimapCurrentArea[playerid]);
PlayerTextDrawSetString(playerid, pVcMinimapTextdraws[playerid][1], td_str);
if(pVcMinimapCurrentArea[playerid] == 0) PlayerTextDrawColor(playerid, pVcMinimapTextdraws[playerid][1], 0x95CAFCFF); //water color
else PlayerTextDrawColor(playerid, pVcMinimapTextdraws[playerid][1], -1);
PlayerTextDrawShow(playerid, pVcMinimapTextdraws[playerid][1]);
UpdateVcMinimapPlayerLocation(playerid);
}
}
}
public OnPlayerLeaveDynamicArea(playerid, areaid)
{
if(pVcMinimap[playerid])
{
new streamer_info[2];
Streamer_GetArrayData(STREAMER_TYPE_AREA, areaid, E_STREAMER_EXTRA_ID, streamer_info);
if(streamer_info[0] == AREA_TYPE_MINIMAP && streamer_info[1] == 0) //player left vc map
{
pVcMinimapCurrentArea[playerid] = streamer_info[1];
new td_str[64];
format(td_str, sizeof td_str, "mdl"#MINIMAP_MODEL_ID":%d", pVcMinimapCurrentArea[playerid]);
PlayerTextDrawSetString(playerid, pVcMinimapTextdraws[playerid][1], td_str);
if(pVcMinimapCurrentArea[playerid] == 0) PlayerTextDrawColor(playerid, pVcMinimapTextdraws[playerid][1], 0x95CAFCFF); //water color
else PlayerTextDrawColor(playerid, pVcMinimapTextdraws[playerid][1], -1);
PlayerTextDrawShow(playerid, pVcMinimapTextdraws[playerid][1]);
UpdateVcMinimapPlayerLocation(playerid);
}
}
}
public OnVcMinimapRequestUpdate(playerid)
{
UpdateVcMinimapPlayerLocation(playerid);
}
CreatePlayerVcMinimap(playerid)
{
if(pVcMinimap[playerid])
return false;
//Get player current area
pVcMinimapCurrentArea[playerid] = 0;
new player_areas[20];
GetPlayerDynamicAreas(playerid, player_areas);
for(new i = 0; i < sizeof player_areas; i ++)
{
if(player_areas[i] != INVALID_STREAMER_ID)
{
new streamer_info[2];
Streamer_GetArrayData(STREAMER_TYPE_AREA, player_areas[i], E_STREAMER_EXTRA_ID, streamer_info);
if(streamer_info[0] == AREA_TYPE_MINIMAP && streamer_info[1] > 0)
{
pVcMinimapCurrentArea[playerid] = streamer_info[1];
break;
}
}
}
//Minimap Border
pVcMinimapTextdraws[playerid][0] = CreatePlayerTextDraw(playerid, MINIMAP_TEXTDRAW_POS_X - MINIMAP_TEXTDRAW_BORDER_SIZE, MINIMAP_TEXTDRAW_POS_Y - MINIMAP_TEXTDRAW_BORDER_SIZE, "LD_SPAC:white");
PlayerTextDrawTextSize(playerid, pVcMinimapTextdraws[playerid][0],
/*SizeX*/ MINIMAP_TEXTDRAW_SIZE_X + (MINIMAP_TEXTDRAW_BORDER_SIZE * 2.0),
/*SizeY*/ MINIMAP_TEXTDRAW_SIZE_Y + (MINIMAP_TEXTDRAW_BORDER_SIZE * 2.0));
PlayerTextDrawAlignment(playerid, pVcMinimapTextdraws[playerid][0], 1);
PlayerTextDrawColor(playerid, pVcMinimapTextdraws[playerid][0], 255);
PlayerTextDrawSetShadow(playerid, pVcMinimapTextdraws[playerid][0], 0);
PlayerTextDrawBackgroundColor(playerid, pVcMinimapTextdraws[playerid][0], 255);
PlayerTextDrawFont(playerid, pVcMinimapTextdraws[playerid][0], 4);
PlayerTextDrawSetProportional(playerid, pVcMinimapTextdraws[playerid][0], 0);
PlayerTextDrawShow(playerid, pVcMinimapTextdraws[playerid][0]);
//Minimap
new td_str[64];
format(td_str, sizeof td_str, "mdl"#MINIMAP_MODEL_ID":%d", pVcMinimapCurrentArea[playerid]);
pVcMinimapTextdraws[playerid][1] = CreatePlayerTextDraw(playerid, MINIMAP_TEXTDRAW_POS_X, MINIMAP_TEXTDRAW_POS_Y, td_str);
PlayerTextDrawTextSize(playerid, pVcMinimapTextdraws[playerid][1], MINIMAP_TEXTDRAW_SIZE_X, MINIMAP_TEXTDRAW_SIZE_Y);
PlayerTextDrawAlignment(playerid, pVcMinimapTextdraws[playerid][1], 1);
if(pVcMinimapCurrentArea[playerid] == 0) PlayerTextDrawColor(playerid, pVcMinimapTextdraws[playerid][1], 0x95CAFCFF); //water color
else PlayerTextDrawColor(playerid, pVcMinimapTextdraws[playerid][1], -1);
PlayerTextDrawSetShadow(playerid, pVcMinimapTextdraws[playerid][1], 0);
PlayerTextDrawBackgroundColor(playerid, pVcMinimapTextdraws[playerid][1], 255);
PlayerTextDrawFont(playerid, pVcMinimapTextdraws[playerid][1], 4);
PlayerTextDrawSetProportional(playerid, pVcMinimapTextdraws[playerid][1], 0);
PlayerTextDrawShow(playerid, pVcMinimapTextdraws[playerid][1]);
//Timer
pVcMinimapTimer[playerid] = SetTimerEx("OnVcMinimapRequestUpdate", MINIMAP_UPDATE_INTERVAL, true, "i", playerid);
pVcMinimap[playerid] = true;
return true;
}
DestroyPlayerVcMinimap(playerid)
{
if(!pVcMinimap[playerid])
return false;
if(pVcMinimapTimer[playerid] != -1)
{
KillTimer(pVcMinimapTimer[playerid]);
pVcMinimapTimer[playerid] = -1;
}
for(new i, j = sizeof pVcMinimapTextdraws[]; i != j; i ++)
{
if(pVcMinimapTextdraws[playerid][i] != PlayerText:INVALID_TEXT_DRAW)
{
PlayerTextDrawDestroy(playerid, pVcMinimapTextdraws[playerid][i]);
pVcMinimapTextdraws[playerid][i] = PlayerText:INVALID_TEXT_DRAW;
}
}
pVcMinimap[playerid] = false;
return true;
}
UpdateVcMinimapPlayerLocation(playerid)
{
if(pVcMinimapTextdraws[playerid][2] != PlayerText:INVALID_TEXT_DRAW)
{
PlayerTextDrawDestroy(playerid, pVcMinimapTextdraws[playerid][2]);
pVcMinimapTextdraws[playerid][2] = PlayerText:INVALID_TEXT_DRAW;
}
new area = pVcMinimapCurrentArea[playerid];
if(area > 0)
{
new Float:td_x, Float:td_y, Float:pos[3];
GetPlayerPos(playerid, pos[0], pos[1], pos[2]);
Vc3dTo2d(MINIMAP_TEXTDRAW_POS_X, MINIMAP_TEXTDRAW_POS_Y, MINIMAP_TEXTDRAW_SIZE_X, MINIMAP_TEXTDRAW_SIZE_Y, pos[0], pos[1], pos[2], td_x, td_y, minimapAreas_Coords[area - 1][0], minimapAreas_Coords[area - 1][1], minimapAreas_Coords[area - 1][2], minimapAreas_Coords[area - 1][3]);
new Float:angle;
if(IsPlayerInAnyVehicle(playerid)) GetVehicleZAngle(GetPlayerVehicleID(playerid), angle);
else GetPlayerFacingAngle(playerid, angle);
pVcMinimapTextdraws[playerid][2] = CreatePlayerTextDraw(playerid, td_x - (MINIMAP_TEXTDRAW_ICON_SIZE_X / 2.0), td_y - (MINIMAP_TEXTDRAW_ICON_SIZE_Y / 2.0), GetPlayerIconByAngle(angle));
PlayerTextDrawTextSize(playerid, pVcMinimapTextdraws[playerid][2], MINIMAP_TEXTDRAW_ICON_SIZE_X, MINIMAP_TEXTDRAW_ICON_SIZE_Y);
PlayerTextDrawFont(playerid, pVcMinimapTextdraws[playerid][2], 4);
PlayerTextDrawColor(playerid, pVcMinimapTextdraws[playerid][2], 0xCCCCCCFF);
PlayerTextDrawShow(playerid, pVcMinimapTextdraws[playerid][2]);
}
}
GetPlayerIconByAngle(Float:angle)
{
new icon[32], compass = GetCompassByAngle(angle);
switch(compass)
{
case 0: format(icon, sizeof icon, "mdl"#MINIMAP_MODEL_ID":player_icon_n");
case 1: format(icon, sizeof icon, "mdl"#MINIMAP_MODEL_ID":player_icon_nw");
case 2: format(icon, sizeof icon, "mdl"#MINIMAP_MODEL_ID":player_icon_w");
case 3: format(icon, sizeof icon, "mdl"#MINIMAP_MODEL_ID":player_icon_sw");
case 4: format(icon, sizeof icon, "mdl"#MINIMAP_MODEL_ID":player_icon_s");
case 5: format(icon, sizeof icon, "mdl"#MINIMAP_MODEL_ID":player_icon_se");
case 6: format(icon, sizeof icon, "mdl"#MINIMAP_MODEL_ID":player_icon_e");
case 7: format(icon, sizeof icon, "mdl"#MINIMAP_MODEL_ID":player_icon_ne");
default: format(icon, sizeof icon, "mdl"#MINIMAP_MODEL_ID":player_icon");
}
return icon;
}
Float:FixRotation(Float:rotation, &Float:frotation = 0.0)
{
frotation = rotation;
while(frotation < 0.0) frotation += 360.0;
while(frotation >= 360.0) frotation -= 360.0;
return frotation;
}
GetCompassByAngle(Float:angle)
{
new Float:fixed_angle;
FixRotation(angle, fixed_angle);
if((fixed_angle >= 337.5 && fixed_angle <= 360.0) || (fixed_angle >= 0.0 && fixed_angle <= 22.5)) return 0; //n
else if(fixed_angle >= 22.5 && fixed_angle <= 67.5) return 1; //nw
else if(fixed_angle >= 67.5 && fixed_angle <= 112.5) return 2; //w
else if(fixed_angle >= 112.5 && fixed_angle <= 157.5) return 3; //sw
else if(fixed_angle >= 157.5 && fixed_angle <= 202.5) return 4; //s
else if(fixed_angle >= 202.5 && fixed_angle <= 247.5) return 5; //se
else if(fixed_angle >= 247.5 && fixed_angle <= 292.5) return 6; //e
else if(fixed_angle >= 292.5 && fixed_angle <= 337.5) return 7; //ne
return -1;
}
Vc3dTo2d(Float:map_x, Float:map_y, Float:map_size_x, Float:map_size_y, Float:x, Float:y, Float:z, &Float:td_x, &Float:td_y, Float:minX = VICE_CITY_MIN_X, Float:minY = VICE_CITY_MIN_Y, Float:maxX = VICE_CITY_MAX_X, Float:maxY = VICE_CITY_MAX_Y)
{
#pragma unused z
/* Map limits */
if(x > maxX) x = maxX;
else if(x < minX) x = minX;
if(y > maxY) y = maxY;
else if(y < minY) y = minY;
/* Calculations */
new Float:map_width = floatsub(maxX, minX),
Float:prop_X = floatdiv(map_size_x, map_width),
Float:mv_X = floatsub(map_width, maxX);
new Float:map_height = floatsub(minY, maxY),
Float:prop_Y = floatdiv(map_size_y, map_height),
Float:mv_Y = floatsub(map_height, minY);
/* Conversion */
x += mv_X;
y += mv_Y;
/* Result */
td_x = map_x + floatmul(prop_X, x),
td_y = map_y + floatmul(prop_Y, y);
}