Continue Screen

Recently, @DCurrent has uploaded a continue bug patch for the actual release of OpenBOR, and he suggested that the script can be used to build a custom continue screen. It would be worth checking it out:

 
As a suggestion, you can rush the countdown by pressing the directional buttons instead of start or attack buttons.
Only the start button works (countdown entity declared as type none instead of type text) because I have an invisible fake player entity working as anim respawn (though it's switch to a follow animation via script) for going back to the select screen. With that working, I have that countdown entity set with type none, but there's no need to switch to another animation after pressing start. When I use type none in CountD entity (instead of type text), it works fine (with a fake player) to continue without switching animation after pressing start. Maybe I wouldn't need to set it type text (as well as going without countdown entity).

Another suggestion is to use the combo "timetick+updated" events instead of creating a "countdown" entity. This way the countdown will not be stopped by type text entities.
How can I do that? If I use updated.c, could I #include tick.c or timetick.c? How can I draw a sprite (shown in the attachment) to act as a countdown instead of using it as an entity and drawing fonts? Also, I want to spawn a full black screen along with the count sprites together. After I extracted your SOR2X mod and looked at timetick.c, I see globalvars which I'm not so good at. However, looking at the clock script (main one in "updated" folder) helped me compare it with the directional jumping script. Your updated.c along with #import lines, is easy to read where they come from, yet complex to emulate and do.

Thanks for your suggestions, Kratus! I don't know what I'm gonna do with it since I have the countdown sprites to use instead of regular fonts. Do you mind you'd show a sample of using a certain sprite instead of a font? I'm not gonna use either drawstring or settextobj. Maybe drawsprite/loadsprite could work?

@afhc2x17 Thanks, but I'm using one version of it from around 2016 for that. :) I will use the latest version of it some time.
 

Attachments

  • count001.png
    count001.png
    20.3 KB · Views: 2
Do you mind you'd show a sample of using a certain sprite instead of a font? I'm not gonna use either drawstring or settextobj. Maybe drawsprite/loadsprite could work?
You can create separated sprites of every letter/number from your font table. After that, you can load/draw every sprite using the script example below:

C:
if(getlocalvar("image") == NULL()) //First, load a image and save into a variable if NULL()
{
    setlocalvar("image", loadsprite("data/sprites/image.png"));
}
else //And then, draw the previously saved image if not NULL()
{
    drawsprite(getlocalvar("image"), x_position, y_position, z_layer);
}

EDIT: Fixed the script, closed the local variable "image" properly inside the drawsprite function.
 
Last edited:
@Kratus, I'm having problem with adding scripts, especially with updated.c. How can I make the image display here?

Log:
Code:
Total Ram: 2147483647 Bytes
 Free Ram: 523612160 Bytes
 Used Ram: 6266880 Bytes

debug:nativeWidth, nativeHeight, bpp, Hz  1366, 768, 24, 60
OpenBoR v3.0 Build , Compile Date: Dec 12 2016

Game Selected: ./Paks/My Mod.pak

FileCaching System Init......    Disabled
Initializing video............
Reading video settings from 'data/video.txt'.
Initialized video.............    320x240 (Mode: 0, Depth: 32 Bit)

Loading menu.txt.............    Done!
Loading fonts................    1 2 3 4 5 6 7 8 9 10 Done!
Timer init...................    Done!
Initialize Sound..............    
Loading sprites..............    Done!
Loading level order..........    Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Done!
Loading model constants......    Done!
Loading script settings......    Done!
Loading scripts..............    

Script error: data/scripts/updated.c, line 85: Unknown error ';' (in production 'arg_expr_list2')

    drawsprite(getlocalvar("image", x_position, y_position, z_layer);
                                                                    ^


********** An Error Occurred **********
*            Shutting Down            *

Failed to parse script file: 'data/scripts/updated.c'!
Total Ram: 2147483647 Bytes
 Free Ram: 493596672 Bytes
 Used Ram: 25059328 Bytes

Release level data...........
Done!

Release graphics data........    Done!
Release game data............


Release game data............    Done!
Release timer................    Done!
Release input hardware.......    Done!
Release sound system.........    Done!
Release FileCaching System...    Done!

**************** Done *****************

Failed to parse script file: 'data/scripts/updated.c'!

updated.c:
Code:
//#import data/scripts/

void main(){
//   Screeno();
   drawClock();
}

void Screeno(){
    void counter = getlocalvar("counter");
    if(openborvariant("in_menuscreen")) // Check if the game is in menu screen
   {    counter = setlocalvar("counter",0); 
   }if(openborvariant("in_titlescreen") && (counter!=1)){
        void subent;
        loadmodel("beso");
        clearspawnentry();
        setspawnentry("name", "beso");
        setspawnentry("coords", 1,0,-1);
        subent=spawn();
        changeentityproperty(subent, "position", 1,0,-1);
        counter = setlocalvar("counter",1);
    }
}

void drawClock()
{//Draw custom clock used for level timer
    float hRes        = openborvariant("hresolution");
    float time        = openborvariant("game_time");
    float channel    = 80;
    float maxTime    = 39600;
    float black        = rgbcolor(0x00,0x00,0x00);
    float red        = rgbcolor(0x80,0x00,0x00);
    float white        = rgbcolor(0xFF,0xFF,0xFF);
    int xSprite        = 226;
    int xBox        = 0;
    int yBox        = 269;
    int font0        = 3;
    int font1        = 7;
    int iconLayer    = 60000;
    int barLayer    = 50000;
    int backLayer    = 1000000001;
    int textLayer    = 1000000003;
    
    //APPLY DRAWMETHOD EFFECTS
    setdrawmethod(NULL(),1,256,256,0,0,0,6);
    changedrawmethod(NULL(), "channelr", channel); //CHANNEL DRAWMETHOD SETTINGS
    changedrawmethod(NULL(), "channelg", channel); //CHANNEL DRAWMETHOD SETTINGS
    changedrawmethod(NULL(), "channelb", channel); //CHANNEL DRAWMETHOD SETTINGS
    
    //GAME TIMER
    if(openborvariant("pause") == 0 && openborvariant("in_options") != 1){ //CHECK IF THE GAME IS NOT PAUSED OR IN OPTIONS
        if(getglobalvar("levelTime") == "timeline"){
            drawsprite(getglobalvar("timeIcon"), xSprite, 263, iconLayer); //TIME ICON
            drawbox(xBox, yBox, (maxTime*hRes)/(maxTime), 3, barLayer, black); //BLACK BORDER
            drawbox(xBox, yBox+1, (maxTime*hRes)/(maxTime), 1, barLayer+1, red); //RED FILL
            drawbox(xBox, yBox+1, (time*hRes)/(maxTime), 1, barLayer+2, white); //WHITE BAR
        }
        else
        if(getglobalvar("levelTime") == "numeric"){
            drawsprite(getglobalvar("timeIcon"), xSprite, 249, iconLayer); //TIME ICON
            drawstring((hRes-strwidth(""+time/400, font0))/2, 256, font0, time/400, barLayer); //CLOCK
        }
        else
        if(getglobalvar("levelTime") == "both"){
            drawsprite(getglobalvar("timeIcon"), xSprite, 246, iconLayer); //TIME ICON
            drawstring((hRes-strwidth(""+time/400, font0))/2, 253, font0, time/400, barLayer); //CLOCK
            drawbox(xBox, yBox, (maxTime*hRes)/(maxTime), 3, barLayer, black); //BLACK BORDER
            drawbox(xBox, yBox+1, (maxTime*hRes)/(maxTime), 1, barLayer+1, red); //RED FILL
            drawbox(xBox, yBox+1, (time*hRes)/(maxTime), 1, barLayer+2, white); //WHITE BAR
        }
    }
    
    //"CONTINUE" SCREEN TIMER
    if(getglobalvar("activeText") == "continue"){
        //if(openborvariant("game_time") <= (maxTime/10) && openborvariant("game_time") > 0){
            /*setdrawmethod(NULL(),1,256,256,0,0,0,2);
            drawsprite(getglobalvar("back1"), 0, 0, backLayer);
            drawstring((hRes-strwidth("CONTINUE?", font1))/2+1, 120, font1, "CONTINUE?", textLayer);
            drawstring((hRes-strwidth(""+time/400, font1))/2+1, 138, font1, openborvariant("game_time")/400, textLayer);*/
if(getlocalvar("image") == NULL()) //First, load a image and save into a variable if NULL()
{
    setlocalvar("image", loadsprite("data/chars/misc/continueanim/count09.png"));
}
else //And then, draw the previously saved image if not NULL()
{
    drawsprite(getlocalvar("image", x_position, y_position, z_layer);
}
        }else{
            setglobalvar("activeText", 0);
        }
    }
}

timetick.c:
Code:
void main(){
    timeTick();
}

void timeTick()
{//Script to avoid engine "noshare" BUG that don't give enough time to press start button and continue the game if the all players are dead
 //This bug happens only if "noshare" command is not present in "levels.txt". If it is present with flag 1, this bug not happens and the engine give you 10 seconds
    float limit    = 4000; //TIME LIMIT TO CHECK IF THERE'S A CONTDOWN RUNNING
    float add    = 3960; //TIME TO BE ADDED IF ALL PLAYERS ARE DEAD BUT HAS CREDITS TO USE
    
    if(getglobalvar("activeText") == "continue"){ //CONTINUE SCREEN IS BEING SHOWN??
        if(openborvariant("count_players") > 0){ //PLAYERS ARE IN THE SCREEN??
            setglobalvar("activeText", 0); //DISABLE CONTINUE COUNTER
        }
    }
    
    if(getglobalvar("activeText") != "continue"){ //CONTINUE SCREEN IS NOT BEING SHOWN??
        if(    getplayerproperty(0, "joining") != 1 &&
            getplayerproperty(1, "joining") != 1 &&
            getplayerproperty(2, "joining") != 1 &&
            getplayerproperty(3, "joining") != 1 ){

            if(openborvariant("count_players") <= 0){ //NO PLAYERS IN THE SCREEN??
                if(getplayerproperty(0, "credits") > 0){ //ALREADY HAVE CREDITS TO PLAY??
                    if(openborvariant("game_time") < limit){ //CONTINUE COUNTER IS LESS THAN 10 SECONDS??
                        changeopenborvariant("game_time", add); //CHANGE CONTINUE TIMER TO 10 SECONDS
                        setglobalvar("activeText", "continue"); //SET CONTINUE SCREEN FLAG TO 1
                    }
                }
            }
        }
    }
}

I think the old engine doesn't understand what "GAME_TICK" means.
 
Thanks for the correction, Kratus. But check with the compiled date of the engine in the log and it doesn't read "game_time".

Code:
Total Ram: 2147483647 Bytes
 Free Ram: 574074880 Bytes
 Used Ram: 6262784 Bytes

debug:nativeWidth, nativeHeight, bpp, Hz  1366, 768, 24, 60
OpenBoR v3.0 Build , Compile Date: Dec 12 2016

Game Selected: ./Paks/My Mod.pak

FileCaching System Init......    Disabled
Initializing video............
Reading video settings from 'data/video.txt'.
Initialized video.............    320x240 (Mode: 0, Depth: 32 Bit)

Loading menu.txt.............    Done!
Loading fonts................    1 2 3 4 5 6 7 8 9 10 Done!
Timer init...................    Done!
Initialize Sound..............   
Loading sprites..............    Done!
Loading level order..........    Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Command 'versusdamage' not understood in level order!Done!
Loading model constants......    Done!
Loading script settings......    Done!
Loading scripts..............    openborvariant: System variable name not found: 'game_time'

Script compile error in 'updated': openborvariant line 27, column 22

********** An Error Occurred **********
*            Shutting Down            *

Can't compile script 'updated'
Total Ram: 2147483647 Bytes
 Free Ram: 571412480 Bytes
 Used Ram: 24817664 Bytes

Release level data...........
Done!

Release graphics data........    Done!
Release game data............


Release game data............    Done!
Release timer................    Done!
Release input hardware.......    Done!
Release sound system.........    Done!
Release FileCaching System...    Done!

**************** Done *****************

Can't compile script 'updated'

updated.c:
Code:
//#import data/scripts/
void main(){
//   Screeno();
   drawClock();
}
void Screeno(){
    void counter = getlocalvar("counter");
    if(openborvariant("in_menuscreen")) // Check if the game is in menu screen
   {    counter = setlocalvar("counter",0); 
   }if(openborvariant("in_titlescreen") && (counter!=1)){
        void subent;
        loadmodel("beso");
        clearspawnentry();
        setspawnentry("name", "beso");
        setspawnentry("coords", 1,0,-1);
        subent=spawn();
        changeentityproperty(subent, "position", 1,0,-1);
        counter = setlocalvar("counter",1);
    }
}
void drawClock()
{//Draw custom clock used for level timer
    float hRes      = openborvariant("hresolution");
    float time      = openborvariant("game_time");
    float channel   = 80;
    float maxTime   = 39600;
    float black     = rgbcolor(0x00,0x00,0x00);
    float red       = rgbcolor(0x80,0x00,0x00);
    float white     = rgbcolor(0xFF,0xFF,0xFF);
    int xSprite     = 226;
    int xBox        = 0;
    int yBox        = 269;
    int font0       = 3;
    int font1       = 7;
    int iconLayer   = 60000;
    int barLayer    = 50000;
    int backLayer   = 1000000001;
    int textLayer   = 1000000003;
    int x_position = openborvariant("hresolution")/2;
    int y_position = 120;
    int z_layer = 400000000;
    
    //APPLY DRAWMETHOD EFFECTS
    setdrawmethod(NULL(),1,256,256,0,0,0,6);
    changedrawmethod(NULL(), "channelr", channel); //CHANNEL DRAWMETHOD SETTINGS
    changedrawmethod(NULL(), "channelg", channel); //CHANNEL DRAWMETHOD SETTINGS
    changedrawmethod(NULL(), "channelb", channel); //CHANNEL DRAWMETHOD SETTINGS
    
    //GAME TIMER
    if(openborvariant("pause") == 0 && openborvariant("in_options") != 1){ //CHECK IF THE GAME IS NOT PAUSED OR IN OPTIONS
        if(getglobalvar("levelTime") == "timeline"){
            drawsprite(getglobalvar("timeIcon"), xSprite, 263, iconLayer); //TIME ICON
            drawbox(xBox, yBox, (maxTime*hRes)/(maxTime), 3, barLayer, black); //BLACK BORDER
            drawbox(xBox, yBox+1, (maxTime*hRes)/(maxTime), 1, barLayer+1, red); //RED FILL
            drawbox(xBox, yBox+1, (time*hRes)/(maxTime), 1, barLayer+2, white); //WHITE BAR
        }
        else
        if(getglobalvar("levelTime") == "numeric"){
            drawsprite(getglobalvar("timeIcon"), xSprite, 249, iconLayer); //TIME ICON
            drawstring((hRes-strwidth(""+time/400, font0))/2, 256, font0, time/400, barLayer); //CLOCK
        }
        else
        if(getglobalvar("levelTime") == "both"){
            drawsprite(getglobalvar("timeIcon"), xSprite, 246, iconLayer); //TIME ICON
            drawstring((hRes-strwidth(""+time/400, font0))/2, 253, font0, time/400, barLayer); //CLOCK
            drawbox(xBox, yBox, (maxTime*hRes)/(maxTime), 3, barLayer, black); //BLACK BORDER
            drawbox(xBox, yBox+1, (maxTime*hRes)/(maxTime), 1, barLayer+1, red); //RED FILL
            drawbox(xBox, yBox+1, (time*hRes)/(maxTime), 1, barLayer+2, white); //WHITE BAR
        }
    }
    
    //"CONTINUE" SCREEN TIMER
    if(getglobalvar("activeText") == "continue"){
        if(openborvariant("game_time") <= (maxTime/10) && openborvariant("game_time") > 0){
            //setdrawmethod(NULL(),1,256,256,0,0,0,2);
            drawsprite(getglobalvar("back1"), 0, 0, backLayer);
            drawstring((hRes-strwidth("CONTINUE?", font1))/2+1, 120, font1, "CONTINUE?", textLayer);
            drawstring((hRes-strwidth(""+time/400, font1))/2+1, 138, font1, openborvariant("game_time")/400, textLayer);
            if(getlocalvar("image") == NULL()) //First, load a image and save into a variable if NULL()
            {
                setlocalvar("image", loadsprite("data/sprites/image.png"));
            }
            else //And then, draw the previously saved image if not NULL()
            {
                drawsprite(getlocalvar("image"), x_position, y_position, z_layer);
            }
        }else{
            setglobalvar("activeText", 0);
        }
    }
}

How can I use it without "game_time"?
 
Thanks for the correction, Kratus. But check with the compiled date of the engine in the log and it doesn't read "game_time".
It seems that you are using an old OpenBOR build, the "game_time" variant works from 4456+.

1665815829727.png

How can I use it without "game_time"?
If I'm not wrong, there's no equivalent variant for "game_time". The closest is the "elapsed_time", but works in a different way.

In fact this variant only works like a "trigger" to allow the countdown on the screen and to define its duration, but you can use any other conditions instead like a death of a specific character, or even creating a custom countdown script starting as soon as there's no players detected on the screen.

Here's an example:
C:
void main()
{
    float seconds  = 200; //THIS IS SAME AS 1 SECOND IN ENGINE CENTISECONDS, USED FOR CONVERSION PURPOSE
    float time    = openborvariant("elapsed_time")/seconds;
    float limit   = 10; //10 SECONDS LIMIT

    //START THE COUNTDOWN TIMER
    if(getlocalvar("countDown") == NULL())
    {
        setlocalvar("countDown", time+limit);
    }

    //DRAW INFO ON THE SCREEN DURING THE COUNTDOWN
    if(time < getlocalvar("countDown"))
    {
        int xPosition  = 100;
        int yPosition  = 100;
        int font        = 7;

        drawstring(xPosition, yPosition, font, getlocalvar("countDown")-time);
    }
}

 
Back
Top Bottom