Jump to content

Photo

Global Script - Scrolling Layers


  • Please log in to reply
29 replies to this topic

#1 kurt91

kurt91

    Follower of Destiny

  • Members
  • Real Name:Kurtis
  • Location:Eastern Washington University

Posted 09 May 2015 - 02:38 AM

I have a screen-wide fog effect that has the edges match up perfectly. I set it up to scroll diagonally using an FFC combo, but the effect breaks during screen transitions. I was told that making a global script to handle that would work, but I don't know how to do that.

 

Also, I want a scrolling background for another area. The background that I have doesn't cover the whole screen, though. It's maybe a quarter of a screen or so, but if I try tiling the entire thing for my map, I'll have to do every screen by hand to make it tile properly. I tried doing so, and nearly went insane. I realized that the scrolling effect that I had in mind for my fog effect would look amazing there as a moving background, and it would also hopefully keep me from having to tile nearly a full Interior-type map.

 

So, here's the request as I need it to keep it as versatile as possible.

 

I would like somebody to make a global scrolling script, with a built-in list that functions the same way as the AutomaticBigEnemy script or Moscowmodder's LttP Map script. The list would let me depict which DMap I need the script to apply to, what map/screen to get the image to scroll from, how tall and wide the image is (measured in combos) starting from the bottom-left corner of the screen, as well as scrolling direction (probably use an integer between 1 and 8, to cover cardinal and diagonal directions) and speed.

 

I know that it sounds very precise and possibly very complicated, but I was aiming for versatility so that a single script could be used for a variety of situations, as well as being able to be uploaded to the database for common use, since it seems like an effect that a lot of people would find useful rather than just me.

 

Is this something that somebody could please make for me? If the full setup is too difficult or not possible, could I simply get a version that only work for one single effect, and I could try to edit it for the other effects that I want to use?



#2 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 10 May 2015 - 04:30 AM

Send me the FFC script, and I'll send you back some global code.

For the most part, changing an FFC mto a global function is very simple, and straightforw3ard. You primarily need to have a condition that tells your global active scrript to carry out the instructions of the function, which would do exactly what the FFC does, with the following exceptions:

  • Arguments must be specified when calling the function, if any apply.
  • You can't modify the global function on the fly, as you could with an FFC. You can do it in other ways, but not with FFC commands.
  • You can't make determinations based on collision in any reasonably easy manner.
  • If the global function isn't using an FFC to do its effects, you'll lose FFC commands. I haven't tried to carry an FFC running globally across screens, but it may be possible to do that instead of using a function to do all of it.
  • You can however, trigger a global function using an FFC, and code the global function so that the FFC passes its arguments to it. Technically, you can do this with items too, so you can have an item that makes it stop raining, or changes anything that the global function allows you to pass to it.

I did exactly that, for jumping (i.e. height, gravity) in a side-scrolling test: Item sets global vars to change jump mechanics. An FFC can do the same.

The global function will otherwise, run every frame as long as its condition, or conditions, are satisfied. That means that you need a boolean series (array best for a series of weather conditions), or single int (variable, or array element) that tells the global script that it's raining, snowing, windy, or what have youthereafyer, whenever one of those conditions is true, the global script draws your effect (via combos, overlays, layers, screens, etc.) onto the layer you specify.

You could also possibly run the effect as an FFC script at all times, but that may also break your transitions.

I made day/night (and other time) cycle overlays, as well as dark room/lit room overlays using global commands, and was going to do the same for weather anyway.

 

The more that I think about it, the more certain I feel that as long as you run the FFC script before Waitdraw(), you don't even need to merge it into your global directly.

 

You could just do this:

const int FFC_WEATHER = 0; //Set this to FFC slot of your weather FFC.
bool isRaining = false;

