0

I'm not sure if this will really make any sense (I've kinda confused my self ) but what I am trying to do is create a mini-game plugin and I'm trying to make it cycle between maps, I create a new class that extends BaseGame I pass in plugin instance, world name and xml file name to the super class BaseGame, The basegame class then parses the information from xml file and setup variables. I have some methods in side the class extending BaseGame because most maps have different game types so I need to do different things for different events for example on TDM I need to stop players breaking this so I want to do this in the listener

@EventHandler
public void blockDestroy(BlockBreakEvent event) {
    plugin.mapCycler.getCurrentWorld().onBreakEvent(event);
}

The problem I face is returning the current world from the MapCycler class because all map classes have different methods, I need a way to return the map classes in a generic method that can return all map classes that extend BaseGame but I still need to be able to access the methods inside the class extending BaseGame.

Please tell me if you need more clarification.

Thanks

Edit 1:

In the BaseGame class it is common methods that will be used in all the World Classes extending BaseGame for example these methods will be used in all the classes extending BaseGame

    public String getMapName() {
    return xmlFileReader.getMapName();
}


public String getMapObjective() {
    return xmlFileReader.getMapObjective();
}
    public void resetInventory(Player player) {
    player.getInventory().clear();
    player.getInventory().setArmorContents(null);
    player.setHealth(20);
    player.setFlying(false);
    player.setGameMode(GameMode.SURVIVAL);
    player.setFoodLevel(20);
}

and in the classes extending the BaseGame class It will have unique method that relate to the world for example

public void blueWin() {
    Bukkit.getServer().broadcastMessage(Messages.colorize("Blue win - nice message in update"));
    for(String player : blueTeamList) {
        Player blue = Bukkit.getServer().getPlayer(player);
        resetInventory(blue);
        Packet206SetScoreboardObjective packet = new Packet206SetScoreboardObjective(plugin.relicWorld.sb.getObjective(plugin.relicWorld.name), 1);//Create Scoreboard create packet
        sendPacket(blue, packet);
        String loc = DatabaseManager.getLastLoc("SELECT * FROM ag_users WHERE user = \'" + blue.getName() + "\'");
        blue.teleport(LocationManager.stringToLoc(loc));
        Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "eco give " + blue.getName() + " 250");   
    }
    for(String player : redTeamList) {
        Player red = Bukkit.getServer().getPlayer(player);
        resetInventory(red);
        Packet206SetScoreboardObjective packet = new Packet206SetScoreboardObjective(plugin.relicWorld.sb.getObjective(plugin.relicWorld.name), 1);//Create Scoreboard create packet
        sendPacket(red, packet);
        String loc = DatabaseManager.getLastLoc("SELECT * FROM ag_users WHERE user = \'" + red.getName() + "\'");
        red.teleport(LocationManager.stringToLoc(loc));
        Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "eco give " + red.getName() + " 50"); 
    }
    Bukkit.unloadWorld(getWorld(), false);
    resetAll();
}

because it's unique to the world.

  • Please post an example, showing what methods you may need to call on different objects. And what are the common methods? – Ruan Mendes Apr 04 '13 at 16:14

2 Answers2

1

They key is that you need to define a uniform interface for your world object. Then you can call the same method (defined in the base class/interface) and through polymorphism each subclass can react differently

interface World{
    public void onBreakEvent(BlockBreakEvent e);
}

class World1 extends BaseGame implements World{
    public void onBreakEvent(BlockBreakEvent e) {
        System.out.println("Breaking from world 1")
    }
}

class World2 extends BaseGame implements World{
    public void onBreakEvent(BlockBreakEvent  e) {
        System.out.println("Breaking from world 2")
    }
}

Now when you call plugin.mapCycler.getCurrentWorld() that should return a World object, that is, it implements the World interface. Each object can react differently but because they all share the interface, they can be treated as if they were the same.

plugin.mapCycler.getCurrentWorld().onBreakEvent(event);
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • That skips the part of extending the BaseGame class – DCSoftware Apr 04 '13 at 16:24
  • @DCSoftware By implementing the `World` interface, you can still extend `BaseGame`. Not sure what your question is... – Ruan Mendes Apr 04 '13 at 16:28
  • Okay, I will try be more clear - What I need is to be able to create many classes that extend BaseGame that have unique methods but I need to be able to return the all the classes from one method – DCSoftware Apr 04 '13 at 16:51
  • @DCSoftware It seems you didn't understand my answer. You can't call different methods from different classes from the same place without nasty `intanceof`s and casting. The right way is to call the methods defined by your interface. If you need them to behave differently for each object, you use polymorphic behavior as I showed you – Ruan Mendes Apr 04 '13 at 17:40
  • I managed to make it work - thank you. I did actually think of the instanceof method to do it but it's not very efficient so now I'm using the interface method.. – DCSoftware Apr 04 '13 at 17:47
  • @DCSoftware Glad it's working. Polymorphism is definitely one of the buzz words in Object Oriented programming – Ruan Mendes Apr 04 '13 at 17:58
0

I think you must define return-type as super class. Then your method can return any class deriving form this super class.

This is called as covariant return type in java. Few examples: sample1, sample2

Here is a sample code :

class A {
    int x = 1;
}

class B extends A {
    int x = 2;
}

class Base {    
    A getObject() {
        System.out.println("Base");
        return new B();
    }
}

public class CovariantReturn extends Base {

    B getObject() {
        System.out.println("CovariantReturn");
        return new B(); 
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        Base test = new CovariantReturn();
        System.out.println(test.getObject() instanceof B);
        System.out.println(test.getObject().x);
    }
}
Community
  • 1
  • 1
Ankur Shanbhag
  • 7,746
  • 2
  • 28
  • 38