Solved 2pspawn equivalent for group

Question that is answered or resolved.

Toranks

Active member
Is there a way to increase the simultaneous number of enemies only when there are more players? Increasing the value of group. Similar to 2pspawn and 2phealth
 
I get you now. No. There's no native way to increase group size based on number of players. Only spawns and health have that option. You'll need to use a script to check number of players and bring more enemies in accordingly. @Bloodbane has a lot of spawn scripts meant to handle different situations, so check some of his posts.

DC
 
it would be like an invisible inmobile enemy that spawns others enemies, then for player 3 it could be 2 of them and for player 4 another. but the tricky thing is triggering its death after its "son" number 3 is dead - or the thing could have a timer of about a minute or a variable timer based on randomized animation, and during those animations it spawns enemies at you... until it dies, these invisibles would have to be the last of the group to spawn so they can extend the group to 3 or 4 more enemies
 
Could I create those scripts directly in the level file associated to a temporary and invisible entity? It would be more convenient to manage
Another question: Is there a variable that returns the number of players in play? Or do I have to ask the script to check one by one?
 
Last edited:
@Toranks
i suppose you can, Bloodbane has done some very good scripts that work on level.txt files

there is also 2 ways to go about for an entity to expand the group.

1 - the entity dies when it detects its last Subentities's death - one way i know is for the spawner to have a script that give its children aliases, the spawner makes a check to see if if the aliased entities are alive, if they die, the spawner dies, end of group on to the next

example: George Foreman Senior only appears if 4 players are present, George Foreman Senior spawns George the2nd & then a few seconds later George the 3rd & George the 4th a while after that, if all the georgers die, main George dies, end of group, move on.

2 - Have the spammer die with a timer, or if its present die normally, or have mod verison of a character "poop" out a subentity that spawns the spawner on death , the spawner lives on a timer but leaves behind its accolytes.

Example: George Foreman Senior come out if 4 players are present, if you trigger George Foreman Senior's faint animation, he drops a grill, but this grill calls the rest of the Georges in to action, & then you see the grill die in a puff of smoke after a minute, the remaining Georges follow you into the next section of the level

i found this while working with Spawner entities in NS Wide, - you can have Straglers even after the group is over!
this means that the transition between groups is "blurred" you can keep moving on but enemies can also be present & carry over to the next section or blockade from a previous kerfuffle - so that is the kind of chaos i tend to embrace & if you make use of randomized script it becomes even less predictable, the only disadvantage is that i have not found a way for these entities to have an easy item e drop after they die, they have to be a dedicated sub section of clone entities in your game to serve only as sub-entities.
 
Could I create those scripts directly in the level file associated to a temporary and invisible entity? It would be more convenient to manage
Another question: Is there a variable that returns the number of players in play? Or do I have to ask the script to check one by one?
I don't know if it can work for your game, but SOR2X has a random spawn system for enemies that checks how many players are alive and other conditions too.
I added it for Jet characters. An invisible enemy needs to be spawned, but all other tasks are done by script.

Invisible entity file
Code:
name            JetX
type            none
lifespan        0.001
shadow            0
alpha            1
onspawnscript     data/scripts/onspawn/jetx.c

remap            data/chars/random/empty.gif data/chars/random/alter1.gif
remap            data/chars/random/empty.gif data/chars/random/alter2.gif
remap            data/chars/random/empty.gif data/chars/random/alter3.gif
remap            data/chars/random/empty.gif data/chars/random/alter4.gif

anim idle
    loop    0
    delay    1
    offset    50 72
    frame    data/chars/random/empty.gif
Invisible entity script
Code:
void main()
{
    jetX();
}

