How would I instantiate a variable?

Discussion in 'Spigot Plugin Development' started by AncientTom, May 2, 2017.

  1. I don't remember having this presented in the Java courses I took.

    I am hooking into WorldGuard Regions to be able to set each region as an event trigger. What I have now is a working starting point, such as it is, but my int variable, "entries" is being added to by every entity that is loaded into the game. I assume that all regions, beginning with the world region, are sharing the same listener method the way I have it now. I need to instantiate "entries" with each separate region and I need a little direction as to how to proceed.

    Code (Text):
    /* Doors.java */
    package net.sleepyvalley.ancienttom.doors;

    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.plugin.java.JavaPlugin;

    import com.mewin.WGRegionEvents.events.RegionEnterEvent;
    import com.mewin.WGRegionEvents.events.RegionLeaveEvent;

    /**
    * @author AncientTom
    */
    public class Doors extends JavaPlugin implements Listener {
       
        private int entries = 0;
       
        @Override
        public void onEnable() {
            getServer().getPluginManager().registerEvents(this, this);
        }

        @Override
        public void onDisable() {
        }

        @EventHandler
        public void onRegionEnter(RegionEnterEvent e) {
            this.entries++;
              e.getPlayer().sendMessage("There are now " + this.entries + " in the " + e.getRegion().getId() + " doorway");
         
        }

        @EventHandler
        public void onRegionLeave(RegionLeaveEvent e) {
            e.getPlayer().sendMessage("You just left " + e.getRegion().getId());
            if (this.entries > 0) {
                this.entries--;
                  e.getPlayer().sendMessage("There are now " + this.entries + " in the " + e.getRegion().getId() + " doorway");
            }
        }


    }
     
    I realize that this is a fundamental function but I am just getting started with Java as a new language.
     
    #1 AncientTom, May 2, 2017
    Last edited: May 2, 2017
  2. You could have a hashmap with some form of region identifier and entries int. Assume a region is identified by a string:
    Code (Text):
    private HashMap<String, Integer> regions = new HashMap<>();
    Then when the event is fired, check if the region is in the hashmap and if not, add it and set the int value to 1. If it does contain it increase the int value by 1.
     
    • Agree Agree x 1
  3. I need this to be dynamic at runtime so that it will work with regions that may not be created yet. I have, right now, a listener that responds to all region entries and increments my variable with each entity to any region. I would like to be able to instantiate my counter with each region to keep separate entry counters.
     
  4. What I suggested does just that. I took a quick look at the WorldGuard API and you could do it like this
    Code (Java):

    private HashMap<ProtectedRegion, Integer> regions; // this hashmap stores any regions for which the event has been fired along with their entries integer

    public YourClass(/* arguments */) {
        regions = new HashMap<>();
    }

    @EventHandler
    public void yourEvent(YourEvent event) {
        ProtectedRegion region = event.getRegion(); // is that the method??
        if (!regions.containsKey(region)) { // the event hasn't been called for this event before
            regions.put(region, 1); // put the region in the map and set the integer to 1
        } else { // it has been called for this region before
            regions.put(region, regions.get(region) + 1); // increase the integer
        }
    }
     
    Then when you need a region's integer, simply use regions.get(region);.
     
  5. Yes! I think that this a good approach. I'll work on it ad see what happens. Also adding a boolean flag to regions to indicate a door region will reduce the clutter. I'll let you know what I come up with.
     
  6. The following modified code is what I came up with using your suggestion as a template and is now working. Thanks.
    This package, right now monitors how many players are in a region. When someone enters a region or exits one, A counter within the counter list that you suggested to use, keeps track of how many players there are within a region and reports that count to the console as a means to test this part of the project. The ultimate goal is to automatically open doors in a door threshold when the first player enters and close them when the last player leaves.
    I had originally had this function working on my servers using Lexlaiden's VariableTriggers scripting plugin. Since that plugin is now abandoned and can no longer be relied on, I figure that it's time that I become self reliant and start coding with Java.
    This should not have been so difficult for me to come up with, but I have not been able to find anything that remotely resembles a complete API reference for sk89's WorldGuard and Regions. You seem to have an understanding of WG's APIs so it must exist somewhere. All that I have found so far is tutorials on how to use a few interfaces that are called API reference but it is so incomplete.
    Code (Text):

    /* Doors.java */
    package net.sleepyvalley.ancienttom.doors;

    import java.util.HashMap;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.plugin.java.JavaPlugin;
    import com.mewin.WGRegionEvents.events.RegionEnterEvent;
    import com.mewin.WGRegionEvents.events.RegionLeaveEvent;
    import com.sk89q.worldguard.protection.regions.ProtectedRegion;

    /**
    * @author AncientTom
    * Contact info: [email protected]
    *               Skype: AncientTom
    */
    public class Doors extends JavaPlugin implements Listener {
     
        private HashMap<ProtectedRegion, Integer> regions; // this hashmap stores any regions for which the event has been fired along with their entries integer
        private String regionID;
     
        @Override
        public void onEnable() {
            regions = new HashMap<>();
            getServer().getPluginManager().registerEvents(this, this);
        }

        @Override
        public void onDisable() {
        }

        @EventHandler
        public void onRegionEnter(RegionEnterEvent event) {
            ProtectedRegion region = event.getRegion(); // is that the method??
            regionID = event.getRegion().getId();
            if (!regions.containsKey(region)) { // the event hasn't been called for this event before
                regions.put(region, 1); // put the region in the map and set the integer to 1
            } else { // it has been called for this region before
                regions.put(region, regions.get(region) + 1); // increase the integer
            }
              event.getPlayer().sendMessage("There are now " + regions.get(region) + " in the " + regionID + " doorway");
       
        }

        @EventHandler
        public void onRegionLeave(RegionLeaveEvent event) {
            ProtectedRegion region = event.getRegion();
            regionID = event.getRegion().getId();
            if (regions.get(region) > 0) {
                regions.put(region, regions.get(region) - 1);
                  event.getPlayer().sendMessage("There are now " + regions.get(region) + " in the " + regionID + " doorway");
            }
        }

    }
     
     
  7. What's the current problem?
     
  8. I finally found sk's WorldGuard API reference but it's for a previous version, 5.7.4-SNAPSHOT. I hope that this is current enough to work with.

    My current need is to figure out how to get the boundary coordinates from the triggering region. I was studying how to set custom flags in order to mark a region as a doorway but it came to me that all I have to do in include the string "door" in the region's name and I can use the name as a flag.
     
  9. 2 & 1/2 hours later, I think I found what I need after a lot of studying, testing the different objects available, and with the help of Eclipse's suggestions. I think this will do it;
    RegionManager rmRegions = container.get(player.getWorld());
    BlockVector minPoint = rmRegions.getRegion(regionID).getMinimumPoint();
    BlockVector maxPoint = rmRegions.getRegion(regionID).getMaximumPoint();
     
    #9 AncientTom, May 3, 2017
    Last edited: May 3, 2017
    • Like Like x 1
  10. Yeay!!! I'm finally getting the feel of how the bukkit/sponge API is organized and am starting to be able to guess what class is most appropriate to start the path to a method that will do the job that I need, with the help of Eclipse suggestions lists. I now find more appropriate methods that I can be using such as 'rmRegions.getRegion(regionID).getMinimumPoint().getX()' which returns a type Double. I can do math with that.

    Yeay, Eclipse! I have tried using IntelliJ Idea several times because that is what the Java Instructor used for his presentations, but I find Idea to be to bloated and it's functionality to weird. NetBeans by Oricle has kind of established a standard that Eclipse holds it's structure to. Idea seems to have gone off the deep end throwing caution to the wind. Perhaps to the experienced Java developer, Idea makes sense, but to me, it is congested with to many enrichments to be an efficient working environment.
     
    #10 AncientTom, May 4, 2017
    Last edited: May 4, 2017
    • Agree Agree x 1