ZScript Hello World

From ZDoom Wiki
Jump to navigation Jump to search

This is a bare-bones bit of ZScript that logs "Hello World!" into the console. It is to be used as a base for doing more ZScript work and is not intended to show any additional functionality that cannot be done in DECORATE or ACS.

First, we need to set the ZScript version so we can use all available features. (If we do not do this, GZDoom will assume for compatibility reasons that the target version is 2.3.0 and refuse to compile anything with features from later versions.)

As of the creation of this page, the latest release of GZDoom is 3.3.2. ZScript version numbers will typically just use the first two numbers, so we will insert the following:

 version "3.3"

Next, we need to create a script that logs "Hello World!" into the console.

 version "3.3"
 
 void HelloWorld()
 {
   A_Log("Hello World!");
 }

This alone is not workable, because this script is not contained in any particular class. Since we can put this in a whole bunch of different places, let's make it a static function in its own struct:

 version "3.3"
 
 struct HelloWorldStruct play
 {
   static void HelloWorld (actor caller)
   {
     caller.A_Log("Hello World!");
   }
 }

Now this will compile, but there is no event that actually makes this thing happen.

Ideally this should happen when the player first enters the map. This would be governed by an EventHandler, but that would have to be called in MAPINFO which means this tutorial can't be self-contained.

So what is the first interactive object you are guaranteed to be able to use in both Hangar and Entryway? The armour bonus.

Now all inventory items have a virtual function called "Touch" that is called whenever something touches that item that is flagged as being capable of picking items up. By overriding this for an armour bonus (by using a replacement similar to what we do in DECORATE), we can have that virtual function call the Hello World script we just wrote:

 version "3.3"
 
 struct HelloWorldStruct play
 {
   static void HelloWorld (actor caller)
   {
     caller.A_Log("Hello World!");
   }
 }
 
 class HelloArmour : ArmorBonus replaces ArmorBonus
 {
   override void Touch (actor toucher)
   {
     HelloWorldStruct.HelloWorld(toucher);  //calls the HelloWorld script
     super.Touch(toucher);  //calls the parent Touch() sequence to allow pickup
   }
 }

Now every time you pick up an armour bonus you will get "Hello World!" logged into your console in addition to the regular pickup message.

If you want, you can have it log "Hello World!" when you kill a zombieman instead:

 version "3.3"
 
 struct HelloWorldStruct play
 {
   static void HelloWorld (actor caller)
   {
     caller.A_Log("Hello World!");
   }
 }
 
 class HelloZombie : ZombieMan replaces ZombieMan
 {
   override void Die (actor source, actor inflictor, int dmgflags)
   {
     if (source)  //make sure the killer actually exists before making it do things
     {
       HelloWorldStruct.HelloWorld(source);  //calls the HelloWorld script
     }
     super.Die(source, inflictor, dmgflags);  //calls the parent Die() sequence
   }
 }