[Ajuda] MapAndreas - Detectar possнvel bloqueio
#1

Estou desenvolvendo um sistema de boias assassinas inteligentes. - Sim.

Estou fazendo um sistema para elas desviarem de construзхes grandes, como prйdios, com o auxнlio do MapAndreas.

Estou usando o seguinte code:

pawn Код:
stock AtualizarPos(Float:x, Float:y, Float:z, Float:fx, Float:fy, Float:fz)
{
    // Getar direзгo que o objeto estб em relaзгo ao player:
    new Float:valorx = x - fx, Float:valory = y - fy, Float:outX,Float:outY, Float:outZ;
    if(valorx < 0)
    {
        //SendClientMessageToAll(-1, "valorx > x");
        new Float:preview = x + 1, Float:zprev;
        MapAndreas_FindZ_For2DCoord(preview, y, zprev);
        if(zprev < z + 5 && zprev > z - 5)
        {
            outX = x + 1;
        }
    }
    if(valorx > 0)
    {
        //SendClientMessageToAll(-1, "valorx < x");
        new Float:preview = x - 1, Float:zprev;
        MapAndreas_FindZ_For2DCoord(preview, y, zprev);
        if(zprev < z + 5 && zprev > z - 5)
        {
             outX = x - 1;
        }

    }
    if(valory < 0)
    {
        //SendClientMessageToAll(-1, "valorx > y");
        new Float:preview = y + 1, Float:zprev;
        MapAndreas_FindZ_For2DCoord(x, preview, zprev);
        if(zprev < z + 2 && zprev > z - 2)
        {
            outY = y + 1;
            outZ = zprev;
        }
    }
    if(valory > 0)
    {
        //SendClientMessageToAll(-1, "valorx < y");
        new Float:preview = y - 1, Float:zprev;
        MapAndreas_FindZ_For2DCoord(x, preview, zprev);
        if(zprev < z + 5 && zprev > z - 5)
        {
            outY = y - 1;
            outZ = zprev;
        }
    }
    MoveObject(KoB, outX, outY, outZ+11, 2);
    return 1;
}
Sу que quando desanulo os if(zprev < z + 5 && zprev > z - 5) o NPC comeзa a se descolar na diagonal, mesmo que nгo tenha algo para interromper a passagem dele.

Estou fazendo algo errado, alguem pode me apontar o erro ou me apontar uma outra maneira para detectar se existe uma construзгo na minha frente?
Reply
#2

Se existe uma construзгo? Para isto eu criei CHK Path. Ele checa se a uma coordenada diagonal de XY e XY tem algum objeto para atrapalhar a ligaзгo. Й lento, mas funciona.

pawn Код:
CHK_Path(npcid, Float:x,Float:y) {

    static
    Float:px,
    Float:py,
    Float:pz,
    Float:andreasZ;

    if(!GetPlayerPos(npcid, px, py, pz)) return false;

    // fixs cartesian plane

    if(y > 0) y *= 02;
    if(y < 0) y *= -1;

    if(x > 0) x *= 02;
    if(x < 0) x *= -1;

    //

    if(py > 0) py *= 02;
    if(py < 0) py *= -1;

    if(px > 0) px *= 02;
    if(px < 0) px *= -1;

    // fix negative values
    if(px > x) {
        px ^= x;
        x ^= px;
        px ^= x;
    }

    if(py > y) {
        py ^= y;
        y ^= py;
        py ^= y;
    }
    // now py < y and px < x

    // diagonal path finding
    for(new Float:nx = nx - px; nx > 0.0; nx -= 1.5) {
        for(new Float:ny = y - py; ny > 0.0; ny -= 1.5) {
            MapAndreas_FindZ_For2DCoord(nx, ny, andreasZ);
            if(andreasZ > pz - 1.0) {
                return false;
            }
        }
    }
    return true;
}
Implementaзгo do algorнtimo:
http://forum.sa-mp.com/showpost.php?...postcount=1855

- Vou tentar implementar no seu cуdigo
Reply
#3

Quote:
Originally Posted by ipsBruno
Посмотреть сообщение
Se existe uma construзгo? Para isto eu criei CHK Path. Ele checa se a uma coordenada diagonal de XY e XY tem algum objeto para atrapalhar a ligaзгo. Й lento, mas funciona.

pawn Код:
CHK_Path(npcid, Float:x,Float:y) {

    static
    Float:px,
    Float:py,
    Float:pz,
    Float:andreasZ;

    if(!GetPlayerPos(npcid, px, py, pz)) return false;

    // fixs cartesian plane

    if(y > 0) y *= 02;
    if(y < 0) y *= -1;

    if(x > 0) x *= 02;
    if(x < 0) x *= -1;

    //

    if(py > 0) py *= 02;
    if(py < 0) py *= -1;

    if(px > 0) px *= 02;
    if(px < 0) px *= -1;

    // fix negative values
    if(px > x) {
        px ^= x;
        x ^= px;
        px ^= x;
    }

    if(py > y) {
        py ^= y;
        y ^= py;
        py ^= y;
    }
    // now py < y and px < x

    // diagonal path finding
    for(new Float:nx = nx - px; nx > 0.0; nx -= 1.5) {
        for(new Float:ny = y - py; ny > 0.0; ny -= 1.5) {
            MapAndreas_FindZ_For2DCoord(nx, ny, andreasZ);
            if(andreasZ > pz - 1.0) {
                return false;
            }
        }
    }
    return true;
}
Implementaзгo do algorнtimo:
http://forum.sa-mp.com/showpost.php?...postcount=1855

