SOLVED Quakeframe sometimes not shaking

Viper Snake

Member
Sometimes quakeframe fails to the shake screen. I'm on the latest version of OpenBOR, but I've always had this problem with every version I've used. Here is the quake entity that I spawn:

Code:
name    	quake_heavy
type		none
cantgrab 	1
nodrop  	2
offscreenkill	9999
antigravity 100
animationscript data/scripts/script.c

anim	idle
	loop	0
	delay	1
	offset  0 0
	quakeframe 1 1 -8
	frame	data/chars/marianne/blank.png
	delay	15
	frame	data/chars/marianne/blank.png
	@cmd	suicide
	frame	data/chars/marianne/blank.png
 
you dont have enough frames for shake, try adding more frames, or changing 8 in quake command to something like 3 but that wotn be too shakey.change that delay 15 and its frame, try to have at least 8 frames.
 
Yeah "quakeframe" quaking is quite tricky as it's binded and synced to the animation.

For more control and precision it's a good thing to have a scripted quake system.
 
bWWd said:
you dont have enough frames for shake, try adding more frames, or changing 8 in quake command to something like 3 but that wotn be too shakey.change that delay 15 and its frame, try to have at least 8 frames.

I tried adding lots of extra frames and different amounts of delay but it still sometimes fails.

Piccolo said:
Yeah "quakeframe" quaking is quite tricky as it's binded and synced to the animation.

For more control and precision it's a good thing to have a scripted quake system.

Could I get an example please? The only solution I've seen on Chrono Crash was using script to spawn an entity with quakeframe.
 
Viper Snake said:
Could I get an example please? The only solution I've seen on Chrono Crash was using script to spawn an entity with quakeframe.

White Dragon developped one, and I use a custom version based on his code.

Here's both

Code:
void quake() {
    int loop = getglobalvar("quake_loop");
    int refresh_time = getglobalvar("quake_refreshtime");
    int intensity = getglobalvar("quake_intensity");

    if ( loop != NULL() && refresh_time != NULL() && intensity != NULL() && openborvariant("in_level") ) {
        int currentTime = openborvariant("elapsed_time");
	
	int lastQuakeTime = getlocalvar("last_quake_time");


	if (lastQuakeTime == NULL() || currentTime - lastQuakeTime >= refresh_time ) {
	    log("\nQuake !");
            changelevelproperty("quake", intensity);
	    setlocalvar("last_quake_time", currentTime );

            if ( loop > 1 ) --loop;
            else loop = NULL();

            setglobalvar("quake_loop", loop);

            if ( loop == NULL() ) {
                setglobalvar("quake_refreshtime", NULL());
                setglobalvar("quake_intensity", NULL());
		setlocalvar("last_quake_time", NULL());
            }
        }
        
    } // fine if loop
}

Code:
// From White Dragon
void quakeWD() {
    int loop = getglobalvar("quake_loop");
    int refresh_time = getglobalvar("quake_refreshtime");
    int intensity = getglobalvar("quake_intensity");

    if ( loop != NULL() && refresh_time != NULL() && intensity != NULL() && openborvariant("in_level") ) {
        int time = openborvariant("elapsed_time");
        int ETA = refresh_time*loop;
	
// 	int finishTime = getlocalvar("finish_quake_time");

        if ( getlocalvar("finish_quake_time") == NULL() ) setlocalvar("finish_quake_time",get_next_time(ETA));

        if ( time%refresh_time == 0 ) {
// 	if (finishTime == NULL() || finishTime - time < 0 ) {
		 log("\nQuake !");
            changelevelproperty("quake", intensity);
	    setlocalvar("finish_quake_time",time+ ETA);

            if ( loop > 0 ) --loop;
            else loop = NULL();
            if ( time > getlocalvar("finish_quake_time") ) loop = NULL();

            setglobalvar("quake_loop", loop);

            if ( loop == NULL() ) {
                setglobalvar("quake_refreshtime", NULL());
                setglobalvar("quake_intensity", NULL());
                setlocalvar("finish_quake_time", NULL());
            }
        }
        if ( time > getlocalvar("finish_quake_time") ) {
            setglobalvar("quake_loop", NULL());
            setglobalvar("quake_refreshtime", NULL());
            setglobalvar("quake_intensity", NULL());
            setlocalvar("finish_quake_time", NULL());
        }
    } // fine if loop
}

int get_next_time(int next_time) {
	int time = openborvariant("elapsed_time");
	int MAX_INT = openborconstant("MAX_INT");

	if ( next_time != (time+next_time)-time ) {
        changeopenborvariant("elapsed_time", 0);
        time = openborvariant("elapsed_time");
	}

    if ( time < 0 ) {
        changeopenborvariant("elapsed_time", 0);
        time = openborvariant("elapsed_time");
    }

    if ( time+next_time >= MAX_INT ) {
        changeopenborvariant("elapsed_time", 0);
        time = openborvariant("elapsed_time");

    }

    return (time+next_time);
}


You need either one of those (they work a bit differently) and call them in your updated.c main function.


Then you call this function :

Code:
void quake(int loop, int delay, int force){
	setglobalvar("quake_loop", loop);
	setglobalvar("quake_refreshtime", delay);
	setglobalvar("quake_intensity", force);
}

in your entity model file to set a per frame quake.
 