void jetX()
{//Spawn enemy according player count
    void difficulty = getglobalvar("difficulty");
    void partner    = getglobalvar("partnerAlive");
    int set         = openborvariant("current_set");
    int branch      = openborvariant("current_branch");
    int pCount      = openborvariant("count_players");
    if(partner > 0){pCount = pCount+partner;}
    
    if(set == 0 || set == 2){
        if(branch == "sor2_st2c"){
            if(difficulty != "mania"){
                if(pCount >= 2){enemyX("JetB", 0, 0, 0, 0, 0, 1);}
            }
            if(difficulty == "mania"){
                enemyX("JetB", 0, 0, 0, 0, 0, 1);
            }
        }
        
        if(branch == "sor2_st5c"){
            if(difficulty != "mania"){
                if(pCount >= 1 && pCount <= 2){enemyX("JetB", 0, 0, 0, 0, 0, 2);}else
                if(pCount >= 3 && pCount <= 4){enemyX("JetB", 0, 0, 0, 0, 0, 2);enemyX("JetB", 50, 0, 0, 1, 0, 3);}
            }
            if(difficulty == "mania"){
                enemyX("JetB", 0, 0, 0, 0, 0, 2);
                enemyX("JetB", 50, 0, 0, 1, 0, 3);
            }
        }
        
        if(branch == "sor2_st7b"){
            if(difficulty != "mania"){
                if(pCount >= 1 && pCount <= 2){enemyX("JetB", 0, 0, 0, 0, 0, 5);}else
                if(pCount >= 3 && pCount <= 4){enemyX("JetB", 0, 0, 0, 0, 0, 5);enemyX("JetB", 50, 0, 0, 1, 0, 4);}
            }
            if(difficulty == "mania"){
                enemyX("JetB", 0, 0, 0, 0, 0, 5);
                enemyX("JetB", 50, 0, 0, 1, 0, 5);
            }
        }
    }
}

void enemyX(void vName, float dx, float dy, float dz, int iDir, int boss, int map)
{//Spawns random enemy next to caller (DEFAULT, FOR SUB-BOSSES OR BOSSES)
    void self = getlocalvar("self");
    void vSpawn;
    loadmodel(vName);
    clearspawnentry();
    setspawnentry("name", vName);
    setspawnentry("boss", boss);
    setspawnentry("map", map);
    vSpawn = spawn();
    bindentity(vSpawn, self, dx, dz, dy, iDir);
    return vSpawn;
}

In addition, SOR2X has some scripts for the survival modes that spawn enemies by script according to some conditions. If you have the pak file, the main script is in the path "data/scripts/updatelevel/spawn_time.c"
 
I'm trying to do it in a simple way, and I've tried the following, but it doesn't work. Only one step fails, see if anybody can help me.
First I create a temporary entity that lasts a few seconds, ghosttime. Then I declare a local variable that indicates what level it is. And I call the script.
C#:
spawn   ghosttime
@script
void main()
    {
    setlocalvar("leveln","1lvl");
    }
@end_script
spawnscript    data/scripts/spawn2p.c
health    20
coords  850 440
at      100

The content of the file spawn2p.c is as follows:

C#:
void main()
    {
    void level = getlocalvar("leveln");
    int pCount = openborvariant("count_players");
 
    if(pCount > 1){
        if(level == "1lvl"){enemyX("kraven", 10, 10, 0, 0, 2);enemyX("brock", 20, 20, 0, 0, 2);enemyX("ren", 30, 30, 0, 0, 2);enemyX("fatguy", 40, 40, 0, 0, 2);}
    }
}




void enemyX(void vName, float dx, float dy, float dz, int iDir, int map)
{//Spawns enemy next to caller
    void self = getlocalvar("self");
    void vSpawn;
    loadmodel(vName);
    clearspawnentry();
    setspawnentry("name", vName);
    setspawnentry("map", map);
    vSpawn = spawn();
    bindentity(vSpawn, self, dx, dz, dy, iDir);
    return vSpawn;
}

