AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   Solved choosing only "x" number of origin to spawn (https://forums.alliedmods.net/showthread.php?t=325179)

SHIELD755 06-11-2020 03:35

choosing only "x" number of origin to spawn
 
hii,

i am spawning an enitity using this code to any Origin

PHP Code:

public load_flags()
{
    new 
szMapName[32]
    
get_mapname(szMapName31)
    
strtolower(szMapName)
    
    
formatex(g_szConfigFile127"addons/amxmodx/configs/testing")
    
    if( !
dir_exists(g_szConfigFile)) 
    {
        
mkdir(g_szConfigFile)
        
format(g_szConfigFile127"%s/%s.txt"g_szConfigFileszMapName )
        return
    }
    
    
format(g_szConfigFile127"%s/%s.txt"g_szConfigFileszMapName)
    if(!
file_exists(g_szConfigFile)) 
    {
        
fopen(g_szConfigFile"at")
        return
    }
    
    new 
iFile fopeng_szConfigFile"rt" )
    if(!
iFile) return
    
    new 
x[16], y[16], z[16], szDesc[32], szData[charsmax(x) + charsmax(y) + charsmax(z) + charsmax(szDesc)]
    
    new 
Float:vOrigin[3]
    
    while(!
feof(iFile)) 
    {
        
fgets(iFileszDatacharsmax(szData))
        
trim(szData)
        
        if(!
szData[0]) continue;
        
        
parse(szDatax15y15z15szDesc31)
        
        
vOrigin[0] = str_to_float(x)
        
vOrigin[1] = str_to_float(y)
        
vOrigin[2] = str_to_float(z)
        
        
spawn_testing(vOriginszDesc)
    }
    
    
fcloseiFile )


and this is my Spawn file (X Y Z coordinate)

Code:

323 -1007 67   
321 -1242 67
128 -2027 67
224 -2214 67
153 -1854 -60
121 -236 67
-419 357 51
-100 1353 51
534 1473 51 7
1478 659 435 7

let in this file there are 10 origins and what i wanted is to spawn my entitiy to only "n" origins (the "n" can be 6 origins from 10 origins, It can be Random) only

i don't wanna spawn my enitity to all 10 ORIGINS :nono: , it can choose any 6 random origins from 10 origins from file

THANKS IN ADVANCED !! :wink:

Black Rose 06-11-2020 08:11

Re: choosing only "x" number of origin to spawn
 
You buffer and randomize.

Code:
    new x[16], y[16], z[16], szDesc[32], szData[charsmax(x) + charsmax(y) + charsmax(z) + charsmax(szDesc)]         new Float:vOrigin[3]         while(!feof(iFile))     {         fgets(iFile, szData, charsmax(szData))         trim(szData)                 if(!szData[0]) continue;                 parse(szData, x, 15, y, 15, z, 15, szDesc, 31)                 vOrigin[0] = str_to_float(x)         vOrigin[1] = str_to_float(y)         vOrigin[2] = str_to_float(z)                 spawn_testing(vOrigin, szDesc)     }
->
Code:
    new x[16], y[16], z[16], szDesc[32][32], szData[charsmax(x) + charsmax(y) + charsmax(z) + charsmax(szDesc[])];         new Float:vOrigin[32][3], count;         while(!feof(iFile))     {         fgets(iFile, szData, charsmax(szData));         trim(szData);                 if(!szData[0]) continue;                 parse(szData, x, 15, y, 15, z, 15, szDesc[count], 31);                 vOrigin[count][0] = str_to_float(x);         vOrigin[count][1] = str_to_float(y);         vOrigin[count][2] = str_to_float(z);         count++;             }     for ( new i, rand1, rand2 ; i < 100 ; i++ ) {         rand1 = random(count);         rand2 = random(count);         vOrigin[count][0] = vOrigin[rand2][0];         vOrigin[count][1] = vOrigin[rand2][1];         vOrigin[count][2] = vOrigin[rand2][2];         copy(szDesc[count], charsmax(szDesc[]), szDesc[rand2]);         vOrigin[rand2][0] = vOrigin[rand1][0];         vOrigin[rand2][1] = vOrigin[rand1][1];         vOrigin[rand2][2] = vOrigin[rand1][2];         copy(szDesc[rand2], charsmax(szDesc[]), szDesc[rand1]);         vOrigin[rand1][0] = vOrigin[count][0];         vOrigin[rand1][1] = vOrigin[count][1];         vOrigin[rand1][2] = vOrigin[count][2];         copy(szDesc[rand1], charsmax(szDesc[]), szDesc[count]);     }         for ( new i ; i < 6 /* or pcvar */ ; i++ )         spawn_testing(vOrigin[i], szDesc)