global script active {
    void run(){
        while(true){
            if ( isRaining && !RainEffects ){
                RunFFCScript(FFC_WEATHER); //We want this before waitdraw.
            }
            
            ///Pre-Waitdraw commands.
            
            Waitdraw();
            
            ///Post-Waitdraw() commands.
            
            Waitframe();
        }
    }
}

bool RainEffects(){
    return FFCRunning(FFC_WEATHER);
}


bool FFCRunning(int ffcslot) {
    if ( FindFFCRunning(ffcslot) == 0 ){
        return false;
    }
    else {
        return true;
    }
}
       

Try adding those two functions, the constant, and that global boolean, to your global script, and add the code in the if statement before Waitdraw().

 

I'm pretty sure that should keep the FFC running at all times.

 

You'd need to define scrolling background here, as ZC doesn't have a normal layer beneath zero, and I don't think that doing Draw commands to layer -1 would work... FFCs can't draw 'under' either.

 

If it's for a sidescrolling game, or something, and you want to simulate parallax scrolling, you might be able to get away with a bitmap on-screen that always moved when the player moved, and that would indeed be a chore.

 

If you simply want to simulate motion, you can do that with combo cycling, but if you want horizontal combo updating that moves with the player, or even bitmap updating, whhich in all honesty I think would be just as difficult, you enter Z3 scrolling territory.

 

If you want an effect on layer 0 that moves with the player, that's plausible, but a full background just doesn't make any sense for that, so I'm not sure what you're trying to accomplish.

 

P.S. I forgot about the screen flags that allow you to invert layers 2 and 3. I suppose that is what you'd be doing, but setting that on every screen..oh joy.


Edited by ZoriaRPG, 10 May 2015 - 09:23 AM.


#3 kurt91

kurt91

    Follower of Destiny

  • Members
  • Real Name:Kurtis
  • Location:Eastern Washington University

Posted 10 May 2015 - 04:59 PM

EDIT: I apologize in advance for the wall of text. I'm just trying to clear up my request and make it as understandable as possible.

 

Okay, let me try to be a bit more clear. This is a single-screen fog overlay that is currently on Layer 5 for every screen of my forest. It's transparent, and the dithering effect is a two-frame animation, so the fog appears solid, but is even more transparent than normal, which also has the added benefit of helping disguise any transparency color issues that can come up due to how transparency is handled in the engine. However, the drawback is that every single tile of space on the screen is used with a unique combo. No combo is used more than once.

 

zelda003_zps5a36dece.png

(This is an old picture, and there is indeed a tile error on the absolute bottom of the screen shown. This has been fixed already.)

 

This FFC script allows me to make this layer scroll to the lower right, further smoothing the dithering effect visually as well as making the fog appear more natural. It's an incredibly pretty effect to see in-motion.

ffc script ScrollingMist{
    void run(){
        int x_position;
        int y_position;
        int xspeed = 1;
        int yspeed = 1;
        
        for (int i = 0; true; i = (i + 1) % 4){
            if ((i % 4) == 0){
                x_position = (x_position + xspeed) % 255;
                y_position = (y_position + yspeed) % 175;
            }
            Screen->DrawLayer(5, 8, 0x50, 0, x_position, y_position, 0, OP_TRANS);
            Screen->DrawLayer(5, 8, 0x50, 0, x_position, y_position - 176, 0, OP_TRANS);
            Screen->DrawLayer(5, 8, 0x50, 0, x_position - 256, y_position, 0, OP_TRANS);
            Screen->DrawLayer(5, 8, 0x50, 0, x_position - 256, y_position - 176, 0, OP_TRANS);
            Waitframe();
        }
    }
}

I didn't make this myself, it was made from a request I made a while back. Anyways, since it's an FFC script, the fog vanishes completely when you move between screens, and I was told that a global version of this script would fix the issue. Unfortunately, I don't know how to do so.

 

Now, this is a map of a later area of my quest. The layering appears fine in an image, but after fixing an issue that I noticed regarding the grey cliff tiles, I'm going to have to re-arrange the layers so that Layer 3 is drawn as a background. Considering the brown walkable tiles are currently drawn on the same layer as my background, it's going to be a huge pain.

 

