Jump to content

Photo

Combining Newbie Boss with other Global scripts?


  • Please log in to reply
12 replies to this topic

#1 Peteo

Peteo

    Back in Business!

  • Members
  • Real Name:Pete
  • Location:Finland

Posted 03 January 2020 - 02:27 PM

Hey guys, it's your script noob here again. Tried to find the answer myself, but no luck.

 

I really want to use the Newbie Boss Script to spice up my upcoming quest, but how the heck do I combine it with any other global script? Can't figure it out.

 

When I take a look at the script that comes with the Newbie Boss quest sample, there is no global script there to be seen, only the ffc script EZBoss is there. The Newbie Boss setup section says "you also need the GhostZHActiveScript (included in ghost.zh) in your Active global script slot."

So the GhostZHActiveScript loads fine into my global script slot but how do I combine that script with other global scripts when I can't find this GhostZHActiveScript anywhere from the script?



#2 Moosh

Moosh

    Tiny Little Questmaker

  • ZC Developers

Posted 04 January 2020 - 04:28 AM

Alright, so if you've downloaded ghost.zh (or have any modern version of ZC where it comes pre-packaged) the global script is in the ghost_zh/2.8/scripts.z. To combine global scripts you do need a little bit of ZScript understanding. Fortunately it's not too hard once you get used to it. The Active Global script has four different parts:

//Everything outside the script is global space, where constants, function definitions, and global variables go