or
Code:
    new x[16], y[16], z[16], szDesc[32][32], szData[charsmax(x) + charsmax(y) + charsmax(z) + charsmax(szDesc[])];         new Float:vOrigin[32][3], count;         while(!feof(iFile))     {         fgets(iFile, szData, charsmax(szData));         trim(szData);                 if(!szData[0]) continue;                 parse(szData, x, 15, y, 15, z, 15, szDesc[count], 31);                 vOrigin[count][0] = str_to_float(x);         vOrigin[count][1] = str_to_float(y);         vOrigin[count][2] = str_to_float(z);         count++;             }     new vOriginUsed;         for ( new i, temp ; i < 6 /* or pcvar */ ; i++ ) {         do {             temp = random(count);         }         while ( vOriginUsed & (1<<temp) )         spawn_testing(vOrigin[temp], szDesc[temp])         vOriginUsed |= (1<<temp);     }

If you want it dynamic and editable by the end user don't forget to check that there are more locations than requested spawns.

Code:
new pcvar = get_pcvar_num(...); if ( pcvar > count )     pcvar = count; //...

SHIELD755 06-11-2020 08:21

Re: choosing only "x" number of origin to spawn
 
Quote:

Originally Posted by Black Rose (Post 2705125)
You buffer and randomize.

Code:
    new x[16], y[16], z[16], szDesc[32], szData[charsmax(x) + charsmax(y) + charsmax(z) + charsmax(szDesc)]         new Float:vOrigin[3]         while(!feof(iFile))     {         fgets(iFile, szData, charsmax(szData))         trim(szData)                 if(!szData[0]) continue;                 parse(szData, x, 15, y, 15, z, 15, szDesc, 31)                 vOrigin[0] = str_to_float(x)         vOrigin[1] = str_to_float(y)         vOrigin[2] = str_to_float(z)                 spawn_testing(vOrigin, szDesc)     }
->
Code:
    new x[16], y[16], z[16], szDesc[32], szData[charsmax(x) + charsmax(y) + charsmax(z) + charsmax(szDesc)];         new Float:vOrigin[32][3], count;         while(!feof(iFile))     {         fgets(iFile, szData, charsmax(szData));         trim(szData);                 if(!szData[0]) continue;                 parse(szData, x, 15, y, 15, z, 15, szDesc, 31);                 vOrigin[count][0] = str_to_float(x);         vOrigin[count][1] = str_to_float(y);         vOrigin[count][2] = str_to_float(z);         count++;             }     for ( new i, rand1, rand2 ; i < 100 ; i++ ) {         rand1 = random(count);         rand2 = random(count);         vOrigin[count][0] = vOrigin[rand2][0];         vOrigin[count][1] = vOrigin[rand2][1];         vOrigin[count][2] = vOrigin[rand2][2];         vOrigin[rand2][0] = vOrigin[rand1][0];         vOrigin[rand2][1] = vOrigin[rand1][1];         vOrigin[rand2][2] = vOrigin[rand1][2];         vOrigin[rand1][0] = vOrigin[count][0];         vOrigin[rand1][1] = vOrigin[count][1];         vOrigin[rand1][2] = vOrigin[count][2];     }         for ( new i ; i < 6 /* or pcvar */ ; i++ )         spawn_testing(vOrigin[i], szDesc)
