#include <a_samp>
/*
Interior Script - WInts
scripted by: wollodya
version 1.01 - fixed some potential bugs
Credits to:
Seif - his Seifader - fading script
Luk_Ass - som help with scripting
SpiriX23 - assistance in testing and providing a server to test
CorteZz - creating the demonstration video
*/
#define DistanceBetweenPoints(%1,%2,%3,%4,%5,%6) floatsqroot((%1 - %4) * (%1 - %4) + (%2 - %5) * (%2 - %5) + (%3 - %6) * (%3 - %6))
#define MAX_CREATED_WINTERIORS 500
#define MAX_VIEWED_WINTERIORS 200
#define MAX_PLAYERS_WEX 100
#define INVALID_WZONE 999
#define ID_WVEHICLE 587
#define WINT_OBJECT_ID 969
#define WARROW_DISTANCE 50
#define WOBJECT_DISTANCE 200
#define PREPARING_WSECS 5
#define MAX_PLAYER_WOBJECTS 50
#define WVEHICLE_OFFSET 4
#define WPORT_DISTANCE 2.5
#define W_FADE_SPEED 15
#define W_FADE_COLOR 0x000000FF
//define map and zones
#define WZONES_COUNT_WIDTH 6 // count of zones per width
#define MAX_WIDTH_WZONE 3000 // ddistance from the center of SA to the edge
#define WZONE_EXPAND 100
/*
native CreateWInterior(Float:arrowX,Float:arrowY,Float:arrowZ,arrowInterior,Float:targetX,Float:targetY,Float:targetZ,Float:targetAngle,targetInterior);
*/
forward Wints_Init();
forward Wints_Exit();
forward Wints_OnPlayerConnect(playerid);
forward Wints_OnPlayerDisconnect(playerid, reason);
forward Wints_OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid);
// static variables
new Float:IntPos[MAX_CREATED_WINTERIORS][3];
new IntInt[MAX_CREATED_WINTERIORS];
new Float:IntPosTarget[MAX_CREATED_WINTERIORS][3];
new Float:AngleTarget[MAX_CREATED_WINTERIORS];
new IntIntTarget[MAX_CREATED_WINTERIORS];
new IntZone[MAX_CREATED_WINTERIORS];
new bool:InteriorPrepared[MAX_CREATED_WINTERIORS];
new InteriorPreparing[MAX_CREATED_WINTERIORS];
new CurrentInterior[MAX_PLAYERS_WEX];
new InteriorCount = 0;
new ViewedInteriors = 0;
new bool:ZoneSettled[(WZONES_COUNT_WIDTH*WZONES_COUNT_WIDTH)+1] = false;
new bool:object[MAX_PLAYERS_WEX][MAX_CREATED_WINTERIORS];
new objectid[MAX_PLAYERS_WEX][MAX_CREATED_WINTERIORS];
new ObjectsForPlayer[MAX_PLAYERS_WEX];
new vehicle[MAX_CREATED_WINTERIORS];
new bool:ViewedForPlayer[MAX_CREATED_WINTERIORS][MAX_PLAYERS_WEX];
new bool:IsWarping[MAX_PLAYERS_WEX];
new MAX_PLAYER_ID = 0; // effective cycles (thanks to Luk_Ass)
// timer
new timer = -1;
new bool:tick = false;
// don't change!
new Float:vx = -4.283;
new Float:vy = 1.603;
new Float:vz = -0.776;
new Float:ex = -4.283;
new Float:ey = 1.603;
new Float:ez = -2.651;
//--------------- Seifader by Seif -------------------------
new w_colorfade[MAX_PLAYERS_WEX];
new Text:w_screenfade[MAX_PLAYERS_WEX];
forward Wints_ScreenFade(playerid, color, speed);
forward Wints_ScreenFadeColor(playerid, color, speed);
forward Wints_OnPlayerScreenFade(playerid, color, speed);
forward Wints_OnPlayerScreenColorFade(playerid, color, speed);
//-----------------------------------------------------------
public Wints_Init()
{
timer = SetTimer("Wints_Timer",500,1);
Wints_Seifader_OnInit();
return 1;
}
public Wints_Exit()
{
for(new i=0;i<InteriorCount;i++)
{
for(new p=0;p<MAX_PLAYER_ID;p++) if(object[i][p] == true) DestroyPlayerObject(p,objectid[p][i]);
Wints_CancelInterior(i);
}
KillTimer(timer);
Wints_Seifader_OnExit();
return 1;
}
public Wints_OnPlayerConnect(playerid)
{
if (playerid >= MAX_PLAYER_ID)
{
MAX_PLAYER_ID = playerid +1;
}
return 1;
}
public Wints_OnPlayerDisconnect(playerid, reason)
{
if (playerid +1 >= MAX_PLAYER_ID)
{
for(new i = MAX_PLAYER_ID -2; i > -1; i--)
{
if (IsPlayerConnected(i))
{
MAX_PLAYER_ID = i +1;
break;
}
}
if (playerid +1 >= MAX_PLAYER_ID)
{
MAX_PLAYER_ID = 0;
}
}
for(new i=0;i<InteriorCount;i++)
{
if(object[i][playerid] == true)
{
DestroyPlayerObject(playerid,objectid[playerid][i]);
object[i][playerid] = false;
}
}
ObjectsForPlayer[playerid] = 0;
W_Seifader_OnPlayerDisconnect(playerid, reason);
return 1;
}
forward OnPlayerInteriorChangePlus(playerid, newinteriorid, oldinteriorid);
public OnPlayerInteriorChangePlus(playerid, newinteriorid, oldinteriorid)
{
for(new i;i<InteriorCount;i++)
{
if(IntInt[i] == newinteriorid && InteriorPreparing[i] > 0) SetVehiclePos(vehicle[i],IntPos[i][0]-vx+ex,IntPos[i][1]-vy+ey,IntPos[i][2]-vz+ez);
}
}
public Wints_OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid)
{
OnPlayerInteriorChangePlus(playerid, newinteriorid, oldinteriorid);
return 1;
}
forward Wints_Timer();
public Wints_Timer()
{
Wints_CheckPlayersPosition();
if(tick == true)
{
tick = false;
{
for(new i=1;i<=(WZONES_COUNT_WIDTH*WZONES_COUNT_WIDTH);i++) // control of each zone
{
ZoneSettled[i] = false;
for(new p=0;p<MAX_PLAYER_ID;p++)
{
if(IsPlayerConnected(p))
{
if(IsPlayerNearWZone(p,i))
{
ZoneSettled[i] = true;
break;
}
}
}
}
for(new i=0;i<InteriorCount;i++) // spawning/destroying of vehicles, oops... interiors
{
if(ZoneSettled[IntZone[i]] == true)
{
if(InteriorPreparing[i] > 0)
{
new Float:Pos[3], Float:h;
GetVehiclePos(vehicle[i],Pos[0],Pos[1],Pos[2]);
GetVehicleHealth(vehicle[i],h);
if(h < 1000.0) SetVehicleHealth(vehicle[i],1000);
if(!(Pos[0] == 0 && Pos[1] == 0 &&Pos[2] == 0))
{
if(DistanceBetweenPoints(Pos[0],Pos[1],Pos[2],IntPos[i][0]-vx+ex,IntPos[i][1]-vy+ey,IntPos[i][2]-vz+ez) > float(WVEHICLE_OFFSET))
{
SetVehiclePos(vehicle[i],IntPos[i][0]-vx+ex,IntPos[i][1]-vy+ey,IntPos[i][2]-vz+ez);
SetVehicleZAngle(vehicle[i],90);
}
}
} else Wints_PrepareInterior(i);
}
else if(InteriorPreparing[i] > 0) Wints_CancelInterior(i);
}
for(new p=0;p<MAX_PLAYER_ID;p++)
{
if(IsPlayerConnected(p))
{
new Float:Pos[3];
GetPlayerPos(p,Pos[0],Pos[1],Pos[2]);
for(new i=0;i<InteriorCount;i++) // interior marking whether is the player near them
{
if(DistanceBetweenPoints(Pos[0],Pos[1],Pos[2],IntPos[i][0],IntPos[i][1],IntPos[i][2]) <= WARROW_DISTANCE && GetPlayerInterior(p) == IntInt[i])
{
if(ViewedForPlayer[i][p] == false) SetVehicleParamsForPlayer(vehicle[i],p,true,true);
if(InteriorPrepared[i] == true && ViewedForPlayer[i][p] == false) ViewedForPlayer[i][p] = true;
}
else if(ViewedForPlayer[i][p] == true) ViewedForPlayer[i][p] = false;
if(DistanceBetweenPoints(Pos[0],Pos[1],Pos[2],IntPos[i][0],IntPos[i][1],IntPos[i][2]) <= WOBJECT_DISTANCE && GetPlayerInterior(p) == IntInt[i])
{
if(object[i][p] == false)
{
if(ObjectsForPlayer[p] < MAX_PLAYER_WOBJECTS)
{
objectid[p][i] = CreatePlayerObject(p,WINT_OBJECT_ID,IntPos[i][0]+ex,IntPos[i][1]+ey,IntPos[i][2]+ez,90,0,0);
object[i][p] = true;
ObjectsForPlayer[p]++;
}
}
}
else if(object[i][p] == true)
{
DestroyPlayerObject(p,objectid[p][i]);
object[i][p] = false;
ObjectsForPlayer[p]--;
}
}
}
}
for(new i=0;i<InteriorCount;i++) // delay to set yellow arrow
{
if(InteriorPreparing[i] >= PREPARING_WSECS+1 && InteriorPrepared[i] == false)
{
InteriorPrepared[i] = true;
}
else if(InteriorPreparing[i] > 0 && InteriorPreparing[i] < PREPARING_WSECS+1)
{
InteriorPreparing[i]++;
}
}
}
}
else tick = true;
return 1;
}
stock CreateWInterior(Float:posX,Float:posY,Float:posZ,int,Float:posXtarg,Float:posYtarg,Float:posZtarg,Float:Angletarg,inttarg)
{
if(InteriorCount == MAX_CREATED_WINTERIORS) return -1;
IntPos[InteriorCount][0] = posX;
IntPos[InteriorCount][1] = posY;
IntPos[InteriorCount][2] = posZ;
IntInt[InteriorCount] = int;
IntPosTarget[InteriorCount][0] = posXtarg;
IntPosTarget[InteriorCount][1] = posYtarg;
IntPosTarget[InteriorCount][2] = posZtarg;
AngleTarget[InteriorCount] = Angletarg;
IntIntTarget[InteriorCount] = inttarg;
IntZone[InteriorCount] = Wints_GetPointZone(posX,posY);
InteriorCount++;
return InteriorCount;
}
stock Wints_GetPointZone(Float:posX,Float:posY)
{
if(posX > MAX_WIDTH_WZONE || posX < -MAX_WIDTH_WZONE || posY > MAX_WIDTH_WZONE || posY < -MAX_WIDTH_WZONE) return INVALID_WZONE;
new zone = (floatround((posY+=MAX_WIDTH_WZONE)/((MAX_WIDTH_WZONE*2)/WZONES_COUNT_WIDTH),floatround_floor)*WZONES_COUNT_WIDTH)+floatround((posX+=MAX_WIDTH_WZONE)/((MAX_WIDTH_WZONE*2)/WZONES_COUNT_WIDTH),floatround_ceil);
if(zone <= 0 || zone > WZONES_COUNT_WIDTH*WZONES_COUNT_WIDTH) return INVALID_WZONE;
return zone;
}
stock Wints_PrepareInterior(interior)
{
if(ViewedInteriors >= MAX_VIEWED_WINTERIORS) return 0;
if(InteriorPreparing[interior] > 0) return 0;
InteriorPreparing[interior] = 1;
InteriorPrepared[interior] = false;
vehicle[interior] = CreateVehicle(ID_WVEHICLE,IntPos[interior][0]-vx+ex,IntPos[interior][1]-vy+ey,IntPos[interior][2]-vz+ez,90,0,0,-1);
LinkVehicleToInterior(vehicle[interior],IntInt[interior]);
ViewedInteriors++;
return 1;
}
stock Wints_CancelInterior(interior)
{
if(InteriorPreparing[interior] == 0) return 0;
InteriorPrepared[interior] = false;
InteriorPreparing[interior] = 0;
DestroyVehicle(vehicle[interior]);
ViewedInteriors--;
return 1;
}
stock Wints_CheckPlayersPosition()
{
for(new p=0;p<MAX_PLAYER_ID;p++)
{
if(IsPlayerConnected(p) && GetPlayerState(p) == PLAYER_STATE_ONFOOT)
{
new Float:pos[3];
GetPlayerPos(p,pos[0],pos[1],pos[2]);
for(new i=0;i<InteriorCount;i++)
{
if(DistanceBetweenPoints(pos[0],pos[1],pos[2],IntPos[i][0],IntPos[i][1],IntPos[i][2]) <= WPORT_DISTANCE)
{
if(!IsWarping[p]) Wints_StartPlayerWarp(p,i);
break;
}
}
}
}
return 1;
}
stock IsPlayerNearWZone(player, zone)
{
new Float:a, Float:b, Float:c, Float:d;
new var1, var2, Float:z;
z = float(zone);
new Float:f=z/WZONES_COUNT_WIDTH;
var1 = floatround(f, floatround_ceil); // riadok
var2 = floatround(z-((var1-1)*WZONES_COUNT_WIDTH)); //stlpec
a = 0.0-MAX_WIDTH_WZONE+((var2-1)*((MAX_WIDTH_WZONE*2)/WZONES_COUNT_WIDTH)-WZONE_EXPAND);
b = a+((MAX_WIDTH_WZONE*2)/WZONES_COUNT_WIDTH)+(WZONE_EXPAND*2);
c = 0.0-MAX_WIDTH_WZONE+((var1-1)*((MAX_WIDTH_WZONE*2)/WZONES_COUNT_WIDTH)-WZONE_EXPAND);
d = c+((MAX_WIDTH_WZONE*2)/WZONES_COUNT_WIDTH)+(WZONE_EXPAND*2);
new Float:X, Float:Y, Float:Z;
GetPlayerPos(player, X, Y, Z);
if(X <= b && X >= a && Y <= d && Y >= c) return 1;
return 0;
}
stock Wints_StartPlayerWarp(p,i)
{
W_FadePlayerScreenToColor(p, W_FADE_COLOR, W_FADE_SPEED);
PlayerPlaySound(p, 1083, 0,0,0);
CurrentInterior[p] = i;
TogglePlayerControllable(p, false);
IsWarping[p] = true;
return 1;
}
public Wints_OnPlayerScreenColorFade(playerid, color, speed)
{
new bool:ichanged;
W_FadePlayerScreen(playerid, W_FADE_COLOR, W_FADE_SPEED);
if(GetPlayerInterior(playerid) != IntIntTarget[CurrentInterior[playerid]]) ichanged = true;
SetPlayerInterior(playerid, IntIntTarget[CurrentInterior[playerid]]);
if(ichanged == false) OnPlayerInteriorChangePlus(playerid,IntIntTarget[CurrentInterior[playerid]],-1);
SetPlayerPos(playerid,IntPosTarget[CurrentInterior[playerid]][0],IntPosTarget[CurrentInterior[playerid]][1],IntPosTarget[CurrentInterior[playerid]][2]);
SetPlayerFacingAngle(playerid, AngleTarget[CurrentInterior[playerid]]);
SetCameraBehindPlayer(playerid);
return 1;
}
public Wints_OnPlayerScreenFade(playerid, color, speed)
{
TogglePlayerControllable(playerid, 1);
IsWarping[playerid] = false;
return 1;
}
//------------------------------ Seifader by Seif ----------------------------------
stock Wints_Seifader_OnInit()
{
for(new all = 0; all < MAX_PLAYERS_WEX; all++)
{
w_screenfade[all] = TextDrawCreate(0.0, 0.0, "_");
TextDrawFont(w_screenfade[all], 1);
TextDrawLetterSize(w_screenfade[all], 0.0, 50.0);
TextDrawUseBox(w_screenfade[all], true);
TextDrawColor(w_screenfade[all], 0);
TextDrawBoxColor(w_screenfade[all], 0);
w_colorfade[all] = 0;
}
}
stock Wints_Seifader_OnExit()
{
for(new all = 0; all < MAX_PLAYERS_WEX; all++) TextDrawDestroy(w_screenfade[all]);
}
stock W_Seifader_OnPlayerDisconnect(playerid, reason)
{
#pragma unused reason
TextDrawHideForPlayer(playerid, w_screenfade[playerid]);
}
stock W_FadePlayerScreen(playerid, color, speed)
{
w_colorfade[playerid] = color;
TextDrawBoxColor(w_screenfade[playerid], color);
TextDrawShowForPlayer(playerid, w_screenfade[playerid]);
SetTimerEx("Wints_ScreenFade", 100, 0, "ddd", playerid, color, speed);
}
stock W_FadePlayerScreenToColor(playerid, color, speed)
{
color -= 255;
w_colorfade[playerid] = color;
TextDrawBoxColor(w_screenfade[playerid], color);
TextDrawShowForPlayer(playerid, w_screenfade[playerid]);
SetTimerEx("Wints_ScreenFadeColor", 100, 0, "ddd", playerid, color, speed);
}
public Wints_ScreenFade(playerid, color, speed)
{
if (color <= (w_colorfade[playerid] - 255))
{
TextDrawHideForPlayer(playerid, w_screenfade[playerid]);
Wints_OnPlayerScreenFade(playerid, color, speed);
}
else
{
color -= speed;
if (color <= (w_colorfade[playerid] - 255)) color = (w_colorfade[playerid] - 255);
TextDrawBoxColor(w_screenfade[playerid], color);
TextDrawShowForPlayer(playerid, w_screenfade[playerid]);
SetTimerEx("Wints_ScreenFade", 100, 0, "ddd", playerid, color, speed);
}
}
public Wints_ScreenFadeColor(playerid, color, speed)
{
if (color >= (w_colorfade[playerid] + 255))
{
Wints_OnPlayerScreenColorFade(playerid, color, speed);
}
else
{
color += speed;
if (color >= (w_colorfade[playerid] + 255)) color = (w_colorfade[playerid] + 255);
TextDrawBoxColor(w_screenfade[playerid], color);
TextDrawShowForPlayer(playerid, w_screenfade[playerid]);
SetTimerEx("Wints_ScreenFadeColor", 100, 0, "ddd", playerid, color, speed);
}
}