global script Main2
{
	void run()
	{
		
		//Initialization goes here
		
		while(true)
		{
			//Update part 1 goes here
			
			Waitdraw();
			
			//Update part 2 goes here
			
			Waitframe();
		}
	}
}
  • Global space: Used by functions(), CONSTANTS, and GlobalVariables. This tends to be the biggest part of the script if it's well written because for organization purposes, we want the global script itself to be as clean and compact as possible.
  • Init: Everything between void run(){ and while(true){. This part of the script runs on the first frame whenever the game starts after you die, F6, or load a file. It's used for initializing data used by the script. 
  • Update 1: Everything from while(true){ to Waitdraw();. If a script doesn't have Waitdraw(); it can be assumed that everything there goes in this section. Stuff here happens every frame.
  • Update 2: Everything from Waitdraw(); to Waitframe();. This is the same as above but happens at a different point in the gameplay loop and is required for some scripts to work properly. Among other things it runs after the player's inputs have been processed and moved Link for the frame, so scripts that handle Link's position will rely on this.

 

A well written script like the ghost.zh one will have all of its instructions condensed into nice clean update function calls that you can paste into the same parts of the script to combine them. With the less well written scripts out there the logic is still the same but you'll have to contend with copying bigger blocks of ZScript around. Let us know if you run into any such cruddy global scripts, since there's likely a better one out there, or a better one could be made. 

 

If you find yourself having trouble still, there is a tool that somewhat automates the process, though I still recommend trying to combine scripts manually first. The tool is somewhat hackish and no substitute for a human touch. 

 

Lastly, whichever method you go with, you should save constant backups both online and offline. Losing or breaking script files is the new quest corruption for the modern era.


  • ShadowTiger likes this

#3 Peteo

Peteo

    Back in Business!

  • Members
  • Real Name:Pete
  • Location:Finland

Posted 04 January 2020 - 08:32 AM

Allright, found the global script from the ghost_zh/2.8/scripts.z.  Had to download the latest ZC Alpha to get this file (wasn't included with ZC 2.53 which I've been using)

global script GhostZHActiveScript
{
    void run()
    {
        InitializeGhostZHData();

        while(true)
        {
            UpdateGhostZHData();
            UpdateEWeapons();
            CleanUpGhostFFCs(); // Only needed if __GH_USE_DRAWCOMBO is 0

            Waitdraw();
            
            AutoGhost();
            DrawGhostFFCs();

            Waitframe();
        }
    }
}

So I just take this global script and combine it with my other global scripts, rename it to something like "AllGlobalscripts" and forget about the GhostZHActiveScript and instead assign this new "AllGlobalscripts" as my global script, right?

 

Now I have read a guide how to combine Global scripts and I think it is quite simple and self explanatory when the scripts are either simple of very similar. But I still want to make sure I get it right. So let's say I was to combine a Bombs Shake Screen global script and a Shield Got Eaten Message global script with the GhostZHActiveScript. Would it look like this?

 

Here's the global part of the bomb script

global script Active {
    void run(){
        while(true){
            BombsScreenShake(); //put this line into your global loop (to combine this script with your global script)
            Waitframe();
        }
    }
}

Here's the global part of "you lost your shield" script

global script check_for_shield_vanish{
     void run(){
         while(true){
               waitframe_give_message_if_shield_vanished(); //this is the shield code, replaces the normal waitframe
          }
    }
}

And here's how I'd combine them. Did I do it right? Or should I only have one waitframe there (from the shield script)?

global script AllGlobalscripts
{
    void run()
    {
        InitializeGhostZHData();

        while(true)
        {
	    BombsScreenShake(); //put this line into your global loop (to combine this script with your global script)
            waitframe_give_message_if_shield_vanished(); //this is the shield code, replaces the normal waitframe
            UpdateGhostZHData();
            UpdateEWeapons();
            CleanUpGhostFFCs(); // Only needed if __GH_USE_DRAWCOMBO is 0

            Waitdraw();
            
            AutoGhost();
            DrawGhostFFCs();

            Waitframe();
        }
    }
}

Apologies for all these silly questions. I'm dumb as a rock when it comes to this scripting stuff. I'll probably test out the combiner at some point but first I'd like to understand this stuff myself like you suggested.


Edited by Peteo, 04 January 2020 - 08:43 AM.


#4 Emily

Emily

    Scripter / Dev

  • ZC Developers

Posted 04 January 2020 - 09:00 AM

Allright, found the global script from the ghost_zh/2.8/scripts.z.  Had to download the latest ZC Alpha to get this file (wasn't included with ZC 2.53 which I've been using)

global script GhostZHActiveScript
{
    void run()
    {
        InitializeGhostZHData();

        while(true)
        {
            UpdateGhostZHData();
            UpdateEWeapons();
            CleanUpGhostFFCs(); // Only needed if __GH_USE_DRAWCOMBO is 0

            Waitdraw();
            
            AutoGhost();
            DrawGhostFFCs();

            Waitframe();
        }
    }
}

So I just take this global script and combine it with my other global scripts, rename it to something like "AllGlobalscripts" and forget about the GhostZHActiveScript and instead assign this new "AllGlobalscripts" as my global script, right?

 

Now I have read a guide how to combine Global scripts and I think it is quite simple and self explanatory when the scripts are either simple of very similar. But I still want to make sure I get it right. So let's say I was to combine a Bombs Shake Screen global script and a Shield Got Eaten Message global script with the GhostZHActiveScript. Would it look like this?

 

Here's the global part of the bomb script

global script Active {
    void run(){
        while(true){
            BombsScreenShake(); //put this line into your global loop (to combine this script with your global script)
            Waitframe();
        }
    }
}

Here's the global part of "you lost your shield" script

global script check_for_shield_vanish{
     void run(){
         while(true){
               waitframe_give_message_if_shield_vanished(); //this is the shield code, replaces the normal waitframe
          }
    }
}

And here's how I'd combine them. Did I do it right? Or should I only have one waitframe there (from the shield script)?

global script AllGlobalscripts
{
    void run()
    {
        InitializeGhostZHData();

        while(true)
        {
	    BombsScreenShake(); //put this line into your global loop (to combine this script with your global script)
            waitframe_give_message_if_shield_vanished(); //this is the shield code, replaces the normal waitframe
            UpdateGhostZHData();
            UpdateEWeapons();
            CleanUpGhostFFCs(); // Only needed if __GH_USE_DRAWCOMBO is 0

            Waitdraw();
            
            AutoGhost();
            DrawGhostFFCs();

            Waitframe();
        }
    }
}

Apologies for all these silly questions. I'm dumb as a rock when it comes to this scripting stuff. I'll probably test out the combiner at some point but first I'd like to understand this stuff myself like you suggested.

Err, if that function replaces the normal waitframe, then it needs to replace waitframe, not put it at the top. For the record, having a function that REPLACES waitframe, is INCREDIBLY unusual, mostly because it makes it harder to combine scripts.



#5 Avaro

Avaro

    o_o

  • Members
  • Real Name:Robin
  • Location:Germany

Posted 04 January 2020 - 11:18 AM

Yeah that Shield script sounds rather weird. Other global scripts will break if you have more than 1 waitframe.

 

But other than that you're doing it right. Ghost can be confusing to set up, and newbie boss too. There's an "autoGhostReadme.txt" which includes all info on how to use ghost.zh. So I hope it goes well eventually :)


Edited by Avaro, 04 January 2020 - 11:19 AM.


#6 Emily

Emily

    Scripter / Dev

  • ZC Developers

Posted 04 January 2020 - 11:40 AM

Using 2.55, ghost is 99% outdated. Old ghost scripts require it, obviously, but npc scripts are infinitely better for anything new. (Ghost will eventually have a 2.55 update using npc scripts)



#7 Peteo

Peteo

    Back in Business!

  • Members
  • Real Name:Pete
  • Location:Finland

Posted 04 January 2020 - 12:13 PM

Yeah that Shield script sounds rather weird. Other global scripts will break if you have more than 1 waitframe.

 

Yeah, even with my poor scripting knowledge I thought it was a weird code. Found it laying there in one of my old ZC files, don't know where I got it from as I see no shield_vanish_message script in the database here. Wonder if ZC 2.55 will have these item pickup messages or item lost messages built in... At first glance there seems to be much more there than in ZC 2.53 that I've been playing with the last month.


Edited by Peteo, 04 January 2020 - 12:14 PM.


#8 Moosh

Moosh

    Tiny Little Questmaker

  • ZC Developers

Posted 04 January 2020 - 03:52 PM

In addition to stuff other people've said, that ghost.zh global script looks old? You sure this is the right version? Every version of ghost since the very oldest has had just three functions in the global:

global script GhostZHActiveScript
{
    void run()
    {
        StartGhostZH();
        
        while(true)
        {
            UpdateGhostZH1();
            Waitdraw();
            UpdateGhostZH2();
            Waitframe();
        }
    }
}


#9 Peteo

Peteo

    Back in Business!

  • Members
  • Real Name:Pete
  • Location:Finland

Posted 04 January 2020 - 04:12 PM

 

In addition to stuff other people've said, that ghost.zh global script looks old? You sure this is the right version? Every version of ghost since the very oldest has had just three functions in the global:

global script GhostZHActiveScript
{
    void run()
    {
        StartGhostZH();
        
        while(true)
        {
            UpdateGhostZH1();
            Waitdraw();
            UpdateGhostZH2();
            Waitframe();
        }
    }
}

 

Well that GhostZHActiveScript you say is old came with the ZC 2.55 Alpha 47 package I downloaded today. How can it be old?

 

However I did check again and there are two "ghost2_scripts" files in the 2.8 folder. The other is a .zh file and the other is a .zs file. Seems the zh has the old one I posted and the zs has the new one you posted.


Edited by Peteo, 04 January 2020 - 04:14 PM.


#10 Moosh

Moosh

    Tiny Little Questmaker

  • ZC Developers

Posted 04 January 2020 - 04:56 PM

That seems very confusing. The .zs one should be current. IDK why the other was left included.



#11 Peteo

Peteo

    Back in Business!

  • Members
  • Real Name:Pete
  • Location:Finland

Posted 10 January 2020 - 06:48 PM

So going back to that shield script you guys were wondering about... is there a better way to do the "Shield Got Eaten Message" script than with Global Scripts and with replacing the waitframe like in the code I have? Here's the full script:

const int shield_id=8;//please put the right number thats the item id of shield
const int shield_lost_string=452;//the string you want to play if the shield is lost
const int shield_lost_sound=19;//the sound that should play when the shield is lost
bool waitframe_check_shield_vanish(){
   bool link_has_shield=Link->Item[shield_id];
   Waitframe();
   if(link_has_shield&&!Link->Item[shield_id]) return true; //means link lost the shield
   else return false;
}
void waitframe_give_message_if_shield_vanished(){
     if(waitframe_check_shield_vanish()){
             Screen->Message(shield_lost_string);
            if(shield_lost_sound>0) Game->PlaySound(shield_lost_sound);
          }
}
global script check_for_shield_vanish{
     void run(){
         while(true){
               waitframe_give_message_if_shield_vanished(); //this is the shield code, replaces the normal waitframe
          }
    }
}

I intend to have many global scripts in my quest but I also would like to have a shield lost message because... well, since there'll be item pickup messages then there should be item lost messages too, I'm a perfectionist. Any help figuring out a better script for this purpose would be greatly appreciated.



#12 Emily

Emily

    Scripter / Dev

  • ZC Developers

Posted 10 January 2020 - 11:26 PM

const int SHIELD_ID = 8; //Constants should be in all-caps.
const int SHIELD_LOST_STRING = 452;
const int SHIELD_LOST_SOUND = 19;

global script active
{
	void run()
	{
		bool hasShield;
		while(true)
		{
			if(hasShield && !Link->Item[SHIELD_ID])
			{
				lost_shield();
			}
			hasShield = Link->Item[SHIELD_ID];
			Waitframe();
		}
	}
	
	void lost_shield()
	{
		if(SHIELD_LOST_STRING) Screen->Message(SHIELD_LOST_STRING);
		if(SHIELD_LOST_SOUND) Game->PlaySound(SHIELD_LOST_SOUND);
	}
}

Far better than what you have there.



#13 Peteo

Peteo

    Back in Business!

  • Members
  • Real Name:Pete
  • Location:Finland

Posted 11 January 2020 - 04:29 AM

That's much better indeed, thanks venrob!




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users