Sorry for nit-picking, but
- the on disconnect / on quit event won't kill the timers (ocoff alias), as they don't know a $chan value. But then, you don't need those events at all - you don't start any offline timer smile
- what's the use of the variable if you evaluate it instantly to the $chan?
- all the scripts (not only yours) do evaluate the channel name in a timer command frown


My two cents:
Code:
; ----- SETUP START -----
; duration (in s) to wait for op after join and between requests
alias oc.delay { return 15 }
; numer of times to ask for ops before part
alias oc.request { return 3 }
; ----- SETUP END -----

on me:*:join:#: oc.beg
on me:*:part:#: oc.off 
on *:deop:#: if ($opnick == $me) oc.beg
on *:kick:#: if ($knick == $me) oc.off
on *:op:#: if ($opnick == $me) oc.off

alias -l oc.beg {
  .timeroc $+ # $$oc.request $$oc.delay oc
  oc.ask # $calc($oc.request * $oc.delay)
}
alias -l oc {
  var %c = $mid($ctimer,3-)
  if ($me isop %c) { .timeroc $+ %c off }
  elseif ($timer($ctimer).reps == 0) { part %c }
  else { oc.ask %c $calc($timer($ctimer).reps * $timer($ctimer).delay) }
}
alias -l oc.off { .timeroc $+ $chan off }
alias -l oc.ask { msg $1 I need to be opped. If I don't get ops, I'll auto-part in $duration($2) }