zelda001_zpsumn3gjij.png

(Sorry for the huge image, it's the only one I have at the moment)

 

The problem here is that while it's a tiled background, the size of the area being tiled does not gracefully fit into a single screen, and it takes 10 unique screens until it tiles as seen in the map, and even then it still has issues in some spots where it doesn't line up right.

 

If I can use a similar effect as my fog overlay, except applied to a smaller source image and placed on a Layer-3-as-background, it would not only save me a huge amount of tiling work, but would add to the visual atmosphere of the area. Since it's a nice effect with a variety of possible uses, the script description that I requested before to make is a single universal multi-use script rather than a separate individual version made for each situation. This way, it would be easier to set up and get working, as well as be a very useful addition to the script database.

 

The idea is to mimic the script layout of a script like this...

// Main BigEnemy definition table. When adding more enemies that need to be bigger, repeat
// "BigEnemy" function for each extend enemy with the following arguments:
// 1. "n". it`s a pointer to affected enemy. Don`t change.
// 2. Enemy ID of affected enemy.
// 3. Draw X offset
// 4. Draw Y offset
// 5. Hitbox X offset
// 6. Hitbox Y offset
// 7. Hitbox width, in pixels.
// 8. Hitbox height, in pixels.
// 9. TileWidth, in tiles.
// 10. TileHeight, in tiles.
// 11. Custom animation flags.
void SetBigEnemySettings( npc n){
  //BigEnemy(n, 188, -32,-48,-32,-48,64,64,4,4,9);//Test Giant Goomba
    BigEnemy(n, 191, 0,-16, 0, 0, 16, 16, 1, 2, 0); //Ghost Armor (GFX: 19 Tall, 16 Wide   HIT: 16 Tall, 16 Wide)
    BigEnemy(n, 190,-4,-2, 0, 0, 23, 20, 2, 2, 0); //Purple Slime 
    BigEnemy(n, 177, 0, 0, 0, 0, 32, 32, 2, 2, 0); //Giant Squid
    BigEnemy(n, 180,-8,-8,-8,-8, 32, 32, 2, 2, 0); //Corrupt Fairy
    BigEnemy(n, 183,-8,-8,-8,-8, 32, 32, 2, 2, 9); //Twin Scorpions
    BigEnemy(n, 187, 0, 0, 5, 7, 21, 24, 2, 2, 0); //Hero's Shade Core
}

...and use a definition table to input what layer is being used for the effect, how big the tiled image is, and what direction to set movement to, so that it would be a single universal script. Is that possible, or not? If not, then may I simply request the fog version, with directions on how to modify it to work for my other background effect?


Edited by kurt91, 10 May 2015 - 05:01 PM.


#4 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 10 May 2015 - 09:55 PM

Try this:

int x_position = 0;
int y_position = 0;
int xspeed = 1;
int yspeed = 1;


int fogTimer = 60; //Fog X and Y move at 1 pixel per second.

bool isFoggy = true; //You need to set this to false in areas without fog, and true in areas with fog.

global script active {
    void run(){
        while(true){
            if ( isFoggy ){
                MoveFog();
                DrawFog();
            }
            
            ///Pre-Waitdraw commands.
            
            Waitdraw();
            
            ///Post-Waitdraw() commands.
            
            Waitframe();
        }
    }
}

void UpdateFogLocation(){
    

void MoveFog(){
    if ( fogTimer > 0 ) {
        fogTimer--;
    }
    else if ( fogTimer == 0 ) {
        if ( xspeed < 255 ) {
            xspeed++;
        }
        else if ( xspeed == 255 ) {
            xspeed = 0;
        }
        if ( yspeed < 175 ) {
            yspeed++;
        }
        else if ( yspeed == 175 ) {
            yspeed = 0;
        }
        fogTimer = 60;
    }
}


    

void DrawFog(){
    Screen->DrawLayer(5, 8, 0x50, 0, x_position+xspeed, y_position+yspeed, 0, OP_TRANS); //Note: You can define transparent values from 0 to 100.
    Screen->DrawLayer(5, 8, 0x50, 0, x_position+xspeed, y_position+yspeed - 176, 0, OP_TRANS);
    Screen->DrawLayer(5, 8, 0x50, 0, x_position+xspeed - 256, y_position+yspeed, 0, OP_TRANS);
    Screen->DrawLayer(5, 8, 0x50, 0, x_position+xspeed - 256, y_position+yspeed - 176, 0, OP_TRANS);
}
 

If that works as desired, you could change Screen->Drawlayer( 5, 8, etc... to

const int FOGLAYER = 5;
const int BGLAYER = 3;
 
void DrawFog(int layer){
    Screen->DrawLayer(layer, 8, 0x50, 0, x_position+xspeed, y_position+yspeed, 0, OP_TRANS); //Note: You can define transparent values from 0 to 100.
    Screen->DrawLayer(layer, 8, 0x50, 0, x_position+xspeed, y_position+yspeed - 176, 0, OP_TRANS);
    Screen->DrawLayer(layer, 8, 0x50, 0, x_position+xspeed - 256, y_position+yspeed, 0, OP_TRANS);
    Screen->DrawLayer(layer, 8, 0x50, 0, x_position+xspeed - 256, y_position+yspeed - 176, 0, OP_TRANS);
}
 

Then make if/else statements based on if you want it to be fog, or clouds, and call DrawFog as:

DrawFog(FOGLAYER);

...and...

DrawFog(BGLAYER);

...respectively.

 

If the movement isn't right, you may want to pass that on back to whomever coded the FFC for you, so that he can adjust it to the parameters that you want. The above is merely a framework for converting an FFC into a global function. You need to have the timers as globals though, for it to work; instead of local vars inside an FFC.


Edited by ZoriaRPG, 10 May 2015 - 10:08 PM.


#5 kurt91

kurt91

    Follower of Destiny

  • Members
  • Real Name:Kurtis
  • Location:Eastern Washington University

Posted 19 May 2015 - 07:05 PM

I'm sorry for taking so long to reply.

 

Anyways, I'm looking at the script you have written down, and I don't understand how I set it to only work on specific DMaps. Am I placing an FFC on every screen to tell it that there's meant to be fog or a moving background? I'm doing it on a per-entire-DMap basis, so is there a way to check if the player is on the specified DMap and if so, activate the desired effect?



#6 justin

justin

    Adept

  • Members

Posted 19 May 2015 - 07:58 PM

he didn't give you a way in that script to tell which screens are foggy.  but did provide a variable isFoggy to tell the script when it is supposed to be foggy.  you'd need to script something to set isFoggy to true or false.

 

a simple ffc script on each foggy screen

ffc script Foggy
{
 void run()
 {
  while(true)
  {
   isFoggy = true;
   Waitframe();
  }
 }
}
 
//and then you'd include a statement in your global loop before the Waitframe(); setting isFoggy to false

or you could do it based on dmap if the fogginess is across a whole dmap.  using one of the DMap script flags

// in global loop before the if (isFoggy) {  line
isFoggy = GetDMapFlag(Game->GetCurDMap(), DMF_SCRIPT1);
 
// DMF_SCRIPT can be anything from 1-5 depending on what you choose in the editor.

or instead of ffcs, you could use a script screen flag.  on the second page of your screen flags, under misc you have 5 script screen flags.  set it, and put this in your global loop

 

// in global loop before the if (isFoggy) {    line
if( ScreenFlag(SF_MISC,100b) == 1) isFoggy = true;
 
// a little more complicated to modify, 100b is the third flag in the Misc list, ie. Script1.  for flag Script2 you'd change 100b to 1000b. Script 3 = 10000b, etc.

Edited by justin, 19 May 2015 - 08:11 PM.


#7 kurt91

kurt91

    Follower of Destiny

  • Members
  • Real Name:Kurtis
  • Location:Eastern Washington University

Posted 22 June 2015 - 08:53 PM

So, now that I'm done with college classes for now, I have more time to sit down and work on this. I put together a global script, but now it freezes whenever I enter the forest. Here's what I did...

 

global script Slot_2{
    void run(){
        //Initial startup: set Link's level to 1, not 0
        if(Game->Counter[CR_LEVEL] <= 0){
            Game->MCounter[CR_LEVEL] = EXP_MAX_LEVEL;
            Game->Counter[CR_LEVEL] = 1;
        }
        bool LinkHasDrowned = false;
        bool shieldOn;
        int LinkHP_temp = Link->HP;
        bool Link_damage_variance = true;
  DamageNumbersInitialize();
  StartGhostZH();
 
        while(true){
            Game->Counter[CR_SCRIPT2] = Link->HP;
            Game->Counter[CR_SCRIPT3] = Link->MP;
            Game->Counter[CR_SCRIPT4] = Link->MaxHP;
            Game->Counter[CR_SCRIPT5] = Link->MaxMP;
            if ( LinkHasDrowned == true && Link->Action != LA_DROWNING )
                LinkHasDrowned = false;
            if( Link->Action == LA_DROWNING && LinkHasDrowned == false){
                LinkHasDrowned = true;
                Game->PlaySound(LinkDrownSFX);
            }
            NoMap();
            if ( Link->PressEx1 ){
                Link->PressEx1 = false;
                freezeScreen();
                showMap();
                unfreezeScreen();
            }
            if( !shieldOn && shieldItem ){ //Enable shield when using dummy
                shieldOn=true; //Set shield state to on
                Link->Item[shieldItem]=true; //Give the shield
                Game->PlaySound(SFX_GBSHIELD); //Play the sound
            }
            else if( ( (shieldButton && !Link->InputA)||(!shieldButton && !Link->InputB)) //When button is released
                    && shieldOn){ //And shield is still on
                Link->Item[shieldItem]=false; //Remove shield
                shieldItem = 0; //Reset shield item variable
                shieldOn = false; //Set shield state to off
            }
            EnemyHitSounds();
            AutoBigEnemy();
            HealthBarTileBasedGlobalFunction();
            UpdateGhostZH1();
            LayerScroll();
            Waitdraw();
            DrawHitboxes(); //DEBUGGING SCRIPT
            UpdateGhostZH2();
      EnemyDamageNumbers();
 LinkHP_temp = LinkDamageNumbers(LinkHP_temp, Link_damage_variance);
 DamageNumbers();
 booting = StompBooting();
            Waitframe();
        }
    }
}
 
void LayerScroll(){
int LayerMovement;
 
LayerMovement = Game->GetCurDMap();
if (LayerMovement == 3){
ForestMist();
}
}
 
void ForestMist(){
int x_position;
     int y_position;
     int xspeed = 1;
     int yspeed = 1;
        
     for (int i = 0; true; i = (i + 1) % 4){
         if ((i % 4) == 0){
             x_position = (x_position + xspeed) % 255;
             y_position = (y_position + yspeed) % 175;
         }
         Screen->DrawLayer(5, 8, 0x50, 0, x_position, y_position, 0, OP_TRANS);
         Screen->DrawLayer(5, 8, 0x50, 0, x_position, y_position - 176, 0, OP_TRANS);
         Screen->DrawLayer(5, 8, 0x50, 0, x_position - 256, y_position, 0, OP_TRANS);
         Screen->DrawLayer(5, 8, 0x50, 0, x_position - 256, y_position - 176, 0, OP_TRANS);
    }
    Waitframe();
}

 

I put my additional script, LayerScroll(), before WaitDraw(). LayerScroll simply uses the current DMap to see if it needs to activate layer scrolling, and then hands the actual task to the appropriate script, this case being ForestMist(). Since it comes before WaitDraw() as well as WaitFrame(), I didn't think it would freeze upon entering the appropriate DMap. I figured that maybe I didn't work out the WaitFrame() placement correctly, so I added an additional one inside the ForestMist() script as well. It still freezes. Any idea what I did wrong?



#8 ywkls

ywkls

    Master

  • Members

Posted 22 June 2015 - 10:49 PM

I don't know if this is the case or not (I'm no scripting expert) but this is probably the source of your problems.

for (int i = 0; true; i = (i + 1) % 4){
         if ((i % 4) == 0){
             x_position = (x_position + xspeed) % 255;
             y_position = (y_position + yspeed) % 175;
         }
         Screen->DrawLayer(5, 8, 0x50, 0, x_position, y_position, 0, OP_TRANS);
         Screen->DrawLayer(5, 8, 0x50, 0, x_position, y_position - 176, 0, OP_TRANS);
         Screen->DrawLayer(5, 8, 0x50, 0, x_position - 256, y_position, 0, OP_TRANS);
         Screen->DrawLayer(5, 8, 0x50, 0, x_position - 256, y_position - 176, 0, OP_TRANS);
    }

By setting the second argument of the for loop to true, it runs indefintely. Once that for loop is activated, I think it is what is causing this freeze because nothing else will run. To prevent this, place a Waitframe() inside the end of that for loop.

 

I've used a few for loops like that myself to create circular movement that goes on forever, and always included that extra waitframe there.; The other one that you have after that loop is unnecessary. (It could also be freezing things.)

 

Another tip is that if you ever want a perpetual for loop like that to do anything else, like stop; is that you need to create conditional arguments inside the loop to bring it to a halt. Once those conditions are true, it would call the break command.. 



#9 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 22 June 2015 - 10:55 PM

You have to modify that function. Since it's in your global now instead of confined to its own FFC, you don't even need a loop in there. No waitframe, either. You'll need to pass the counter variable to it, though (and have it return that value so it can change from frame to frame).



#10 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 23 June 2015 - 12:58 AM

I may as well mention, that there is a header for scrolling/panning effects. (Not Z3 scrolling!)

 

It produces some utility functions for cinematic panning, but I don't know if I'm permitted to redist it, or if the author wants it in the public domain.

 

I will ask, and paint the author to this thread...



#11 kurt91

kurt91

    Follower of Destiny

  • Members
  • Real Name:Kurtis
  • Location:Eastern Washington University

Posted 02 August 2015 - 10:28 PM

Been a bit, hasn't it?

 

There are two new issues that I just noticed while testing my quest. I finally got the script to work, with the mist sticking around during screen transitions without freezing everything. It looks just as pretty as I had hoped. Unfortunately, I can't get it to stop when I leave the forest. I tried putting another DMap check inside the loop, but it still keeps going.

 

The other problem is that this script somehow breaks the Simple GB Shield as well as the Automatic BigEnemy script that I'm using. The shield simply doesn't raise at all, although other B Button items work just fine. The BigEnemy script stops working entirely, with the enemies graphics and hitboxes shrunk back down to normal. Considering I've got multiple bosses placed in the woods, this is a big issue.

 

Other scripts that stopped working are the debugging "show hitboxes" script that I'm using, (It's really helpful for making sure BigEnemy hitbox adjustments are lined up properly.) as well as the Enemy HP Meters script. I'm going to assume at this point that it's also affecting any script that has to draw to the screen at any point, since it doesn't affect my Apple script. (Essentially an item script that lets me carry up to five items that act like Heart Containers when used. Funny how my very first badly-programmed script works perfectly, but the better-made ones are breaking!)

 

My current mist script looks like this now...

 
global script Slot_2{
    void run(){
        //Initial startup: set Link's level to 1, not 0
        if(Game->Counter[CR_LEVEL] <= 0){
            Game->MCounter[CR_LEVEL] = EXP_MAX_LEVEL;
            Game->Counter[CR_LEVEL] = 1;
        }
        bool LinkHasDrowned = false;
        bool shieldOn;
        int LinkHP_temp = Link->HP;
        bool Link_damage_variance = true;
  DamageNumbersInitialize();
  StartGhostZH();
 
        while(true){
            Game->Counter[CR_SCRIPT2] = Link->HP;
            Game->Counter[CR_SCRIPT3] = Link->MP;
            Game->Counter[CR_SCRIPT4] = Link->MaxHP;
            Game->Counter[CR_SCRIPT5] = Link->MaxMP;
            if ( LinkHasDrowned == true && Link->Action != LA_DROWNING )
                LinkHasDrowned = false;
            if( Link->Action == LA_DROWNING && LinkHasDrowned == false){
                LinkHasDrowned = true;
                Game->PlaySound(LinkDrownSFX);
            }
            NoMap();
            if ( Link->PressEx1 ){
                Link->PressEx1 = false;
                freezeScreen();
                showMap();
                unfreezeScreen();
            }
            if( !shieldOn && shieldItem ){ //Enable shield when using dummy
                shieldOn=true; //Set shield state to on
                Link->Item[shieldItem]=true; //Give the shield
                Game->PlaySound(SFX_GBSHIELD); //Play the sound
            }
            else if( ( (shieldButton && !Link->InputA)||(!shieldButton && !Link->InputB)) //When button is released
                    && shieldOn){ //And shield is still on
                Link->Item[shieldItem]=false; //Remove shield
                shieldItem = 0; //Reset shield item variable
                shieldOn = false; //Set shield state to off
            }
            EnemyHitSounds();
            AutoBigEnemy();
            HealthBarTileBasedGlobalFunction();
            UpdateGhostZH1();
            LayerScroll();
            Waitdraw();
            DrawHitboxes(); //DEBUGGING SCRIPT
            UpdateGhostZH2();
      EnemyDamageNumbers();
 LinkHP_temp = LinkDamageNumbers(LinkHP_temp, Link_damage_variance);
 DamageNumbers();
 booting = StompBooting();
            Waitframe();
        }
    }
}
 
void LayerScroll(){
int LayerMovement;
 
LayerMovement = Game->GetCurDMap();
if (LayerMovement == 3){
ForestMist();
}
}
 
void ForestMist(){
int x_position;
     int y_position;
     int xspeed = 1;
     int yspeed = 1;
     int LayerMovement = Game->GetCurDMap();
        
     for (int i = 0; true; i = (i + 1) % 4){
         if (LayerMovement == 3){
             if ((i % 4) == 0){
                 x_position = (x_position + xspeed) % 255;
                 y_position = (y_position + yspeed) % 175;
             }
             Screen->DrawLayer(5, 8, 0x50, 0, x_position, y_position, 0, OP_TRANS);
             Screen->DrawLayer(5, 8, 0x50, 0, x_position, y_position - 176, 0, OP_TRANS);
             Screen->DrawLayer(5, 8, 0x50, 0, x_position - 256, y_position, 0, OP_TRANS);
             Screen->DrawLayer(5, 8, 0x50, 0, x_position - 256, y_position - 176, 0, OP_TRANS);
             Waitframe();
         }
     }
}
 

(I didn't copy any code that looked unnecessary for this issue. If it helps, I can upload my entire script buffer, or just upload my quest as-is.)


Edited by kurt91, 02 August 2015 - 10:33 PM.


#12 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 02 August 2015 - 10:47 PM

ForestMist() has the same problem it had before. A good rule of thumb is that any function called by the global script should not have a Waitframe in it. You've also got an infinite loop in there, meaning it will get stuck and never return to the main global loop. I made that fog scrolling as an FFC script, remember, hence the infinite for loop. That can just be removed entirely. Since it's a function, none of the local variables can be retained frame to frame, so the easy way to fix that is to make everything a global variable. Then the function can change them no problem. The new function might look something like this.

void ForestMist(){
//int x_position; make this global instead
//int y_position; this too
     int xspeed = 1;
     int yspeed = 1;
     int LayerMovement = Game->GetCurDMap();
        
 
         if (LayerMovement == 3){
 
                 x_position = (x_position + xspeed) % 255;
                 y_position = (y_position + yspeed) % 175;

             Screen->DrawLayer(5, 8, 0x50, 0, x_position, y_position, 0, OP_TRANS);
             Screen->DrawLayer(5, 8, 0x50, 0, x_position, y_position - 176, 0, OP_TRANS);
             Screen->DrawLayer(5, 8, 0x50, 0, x_position - 256, y_position, 0, OP_TRANS);
             Screen->DrawLayer(5, 8, 0x50, 0, x_position - 256, y_position - 176, 0, OP_TRANS);

     }
}

Without the i variable, this mist will also go quite fast, so you'll either have to replicate that in your global loop or just lower the x and y speeds to less than 1.



#13 kurt91

kurt91

    Follower of Destiny

  • Members
  • Real Name:Kurtis
  • Location:Eastern Washington University

Posted 02 August 2015 - 11:13 PM

It works great now! A slight bit of lag, though. Makes it so Link moves more like he did in the GB games rather than the faster NES game. Noticeable, but it's a constant lowered speed rather than lag spikes, so it's still playable. The only odd thing about it is that now the fog overlaps itself by a pixel when it didn't before, but I should be able to tweak that through the script.

 

Thank you very much for the help.

 

EDIT: Come to think of it, I think that the lag may be because it's checking the current DMap on every frame rather than when a new screen is loaded. Is it possible to keep the animation going every frame as it currently is, but only check the DMap once per screen? That may fix the speed.

 

EDIT II: After tweaking values in the positioning, I'm thinking that the reason that it separates may be connected to the frame rate. When I lowered values by 1, there was additional overlap. When I increased them by one, there's a visible line of separation between them, that flickers every other frame. Does that make any sense to you?


Edited by kurt91, 02 August 2015 - 11:23 PM.


#14 Deedee

Deedee

    Bug Frog Dragon Girl

  • Moderators
  • Real Name:Deedee
  • Pronouns:She / Her, They / Them
  • Location:Canada

Posted 03 August 2015 - 01:43 AM

I don't think you really needed a global script for that. In ScreenData, there is an option to load the screens script when scrollin onto the screen. Set it on every screen in the forest and the script (and therefore the fog) should work in screen transitions.

If you need the global loop, then add a bool inside the main loop (near the top), have the bool be set to false after checking dmap, make a conditional statement around the check asking if the bool is true, and set the bool to true if he is scrolling screens (Link-›Action == LA_SCROLLING).

I don't think you really needed a global script for that. In ScreenData, there is an option to load the screens script when scrollin onto the screen. Set it on every screen in the forest and the script (and therefore the fog) should work in screen transitions.

If you need the global loop, then add a bool inside the main loop (near the top), have the bool be set to false after checking dmap, make a conditional statement around the check asking if the bool is true, and set the bool to true if he is scrolling screens (Link-›Action == LA_SCROLLING).

#15 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 03 August 2015 - 02:00 AM

Try moving LayerScroll() to after Waitdraw(). Not guaranteed to do anything at all, but worth trying. Checking the DMap doesn't seem like it should slow anything down. Try commenting out the function call in your global and see if there's still lag. If there is, try doing the same to other functions, one at a time, to isolate the source.

 

Dimentio, the screen init flag won't work for this. All that flag does is make a script run for one frame on screen init. It's great for making combo changes without the player seeing them, but it won't work for draw functions that need to be called continuously.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users