ID:2085669
 
(See the best response by Ter13.)
I'm designing a minimap snippet, and so far its going really good. I got it to where the image of the entire map is put together in 1 huge icon. Now my goal is to display a small area of the icon depending on where the user is located. My innate impulse is to have all the terrains crop out their designated piece from the big icon, and when a player moves over that terrain it will easily display the icon. I can see this working but I'm worried it will take hold of too much ram. And I don't want to crop the image everytime a player moves cause they could certainly cause some lag though I'm unsure of the effectiveness of cropping icons. Let me know what do you think would be my best approach for an effective solution?

Okay, cropping per Movement seems to be getting me the best results.
Have another player connect.

Watch what happens.

Dynamic cropping is a terrible idea because the icons you are generating per-movement are never thrown away.

In fact, minimaps and BYOND are like oil and water.
Couldn't you use the matrix datum to zoom up on a certain spot?
I don't see how that could work. Need a way to make parts of the icon not visible. Someone did join and it worked just fine. thought I know it can be a different story in a populated game.
I'd go about it by using a second map, may sound odd but it does the cropping for you, then you can just move the image or zoom as you'd like.

EDIT: I wonder if it's possible to make the second map a circle with the transparency thing to get a circle minimap, that'd be cool.
Best response
Nah, use a master plane.

Just set it up so that only a square is white, and the rest of the plane is black, then multiply colors.

No need for a second map, and you can use round shapes.

@Rotem: That's not possible with a second map. You can't have in-window transparency.
What you guys are saying makes no sense to me. but I'm in the mist of trying it.
I don't understand what you mean by master plane and you're saying I should create white square which will be the visible area of the map then multiple it to a black square which is the same size of the big map icon, then add the big map on top of it? I don't understand the process you are suggesting.
Yeah so not particular sure on what you mean but here is an example.
        Test()
var/icon/worldicon=wholemap[1]//Big Map Icon
var/size=worldicon.Width()// What the size of the icon
var/icon/black=new('blank.dmi',"black")
black.Scale(64,64)
black*=worldicon
var/obj/j=new/obj/Background
j.plane=1
j.icon=black
j.loc=src.loc
Look up appearance_flags in reference, scroll down there's a nice plane master example there.

In your code you're using icon operations you should probably avoid, you'll notice "matrix datum" was mentioned before, look up "matrix" and "transform" in the reference as well.

You will also need BYOND 510 beta for plane master.
Okay well guys you are freaking awesome. I got it to work with plane master and its really smooth. Running into 2 minor issues.

1) The map is taking some a slight alpha even if I take dynamically set its alpha to 255 it still has it.
2) When I bring my players location near east area of the map, the screen will glitch cuz the minimap that is shifting screen_loc is something like "-1:-1,4:-8"
Is there a flag or something I can set to make an object not show up as a border object?
1. Could we have a bit more info, some code or anything to look at. I'd rather not guess.


2. Wouldn't screen_loc -1,-1 shift your entire map? I suppose you can try Translate() on the matrix instead to move it without needing to go in the negatives on screen_loc (this is me guessing)

3. If it's lookin' awesome, share some screenies.

Okay, my solution to the border screen object, was to make the minimap object shift purely off of pixeloff set.

The code is ready to go. I just would like to know of a way to get rid of its transparency which I believe it gets from the plane_master multiplication.
I'll take a wild guess then, if your plane_master's color looks like this:

color = list(null,null,null,null,"#333f")


Try changing it to full black instead.
All Problems Solved


This is my entire minimap code besides the display of nearby allies/enemies. If you see any potential optimization let me know please.
var/minimap[100]//Not sure if this is the best way to store/initializing saving of turf's minimap icons
proc
TPixelGet1()//Call at world New()
if(!LoadMiniMap())//Checks if theres a previous minimap icon that can be loaded
for(var/p in typesof(/turf))//This loop creates the miniture version of all turfs in game so can be used for
if(p!=/turf)
var/turf/t=new p(locate(1,1,1))
var/icon/i=icon(t.icon,t.icon_state)
i.Scale(3,3)
minimap[t.type]=i
var/mapunitsize=5
var/pixelscale=3
for(var/turf/T in world)
var/icon/worldicon=wholemap[T.z]
if(!wholemap[T.z])
wholemap[T.z]=new/icon('blank.dmi')
var/sizex=world.maxx*pixelscale/mapunitsize
var/sizey=world.maxx*pixelscale/mapunitsize
worldicon=wholemap[T.z]
worldicon.Scale(sizex,sizey)
var/obj/imageobj=minimap[T.type]
if(imageobj)
worldicon.Blend(imageobj.icon,pick(ICON_OVERLAY,ICON_UNDERLAY),T.x*pixelscale/mapunitsize,T.y*pixelscale/mapunitsize)
if(T.x%(world.maxx/2)==0)
sleep(1)
//You might want to use SaveMiniMap() after the entire worldminimaps are created

var/list/wholemap[world.maxz]
obj
WorldMap
blend_mode = BLEND_MULTIPLY
plane = 2
layer=4
proc
ChangeIcon(mob/owner)
set waitfor=FALSE
src.icon=wholemap[owner.z]
var/icon/worldicon=wholemap[1]
var/size=worldicon.Width()
var/minimapratio=world.maxx/size
var/sx=3
var/sy=9
var/px=-3-round(((owner.x-size/4)/minimapratio))
var/py=-2-round(((owner.y-size/4)/minimapratio))
screen_loc="[sx]:[px],[sy]:[py]"
obj/minimap_plane//Master Plane
screen_loc = "3,9"
plane = 2
blend_mode = BLEND_OVERLAY//We want the minimap to be solid, so BLEND_OVERLAY it is
appearance_flags = PLANE_MASTER | NO_CLIENT_COLOR
mouse_opacity = 0
image/visiblearea
plane = 2
blend_mode = BLEND_ADD
icon = 'blank.dmi'//White icon depicts minimap size
icon_state="white"
image/border
plane = 2
blend_mode = BLEND_ADD
icon = 'blank.dmi' //Gives minimap a border
icon_state="black"
proc//Saving and loading so you dont have to recreate the entire world maps each reboot
SaveMiniMap()
var/savefile/F=new("savefiles/minimap")
F<<wholemap
LoadMiniMap()
var/savefile/F=new("savefiles/minimap")
var/list/l
F>>l
if(l)
wholemap=l
return 1
return 0
mob
var
obj
planemaster//defined to display allys/enemy objects on it
worldmap//Each player need a copy of the world map since each image will be shifting depend on the players location
Login()
..()
worldmap=new/obj/WorldMap(src)
planemaster=new/obj/minimap_plane
client.screen += planemaster
planemaster.overlays += /image/border
planemaster.overlays += /image/visiblearea
client.screen += worldmap
world<<"[src] has logged in"
Move()
if(client) spawn(0) worldmap:ChangeIcon(src)
..()