You had a logic problem in the script, changing nicks would infact defeat the script, as the timer was using the contents of $2 the passed nick, and not the current contents of %warned.1 at the time the timer went off.
This code should work.
on *:TEXT:!warn *:*:{
if ($nick == %logged.in.nick) {
set %warned.1 $2
set %reason $4-
TIMERwarner 1 $3 .ban -ku $+ 30 $chan [color:blue]$(%warned.1,)[/color] $4- [color:blue]$(| unset %warned.1,)[/color]
.msg $chan 4 $2 2is being warned because they're3 %reason 2,they need to say 7sorry 2or they will be kbed for 30 secs in10 $3 seconds...
.notice %warned.1 2You better say 7sorry 2, or you will be kicked...
}
}
on *:NICK:{
if ($nick == %warned.1) {
set %warned.1 $newnick
.notice %warned.1 2If that was to get out of this, it didn't work...
}
}
on *:TEXT:sorry:#:{
if ($nick == %warned.1) {
TIMERwarner off
.msg $chan 4 %warned.1 2says they're sorry for3 %reason
.notice %warned.1 2 You were warned because you were3 %reason 2, dont do it again...
.notice %warned.1 2Next time there will be no warning... Just a KB!
[color:blue]unset %warned.1[/color]
}
}
The first blue section replaces $2 with the $(%warned.1,) this is so the timer has the variable %warned.1 in there not the contents of $2 since changing nick would bet $2, being that it is the old nick. The $(<text>,) is needed to tell mirc, DONT evaluate <text> (in this case dont get the contents of %warned.1) but just leave it as "%warned.1".
The second blue section adds a second command to the timer "| unset %warned.1" command sepertor and unset command, both are incased in another $(<text>,) to tell mirc this is still part of the timer command, and to not cause %warned.1 to be evaluated, as it might have been
The 3rd blue bit is just unsetting the %warned.1 in the sorry section.