why not use the bor engine its easier
quakeframe has something to do with delay and number of frame has mentioned above... this way could work fine... it shakes the screen 10 times in 5 pixels...
anim idle
loop 0
delay 5
offset  0 0
quakeframe 1 10 5
frame data/chars/marianne/blank.png #0
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png #10
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
@cmd suicide
frame data/chars/marianne/blank.png

also if you have 3 frames in the animation and set quakeframe to 10 it will shake but only the frist time after that quakeframe will not work any longer until the next level
 
jonsilva said:
why not use the bor engine its easier

As I said earlier, "for more control and precision".

And once the scripted system is set up, it's arguably easier to use it with a @cmd call (that create a custom quake effect) than spawning a subentity (that create a fixed quake effect). As with almost anything scripted, setting it up is a long term investement.
 
jonsilva said:
why not use the bor engine its easier
quakeframe has something to do with delay and number of frame has mentioned above... this way could work fine... it shakes the screen 10 times in 5 pixels...
anim idle
loop 0
delay 5
offset  0 0
quakeframe 1 10 5
frame data/chars/marianne/blank.png #0
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png #10
frame data/chars/marianne/blank.png
frame data/chars/marianne/blank.png
@cmd suicide
frame data/chars/marianne/blank.png

also if you have 3 frames in the animation and set quakeframe to 10 it will shake but only the frist time after that quakeframe will not work any longer until the next level

Thank you for this, I understand how to use quakeframe much better now.

Piccolo said:
Viper Snake said:
Could I get an example please? The only solution I've seen on Chrono Crash was using script to spawn an entity with quakeframe.

White Dragon developped one, and I use a custom version based on his code.

Here's both

Code:
void quake() {
    int loop = getglobalvar("quake_loop");
    int refresh_time = getglobalvar("quake_refreshtime");
    int intensity = getglobalvar("quake_intensity");

    if ( loop != NULL() && refresh_time != NULL() && intensity != NULL() && openborvariant("in_level") ) {
        int currentTime = openborvariant("elapsed_time");
	
	int lastQuakeTime = getlocalvar("last_quake_time");


	if (lastQuakeTime == NULL() || currentTime - lastQuakeTime >= refresh_time ) {
	    log("\nQuake !");
            changelevelproperty("quake", intensity);
	    setlocalvar("last_quake_time", currentTime );

            if ( loop > 1 ) --loop;
            else loop = NULL();

            setglobalvar("quake_loop", loop);

            if ( loop == NULL() ) {
                setglobalvar("quake_refreshtime", NULL());
                setglobalvar("quake_intensity", NULL());
		setlocalvar("last_quake_time", NULL());
            }
        }
        
    } // fine if loop
}

Code:
// From White Dragon
void quakeWD() {
    int loop = getglobalvar("quake_loop");
    int refresh_time = getglobalvar("quake_refreshtime");
    int intensity = getglobalvar("quake_intensity");

    if ( loop != NULL() && refresh_time != NULL() && intensity != NULL() && openborvariant("in_level") ) {
        int time = openborvariant("elapsed_time");
        int ETA = refresh_time*loop;
	
// 	int finishTime = getlocalvar("finish_quake_time");

        if ( getlocalvar("finish_quake_time") == NULL() ) setlocalvar("finish_quake_time",get_next_time(ETA));

        if ( time%refresh_time == 0 ) {
// 	if (finishTime == NULL() || finishTime - time < 0 ) {
		 log("\nQuake !");
            changelevelproperty("quake", intensity);
	    setlocalvar("finish_quake_time",time+ ETA);

            if ( loop > 0 ) --loop;
            else loop = NULL();
            if ( time > getlocalvar("finish_quake_time") ) loop = NULL();

            setglobalvar("quake_loop", loop);

            if ( loop == NULL() ) {
                setglobalvar("quake_refreshtime", NULL());
                setglobalvar("quake_intensity", NULL());
                setlocalvar("finish_quake_time", NULL());
            }
        }
        if ( time > getlocalvar("finish_quake_time") ) {
            setglobalvar("quake_loop", NULL());
            setglobalvar("quake_refreshtime", NULL());
            setglobalvar("quake_intensity", NULL());
            setlocalvar("finish_quake_time", NULL());
        }
    } // fine if loop
}

int get_next_time(int next_time) {
	int time = openborvariant("elapsed_time");
	int MAX_INT = openborconstant("MAX_INT");

	if ( next_time != (time+next_time)-time ) {
        changeopenborvariant("elapsed_time", 0);
        time = openborvariant("elapsed_time");
	}

    if ( time < 0 ) {
        changeopenborvariant("elapsed_time", 0);
        time = openborvariant("elapsed_time");
    }

    if ( time+next_time >= MAX_INT ) {
        changeopenborvariant("elapsed_time", 0);
        time = openborvariant("elapsed_time");

    }

    return (time+next_time);
}


You need either one of those (they work a bit differently) and call them in your updated.c main function.


Then you call this function :

Code:
void quake(int loop, int delay, int force){
	setglobalvar("quake_loop", loop);
	setglobalvar("quake_refreshtime", delay);
	setglobalvar("quake_intensity", force);
}

in your entity model file to set a per frame quake.

This also worked perfectly for me, thank you for sharing.
 
Back
Top Bottom