Adding player to a List on toggle

Discussion in 'Plugin Development' started by Minermax7, Jan 17, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    Minermax7

    Hey guys, I am working on a plugin and am currently adding a godmode command. I have completed it, although I haven't figured out how to add them to a list/hashmap.

    I know this code is incorrect, but I require help on how to fix it. What I need, is when a player types /god for the first time, it tells them it is enabled and adds them to the list, when they type it again, they are messaged it is disabled and removes them from the list.

    Code so far:
    Code:
    public Set<String> godModePlayers = new HashSet<String>();
    
        public boolean isInGodMode(Player player) {
            return godModePlayers.contains(player.getName());
        }
    Code:
    if(label.equalsIgnoreCase("god")) {
                    if(isInGodMode(p)) {
                        p.sendMessage(prefix + "God mode disabled.");
                        godModePlayers.remove(p.getName());
                    } else {
                        p.sendMessage(prefix + "God mode enabled.");
                        godModePlayers.add(p.getName());
                    }
                }
    Code:
    @EventHandler(priority = EventPriority.NORMAL)
        public void dmg(final EntityDamageEvent event) {
            Entity e = event.getEntity();
            if(e instanceof Player) {
                Player p = (Player)e;
    
                if(e instanceof Player) {
                    if(godModePlayers.contains(p)) {
                        event.setCancelled(true);
                        p.sendMessage(prefix + "God mode is in effect!");
                    } else {
                        event.setCancelled(false);
                    }
                }
    
            }
        }
    Thanks!
    -minermax7.
     
  2. Offline

    Europia79

    @Minermax7

    Conceptualize a general player object... where we have an accessor to the state of the object: getMode() or isInGodMode() for example.

    How do you get a hold of an instance of this object ? I'd say mirror the way you would with Bukkit:
    Code:java
    1. /**
    2. * Bukkit.getPlayer() mirrored equivalent
    3. * Bukkit.getOnlinePlayers() mirrored equivalent
    4. */
    5. GPlayer player = GodMode.getPlayer(x);
    6. Collection<GPlayer> players = GodMode.getOnlinePlayers();
    7.  


    Your event would then become:
    Code:java
    1. @EventHandler(priority = EventPriority.NORMAL)
    2. public void onDamageEvent(final EntityDamageEvent event) {
    3. Entity entity = event.getEntity();
    4. if(entity instanceof Player) {
    5. // getPlayer() via String, UUID, or Player: Your implementation: You decide
    6. GPlayer p = GodMode.getPlayer(e.getName);
    7. if(p.isInGodMode()) {
    8. event.setCancelled(true);
    9. p.getPlayer().sendMessage(prefix + "God mode is in effect!");
    10. }
    11. }
    12. }


    This means that you'll have to write an implementation for GodMode.getPlayer() that accepts a key (String playerName, UUID playerId, or Player object) and returns type GPlayer which has internal state for god mode... Determining the state of the object (if the player is in god mode) is as easy as isInGodMode() or getMode() for example.

    Populate your container of GPlayer objects (the GodMode container class) by listening to PlayerJoinEvent and remove them via PlayerQuitEvent. PlayerJoinEvent ultimately does the creation of these GPlayer objects (either directly or indirectly):
    Code:java
    1. @EventHandler
    2. public void onPlayerJoin(PlayerJoinEvent event) {
    3. GodMode.addPlayer(event.getPlayer());
    4. }
    5.  
    6. @EventHandler
    7. public void onPlayerQuit(PlayerQuitEvent event) {
    8. GodMode.removePlayer(event.getPlayer());
    9. }
    10.  
    11. @Override
    12. public void onDisable() {
    13. GodMode.onDisable() // or GodMode.clear(); Whatever method name you like
    14. }


    As for the GodMode class: Something along these lines (your implementation details may differ)
    Code:java
    1. public class GodMode {
    2.  
    3. private static final Map<String, GPlayer> pmap = new HashMap<>();
    4.  
    5. public static GPlayer getPlayer(String name) {
    6. return pmap.get(name);
    7. }
    8.  
    9. public static void addPlayer(Player p) {
    10. pmap.put(p.getName(), new GPlayer(p));
    11. }
    12.  
    13. public static void removePlayer(Player p) {
    14. pmap.remove(p.getName());
    15. }
    16.  
    17. public static void onDisable() {
    18. pmap.clear();
    19. }
    20.  
    21. public static Collection<GPlayer> getOnlinePlayers() {
    22. return pmap.values();
    23. }
    24. }


    Also, to answer your question about the command, it would look something like this:
    Code:java
    1. GPlayer p = GodMode.getPlayer(playerName);
    2. if (p.isInGodMode()) {
    3. p.setGodMode(false);
    4. p.getPlayer().sendMessage("God mode has been turned off.");
    5. } else {
    6. p.setGodMode(true);
    7. p.getPlayer().sendMessage("You are now in god mode.");
    8. }
     
    Last edited: Jan 17, 2015
    Minermax7 likes this.
  3. Offline

    Minermax7

    Your way seems much easier, I finally had it working just as you posted this but this is what it looks like:

    Just before the onCommand method:
    Code:
    public boolean isGod = false;
        HashMap<String, Boolean> isGodMode = new HashMap<String, Boolean>();
    Command:
    Code:
    if(label.equalsIgnoreCase("god")) {
    
                    if(!isGod){
                        isGod = true;
                        isGodMode.put(p.getName(), true);
                        p.sendMessage(prefix + "God mode enabled.");
                    }else if(isGod){
                        isGod = false;
                        isGodMode.put(p.getName(), false);
                        p.sendMessage(prefix + "God mode disabled.");
                    } else {
                        return false;
                    }
                }
    Event:
    Code:
    @EventHandler(priority = EventPriority.HIGH)
        public void dmg(final EntityDamageEvent event) {
            Entity e = event.getEntity();
            if(e instanceof Player) {
                Player p = (Player)e;
    
                if(e instanceof Player) {
                    if(isGodMode.get(p.getName()) == Boolean.TRUE){
                        event.setCancelled(true);
                    } else if(isGodMode.get(p.getName()) == Boolean.FALSE){
                        event.setCancelled(false);
                    }
                }
            }
        }
    Although this works, your method makes it look much easier to manipulate and change around when I need, the way I did was mostly through trial and error.. :/ Hahaha
     
  4. Offline

    Europia79

    @Minermax7

    Yes, viewing this simple problem from only the angle of "is the player in god mode?" might make it hard to understand the value of the object oriented approach.

    Along the same lines... consider instead that your plugin is a Super Hero plugin... that gives ordinary players super human abilities: We could keep the GPlayer name (stands for GeneralPlayer) and give them more attributes & abilities. Or we could the change to something more appropriate: SuperPlayer.

    Think about all the things that a SuperPlayer might be able to do:
    Code:java
    1. public interface SuperPlayer extends Player {
    2.  
    3. public Collection<Ability> getAbilities();
    4. public boolean addAbility(Ability ability);
    5. // ...
    6.  
    7. }


    We could fire custom events... Other plugins could listen to these events and obtain SuperPlayer objects (to maybe add effects for example, or keep track of stats for example).

    Now think about the alternative: That your plugin (or even Bukkit or Minecraft itself) did not have these player objects... People would have to interact with a List, Set, or Map to see if a players attributes:
    Code:java
    1. public class Bukkit {
    2.  
    3. public static final Collection<String> flyList = new HashSet<String>();
    4.  
    5. public static Collection<String> getFlyList() { return this.flyList; }
    6.  
    7. }


    To see if a player is flying without Player objects:
    Code:java
    1. @EventHandler
    2. public void onSomeEvent(SomeBukkitEvent event) {
    3.  
    4. if (Bukkit.getFlyList().contains(event.getPlayerName() ) {
    5. // ...
    6. }
    7. }


    Events would no longer supply Player objects (they don't exist in this hypothetical scenario). Events instead would supply the name of the player involved.

    So yeah, your way is working... it's fine for now. Down the road you may (or may not) want to refactor to accommodate more player attributes other than just a GodMode attribute. When that time comes, you'll know what to do.
     
    Minermax7 likes this.
  5. Offline

    Minermax7

    Wow. I must say, out of every post I have seen in Bukkit Forums, you have been the most detailed, in-depth person I have seen. Bukkit Forums needs more people like you. Bravo!
    [diamond] Diamond for you :D

    EDIT:
    I am actually having second thoughts on that super heroes plugin, I am going to attempt to get some stuff done on it. :D
     
    Europia79 likes this.
Thread Status:
Not open for further replies.

Share This Page