- Vou tentar implementar no seu cуdigo
Thanks *-*
Reply
#4

pawn Код:
BolinhaDeKuddy(objectid, Float:x,Float:y) {

    static
        Float:px,
        Float:py,
        Float:pz,
        Float:andreasZ,
        Float:firstPos[5];

    if(!GetObjectPos(objectid, px, py, pz)) return false;

    firstPos[0] = px;
    firstPos[1] = py;
    firstPos[2] = pz;

    firstPos[3] = x;
    firstPos[4] = y;

    // fixs cartesian plane

    if(y > 0) y *= 02;
    if(y < 0) y *= -1;

    if(x > 0) x *= 02;
    if(x < 0) x *= -1;

    //

    if(py > 0) py *= 02;
    if(py < 0) py *= -1;

    if(px > 0) px *= 02;
    if(px < 0) px *= -1;

    // fix negative values
    if(px > x) {
        px ^= x;
        x ^= px;
        px ^= x;
    }

    if(py > y) {
        py ^= y;
        y ^= py;
        py ^= y;
    }
    // now py < y and px < x

    // diagonal path finding
    for(new Float:nx = nx - px; nx > 0.0; nx -= 1.5) {

        for(new Float:ny = y - py; ny > 0.0; ny -= 1.5) {

            MapAndreas_FindZ_For2DCoord(nx, ny, andreasZ);

            if(andreasZ > pz - 1.0) {

                static Float: anglePoint ;

                anglePoint = atan2( firstPos[3] - firstPos[0] , firstPos[4] - firstPos[1] );
                anglePoint = anglePoint > 360 ? anglePoint - 360 : (anglePoint < 0 ? anglePoint + 360 : anglePoint);

                firstPos[0] +=  (06.0 * floatsin(-anglePoint-90.0, degrees)); // sу desviando pra esquerda
                firstPos[1] +=  (06.0 * floatcos(-anglePoint-90.0, degrees)); // sу desviando pra esquerda



                MoveObject(objectid, firstPos[0], firstPos[1], andreasZ, 2); // The speed at which to move the object (units per second).

                SetTimerEx("SegmentContinue", ((1000*((6) / (2))))+1000,   false, "ifff", objectid, firstPos[0], firstPos[1], andreasZ); // apуs desviar obstaculo voltar a seguir jogador. TIMER PRЙ PROGRAMADO COM TEMPO CORRETO
                return false;

            }
        }
    }
    return true;
}

forward SegmentContinue(objectid, Float:x, Float:y, Float:z);
public  SegmentContinue(objectid, Float:x, Float:y, Float:z)  {

    if(BolinhaDeKuddy(objectid, x, y)) {
        MoveObject(objectid, x, y, z, 2);
        SetTimerEx("SegmentContinue", 1000, false, "ifff", objectid, x, y, z);
    }
    return true;
}
Entгo sу use:
pawn Код:
SegmentContinue(objectid, Float:x, Float:y, Float:z)
Acho que nгo deve funcionar, mas a lуgica estб certa.
Reply
#5

Crl, eu tava encucado com essa bagaзa hoje e fiz vбrios testes, atй que coloquei um debug, esse debug mostrou que o mapandreas nгo estava mais sendo carregado ;S

Daн eu fui ver exemplos de scripts com o mapandreas e percebi que precisava disso no OnGamemodeInit: MapAndreas_Init(MAP_ANDREAS_MODE_FULL);

Eu achei que nгo havia necessidade disso pois eu estava testando com o Fs de teste do mapandreas carregado, ele ja carregava o mapandreas pra mim =*

Code final dele:
pawn Код:
#include    a_samp
#include    mapandreas


main()
{
    printf("Gamemode KoIntelligence powered by Kuddy carregado");
    printf("Todos os direitos reservados a KomanZ");
}


new KoB;
public OnGameModeInit()
{
    printf("Iniciando KoIntelligence...");

    SetGameModeText("KoIntelligence");
    AddPlayerClass(0,2034.9125,1336.2625,10.8203,349.3566,0,0,0,0,0,0);
    KoB = CreateObject(1243, 2043.06, 1354.30, 7.37,   0.00, 0.00, 0.00);
    SetTimer("UpdateNPC", 500, true);
    MapAndreas_Init(MAP_ANDREAS_MODE_FULL);

    /*new time = GetTickCount();
    new Float:loopar;
    for(new i; i < 1000000; i++)
    {
        loopar = loopar + random(10);
        MapAndreas_FindZ_For2DCoord(loopar,loopar,pz);
    }
    time = GetTickCount() - time;
    printf("%d MS", time);
    Resultado: 118 MS
    */



    return 1;
}

