This is something I originally wrote for Kingdoms iPhone, which has since been used and tested on Graal Kingdoms for the Easter event. It allows you to create clones ("instances") of a level (or set of levels).
Example usage: You have a quest which can be completed by groups of three players. Each group of three players needs their own private set of levels so that other players don't interfere with their quest. This script will clone the levels and take care of changing links, as well as deleting the levels after you're done with them.
An example of creating an instance:
PHP Code:
temp.instance = new EasterMapInstance();
temp.instance.data.owner = temp.owner;
temp.instance.prepare();
When you create an instance, it does a couple things:
- Copies all the files you specify to a temporary folder.
- For each GMAP specified, it copies all the levels and changes all the links inside them. The GMAP is also loaded via addgmap.
- For each level specified, if links inside the level point to a level which is being copied, those links will be updated to point to that level inside the instance. If the links link outside the instance, they are left alone.
- For each level, a small NPC is inserted which sets level.instance to the instance object. This makes it easy for scripts to interact with the instance.
Creating a new instance type involves adding the following to the main
InstanceManager NPC:
PHP Code:
// Easter Maps
EasterMapInstance = newInstanceTemplate("GameInstance");
EasterMapInstance.join("easter2k11_instance_map");
You then need to create the class which controls the instance. A simplified example from the Easter event:
PHP Code:
// class "easter2k11_instance_map"
public function prepare() {
// choose a random map
this.mapLevelName = EasterMapControl.getRandomMapName();
temp.resources = {
"levels/world/events/easter2k11/maps/" @ realMapLocation
};
this.setResources(resources); // set which resources are needed
this.initResources(); // make a copy of those resources
// close after 10 minutes
this.scheduleEvent(600, "onCloseInstance");
// start the timeout
this.trigger("timeout");
}
public function enterPlayer(temp.pl) {
// this.getResourceName(resourceName) accepts the original name
// and returns the name of the instance-specific resource
temp.pl.setLevel2(this.getResourceName(this.mapLevelName), 32, 32);
}
function onCloseInstance() {
// time ran out; you'll probably want to warp players out first,
// although it will handle it for you if you don't
this.closeInstance();
}
function onTimeOut() {
if (this.data.owner == null || this.data.owner.level.instance != this) { // the owner logged out or left the instance
this.closeInstance();
}
this.setTimer(10);
}
As you can see, it handles all of the hard stuff (like changing links and copying files) for you. It also deletes the temporary files when the instance is closed.
Make sure to close the instance or you will essentially have created a memory leak, and you will also litter the folder with files.
One thing to note is if you are creating GMAPs, it will add them to
gmaps= in server options. There is currently no way to remove them except for manually, so it will crowd server options very fast. There is no negative effect on the server that I am aware of—Kingdoms was running fine with at least 300 maps in
gmaps=—but you will want to remove them periodically. If Stefan adds a way to remove them dynamically, I will update this script.
It should be able to copy any kind of GMAP (including ones generated with the terrain generator or dungeon generator).
Setup
To get started, you first need to give
(npcserver) rights to a location for files to be stored (be sure they're also in folder config). You can change these rights to suit your preferences:
Quote:
rw levels/temp/*.nw
rw levels/temp/*.gmap
|
You must also give it read rights to the location where you store the files to be copied.
Quote:
r levels/world/quests/*.nw
|
Then, upload the scripts in the attached archive. Change the settings in InstanceManager to suit your server's temp path and unstick location (called "emergency exit" since it's where players are kicked to if you close the instance without warping them out).
To add more instances, just modify the Easter example which I left commented out.
If you have any questions or if I left anything out just post here and I'll be happy to help
.