R, 106 9696 88 bytes
function(n,k,l)n*mean(matrix(apply(expand.grid(rep(list(NA,1:k),w<-n+abs(l))),1,sort,l>0),wT)[1:n,])
Credit to Dominic van Essen for the l>0
for the descending
argument to sort
, and for 9 bytes golfedgolfing down. a lot of other bytes!
function(n,k,l,w=n+abs(l)){
D <- expand.grid(rep(list(1:k),w)) # data.frame of all possible die rolls, across rows
S <-apply(D,1,sort,l>0) # sort the rows of D in descending order if l <= 0 and ascending otherwise. This results in columns of dice rolls.
M <- matrix(S,w) # make S a Matrix of w rows. This helps the edge case n = 1.
H <- head(M,n) # take the first n rows of M
mean(colSums(H)) # take the mean of the dice rolls, and return
}