ID:1705706
 
BYOND Version:506
Operating System:Windows 7 Pro
Web Browser:Firefox 33.0
Applies to:Dream Seeker
Status: Open

Issue hasn't been assigned a status value.
Descriptive Problem Summary:

Screen objects with maptext in them don't seem to move with transform = matrix(10, 10, MATRIX_TRANSLATE)

It works fine with objects without maptext in them.


Code Snippet (if applicable) to Reproduce Problem:
        introLettersAnimation
layer = 99
maptext_width = 500
maptext_height = 1000
alpha = 0
New(client/C, Text as text, var/location, var/color, var/size, var/sleepTime = 40 )
..()
if(C)
if(C.mob)

maptext="<b><font face = 'bubble' size=[size] color=[color] >[Text]</font></b>"
screen_loc = location
C.screen += src
animate(src, alpha=255, time = 60, loop =1)
sleep(60)
animate(src, transform = matrix(20, 10, MATRIX_TRANSLATE), alpha=0, time = sleepTime)
sleep(sleepTime)
if(C)
C.screen -= src


Expected Results:
For it to move accordingly.
Actual Results:
Everything else in the animate() works except for the transform.

Workarounds:
None that I know of.

Bump
The actual bug that's going on here is that maptext positioning has not been updated to use transform. because the drawing method maptext uses doesn't support rotation, scaling or skewing, last I knew.

Can we get maptext to update its position based on the c and f matrix coordinates only when in the screen list of the client?

My current project actually depends on a number of hud objects acting in unison. I use transform to position the individual hud elements according to their local position within the interface element. I actually have interface elements implemented as datums which can contain multiple hud objects. When an interface element is moved, the screen_loc of every object is updated to a single value. Because I'm using multiple screen objects, it's much faster to use a single screen_loc for all of the objects in the ui element datum than to update the screen_loc individually for each object.

Transform allows me to use a single string for every object, while keeping the local offset from the parent uielement's position stored in a separate variable.

Since the maptext doesn't relocate in the screen based on the transform variable, this actually breaks my current approach and I have to individually change the screen_loc of any object that has maptext, which is a suboptimal solution.

For reference, he's essentially what I'm doing:

uielement
var/tmp
client/client
list/contents
list/registry
list/__reverse_registry

screen_x = 0
screen_y = 0
anchor_x = "WEST"
anchor_y = "SOUTH"
width = TILE_WIDTH
height = TILE_HEIGHT
proc
//called when any hudobj belonging to this uielement is clicked on
onClick(hudobj/object,location,control,params)

//called when any hudobj belonging to this uielement is dblclicked on
onDblClick(hudobj/object,location,control,params)

//called when any hudobj belonging to this uielement has the mouse down button pressed on it
onMouseDown(hudobj/object,location,control,params)

//called when any hudobj belonging to this uielement has the mouse up button pressed on it
onMouseUp(hudobj/object,location,control,params)

//called when any hudobj belonging to this uielement is dragged
onMouseDrag(hudobj/src_object,atom/over_object,src_location,over_location,src_control,over_control,params)

//called when any hudobj belonging to this uielement is dropped
onMouseDrop(hudobj/src_object,atom/over_object,src_location,over_location,src_control,over_control,params)

//called the mouse enters any hudobj belonging to this uielement
onMouseEntered(hudobj/object,location,control,params)

//called when the mouse exits any hudobj belonging to this uielement
onMouseExited(hudobj/object,location,control,params)

//called when the mouse moves over any hudobj belonging to this uielement
onMouseMove(hudobj/object,location,control,params)

//register a HUD object by name. This makes managing object states from the element level much easier.
RegisterHUDobj(name,hudobj/object)
if(!registry)
registry = list()
__reverse_registry = list()
if(!contents)
contents = list()
//make sure the name isn't already taken
var/hudobj/oldobj = src.registry[name]
if(oldobj)
//if it's taken, simply clear the reverse registry entry for the old object
__reverse_registry[oldobj] = null
oldobj.id = null

//secure the registry links
src.registry[name] = object
__reverse_registry[object] = name

//if the new object isn't already in the contents list, add it.
contents |= object
object.id = name

//return the added object to make use of inline initialization possible
return object

//add elements to the contents list --this won't register object names
Add()
if(!contents)
contents = list()
var/len = args.len
for(var/count in 1 to len)
contents.Add(args[count])

//remove elements from the contents list --this will automatically clean up registered names
Remove()
var/hudobj/object
var/name
var/len = args.len
for(var/count in 1 to len)
object = args[count]
if(islist(object))
.(arglist(object))
else
//make sure to clean up the registry if you are removing a registered object
name = __reverse_registry[object]
if(name)
__reverse_registry.Remove(object)
registry.Remove(name)
object.id = null
if(!registry.len)
registry = null
__reverse_registry = null
if(!contents.len)
contents = null

//add all hud objects in the contents to the client's screen
Show()
client.screen.Add(contents)

//remove all hud objects in the contents from the client's screen
Hide()
client.screen.Remove(contents)

setSize(W,H,UpdatePos=1)
width = W
height = H
if(UpdatePos&&(anchor_x!="WEST"||anchor_y!="SOUTH"))
setPos(screen_x,screen_y,anchor_x,anchor_y)