or
Code:
    new x[16], y[16], z[16], szDesc[32], szData[charsmax(x) + charsmax(y) + charsmax(z) + charsmax(szDesc)];         new Float:vOrigin[32][3], count;         while(!feof(iFile))     {         fgets(iFile, szData, charsmax(szData));         trim(szData);                 if(!szData[0]) continue;                 parse(szData, x, 15, y, 15, z, 15, szDesc, 31);                 vOrigin[count][0] = str_to_float(x);         vOrigin[count][1] = str_to_float(y);         vOrigin[count][2] = str_to_float(z);         count++;             }     new vOriginUsed;         for ( new i, temp ; i < 6 /* or pcvar */ ; i++ ) {         do {             temp = random(count);         }         while ( vOriginUsed & temp )         spawn_testing(vOrigin[temp][i], szDesc)         vOriginUsed |= temp;     }

If you want it dynamic and editable by the end user don't forget to check that there are more locations than requested spawns.

Code:
new pcvar = get_pcvar_num(...); if ( pcvar > count )     pcvar = count; //...

thank you @BLACK ROSE , i will test it :)

Black Rose 06-11-2020 08:35

Re: choosing only "x" number of origin to spawn
 
In the second example I made a mistake:

spawn_testing(vOrigin[temp][i], szDesc)
should be
spawn_testing(vOrigin[temp], szDesc)


Also noticed now that you're using the szDesc which i ignored. I've updated both the examples.

The difference between the 2 examples is that example 1 looks like shit but it might be slightly more random. I would use example 2.

Sorry about that.

NOVA GAMING 06-11-2020 08:40

Re: choosing only "x" number of origin to spawn
 
Quote:

Originally Posted by Black Rose (Post 2705127)
In the second example I made a mistake:

spawn_testing(vOrigin[temp][i], szDesc)
should be
spawn_testing(vOrigin[temp], szDesc)


Also noticed now that you're using the szDesc which i ignored. I've updated both the examples.

The difference between the 2 examples is that example 1 looks like shit but it might be slightly more random. I would use example 2.

Sorry about that.

yeah i also prefer to use 2 @SHIELD
it is also easier

SHIELD755 06-11-2020 08:49

Re: choosing only "x" number of origin to spawn
 
SOLVED ,
thanks @blackrose i tested both are working @Nova yes bro , i use second method

Black Rose 06-15-2020 12:32

Re: choosing only "x" number of origin to spawn
 
Sorry, I haven't been coding for a while...
I made a bitwise mistake in the second code.

Code:
    new vOriginUsed;         for ( new i, temp ; i < 6 /* or pcvar */ ; i++ ) {         do {             temp = random(count);         }
        while ( vOriginUsed & temp )
        spawn_testing(vOrigin[temp], szDesc[temp])
        vOriginUsed |= temp;
    }
->
Code:
    new vOriginUsed;         for ( new i, temp ; i < 6 /* or pcvar */ ; i++ ) {         do {             temp = random(count);         }
        while ( vOriginUsed & (1<<temp) )
        spawn_testing(vOrigin[temp], szDesc[temp])
        vOriginUsed |= (1<<temp);
    }

Let's for example take temp = 3 as an example.

In the first code it would just add 3 to the bitsum resulting in:
Code:

00000000 00000000 00000000 00000011
To make it understandable, assume you have just spawned something in the third location and now you are iterating to see if you can spawn something in the first location.

Here's why it's wrong using vOriginUsed = 3 and new temp = 1:
Code:

  00000000 00000000 00000000 00000011 (vOriginUsed |= 3)
& 00000000 00000000 00000000 00000001 (temp = 1)
= 00000000 00000000 00000000 00000001 (1, true, location has been used and cannot be used again)

It should be like this with vOriginUsed = (1<<3) and temp = 1:
Code:

  00000000 00000000 00000000 00001000 (vOriginUsed |= (1<<3))
& 00000000 00000000 00000000 00000010 ((1<<temp), temp = 1)
= 00000000 00000000 00000000 00000000 (0, false, location has not been used. Free to spawn here.)

Also note that the second code from previously only works with up to 32 locations as you can see from the example above. There are only 32 unique bits in a variable in pawn (4 bytes). I didn't point that out.


All times are GMT -4. The time now is 12:54.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.