Solved secret character

Question that is answered or resolved.

DD Tokki

Well-known member
This may or may not be a feature, so I'm still asking.
Secret characters are unlocked only after clearing the game.
Is there any way to unlock the character for each specific stage?
stage 01 -> boss 01 -> player(boss 01) -> next
stage 02 -> boss 02 -> player(boss 02) -> next
stage 03 -> boss 03 -> player(boss 03) -> next...
I want to unlock the character when clearing the stage without looking at the ending like this.
 
Last edited:
There's script way to unlock/lock a character which I've posted in this thread.
Code:
void main()
{// Update script for locking certain player
//    drawstring(220,130,3, getindexedvar(0));
//    drawstring(220,150,3, getindexedvar(1));

    if(openborvariant("in_selectscreen")==1){
      int models_cached = openborvariant("models_cached");
      int i = 0;
      int C = getglobalvar("Load");

      for( i = 0; i < models_cached; ++i ) {
        char model = getmodelproperty(i,2);

        if( model == "Paladin" && C != 39 ) {
            changemodelproperty(i,4,0);
            return;
        }
      }
    } else if(openborvariant("in_menuscreen")==1){
      setindexedvar(0, NULL());
    }
}

void oncreate()
{
    int C = fileskim("Rise");
    setglobalvar("Load", C);

    setindexedvar(1, 0);
}

void fileskim(char Line)
{
      void file = openfilestream("Test.txt", 1);
      void vLoad;

      if(file != -1){
        setfilestreamposition(file, 0);
        vLoad = getfilestreamargument(file, 0, "string");

        while(vLoad != Line && vLoad != "#End"){
          filestreamnextline(file);
          vLoad = getfilestreamargument(file, 0, "string");         
        }
        if( vLoad == Line ){
          filestreamnextline(file);
          vLoad = getfilestreamargument(file, 0, "int");
          return vLoad;

          closefilestream(file);
        } else if(vLoad == "#End"){
          closefilestream(file);
          return 0;
        }
      } else {
        return 0;
      }
}

