Multiworlds

Discussion in 'Plugin Development' started by CorrieKay, Nov 19, 2012.

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

    CorrieKay

    Hey, ive got a few questions, as I am about to attempt to code a customized multiworld system for my plugin system.

    1) How should i handle server reloads? Not reboots, but reloads ( i know im not supposed to reload, but what if it happens?) World loading if it already is loaded? Do the worlds get dropped or not? Maybe i should iterate over the world list, and check if the world is already loaded?

    2) what happens to a player who is in a world that hypothetically doesnt get loaded? Do they die and respawn in a valid world? Do they get kicked for invalid location?
     
  2. Offline

    CorrieKay

    bump.

    By the way, using the WorldCreator, if i try and load a world without setting its seed, will any terrain generation use a generated (not necessarily its correct seed) seed?

    edit: actually, i wanna know if im doing this right.. (ive been looking at the multiverse system to figure out how to load/create worlds and stuff)

    looks like im basically creating a new instance of a WorldCreator with the desired worlds name, set the type/environment, then call createWorld() on it... right?

    As for loading a world that exists already, im seeing that you basically do the same thing..?
     
  3. Offline

    Jogy34

    1) Don't do anything on server reloads. A server reload keeps any worlds that are loaded loaded and doesn't do anything with worlds that aren't loaded to my knowledge.

    2) If you try to teleport a player to a non-loaded world they will either get teleported to the coordinates of the world they are in or nothing will happen. I'm pretty sure that it's the second one but I'm not 100% sure. A player cannot go into a world that isn't loaded and if they spawn in one then the world loads and if the world doesn't exist they go to the main world defined in the server properties file to the same coordinates that they were at in the other world. This I know from experiance.

    3) If you don't specify a seed one is automatically generated.

    4) Yes that is correct. You want to be careful that you always have the correct world name otherwise one is generated.
     
  4. Offline

    CorrieKay

    Thanks, exactly what i needed.

    How do i generate end/nether worlds, or link existing nether worlds to overworlds? :eek:
     
  5. Offline

    Jogy34

    new WorldCreator("WorldName").enviromnent(Environment.THE_END) //or NETHER for the nether
     
  6. Offline

    CorrieKay

    Oh, i meant how to make it where a specific world can have an end/nether. I created the end and nether, but whenever i try to go through the portals, they dont do anything.
     
  7. Offline

    Jogy34

    O. You would probably have to manually link them then.
     
  8. Offline

    CorrieKay

    Is there an event thrown when they try to portal through a nether/end portal? i checked EntityPortalEnterEvent but it doesnt seem to have any methods to set where theyre going.

    And on top of that, how the hay am i supposed to set exactly where a portal is generated... or... yeah. Sorry, how do i do that? :p
     
  9. Offline

    Jogy34

    You would use that event and then get the world you want to teleport to and then spawn a portal at the closest empty 4x5 area at (x*8, y, z*8), you would then keep track of that location in a config file or something and when you teleport at that portal you go to your new nether world or if you teleport from another portal in your new nether you would go to that portal if it is within 124 blocks of the (x*8, y, z*8) coordinate. If you are going to the nether to spawn a portal it would be at (x/8, y, z/8)
     
  10. Offline

    bergerkiller

    Jogy34
    They don't die. They go back to your main world on the server, which is always loaded.
     
  11. Offline

    fireblast709

    Use the PlayerPortalEvent, combined with the location from Jogy34 to calculate where they should be spawned
     
  12. Offline

    CorrieKay

    mmh... Okay. What about a return portal?
     
  13. Offline

    Jogy34

    Same thing but you would cross check the portal with any previously generated portals that you made and it would be at (x/8, y, z/8) in the nether
     
  14. Offline

    CorrieKay

    i meant creating a return portal. If i just teleport the player to the nether, they get stranded without a portal :\

    Huh.. I found the PortalTravelAgent. That should help.. But do i need an instantiated version, or should i just make my own?

    So im trying to play around with the TravelAgent.. And its kinda not doing what it says :eek:

    It finds a "safe" location, and "creates" a nether portal.. But the location was neither safe (it returned a location that was in a wall) nor was a portal created...

    Heres my code if you guys would wanna look at it.

    Code:
    public class Equestria extends PSCmdExe {
     
        //world1: subworld. world2: parent world
        private HashMap<World,World> worlds = new HashMap<World,World>();
        private HashMap<String,Integer> warpCountdown = new HashMap<String,Integer>();
     
     
        public Equestria() throws Exception{
            super("Equestria", new String[]{"test"});
            FileConfiguration worldconfig = YamlConfiguration.loadConfiguration(new FileInputStream(new File(Mane.getInstance().getDataFolder(),"equestria.yml")));
            for(String world : worldconfig.getConfigurationSection("worldconfig").getKeys(false)){
                Environment e = Environment.NORMAL;
                WorldType wt;
                try{
                    wt = WorldType.valueOf(worldconfig.getString("worldconfig."+world+".type"));
                } catch (Exception e1){
                    wt = WorldType.NORMAL;
                    System.out.println(world+" type is null, defaulting to normal");
                }
                World w = loadWorld(world, e,wt);
                worlds.put(w,w);
                if(worldconfig.getBoolean("worldconfig."+world+".end")){
                    World end = loadWorld(world+"_the_end",Environment.THE_END,WorldType.LARGE_BIOMES);
                    worlds.put(end,w);
                }
                if(worldconfig.getBoolean("worldconfig."+world+".end")){
                    World nether = loadWorld(world+"_nether",Environment.NETHER,WorldType.LARGE_BIOMES);
                    worlds.put(nether,w);
                }
            }
            Bukkit.getScheduler().scheduleSyncRepeatingTask(Mane.getInstance(), new Runnable(){
                public void run(){
                    for(String s : warpCountdown.keySet()){
                        int i = warpCountdown.get(s);
                        i--;
                        if(i < 1){
                            warpCountdown.remove(s);
                            Player p = Bukkit.getPlayerExact(s);
                            if(p!=null){
                                sendMessage(p,"Portals ready when you are!");
                            }
                            continue;
                        }
                        warpCountdown.put(s,i);
                    }
                }
            }, 0, 20);
        }
        public World loadWorld(String worldname, Environment e,WorldType wt){
            World w = Bukkit.getWorld(worldname);
            if(w!=null){
                return w;
            }
            WorldCreator wc = new WorldCreator(worldname);
            wc.environment(e).type(wt);
            return wc.createWorld();
        }
        public World getParentWorld(World world){
            return worlds.get(world);
        }
        public boolean isSubWorld(World child, World parent){
            return worlds.get(child).equals(parent);
        }
        public World getNether(World w){
            World parent = getParentWorld(w);
            for(World sub : worlds.keySet()){
                if(getParentWorld(sub).equals(parent)){
                    if(sub.getEnvironment() == Environment.NETHER){
                        return sub;
                    }
                }
            }
            return null;
        }
        @EventHandler
        public void onPortalEnter(EntityPortalEnterEvent event){
            Entity e = event.getEntity();
            if(e instanceof Player){
                Player p = (Player)e;
                World w = getParentWorld(p.getWorld());
                if(!w.getName().equals("badlands")){
                    return;
                }
                if(warpCountdown.containsKey(p.getName())){
                    return;
                }
                World w1 = p.getWorld();
                TravelAgent ta = new PortalTravelAgent();
                warpCountdown.put(p.getName(), 60);
                if(w1.getEnvironment() == Environment.NETHER){
                    World w2 = getParentWorld(w1);
                    Location loc1 = p.getLocation();
                    loc1.setX(loc1.getX()*8);
                    loc1.setZ(loc1.getZ()*8);
                    loc1.setWorld(w2);
                    Location portalLoc = ta.findOrCreate(loc1);
                    if(loc1.equals(portalLoc)){
                        sendMessage(p,"I cant find a safe place to put a portal on the other side!");
                        return;
                    } else {
                        p.teleport(loc1);
                        sendMessage(p,"Warping through portal! Portals recharging... Ready for another teleport in 60 seconds!");
                        return;
                    }
                }
                if(w1.getEnvironment() == Environment.NORMAL){
                    World w2 = getNether(w1);
                    Location loc1 = p.getLocation();
                    loc1.setX(loc1.getX()/8);
                    loc1.setZ(loc1.getZ()/8);
                    loc1.setWorld(w2);
                    Location portalLoc = ta.findOrCreate(loc1);
                    if(loc1.equals(portalLoc)){
                        sendMessage(p,"I cant find a safe place to put a portal on the other side!");
                        return;
                    } else {
                        p.teleport(loc1);
                        sendMessage(p,"Warping through portal! Portals recharging... Ready for another teleport in 60 seconds!");
                        return;
                    }
                }
                return;
            }
        }
        public boolean handleCommand(CommandSender sender, Command cmd, String label, String[] args){
            World w = Bukkit.getWorld(args[0]);
            ((Player)sender).teleport(w.getSpawnLocation());
            return true;
        }
    }
    
    portal enter event, second from the bottom method

    Oh by the way, whenever this event is thrown, it overloads the server and says the player moved too fast.. :\

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
  15. Offline

    CorrieKay

  16. Offline

    CorrieKay

  17. Offline

    FTWinston

    You shouldn't have to create your own travel agent: normal portalling already has one created.
    You also shouldn't have to run so much of your own logic, or actually do the teleporting yourself: simply calling setTo on the event is enough for it to automatically look for existing nether portals nearby, and create one if necessary, and teleport the player.
     
  18. Offline

    bergerkiller

    Just a heads-up: I had to manually link portals as well. What you need is the following:
    • Find out to what world a given portal teleports. world1 goes to world1_nether, world1_nether goes to world1 for nether portals.
    • Handle the player portal event
    • Manually define the destination location to teleport to.
    Calculation for this is:
    https://github.com/bergerkiller/MyWorlds/blob/master/src/com/bergerkiller/bukkit/mw/Portal.java#L296

    If it is not a normal environment, multiply the x/z with 1/8, if it is a normal world, multiply with 8. Set this destination location in the player portal event.
     
    CorrieKay likes this.
Thread Status:
Not open for further replies.

Share This Page