setPos(X,Y,AnchorX="WEST",AnchorY="SOUTH")
var/ox
var/oy
screen_x = X
anchor_x = AnchorX
screen_y = Y
anchor_y = AnchorY
switch(AnchorX)
if("WEST")
ox = X + client.screen_inner_x
if("EAST")
ox = TILE_WIDTH - width - client.screen_inner_x
if("CENTER")
ox = -ceil(width/2)
switch(AnchorY)
if("SOUTH")
oy = Y + client.screen_inner_y
if("NORTH")
oy = TILE_HEIGHT - height - client.screen_inner_y
if("CENTER")
oy = -ceil(height/2)
var/sloc = "[anchor_x]+0:[ox],[anchor_y]+0:[oy]"
for(var/hudobj/h in contents)
h.screen_loc = sloc

New(client/Client,Width=TILE_WIDTH,Height=TILE_HEIGHT,ScreenX=0,ScreenY=0,AnchorX="WEST",AnchorY="SOUTH")
client = Client
setSize(Width,Height)
setPos(ScreenX,ScreenY,AnchorX,AnchorY)


uielement
chatpanel
var
messages = ""

hudobj/chatbg/background
hudobj/foreground
hudobj/scrollbar/scrollbar
hudobj/scrolltrack/scrolltrack

New(client/Client,Width=DEFAULT_CHAT_WIDTH,Height=DEFAULT_CHAT_HEIGHT)
background = new/hudobj/chatbg(null,src,STATIC)
Add(background)
scrolltrack = RegisterHUDobj("scrolltrack",new/hudobj/scrolltrack(null,src,STATIC))
RegisterHUDobj("scrolltop",new/hudobj(null,src,STATIC,list(icon='chat_buttons.dmi',icon_state="1")))
RegisterHUDobj("scrollup",new/hudobj(null,src,STATIC,list(icon='chat_buttons.dmi',icon_state="2")))
RegisterHUDobj("scrolldown",new/hudobj(null,src,STATIC,list(icon='chat_buttons.dmi',icon_state="3")))
RegisterHUDobj("scrollbottom",new/hudobj(null,src,STATIC,list(icon='chat_buttons.dmi',icon_state="4")))
scrollbar = RegisterHUDobj("scrollbar",new/hudobj/scrollbar(null,src,STATIC))
foreground = new/hudobj(null,src,STATIC,list(transform=matrix(1,0,4,0,1,16)))
Add(foreground)
..()

setSize(Width,Height,UpdatePos=1)
..(clamp(Width,MIN_CHAT_WIDTH,MAX_CHAT_WIDTH),clamp(Height,MIN_CHAT_HEIGHT,MAX_CHAT_HEIGHT),UpdatePos)
background.setSize(width,height)
scrolltrack.setSize(height-64)
scrollbar.setSize(height-64) //change this to account for chat height
var/hudobj/h = registry["scrolltop"]
var/matrix/m = matrix(1,0,width-10,0,1,height-24)
h.transform = m
h = registry["scrollup"]
m.f -= 8
h.transform = m
h = registry["scrolldown"]
m.f = 24
h.transform = m
h = registry["scrollbottom"]
m.f -= 8
h.transform = m
m.f = 32
scrollbar.transform = m
--m.c
scrolltrack.transform = m
foreground.maptext_width = width-20
foreground.maptext_height = height-32

proc
AddMessage(msg)
messages += msg
foreground.maptext = "<DIV valign='bottom'>[messages]</DIV>"

hudobj
chatbg
proc
setSize(W,H)
underlays = list()
var/obj/o = new()
var/sw = (W - 32)/16
var/sx = 16+(W - 48)/2
var/sh = (H - 32)/16
var/sy = 16+(H - 48)/2
var/ew = W - 16
var/eh = H - 16
o.icon = 'chat_placeholder.dmi'
o.layer = FLOAT_LAYER
o.color = "#202020"
o.alpha = 64
o.icon_state = "1"
underlays += o
o.icon_state = "2"
o.transform = matrix(sw,0,sx,0,1,0)
underlays += o
o.icon_state = "3"
o.transform = matrix(1,0,ew,0,1,0)
underlays += o
o.icon_state = "4"
o.transform = matrix(1,0,0,0,sh,sy)
underlays += o
o.icon_state = "5"
o.transform = matrix(sw,0,sx,0,sh,sy)
underlays += o
o.icon_state = "6"
o.transform = matrix(1,0,ew,0,sh,sy)
underlays += o
o.icon_state = "7"
o.transform = matrix(1,0,0,0,1,eh)
underlays += o
o.icon_state = "8"
o.transform = matrix(sw,0,sx,0,1,eh)
underlays += o
o.icon_state = "9"
o.transform = matrix(1,0,ew,0,1,eh)
underlays += o

scrollbar
proc
setSize(H)
overlays = list()
var/obj/o = new()
o.icon = 'chat_scrollbar.dmi'
o.layer = FLOAT_LAYER
o.icon_state = "1"
overlays += o
if(H>8)
o.icon_state = "2"
o.transform = matrix(1,0,0,0,(H-8)/16,4+(H-24)/2)
overlays += o
o.icon_state = "3"
o.transform = matrix(1,0,0,0,1,H-4)
overlays += o

scrolltrack
proc
setSize(H)
overlays = list()
var/obj/o = new()
o.icon = 'chat_scrolltrack.dmi'
o.layer = FLOAT_LAYER
o.color = "#202020"
o.alpha = 128
o.icon_state = "1"
overlays += o
if(H>8)
o.icon_state = "2"
o.transform = matrix(1,0,0,0,(H-8)/16,4+(H-24)/2)
overlays += o
o.icon_state = "3"
o.transform = matrix(1,0,0,0,1,H-4)
overlays += o


Unfortunately, screen locations for maptext don't figure in transform.c or f, so my foreground object renders in the right place, but the maptext renders in the wrong place.
This is near the top of my to-do list.
Friendly bump