Calling hidden characters using scripts is a high level of difficulty for me. once i understood
if( model == "Paladin" && C != 39 ) {
If the number is "39", the character is unlocked, and if it is any other number, the condition is not met, right?

So how should the character be initially set up? If you set "know", there will be no character, and if you set "load", you will be able to select in advance even if you apply this script.
I guess it will take some time to apply this feature.
 
Nope. Locked characters are not selectable in select screen even though they are loaded in models.txt . You can check models.txt for that.
Oh yes, here's the demo with locked Paladin: Map template.
Code:
void writedefault(void Path)
{// Writes file by name Path with default values
// Used when there's no file to start with
      void file = createfilestream();
      filestreamappend(file, 11, 1);
      filestreamappend(file, 22, 0);
      filestreamappend(file, 33, 0);
      filestreamappend(file, 44, 0);
      filestreamappend(file, "Shit", 0);
      filestreamappend(file, 111, 0);
      filestreamappend(file, 122, 0);
      filestreamappend(file, "Bat", 0);
      filestreamappend(file, 133, 0);
      filestreamappend(file, 144, 0);
      filestreamappend(file, "Boss0", 0);
      filestreamappend(file, 155, 0);
      filestreamappend(file, 166, 0);
      filestreamappend(file, "Anime", 0);
      filestreamappend(file, 177, 0);
      filestreamappend(file, 188, 0);
      filestreamappend(file, "Gun", 0);
      filestreamappend(file, 199, 0);
      filestreamappend(file, 200, 0);
      filestreamappend(file, "Boss1", 0);
      filestreamappend(file, 211, 0);
      filestreamappend(file, 222, 0);
      filestreamappend(file, "SF1", 0);
      filestreamappend(file, 233, 0);
      filestreamappend(file, 244, 0);
      filestreamappend(file, "SF2", 0);
      filestreamappend(file, 255, 0);
      filestreamappend(file, 266, 0);
      filestreamappend(file, "Boss2", 0);
      filestreamappend(file, 55, 0);
      filestreamappend(file, 66, 0);
      filestreamappend(file, "#End", 0);

      savefilestream(file, Path);
      closefilestream(file);
}

Code:
void Unlock(int Flag, void Path)
{ // Unlocks certain character based on flag and write the status on file named Path
// 1: Unlocks Rugal
// 2: Unlocks Chun-Li
// 3: Unlocks Griffon
    void file = openfilestream(Path, 1);
    char Code; int Value; char Check; int VCheck;

    if(Flag == 1){
      Code = "Boss0";
      Value = 12;
      Check = "Load";
    } else if(Flag == 2){
      Code = "Boss1";
      Value = 24;
      Check = "Load2";
    } else if(Flag == 3){
      Code = "Boss2";
      Value = 36;
      Check = "Load3";
    }

    if(file == -1){
      writedefault(Path);
    }

    VCheck = getglobalvar(Check);
    
    if(VCheck!=Value){
      fileedit(Path, Code, Value);
      filewrite(Path);
    }
}

Code:
update.c

void main()
{// Update script
    void Scene = openborvariant("current_scene");

    if(openborvariant("in_selectscreen")==1){ // for locking certain player
      int models_cached = openborvariant("models_cached");
      void set = openborvariant("current_set");
      int i = 0;
      int C = getglobalvar("Load");
      int D = getglobalvar("Load2");
      int E = getglobalvar("Load3");

      for( i = 0; i < models_cached; ++i ) {
        char model = getmodelproperty(i,2);

        if( model == "Rugal" && C != 12 && set == 0) {
            changemodelproperty(i,4,0);
        } else if( model == "Chun-Li" && D != 24 && set == 0) {
            changemodelproperty(i,4,0);
       } else if( model == "Griffon" && E != 36 && set == 0) {
            changemodelproperty(i,4,0);
        }
      }
    } else if(openborvariant("in_menuscreen")==1 || openborvariant("in_titlescreen")==1){
      setindexedvar(0, NULL());
//    } else if(openborvariant("in_level")){
//      drawstring(160,110,2, getglobalvar("Lizto")); // testing
    } else if(Scene == "data/scenes/howto.txt"){
      int C = getglobalvar("Load");
      int D = getglobalvar("Load2");
      int E = getglobalvar("Load3");
    }
  }

void oncreate()
{
    int C = fileskim("Boss0", "Test.txt");
    int D = fileskim("Boss1", "Test.txt");
    int E = fileskim("Boss2", "Test.txt");

    setglobalvar("Load", C);
    setglobalvar("Load2", D);
    setglobalvar("Load3", E);

    setindexedvar(1, 0);
}

void fileskim(char Line, void Path)
{
      void file = openfilestream(Path , 1);
      void vLoad;

      if(file != -1){
        setfilestreamposition(file, 0);
        vLoad = getfilestreamargument(file, 0, "string");

        while(vLoad != Line && vLoad != "#End"){
          filestreamnextline(file);
          vLoad = getfilestreamargument(file, 0, "string");         
        }
        if( vLoad == Line ){
          filestreamnextline(file);
          vLoad = getfilestreamargument(file, 0, "int");
          return vLoad;

          closefilestream(file);
        } else if(vLoad == "#End"){
          closefilestream(file);
          return 0;
        }
      } else {
        return 0;
      }
}


I'm trying to hide Rugal, Chun-Li, and Griffon using a script. I wrote this once, did I miss something? As of now, they are not hidden.

In the test game, I checked the hidden things such as Paladin, but there are still many things I don't know.
 
Are you using script.txt in data folder? If not, you should create one and add this line in it:
Code:
alwaysupdate    1

This will allow update.c and updated.c to run in non level sections such as main menu, select screen and howtoplay.
 
Are you using script.txt in data folder? If not, you should create one and add this line in it:
Code:
alwaysupdate    1

This will allow update.c and updated.c to run in non level sections such as main menu, select screen and howtoplay.
yes. Script and txt are also added to the data folder.
But it's still the same situation where the character comes out.

Am I missing something or doing something wrong in the above script?
 
Are you using script.txt in data folder? If not, you should create one and add this line in it:
Code:
alwaysupdate    1

This will allow update.c and updated.c to run in non level sections such as main menu, select screen and howtoplay.
The script seems to be ok. In the game I made for testing, certain characters are hidden. Something seems to be crashing in my original game.
 

Currently, hidden characters are only available on the select screen at the top, so I tested it.
At first, the boss was not selected, and after defeating the boss, the boss can be selected.
Now, I think it would be nice if only the select screen was resolved.
 
I've found the cause,
C:
      for( i = 0; i < models_cached; ++i ) {
        char model = getmodelproperty(i,2);

        if( model == "Rugal" && C != 12 && set == 0) {
            changemodelproperty(i,4,0);
        } else if( model == "Chun-Li" && D != 24 && set == 0) {
            changemodelproperty(i,4,0);
       } else if( model == "Griffon" && E != 36 && set == 0) {
            changemodelproperty(i,4,0);
        }
      }

set==0 means the lock is only applied in first game mode. You'd need to remove it to apply the lock in all modes like this:
C:
      for( i = 0; i < models_cached; ++i ) {
        char model = getmodelproperty(i,2);

        if( model == "Rugal" && C != 12) {
            changemodelproperty(i,4,0);
        } else if( model == "Chun-Li" && D != 24) {
            changemodelproperty(i,4,0);
       } else if( model == "Griffon" && E != 36) {
            changemodelproperty(i,4,0);
        }
      }

HTH
 
I've found the cause,
C:
      for( i = 0; i < models_cached; ++i ) {
        char model = getmodelproperty(i,2);

        if( model == "Rugal" && C != 12 && set == 0) {
            changemodelproperty(i,4,0);
        } else if( model == "Chun-Li" && D != 24 && set == 0) {
            changemodelproperty(i,4,0);
       } else if( model == "Griffon" && E != 36 && set == 0) {
            changemodelproperty(i,4,0);
        }
      }

set==0 means the lock is only applied in first game mode. You'd need to remove it to apply the lock in all modes like this:
C:
      for( i = 0; i < models_cached; ++i ) {
        char model = getmodelproperty(i,2);

        if( model == "Rugal" && C != 12) {
            changemodelproperty(i,4,0);
        } else if( model == "Chun-Li" && D != 24) {
            changemodelproperty(i,4,0);
       } else if( model == "Griffon" && E != 36) {
            changemodelproperty(i,4,0);
        }
      }

HTH
Let's check the script now.
 
I've found the cause,
C:
      for( i = 0; i < models_cached; ++i ) {
        char model = getmodelproperty(i,2);

        if( model == "Rugal" && C != 12 && set == 0) {
            changemodelproperty(i,4,0);
        } else if( model == "Chun-Li" && D != 24 && set == 0) {
            changemodelproperty(i,4,0);
       } else if( model == "Griffon" && E != 36 && set == 0) {
            changemodelproperty(i,4,0);
        }
      }

set==0 means the lock is only applied in first game mode. You'd need to remove it to apply the lock in all modes like this:
C:
      for( i = 0; i < models_cached; ++i ) {
        char model = getmodelproperty(i,2);

        if( model == "Rugal" && C != 12) {
            changemodelproperty(i,4,0);
        } else if( model == "Chun-Li" && D != 24) {
            changemodelproperty(i,4,0);
       } else if( model == "Griffon" && E != 36) {
            changemodelproperty(i,4,0);
        }
      }

HTH
Unlock conditions work well. However, when you clear the stage, exit the game, and turn it back on, unlocked characters become inactive again.
 
I assume you have saved unlocked characters into text file. I don't know the name of your text file.
One thing I could tell you is that, update.c has oncreate() section in which saved states from text file is read.
There are more lines in that section but I'll quote only the ones needed for reading.
C:
void oncreate()
{
    int C = fileskim("Rise", "Test.txt");
    int D = fileskim("Rise2", "Test.txt");

    setglobalvar("Load", C);
    setglobalvar("Load2", D);
}

fileskim is a function you need to copy into update.c
C:
void fileskim(char Line, void Path)
{
      void file = openfilestream(Path , 1);
      void vLoad;

      if(file != -1){
        setfilestreamposition(file, 0);
        vLoad = getfilestreamargument(file, 0, "string");

        while(vLoad != Line && vLoad != "#End"){
          filestreamnextline(file);
          vLoad = getfilestreamargument(file, 0, "string");          
        }
        if( vLoad == Line ){
          filestreamnextline(file);
          vLoad = getfilestreamargument(file, 0, "int");
          return vLoad;

          closefilestream(file);
        } else if(vLoad == "#End"){
          closefilestream(file);
          return 0;
        }
      } else {
        return 0;
      }
}

In newer builds, that function is imported from fileEd.c.

Anyways, fileskim reads saved state from specified text file which is Test.txt. The acquired value is later stored in respective global variable to unlock respective character.
 
I assume you have saved unlocked characters into text file. I don't know the name of your text file.
One thing I could tell you is that, update.c has oncreate() section in which saved states from text file is read.
There are more lines in that section but I'll quote only the ones needed for reading.
C:
void oncreate()
{
    int C = fileskim("Rise", "Test.txt");
    int D = fileskim("Rise2", "Test.txt");

    setglobalvar("Load", C);
    setglobalvar("Load2", D);
}

fileskim is a function you need to copy into update.c
C:
void fileskim(char Line, void Path)
{
      void file = openfilestream(Path , 1);
      void vLoad;

      if(file != -1){
        setfilestreamposition(file, 0);
        vLoad = getfilestreamargument(file, 0, "string");

        while(vLoad != Line && vLoad != "#End"){
          filestreamnextline(file);
          vLoad = getfilestreamargument(file, 0, "string");       
        }
        if( vLoad == Line ){
          filestreamnextline(file);
          vLoad = getfilestreamargument(file, 0, "int");
          return vLoad;

          closefilestream(file);
        } else if(vLoad == "#End"){
          closefilestream(file);
          return 0;
        }
      } else {
        return 0;
      }
}

In newer builds, that function is imported from fileEd.c.

Anyways, fileskim reads saved state from specified text file which is Test.txt. The acquired value is later stored in respective global variable to unlock respective character.
Code:
void oncreate()
{
    int C = fileskim("Boss0", "Test.txt");
    int D = fileskim("Boss1", "Test.txt");
    int E = fileskim("Boss2", "Test.txt");

    setglobalvar("Load", C);
    setglobalvar("Load2", D);
    setglobalvar("Load3", E);

    setindexedvar(1, 0);
}

Code:
void fileskim(char Line, void Path)
{
      void file = openfilestream(Path , 1);
      void vLoad;

      if(file != -1){
        setfilestreamposition(file, 0);
        vLoad = getfilestreamargument(file, 0, "string");

        while(vLoad != Line && vLoad != "#End"){
          filestreamnextline(file);
          vLoad = getfilestreamargument(file, 0, "string");       
        }
        if( vLoad == Line ){
          filestreamnextline(file);
          vLoad = getfilestreamargument(file, 0, "int");
          return vLoad;

          closefilestream(file);
        } else if(vLoad == "#End"){
          closefilestream(file);
          return 0;
        }
      } else {
        return 0;
      }
}

Here is the code written for my game.
"Test.txt" is created in the save folder.

Code:
anim    death
    loop    0
    delay    1
    offset    71 23
    sound    data/sounds/se/misc/lose-bs.wav
    @cmd    degravity    -0.5
    @cmd    screen    0
    @cmd    spawnbind "Unlock0" 0 0 0  
    frame    data/sprites/sprite/chara/rugal/fall-05.gif

In the Rugal file, unlock0 is called.
 
Last edited:
I think spawning Unlock0 should be sufficient to ran Unlock function.

But anyways, I assume this Unlock0 has content similar to Unlock1 and Unlock2? that they write to Test.txt ?
 
I think spawning Unlock0 should be sufficient to ran Unlock function.

But anyways, I assume this Unlock0 has content similar to Unlock1 and Unlock2? that they write to Test.txt ?
Code:
name        Unlock0 (Rugal)
type        none
animationscript    data/scripts/fileEd.c


anim idle
@script
    if(frame==1){
      setglobalvar("Load", 12);
    }
@end_script
    delay    1
    offset    1 1
    frame    data/sprites/empty.gif
    @cmd    Unlock 1 "Test.txt"
    frame    data/sprites/empty.gif
    @cmd    suicide
    frame    data/sprites/empty.gif

Code:
name        Unlock1 (Chun-Li)
type        none
animationscript    data/scripts/fileEd.c


anim idle
@script
    if(frame==1){
      setglobalvar("Load2", 24);
    }
@end_script
    delay    1
    offset    1 1
    frame    data/sprites/empty.gif
    @cmd    Unlock 1 "Test.txt"
    frame    data/sprites/empty.gif
    @cmd    suicide
    frame    data/sprites/empty.gif

Unlock0, 1 write to the test file.

Code:
Test

11
22
33
44
Shit
111
122
Bat
133
144
Boss0
12
166
Anime
177
188
Gun
199
200
Boss1
211
222
SF1
233
244
SF2
255
266
Boss2
55
66
#End

The structure of the files created inside the save is as follows
 
Back
Top Bottom