Room persistent labels

Share your scripts and packages with other Mudlet users.
Post Reply
User avatar
chris
Posts: 493
Joined: Fri Jun 17, 2011 5:39 am

Room persistent labels

Post by chris »

Here's a modified version of vadi's room label code to create labels that persist with rooms

Usage:
pass a string to tmap:roomLabel

The string can be like:
roomid dir offset fg bg message

For instance:
123 n 1,1,0 red blue this is a label north
Code: [show] | [select all] lua
tmap.shortToLong = {["n"]="north", ["ne"]="northeast",["east"]="east",
						 ["se"]="southeast",["s"]="south",["sw"]="southwest",
						 ["w"]="west",["nw"]="northwest",["u"]="up",["d"]="down"}
tmap.dirtypes = {north=1, northeast=2, northwest=3, east=4, west=5,
	south=6, southeast=7, southwest=8, up=9, down=10, ["in"]=11, out=12}
tmap.unitVectors = {[1]={0,1,0}, [2]={1,1,0}, 
		[3]={-1,1,0}, [4]={1,0,0},
		[5]={-1,0,0}, [6]={0,-1,0}, 
		[7]={1,-1,0}, [8]={-1,-1,0},
		[9]={0,0,1}, [10]={0,0,-1}}
-------------------------------------------------
-- room label the room I'm in
-- room label 342 this is a label in room 342
-- room label green this is a green label where I'm at
-- room label green black this is a green to black label where I'm at
-- room label 34 green black this is a green to black label at room 34
-- directional room label:
-- room label 34 nw 5,5,0 this is a green to black label at room 34 offset by 5,5 from the northwest
-- how it works: split input string into tokens by space, then determine
-- what to do by checking first few tokens, and finally call the local
-- function with the proper arguments
function tmap:roomLabel(input)
  local tk = input:split(" ")
  local room, fg, bg, message = tmap.lastId, "yellow", "red", "Some room label"

  -- input always have to be something, so tk[1] at least always exists
  if tonumber(tk[1]) then
    room = tonumber(table.remove(tk, 1)) -- remove the number, so we're left with the colors or msg
  end

  -- next: is this a dir offset?
  local dir = "n"
  if tk[1] and tmap.shortToLong[tk[1]] then
    dir = table.remove(tk, 1)
  end

  -- next: is this a dir offset sequence?
  local dOffset = "1,1,1"
  local dx,dy,dz = 1,1,0
  if tk[1] and string.find(tk[1],"%d,%d,%d") then
    dOffset = table.remove(tk, 1)
	 local dInfo = string.split(dOffset,',')
	 dx = tonumber(dInfo[1])
	 dy = tonumber(dInfo[2])
    dz = tonumber(dInfo[3])
  end
  if tmap.unitVectors[tmap.dirtypes[tmap.shortToLong[dir]]][1] ~= 0 then
  	dx = dx*tmap.unitVectors[tmap.dirtypes[tmap.shortToLong[dir]]][1]
  end
  if tmap.unitVectors[tmap.dirtypes[tmap.shortToLong[dir]]][2] ~= 0 then
	  dy = dy*tmap.unitVectors[tmap.dirtypes[tmap.shortToLong[dir]]][2]
  end
  if tmap.unitVectors[tmap.dirtypes[tmap.shortToLong[dir]]][3] ~= 0 then
	  dz = dz*tmap.unitVectors[tmap.dirtypes[tmap.shortToLong[dir]]][3]
  end

  -- next: is this a foreground color?
  if tk[1] and color_table[tk[1]] then
    fg = table.remove(tk, 1)
  end

  -- next: is this a backround color?
  if tk[1] and color_table[tk[1]] then
    bg = table.remove(tk, 1)
  end

  -- the rest would be our message
  if tk[1] then
    message = table.concat(tk, " ")
  end

  -- if we haven't provided a room ID and we don't know where we are yet, we can't make a label
  if not room then
    tmap:echo("We don't know where we are to make a label here.") return
  end

  local x,y,z = getRoomCoordinates(room)
  local f1,f2,f3 = unpack(color_table[fg])
  local b1,b2,b3 = unpack(color_table[bg])

  -- finally: do it :)

  local lid = createMapLabel(getRoomArea(room), message, x+dx, y+dy, z+dz, f1,f2,f3, b1,b2,b3)
  tmap:echo(string.format("Created new label #%d '%s' in %s.", lid, message, getRoomAreaName(getRoomArea(room))))
  local labels = getRoomUserData(room, "mapLabels")
  --labels is structured like: dir|||id|||label|||x,y,z offset|||fg|||bg!&!dir2|||id|||label|||xyz...
  local lTable = string.split(labels,'!&!')
  local oStr = ""
  local dirSet = false
  local labelRep = tostring(getRoomArea(room))..'.'..tostring(lid)
  for i,v in pairs(lTable) do
    local entry = string.split(v, '|||')
	 if entry[1] == "" then
    elseif entry[1] == dir then
		oStr = oStr..dir..'|||'..labelRep..'|||'..message..'|||'..dOffset..'|||'..fg..'|||'..bg..'!&!'
      dirSet = true
		local linfo = string.split(entry[2], '%.')
		deleteMapLabel(tonumber(linfo[1]),tonumber(linfo[2]))
    else
	 	oStr = oStr..v..'!&!'
    end
  end
  if not dirSet then
		oStr = oStr..dir..'|||'..labelRep..'|||'..message..'|||'..dOffset..'|||'..fg..'|||'..bg..'!&!' 
  end
  oStr = string.sub(oStr,1,-4)
  setRoomUserData(room, "mapLabels",oStr)
end

function tmap:rebuildRoomLabels()
	local labels = searchRoomUserData("mapLabels","")
   for roomid, label in pairs(labels) do
		setRoomUserData(roomid, "mapLabels", "")
		if label == "" then
		else
			local entry = string.split(label, '!&!')
			for i, info in pairs(entry) do
				local li = string.split(info, '|||')
				local linfo = string.split(li[2], '%.')
				tmap:roomLabel(roomid.." "..li[1].." "..li[4].." "..li[5].." "..li[6].." "..li[3])
				deleteMapLabel(tonumber(linfo[1]),tonumber(linfo[2]))
			end
		end
   end
end
--tmap:rebuildRoomLabels()
--tmap:roomLabel("43804 n 1,5,0 this is a test")

Post Reply