Map Instancing

by Forum_account
An easy way to create multiple instances of a map. Each instance is put on its own z level. [More]
To download this library for your Linux/Mac installation, enter this on your command line:

DreamDownload byond://Forum_account.MapInstancing##version=5

Emulator users, in the BYOND pager go to File | Open Location and enter this URL:

byond://Forum_account.MapInstancing##version=5

1738 downloads
Version 5
Date added: Oct 10 2011
Last updated: Jul 14 2012
27 fans
The library provides you with ways to easily make and manage copies of maps. Here's all you need to do to use it:

// make a copy of the second z level
var/Map/map = maps.copy(2)
world << "The new copy is on z level [map.z]."

// later on we call free() to make the z level available for other maps to use
map.free()


Calling maps.copy() makes a copy of a z level and returns a /Map object you can use to manage the map.

When you make a copy of a map, the library creates a "blueprint" of the original map. The blueprint is all you need to make a new copy, you can delete the original:

// make the blueprint for the dungeon
var/MapBase/dungeon = new(2)

// tell the library it can re-use the second a level
maps.clear(2)

// later on, make an instance of the dungeon
var/Map/map = dungeon.make()


Calling maps.clear() tells the library that you're done using a z level and it can use it the next time you ask it to copy a map. Because you've created the blueprint it doesn't matter if the original map is deleted.

You can also save and load these blueprints:

// saving
var/MapBase/base = new(2)
base.save("dungeon.map")

// loading
var/Map/map = maps.copy("dungeon.map")


You save the blueprint of the map, not an actual instance of the map. This lets you create copies of map that aren't compiled into the game's .dmb file. You create a copy of the saved map just like you create a copy of an existing z level, using the maps.copy() proc. The difference is that you pass it the filename.

Version History

Version 5 (posted 03-03-2012)
  • Updated the library to make it work with the Region library. If you place a /region object on a map and copy the map, the copied turfs will be added to the region too.
  • I removed the use_warp verb from the demos, now you automatically use the warp by stepping on it.
Version 4 (posted 02-15-2012)
  • Changed the order of events when maps are created - the area of the turf is now set before the new turf is created, this way the turf's New() proc can check the type of its loc (the area).
  • Removed the z var from the /MapBase object.
  • Added the get() proc on the Map object which returns a list of all objects of the specified type on that map's z level.
  • Added the reset() proc to the /Map object. This is similar to repop except it re-generates the entire map on the same z level. This not only restores deleted objects, but restores the initial state of each object and turf. There is an example of this in the demo called "demo".
  • Added the atom.is_instanced() proc which returns 0 or 1. This is used by the library to determine which objects get stored in the MapBase object. You can override this proc to change which objects are saved. By default, all objects are stored except mobs with clients.
Version 3 (posted 10-12-2011)
  • Added saving and loading and a demo that shows how to use it - see saving-and-loading-demo\demo.dm
Version 2 (posted 10-12-2011)
  • Added the maps.clear() proc to free up existing z levels (even ones that weren't dynamically created by the library).
Version 1 (posted 10-11-2011)
  • Initial version

Comments

KetchupKid: (Jan 10 2012, 8:54 am)
Well I've attempted to fix it. The loading seems to work as it sends me to a new z level when I go to a new map. But its still loading a black screen so I'm thinking that it has to do with saving.

Right now I'm reading through the library again. But I still don't know whats going wrong. If I can't figure it out soon, I'll probably go back to regular maps. I just liked the idea of having all my maps at 1kb.
Forum_account: (Jan 8 2012, 11:39 am)
The saving and loading was added as an afterthought because it was easy to add. If there are more features that could be added to help you with this problem that you think could belong as part of the library, let me know =)
KetchupKid: (Jan 8 2012, 11:37 am)
I think you may be right on #1. I'll look into it. Its setup this way so that it will save the maps when I have them all included and load the saved maps when I don't have them included. But I think its just saving every time.
Forum_account: (Jan 8 2012, 11:33 am)
I'm not sure how that New() proc is being called, but I'm guessing the problem is somewhere in there.

When you're calling it, if the if statement is true it doesn't make an instance of a map, it just creates a base and saves it. It only makes a copy of the if statement is false. If it's not working, I'd guess that either:

1. The else clause in the New() proc is never being executed.

2. The map isn't being saved or loaded properly.

To troubleshoot #1 you just need to change your code. To troubleshoot #2 you'd have to edit the library's code. There's not much code to it. You'd just need to add some output statements to the MapBase object's constructor to make sure it's getting created and getting created properly, and add some output statements to its make() proc to see what is happening when an instance is being made.
KetchupKid: (Jan 8 2012, 8:52 am)
When loading a saved map, it loads a black blank map. I can't figure out what I'm doing wrong.

//Saving and Loading in the New() proc of my mapDatum.
New(Name, Edge_limit_x, Edge_limit_y, Music, start_pos_X, start_pos_Y)
if(world.maxz > 1)
mapBase = new(map_zname(Name))
if(fexists("[Name].map"))
fdel("[Name].map")
mapBase.save("maps/saved/[Name].map")
world << "saved [Name]"
else
_map = maps.copy("maps/saved/[Name].map")
if(_map)
z = _map.z

//map locating
goToMap(var/mapDatum/map)
src.loc = locate(map.start_pos_x, map.start_pos_y, map.z)
if(src.client)
world << map.z
src.client.edge_limit = "SOUTHWEST to [map.edge_limit_x],[map.edge_limit_y]"

//how goToMap() is called
mob.goToMap(tagCore.curMap)


[Edit]
It also doesn't display a z level when calling world << map.z, its just a blank output line.