forward UpdateNPC();
public UpdateNPC()
{
    new Float:x, Float:y, Float:z, Float:px, Float:py, Float:pz;
    GetPlayerPos(0, px, py, pz);

    //MoveObject(KoB, px, py, pz, 2);
    GetObjectPos(KoB, x,y,z);
    MapAndreas_FindZ_For2DCoord(x,y,z);
    //MapAndreas_FindZ_For2DCoord(px,py,pz);
    AtualizarPos(x,y,z,px,py,pz);
    return 1;
}

stock AtualizarPos(Float:x, Float:y, Float:z, Float:fx, Float:fy, Float:fz)
{
    // Getar direзгo que o objeto estб em relaзгo ao player:
    new Float:valorx = x - fx, Float:valory = y - fy, Float:outX,Float:outY, Float:outZ;
    outX = x; outY = y; outZ = z;

    if(valorx < 0)
    {
        //SendClientMessageToAll(-1, "valorx > x");
        new Float:preview = x + 1, Float:zprev;
        MapAndreas_FindZ_For2DCoord(preview, y, zprev);
        if(zprev < z + 2 && zprev > z - 2)
        {
            outX = x + 1;
        }
    }
    if(valorx > 0)
    {
        //SendClientMessageToAll(-1, "valorx < x");
        new Float:preview = x - 1, Float:zprev;
        MapAndreas_FindZ_For2DCoord(preview, y, zprev);
        if(zprev < z + 2 && zprev > z - 2)
        {
             outX = x - 1;
        }

    }
    if(valory < 0)
    {
        //SendClientMessageToAll(-1, "valorx > y");
        new Float:preview = y + 1, Float:zprev;
        MapAndreas_FindZ_For2DCoord(x, preview, zprev);
        if(zprev < z + 2 && zprev > z - 2)
        {
            outY = y + 1;
            outZ = zprev;
        }
    }
    if(valory > 0)
    {
        //SendClientMessageToAll(-1, "valorx < y");
        new Float:preview = y - 1, Float:zprev;
        MapAndreas_FindZ_For2DCoord(x, preview, zprev);
        if(zprev < z + 2 && zprev > z - 2)
        {
            outY = y - 1;
            outZ = zprev;
        }
    }
    MapAndreas_FindZ_For2DCoord(outX, outY, outZ);
    // debug
    new str[128];
    format(str,128,"Movendo para: {0000FF}%f, {FF0000}%f, {00FF00}%f",outX, outY, outZ);
    SendClientMessageToAll(-1, str);
    MoveObject(KoB, outX, outY, outZ, 2);
    return 1;
}

public OnGameModeExit()
{
    return 1;
}

public OnPlayerRequestClass(playerid, classid)
{
    SetPlayerPos(playerid, 1958.3783, 1343.1572, 15.3746);
    SetPlayerCameraPos(playerid, 1958.3783, 1343.1572, 15.3746);
    SetPlayerCameraLookAt(playerid, 1958.3783, 1343.1572, 15.3746);
    return 1;
}
Sua lуgica estб correta tambйm Bruno, sу que meu erro nгo estava na lуgica :*
Enfim, obrigado =D
Agora й sу eu fazer a inteligencia artificial para o bixinho e vamo ve como fica *-*

Vнdeo de como estб o code acima in-game:

[ame]http://www.youtube.com/watch?v=LC2-LIZ1uZ4[/ame]
Reply
#6

Tenho quase certeza que no gamemode do bruno nгo tem isto, por isto que os npc's constantemente atravessam as coisas.
Reply
#7

Quote:
Originally Posted by leonardo1434
Посмотреть сообщение
Tenho quase certeza que no gamemode do bruno nгo tem isto, por isto que os npc's constantemente atravessam as coisas.
Jб posso dizer que meu objeto й mais inteligente que um zumbi :P
Reply
#8

Sim, porйm ele usa a mesma teoria o que torna eles basicamente retardados na mesma equivalкncia.

Enfim, irei conversa com o bruno para perguntar se ele adicionou isto.
Reply
#9

KKKKKKKKK zumbi retardado euri mas vai ser legal uma boia tentar matar o cara dai so vai da gente gritando Corre.
Reply
#10

Quote:
Originally Posted by Kuddy
Посмотреть сообщение
Jб posso dizer que meu objeto й mais inteligente que um zumbi :P
Й verdade. Para mover os zumbis eu tenho que reescrever os arquivos .rec e carrega-los. Por isto nгo coloco este meu cуdigo, laga muito e acaba por travar os zumbis.

Nгo precisa checar se й valorx menor que zero ou valory. Basta usar atan2 e floatsin/floatcos para arrumar a angulaзгo : P
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)