Matrix multiplication isn't too simple for me at the moment, but it doesn't matter because DM's transformation matrices provide procs to just do 2D transformations. I don't have to know that the clockwise rotation matrix is matrix(cos, sin, 0, -sin, cos, 0) or whatever it is, and multiply the matrices together by hand.

Similarly, I don't need the mouse events to be changed in order for them to work how I want them to, because I have this super short and simple snippet that handles everything for me. I don't have to look it at all if all I need to use are the mouse_x and mouse_y variables, because it just works.
In response to Flysbad
Here's my current method for tracking the mouse. The mouse position tracking code is much improved, if you compare the new SetMouseScreenLoc() with the old MousePosition().
#ifndef TILE_WIDTH
#define TILE_WIDTH 32
#endif

#ifndef TILE_HEIGHT
#define TILE_HEIGHT 32
#endif

client
var tmp
mouse_x
mouse_y
mouse_screen_loc

New()
. = ..()
screen += new /atom/movable {
name = ""
layer = -1#INF
mouse_opacity = 2
screen_loc = "SOUTHWEST to NORTHEAST"
}

proc
SetMouseScreenLoc(S) if(S && mouse_screen_loc != S)
// if S starts with the map ID, cut it out
if(!isnum(text2num(S)))
S = copytext(S, findtext(S, ":")+1)
mouse_screen_loc = S

// the first number is the tile-x coordinate; go to the next number, etc.
var tx = text2num(S); S = copytext(S, length("[tx]")+2)
var px = text2num(S); S = copytext(S, length("[px]")+2)
var ty = text2num(S); S = copytext(S, length("[ty]")+2)
var py = text2num(S)

// standard conversion
mouse_x = px + (tx-1)*TILE_WIDTH
mouse_y = py + (ty-1)*TILE_HEIGHT

// Try to catch as many mouse events as possible (though in vain):

MouseEntered(object, location, control, params)
SetMouseScreenLoc(params2list(params)["screen-loc"])
..()

MouseMove(object, location, control, params)
SetMouseScreenLoc(params2list(params)["screen-loc"])
..()

MouseDrag(src_object, over_object, src_location, over_location, src_control, over_control, params)
SetMouseScreenLoc(params2list(params)["screen-loc"])
..()


Aiming
If you want to get a vector from your character to the mouse (e.g. aiming), there are certain complications to deal with, but it usually comes down to this kind of subtraction:
client
var
mouse_dx // the 'd' stands for 'delta'
mouse_dy

proc
UpdateMouseDelta(FromX, FromY)
mouse_dx = mouse_x - FromX
mouse_dy = mouse_y - FromY



For example, if your camera doesn't move, you just subtract your position from the mouse's position, because the mouse's position is effectively a position on the map:
client.UpdateMouseDelta(Cx(), Cy())
// (Cx(), Cy()) is the absolute pixel coordinate of the center of your bounding box
This has to be called whenever you need the deltas because they change depending on your position as well as the mouse's position. You can move while your mouse doesn't, and vice versa.


If your camera is always centered on your character, then you have to keep track of the camera's size:
var view_width = ... // in pixels
var view_height = ...
client.UpdateMouseDelta(view_width/2, view_height/2) // this is roughly the center of your screen
If you keep your view size constant, then you know view_width/height. Otherwise, you just have to make sure that this code is properly informed of any changes to your view size. Also, this code only has to run whenever your mouse moves, or less frequently, because player movement isn't involved in the calculation.


And as an added bonus, I'll mention that you can calculate the magnitude and angle of a vector, such as that mouse delta, using these handy dandy math functions:
proc
// length of hypotenuse of triangle with side lengths x and y
hypot(x, y) return sqrt(x*x + y*y)

// clockwise angle from NORTH to a vector's direction
// returns number in (-180, 180]
atan2(x, y) return (x||y) && (x >= 0 \
? arccos(y/sqrt(x*x+y*y)) \
: -arccos(y/sqrt(x*x+y*y)))
client.UpdateMouseDelta(FromX, FromY)
var mouse_distance = hypot(client.mouse_dx, client.mouse_dy)
var mouse_angle = atan2(client.mouse_dx, client.mouse_dy)



edit: 8 September 2015
You can also detect the movement of the mouse per frame.
client
var tmp
last_mouse_x
last_mouse_y

mouse_moved_x
mouse_moved_y

SetScreenLoc(S)
..()
if(mouse_x != last_mouse_x || mouse_y != last_mouse_y)
mouse_moved_x = mouse_x - last_mouse_x
mouse_moved_y = mouse_y - last_mouse_y
MouseMoved()
last_mouse_x = mouse_x
last_mouse_y = mouse_y

proc
MouseMoved()
Page: 1 2