Creating an Options Panel for a Game Mode by gegeshandong


									                                                                      Game Mode API Tutorial
                                                                      Author: infiniteAlpha
                                                                      Minecraft Version: 1.0.0
                                                                      Minecraft Coder Pack Version: 5.0
                                                                      GMAPI Version:
                                                                      Date: 24 Dec 2011
                                                                      Level: Intermediate

                       Creating an Options Panel for a Game Mode
One of the features of the Game Mode API is the ability to present the player with options that are
specific to a game mode through the use of ‘Panel’ and ‘Control’ objects which are part of the
remodelled UI.

A Panel is a container that holds other UI objects. It’s sort of like a sub-screen. On the create new
world screen is a tab control that lets you select different panels by clicking the options at the left.

A Control is a UI element such as a button, a text box or a check box.

For this tutorial we’re going to add in an options panel that lets the player select if they want to
enable blood rage mode and also if they want cows to spawn at a much higher rate.

01    package net.minecraft.src;
03    import net.minecraft.src.gmapi.interfaces.IGuiElement;
04    import net.minecraft.src.gmapi.ui.*;
06    public class PanelBravoOptions
07      extends Panel
08    {
09      public PanelBravoOptions(IGuiElement parent, String id)
10      {
11        super(parent, id);
12      }
14        @Override
15        public void OnDraw()
16        {
17          super.OnDraw();
18        }
20        @Override
21        public String GetTitle()
22        {
23          return "Bravo";
24        }
25    }
                                                                - Listing 1
Listing 1 shows the basics that you want to start with when creating a Panel. A constructor, OnDraw
and GetTitle. That is enough to get a blank panel to display. Lets add some controls to make it more
usefule though.

01       ControlCheckBox cb1;
02       ControlCheckBox cb2;
04       ControlLabel l1;
06       @Override
07       public void OnLoad()
08       {
09         cb1 = new ControlCheckBox(this, "cb1");
10         cb1.SetPosition(8, 25, false);
11         cb1.SetLabel("Spawn lots of cows");
12         AddElement("cb1", cb1);
14           cb2 = new ControlCheckBox(this, "cb2");
15           cb2.SetPosition(8, 37, false);
16           cb2.SetLabel("Enable Blood Rage");
17           AddElement("cb2", cb2);
19           l1 = new ControlLabel(this, "l1");
20           l1.SetPosition(10, 5, false);
21           l1.SetLabel("Bravo Options");
22           AddElement("l1", l1);
24           super.OnLoad();
25       }
                                                                - Listing 2

First we need to add some variables to the panel class for the options we want. There are two
checkboxes and also a text label.

We initialise the controls in the panel’s OnLoad method. Each control needs 2 parameters for it’s
constructor. The first is a parent object, which in this case is the panel so we can use the ‘this’
keyword. The second parameter is a String value that is used to identify the control, so the value
should be different for each control.

Next we set the position for each control. This takes a little bit of trial and error to get it the way you
like. The parameters are left coordinate, top coordinate and a boolean to say if the position is
absolute. An absolute position will position itself with respect to the top left corner of the game
window. A relative (not absolute) position will position itself with respect to the top left corner of
the parent element.

Next we set the label for each control.

The last thing to do for any control is to call AddElement. The first parameter is the id String and the
second parameter is the control object itself. AddElement registers the control so that it is
automatically drawn each frame and it automatically gets messages such as OnMouseClick.

With the controls set up this panel would display okay and the controls would function but we need
to implement a way for the controls to let the panel know when something has happened. That is
what the method OnGuiEvent is for. Whenever the player interacts with a control, the control sends
a message back to the parent object – which is our panel. Let’s look at how to handle that message.

01      @Override
02      public void OnGuiEvent(String sender, String event)
03      {
04        if(sender.equals("cb1"))
05        {
06          if(event.equals(ControlCheckBox.StateChanged))
07            GameModeBravo.lotsOfCows = cb1.GetState();
08        }
09        else if(sender.equals("cb2"))
10        {
11          if(event.equals(ControlCheckBox.StateChanged))
12            GameModeBravo.enableBloodRage = cb2.GetState();
13        }
14      }
                                                - Listing 3

The OnGuiEvent method has two parameters, the id of the control sending the message and the
event that actually happened.

The first thing we do is check if the message was sent by one of the checkbox controls, if so we check
to see if the message was ‘ControlCheckBox.StateChanged’ which tells us that the player has clicked
the checkbox and the state has changed. Then we set a variable to whatever the checkbox state is
currently set to. We still need to add those variables to the game mode class though so let’s do that

01      public static boolean lotsOfCows = false;
02      public static boolean enableBloodRage = false;
                                                              - Listing 4

Now we have the variables and they are being set by the options panel, we need to actually make
the game mode do something based on the settings.

Go to the OnEntityKilled method in the game mode bravo class and find the part where blood rage is
activated. We’re going to modify it to only allow blood rage mode to activate if enableBloodRage is
set to true.

01    if(totalCowsKilled % 10 == 0 && enableBloodRage)
02    {
03      bloodRageActive = true;
04      bloodRageTimer = GameModeManager.GetWorld().getWorldTime() + 600;
05    }
                                                 - Listing 5

Next we need to go to the custom cow class we made a few tutorials back and modify it to spawn
more cows if the ‘Lots of cows’ checkbox is set. We’re going to change the EntityCowBravo.OnLoad
method. Find the line that adds the custom cow to the spawn list and change it to the following.

01    if(GameModeBravo.lotsOfCows)
02          ModLoader.AddSpawn(EntityCowBravo.class, 16, 8, 16,
03        else
04         ModLoader.AddSpawn(EntityCowBravo.class, 8, 4, 4,
                                                  - Listing 6

What we’ve done here is to add the custom cow to the spawn list with different parameters
depending on the setting of the variable lotsOfCows.

The next thing we need to do is to add the new variables to OnReadFromNBT and OnWriteToNBT so
that the game settings are saved for each world.

01      @Override
02      public void OnReadFromNBT(NBTTagCompound nbt)
03      {
04        totalCowsKilled = nbt.getInteger("CowsKilled");
05        bloodRageActive = nbt.getBoolean("BloodRageActive");
06        bloodRageTimer = nbt.getLong("BloodRageTimer");
08          enableBloodRage = nbt.getBoolean("EnableBloodRage");
09          lotsOfCows = nbt.getBoolean("LotsOfCows");
10      }
12      @Override
13      public void OnWriteToNBT(NBTTagCompound nbt)
14      {
15        nbt.setInteger("CowsKilled", totalCowsKilled);
16        nbt.setBoolean("BloodRageActive", bloodRageActive);
17        nbt.setLong("BloodRageTimer", bloodRageTimer);
19          nbt.setBoolean("EnableBloodRage", enableBloodRage);
20          nbt.setBoolean("LotsOfCows", lotsOfCows);
21      }
                                                           - Listing 7

Now all that’s left to do is tell the GameModeManager to use this panel. In your game mode bravo
class, add the following variable and override.

01      private static PanelBravoOptions options;
03      @Override
04      public Panel[] GetPanels(IGuiElement parent)
05      {
06        if(options == null)
07          options = new PanelBravoOptions(parent, "bravooptionspanel");
08        return new Panel[]{options};
09      }
                                                 - Listing 8

This creates a new instance of the panel and returns it when GameModeManager asks for options
panels. If you need more than one panel, you can return more in the array.

To top