domingo, 10 de março de 2013

0 Manipular Semáforos - Proof of concept (Desenvolvimento)

Isto é um FILTERSCRIPT (desculpem o erro no titulo, é que inicialmente era para ser uma include )

Código:

pawn Code:
#include a_samp #define AMARELO     1 #define VERMELHO    2 #define VERDE       0 #define MAX_TLS 2000 // ------------------------------ forward OnTrafficLightChange(); forward OnPlayerUpdateEx(); // ------------------------- enum trLights {     tl_Zone,     Float:tl_X,     Float:tl_Y,     Float:tl_Z,     Float:tl_GZX,     Float:tl_GZY,     tl_Sentido } // ------------------------- new totalTFS = 0; new semaforoAtual[2]; new bool:syncSinal = false; new bool:enviada[MAX_PLAYERS] ; new playesOnline, SemaforoTimer; new gTrafficLights[MAX_TLS][trLights] ; new Text:semaforoText[MAX_PLAYERS]; // ------------------------- public OnFilterScriptInit() {     // parte para adicionar os semáforos     addTrafficLight(2042.0878, 1283.0818, 2);     createGangZone();     SetTimer("OnPlayerUpdateEx", 400, true);     return true; } public OnPlayerConnect(playerid) {     semaforoText[playerid] = TextDrawCreate(35.0, 433.0, "Sem˜foro: ~r~Vermelho");     TextDrawAlignment(semaforoText[playerid], 0);     TextDrawBackgroundColor(semaforoText[playerid],0x000000ff);     TextDrawFont(semaforoText[playerid],1);     TextDrawLetterSize(semaforoText[playerid],0.2999, 0.9);     TextDrawBoxColor(semaforoText[playerid],0x00000050);     TextDrawSetShadow(semaforoText[playerid],1);     TextDrawColor(semaforoText[playerid],-1);     TextDrawSetOutline(semaforoText[playerid],1);     TextDrawSetProportional(semaforoText[playerid],1);     playesOnline++;     if(playesOnline == 1) {         semaforoAtual[0] = VERMELHO;         semaforoAtual[1] = VERDE;         syncSinal = false;     }     return TogglePlayerClock(playerid, true); } public OnPlayerDisconnect(playerid, reason) {     playesOnline--;     if(!playesOnline) {         syncSinal = false;         KillTimer(SemaforoTimer);     }     return true; } public OnPlayerSpawn(playerid) {     TextDrawHideForPlayer(playerid, semaforoText[playerid]);     for(new t = 0; t != totalTFS; t++) {         GangZoneShowForPlayer(playerid, gTrafficLights[t][tl_Zone], 0xFFFF0096);     }     return true; } public OnPlayerUpdate(playerid) {     return true; } public OnPlayerUpdateEx() {     for(new i; i != MAX_PLAYERS; i++) {         if(IsPlayerConnected(i)) {             for(new t = 0; t != totalTFS; t++) {                 if(!IsPlayerInArea(i, gTrafficLights[t][tl_GZX], gTrafficLights[t][tl_Y], gTrafficLights[t][tl_X], gTrafficLights[t][tl_GZY])) {                     TextDrawHideForPlayer(i, semaforoText[i]);                     if(                         (                             ((gTrafficLights[t][tl_Sentido] == 2 || gTrafficLights[t][tl_Sentido] == 0) && semaforoAtual[0] == VERMELHO)                                 ||                             ((gTrafficLights[t][tl_Sentido] == 3 || gTrafficLights[t][tl_Sentido] == 1) && semaforoAtual[1] == VERMELHO)                         )                         &&                             enviada[i] == true                     ) {                         if(gettime() - GetPVarInt(i, #sinaleiraPassada) < 10 && IsPlayerInAnyVehicle(i)) {                             SendClientMessage(i, 0xFF0000FF , "[Info] Voce passou com a sinaleira vermelha. Espere ela ficar verde !!");                         }                         enviada[i] = false;                     }                 }                 else {                     if(AnguloSentido(i,gTrafficLights[t][tl_Sentido])) {                         if(                             ((gTrafficLights[t][tl_Sentido] == 2 || gTrafficLights[t][tl_Sentido] == 0) && semaforoAtual[0] == VERMELHO)                             ||                             ((gTrafficLights[t][tl_Sentido] == 3 || gTrafficLights[t][tl_Sentido] == 1) && semaforoAtual[1] == VERMELHO)                         ) {                             TextDrawSetString(semaforoText[i], "Sem˜foro: ~r~Vermelho");                             TextDrawShowForPlayer(i, semaforoText[i]);                             if(!enviada[i]) {                                 SetPVarInt(i, #sinaleiraPassada, gettime());                                 enviada[i] = true;                             }                         }                         else {                             TextDrawSetString(semaforoText[i], "Sem˜foro: ~g~Verde");                             TextDrawShowForPlayer(i, semaforoText[i]);                         }                     }                 }             }         }     }     return true; } public OnPlayerCommandText(playerid, cmdtext[]) {     if(!strcmp("/ajudasinal", cmdtext)) {         if(!IsPlayerAdmin(playerid)) return false;         SendClientMessage(playerid,-1,"Para sincronizar os semáforos vá para o semáforo /irsinal. Quando ele ficar vermelho digite /syncsinal");         return true;     }     if(!strcmp("/syncsinal", cmdtext)) {         if(!IsPlayerAdmin(playerid)) return false;         SendClientMessage(playerid,-1,"Você sincronizou os sinais. Certifique-se que o comando foi digitado quando o sinal do barco pirata ficou vermelho");         SendClientMessage(playerid,-1,"Caso ache que a sincronização não foi boa, dê novamente /syncsinal na próxima vez que este sinal ficar vermelho");         KillTimer(SemaforoTimer);         syncSinal = true;         return SetTimer("OnTrafficLightChange", 18506, false);     }     if(!strcmp("/irsinal", cmdtext)) {         if(!IsPlayerAdmin(playerid)) return false;         SendClientMessage(playerid,-1,"Você foi ao semáforo principal. Digite /syncsinal rapidamente da próxima vez que ele ficar vermelho !!");         return SetPlayerPos(playerid, 2049.0024,1308.0459,10.6719);     }     return false; } public OnTrafficLightChange() {     switch(semaforoAtual[0]) {         case VERDE: {             semaforoAtual[0] = AMARELO;             semaforoAtual[1] = AMARELO;             SemaforoTimer = SetTimer("OnTrafficLightChange", 1700, false);         }         case AMARELO: {             semaforoAtual[1] = VERDE;             semaforoAtual[0] = VERMELHO;             SemaforoTimer = SetTimer("OnTrafficLightChange", 19000, false);         }         case VERMELHO: {             semaforoAtual[1] = AMARELO;             semaforoAtual[0] = VERDE;             /*             if(!syncSinal) {                 for(new i; i != MAX_PLAYERS; i++) {                     if(IsPlayerAdmin(i)) {                         SendClientMessage(i, 0xFF0000FF,"O semáforos parecem estar dessincronizados. Digite /ajudasinal para ver melhor sobre isto");                     }                 }             }             */             SemaforoTimer = SetTimer("OnTrafficLightChange", 8900, false);         }     }     return true; } ///////////////////////////////////////////// // //  Checar se jogador está na área do semáforo //  Por Bruno da Silva // ///////////////////////////////////////////// IsPlayerInArea(playerid, Float:xmin, Float:ymin, Float:xmax , Float:ymax) {     static         Float:X,         Float:Y,         Float:Z     ;     GetPlayerPos(playerid, X, Y, Z);     return (X >= xmin && X <= xmax && Y >= ymin && Y <= ymax) ; } ///////////////////////////////////////////// // //  Adicionar novo semáforo //  Por Bruno da Silva // ///////////////////////////////////////////// addTrafficLight(Float:x, Float:y, sentido = 0) {     gTrafficLights[totalTFS][tl_X] = x;     gTrafficLights[totalTFS][tl_Y] = y;     gTrafficLights[totalTFS][tl_GZX] = 0.0;     gTrafficLights[totalTFS][tl_GZY] = 0.0;     gTrafficLights[totalTFS][tl_Sentido] = sentido;     return totalTFS++, true; } ///////////////////////////////////////////// // //  Verificar se sentido é igual a direção // //  true = sim //  false = não // //  Por Bruno da Silva // ///////////////////////////////////////////// AnguloSentido(playerid,sentido) {         return (GetPlayerDirection(playerid) == sentido); } /////////////////////////////////////// // //  Pegar direção do jogador // //  0 = Norte //  1 = Oeste //  2= Sul //  3= Leste // //  Por Bruno da Silva // /////////////////////////////////////// GetPlayerDirection(playerid) {     static         Float:Angle     ;     GetPlayerFacingAngle(playerid, Angle);     /*         - - - -  - - - - - -  - - - - - -  - -                     north (0)             (90) west   east (270)                     south (180)         - - - - - -- - - - - -  - - - -  - - - -     */     if(000 < Angle < 090)   return 0;     if(089 < Angle < 180)   return 1;     if(179 < Angle < 270)   return 2;     if(269 < Angle < 361)   return 3;     return -1; } createGangZone() {     for(new t = 0; t < totalTFS; t++) {         switch(gTrafficLights[t][tl_Sentido]) {                                                       // sul             case 2: gTrafficLights[t][tl_GZY] = gTrafficLights[t][tl_Y] + 60.0, gTrafficLights[t][tl_X] = gTrafficLights[t][tl_X] + 15.0, gTrafficLights[t][tl_GZX] = gTrafficLights[t][tl_X] - 20.0;                                                       // norte             case 0: gTrafficLights[t][tl_GZY] = gTrafficLights[t][tl_Y] - 60.0, gTrafficLights[t][tl_X] = gTrafficLights[t][tl_X] + 15.0, gTrafficLights[t][tl_GZX] = gTrafficLights[t][tl_X] - 20.0;                                                     // oeste             case 3: gTrafficLights[t][tl_GZX] = gTrafficLights[t][tl_X] - 60.0, gTrafficLights[t][tl_Y] = gTrafficLights[t][tl_Y] + 15.0, gTrafficLights[t][tl_GZY] = gTrafficLights[t][tl_Y] - 20.0;                                                     // leste             case 1: gTrafficLights[t][tl_GZX] = gTrafficLights[t][tl_X] + 60.0, gTrafficLights[t][tl_Y] = gTrafficLights[t][tl_Y] + 15.0, gTrafficLights[t][tl_GZY] = gTrafficLights[t][tl_Y] - 20.0;             default: return false;         }         gTrafficLights[t][tl_Zone] = GangZoneCreate(gTrafficLights[t][tl_GZX], gTrafficLights[t][tl_GZY], gTrafficLights[t][tl_X], gTrafficLights[t][tl_Y]);         GangZoneShowForAll(gTrafficLights[t][tl_Zone], 0xFFFF0096);     }     return true; }