This condition, doesn't works, without this, enemies spawn correctly.
C#:
if (level == "1lvl") {

I need this condition to be able to add all spawns to the same spawn2p.c file, for convenience.

What am I doing wrong, or what is missing?

PD: Openbor wiki is wrong, it should be "players", not "enemies":
  • "count_players", - counts how many enemies are active
 
Last edited:
I'm trying to do it in a simple way, and I've tried the following, but it doesn't work. Only one step fails, see if anybody can help me.
First I create a temporary entity that lasts a few seconds, ghosttime. Then I declare a local variable that indicates what level it is. And I call the script.
C#:
spawn   ghosttime
@script
void main()
    {
    setlocalvar("leveln","1lvl");
    }
@end_script
spawnscript    data/scripts/spawn2p.c
health    20
coords  850 440
at      100

The content of the file spawn2p.c is as follows:

C#:
void main()
    {
    void level = getlocalvar("leveln");
    int pCount = openborvariant("count_players");
 
    if(pCount > 1){
        if(level == "1lvl"){enemyX("kraven", 10, 10, 0, 0, 2);enemyX("brock", 20, 20, 0, 0, 2);enemyX("ren", 30, 30, 0, 0, 2);enemyX("fatguy", 40, 40, 0, 0, 2);}
    }
}




void enemyX(void vName, float dx, float dy, float dz, int iDir, int map)
{//Spawns enemy next to caller
    void self = getlocalvar("self");
    void vSpawn;
    loadmodel(vName);
    clearspawnentry();
    setspawnentry("name", vName);
    setspawnentry("map", map);
    vSpawn = spawn();
    bindentity(vSpawn, self, dx, dz, dy, iDir);
    return vSpawn;
}

This condition, doesn't works, without this, enemies spawn correctly.
C#:
if (level == "1lvl") {

I need this condition to be able to add all spawns to the same spawn2p.c file, for convenience.

What am I doing wrong, or what is missing?

Try changing "localvar" to "globalvar", because they are more persistent when two different scripts need to trade data.
 
It also doesn't work with setglobalvar / getglobalvar :(
My only alternative now is use a different script file for each spawn 2pspawn01.c, 2pspawnXX.c ... etc, repeating the same code

Edit:
setglobalvar("leveln",101);
and
if(level == 101)

This doesn't work neither
 
Last edited:
It also doesn't work with setglobalvar / getglobalvar :(
My only alternative now is use a different script file for each spawn 2pspawn01.c, 2pspawnXX.c ... etc, repeating the same code
@Toranks
Tested your script in SOR2X and it really didn't work, but I found the problem. It seems that you can't use in-line scripts together with "spawnscripts" in the same spawn occurrence. At this point, we have two options:

1) Split the process in two spawns, and then it gives the enough time to the "spawnscript" reads the variable previously saved. Tested with localvar but didn't work, only globalvar.

level file
Code:
spawn        BlockadeZ 1
@script
void main()
{
    setglobalvar("leveln","1lvl");
}
@end_script
flip        1
coords        0 470 0
at            0

spawn        FakeWall 1
spawnscript    data/scripts/levelspawn/music_boss1.c
flip        1
coords        588 384 0
at            0

spawn script
Code:
void main()
{
    if(getglobalvar("leveln") == "1lvl"){musicBoss1();}
}

2)Use the #import function. This way you can create various "spawnscripts" but for convenience you can make all them import the same "main" file, like this:

level file
Code:
spawn        FakeWall 1
spawnscript    data/scripts/levelspawn/music_boss1.c
flip        1
coords        588 384 0
at            0

spawn        FakeWall 1
spawnscript    data/scripts/levelspawn/music_boss2.c
flip        1
coords        588 384 0
at            0

spawn        FakeWall 1
spawnscript    data/scripts/levelspawn/music_boss3.c
flip        1
coords        588 384 0
at            0

spawn script 1
Code:
#import "data/scripts/levelspawn/main_music.c"
void main()
{
    if(getglobalvar("leveln") == "1lvl"){musicBoss1();}
}

spawn script 2
Code:
#import "data/scripts/levelspawn/main_music.c"
void main()
{
    if(getglobalvar("leveln") == "2lvl"){musicBoss2();}
}

spawn script 3
Code:
#import "data/scripts/levelspawn/main_music.c"
void main()
{
    if(getglobalvar("leveln") == "3lvl"){musicBoss3();}
}

This way you can use the "main" file to have the full script for easy editing, no need to create various scripts in different files.
 
@Toranks
Tested your script in SOR2X and it really didn't work, but I found the problem. It seems that you can't use in-line scripts together with "spawnscripts" in the same spawn occurrence. At this point, we have two options:
Method 1 works and is very simple, thanks!
Now I only need where and what spawn on every stage :giggle:

Level file:
C#:
spawn   ghost1
@script
void main()
    {
    setglobalvar("leveln","1lvl");
    }
@end_script
coords  850 440
at      100


spawn   ghosttime
health    20
spawnscript    data/scripts/spawn3p.c
coords  850 340
at      100

script spawn3p.c:

C#:
void main()
    {
    void level = getglobalvar("leveln");
    int pCount = openborvariant("count_players");
   
    if(pCount > 2){
        if(level == "1lvl"){enemyX("kraven", 10, 10, 0, 0, 2);enemyX("brock", 20, 20, 0, 0, 2);enemyX("ren", 30, 30, 0, 0, 2);enemyX("fatguy", 40, 40, 0, 0, 2);}
    }
}




void enemyX(void vName, float dx, float dy, float dz, int iDir, int map)
{//Spawns enemy next to caller
    void self = getlocalvar("self");
    void vSpawn;
    loadmodel(vName);
    clearspawnentry();
    setspawnentry("name", vName);
    setspawnentry("map", map);
    vSpawn = spawn();
    bindentity(vSpawn, self, dx, dz, dy, iDir);
    return vSpawn;
}
 
Last edited:
Back
Top Bottom