Estou ainda estudando, pois as vezes o semáforo acaba ficando desincronizado

Como deixar o semáforo preciso?
Para deixar o semáforo preciso, você deve entrar no servidor. Logo que entrar no servidor, vá para o seguinte semáforo:



Comando para ir nele: /irsinal

Logo que este semáforo ficar VERMELHO (não antes nem depois, mas sim quando ele FICAR) você deverá digitar o seguinte comando:
/syncsinal

Após isto todos semáforos ficaram sincronizados por um determinado periodo (o delay é de 20 a 500 ms logo em questão de umas 6 horas os semáforos podem estar alguns segundos DESSINCRONIZADOS !! Então deve repetir o processo)

Lembrando que quem tem que sincronizar é o primeiro jogador que entrar no servidor e ele precisa estar logado na /rcon

Como detectar se o jogador passou com semáforo vermelho?

Na linha 129 do código tem a seguinte mensagem:
pawn Code:
SendClientMessage(i, 0xFF0000FF , "[Info] Voce passou com a sinaleira vermelha. Espere ela ficar verde !!");

Essa mensagem é enviada quando o jogador ultrapassa o semáforo no sentido correto (capitão obvio)

Como adicionar semáforos
Para adicionar mais semáforos existe a função addTrafficLight

Para adicionar basta:
addTrafficLight(coordenada x, coordenada y, direcao)

Como saber qual a direção do semáforo?

Quote:
Sentido norte sul -> 2
Sentido sul norte -> 0

Sentido oeste leste -> 1
Sentido leste oeste -> 3
Atualizado 18/07/2012 - 23:04
Creditos IpsBruno

0 comentários: