# OpenVerse Avatar Functions Module # # This module includes all the functions related # to avatars and avatar movement. # # Module Name - Avatar Functions # Current Maintainter - Cruise # Sourced By - InitMainWindow # # Copyright (C) 1999 David Gale # For more information visit http://OpenVerse.org/ # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, # USA. # Additional Notes # # Performance enhancements with string comparisons. # Performance using curleybraces around functions # CRUISE - 11/08/2001 - Will only call itself if the avatar has multiple # frames and the animate option is set. # proc AnimateAvatar {} { global MV if {$MV(anim.current) == -1} { ChangeAvatar $MV(anim.0) set MV(anim.stop) 1 set MV(anim.running) 0 return } set delay 0 if {$MV(anim.current) == 1 && !$MV(anim.new)} { set delay $MV(anim.final_delay) } if {$MV(anim.running) && $MV(anim.new)} { ChangeAvatar "$MV(anim.0)" set MV(anim.new) 0 incr MV(anim.current) if {$MV(anim.current) > $MV(anim.frames)} {set MV(anim.current) 1} return } set MV(anim.new) 0 if $MV(anim.stop) { ChangeAvatar "$MV(anim.0)" set MV(anim.running) 0 return } ChangeAvatar "$MV(anim.[expr $MV(anim.current) -1])" set MV(anim.running) 1 incr MV(anim.current) if {$MV(anim.current) > $MV(anim.frames)} { set MV(anim.current) 1 } set do_delay [expr $MV(anim.delay) + $delay] if {$MV(anim.frames) > 1 && $MV(anim.animated)} { after $do_delay AnimateAvatar } } proc RaiseAvatar {who} { global MV errorInfo # Performance Enchancement DRG if {![string compare $who $MV(nick)]} { set image $MV(img) } else { if {[catch {set image $MV($who.icon)}]} { DebugIt "ERROR, Unable to raise $who (RaiseAvatar) Please report this error to cruise@openverse.org" other DebugIt "$errorInfo" other DebugIt "ERROR, Unable to raise $who (RaiseAvatar) Please report this error to cruise@openverse.org" other return } } .top.c raise $image if $MV(names) { KillName $who ShowName $who } } proc AnimateMe {what which} { global MV switch $which { 1 { set file "$MV(avatar_files.$what)" } 2 { set file "$MV(avatar_setup.$what)" } 3 { if {![file exists "$MV(anims)/$what"]} {return} set file "$what" } default { set file "default.av" } } if {[winfo exists .setup.na.l.b.avatars.entry]} { .setup.na.l.b.avatars.entry delete 0 end .setup.na.l.b.avatars.entry insert end "$file" } catch {source "$MV(anims)/$file"} AnimateAvatar } proc ShowNames {} { global MV if $MV(names) { ShowName $MV(nick) # # Process Plugins! # foreach plugin $MV(plugin.traps.ShowNames) { if {![$MV(plugin.traps.ShowNames.$plugin) $MV(nick)]} {return} } foreach who $MV(people) { ShowName $who # # Process Plugins! # foreach plugin $MV(plugin.traps.ShowNames) { if {![$MV(plugin.traps.ShowNames.$plugin) $who]} {return} } } } else { KillName $MV(nick) # # Process Plugins! # foreach plugin $MV(plugin.traps.KillNames) { if {![$MV(plugin.traps.KillNames.$plugin) $MV(nick)]} {return} } foreach who $MV(people) { KillName $who # # Process Plugins! # foreach plugin $MV(plugin.traps.KillNames) { if {![$MV(plugin.traps.KillNames.$plugin) $who]} {return} } } } } proc KillName {who} { global MV catch { .top.c delete $MV($who.nametext) .top.c delete $MV($who.nameplate) } } # # This is the function which displays the name on the screen. # For the name plate. # # CRUISE - 10/24/2001 - took color codes out of name tags. # proc ShowName {who} { global MV # Performance Enhancement DRG if {![string compare $who $MV(nick)]} { set MV($MV(nick).x) $MV(x) set MV($MV(nick).y) $MV(y) set MV($MV(nick).name_x_offset) $MV(anim.x_off) set MV($MV(nick).name_y_offset) $MV(anim.y_off) } # # Replace underscores with spaces # set who_words [split $who "_"] set who_text [join $who_words " "] # # Strip the color codes # set who_text [StripColorCodes $who_text] set width [expr [string length $who_text] * 8] if $MV($who.moving) { set x $MV($who.current_x) set y $MV($who.current_y) } else { set x $MV($who.x) set y $MV($who.y) } # # Set so that a plugin can access this information. # set MV($who.name_tl_x) [expr ($x + $MV($who.name_x_offset)) - ($width / 2)] set MV($who.name_tl_y) [expr ($y + $MV($who.name_y_offset)) - 8] set MV($who.name_br_x) [expr ($x + $MV($who.name_x_offset)) + ($width / 2)] set MV($who.name_br_y) [expr ($y + $MV($who.name_y_offset)) + 8] set MV($who.nameplate) [.top.c create rectangle \ [expr ($x + $MV($who.name_x_offset)) - ($width / 2)] \ [expr ($y + $MV($who.name_y_offset)) - 8] \ [expr ($x + $MV($who.name_x_offset)) + ($width / 2)] \ [expr ($y + $MV($who.name_y_offset)) + 8] -fill black] set MV($who.nametext) [.top.c create text \ [expr ($x + $MV($who.name_x_offset))] \ [expr ($y + $MV($who.name_y_offset))] \ -text $who_text -fill white] update idletasks # # Process Plugins! # foreach plugin $MV(plugin.traps.ShowName) { if {![$MV(plugin.traps.ShowName.$plugin) $who]} {return} } } proc ChangeAvatar {what} { global MV if {![file exists "$MV(images)/$what"]} { image create photo OpenVerse_Image_pic -file "$MV(images)/default.gif" return } # # Do not allow image files with spaces in their names. # Cruise - 10/18/2001 # if {[string first " " "$what"] != -1} { ThrowError "[Trns space_in_filename] (IMAGE NAME IS $what)" image create photo OpenVerse_Image_pic -file "$MV(images)/default.gif" return } image create photo OpenVerse_Image_pic -file "$MV(images)/$what" set MV(avatar) $what SendToServer "AVATAR $what $MV(anim.x_off) $MV(anim.y_off) [file size "$MV(images)/$what"] $MV(anim.baloon_x) $MV(anim.baloon_y)" if $MV(names) { KillName $MV(nick) ShowName $MV(nick) } # # Process Plugins! # foreach plugin $MV(plugin.traps.ChangeAvatar) { if {![$MV(plugin.traps.ChangeAvatar.$plugin) $what]} {return} } } proc DoAvatars {} { global MV set anims 0 set depth 0 set count 1 destroy $MV(avatar_menu).m if $MV(use_windowmanager_colors) { menu $MV(avatar_menu).m } else { menu $MV(avatar_menu).m -bg $MV(colors.av.bg) \ -fg $MV(colors.av.fg) -activeforeground $MV(colors.av.afg) \ -activebackground $MV(colors.av.abg) } set MV(avatar_files.0) "default.av" foreach file [List_Avatars] { if !$depth { incr depth $MV(avatar_menu).m add cascade -menu \ $MV(avatar_menu).m.m$depth -label "[Trns avatars] $depth" if $MV(use_windowmanager_colors) { menu $MV(avatar_menu).m.m$depth } else { menu $MV(avatar_menu).m.m$depth -bg $MV(colors.av.bg) \ -fg $MV(colors.av.fg) -activeforeground $MV(colors.av.afg) \ -activebackground $MV(colors.av.abg) } } set MV(avatar_files.$count) "[file tail $file]" if {[file tail $file] == "default.av"} { set MV(default_avatar_number) $count } $MV(avatar_menu).m.m$depth add command -label [file tail $file] \ -command "AnimateMe $count 1" incr anims incr count if {$anims > 19} { incr depth $MV(avatar_menu).m add cascade -menu \ $MV(avatar_menu).m.m$depth -label "[Trns avatars] $depth" if $MV(use_windowmanager_colors) { menu $MV(avatar_menu).m.m$depth } else { menu $MV(avatar_menu).m.m$depth -bg $MV(colors.av.bg) \ -fg $MV(colors.av.fg) -activeforeground $MV(colors.av.afg) \ -activebackground $MV(colors.av.abg) } set anims 0 } } } proc MoveTo {x y pushed} { global MV set ret 0 if !$pushed { # # Process Plugins! # foreach plugin $MV(plugin.traps.MoveTo.Pre) { if {![$MV(plugin.traps.MoveTo.Pre.$plugin) $x $y]} {return} } foreach link $MV(server_links) { if {$x >= $MV(server_links.$link.x1) && $x <= $MV(server_links.$link.x2) && $y >= $MV(server_links.$link.y1) && $y <= $MV(server_links.$link.y2)} { DebugIt "Openening URL $MV(server_links.$link.url)" other set MV(url.-1.-99.what) $MV(server_links.$link.url) URL_OpenWeb -1 -99 set ret 1 } } if !$ret { foreach tell $MV(server_tells) { if {$x >= $MV(server_tells.$tell.x1) && $x <= $MV(server_tells.$tell.x2) && $y >= $MV(server_tells.$tell.y1) && $y <= $MV(server_tells.$tell.y2)} { DebugIt "Telling Server $tell" other SendToServer "TELL $tell" set ret 1 } } } if !$ret { foreach link $MV(server_exits) { if {$x >= $MV(server_exits.$link.x1) && $x <= $MV(server_exits.$link.x2) && $y >= $MV(server_exits.$link.y1) && $y <= $MV(server_exits.$link.y2)} { DebugIt "Clicked Exit $MV(server_exits.$link.host)" other ConnectToRoom $MV(server_exits.$link.host) $MV(server_exits.$link.port) set ret 1 break } } } } if !$ret { SendToServer "MOVE $MV(nick) $x $y $MV(movespeed)" set string "$x $y $MV(x) $MV(y) $MV(movespeed) 1 0" set MV(x) $x set MV(y) $y update idletasks lappend MV($MV(nick).moves) $string MoveAvatars 0 } } proc DoTheMove {person} { global MV set length [llength $MV($person.moves)] if !$length {return} set info [split [lindex $MV($person.moves) 0] " "] set delete_flag [lindex $info 6] if $delete_flag {return} set x [lindex $info 0] set y [lindex $info 1] set xx [lindex $info 2] set yy [lindex $info 3] set speed [lindex $info 4] set nametag [lindex $info 5] if {![string compare $person $MV(nick)]} { set image $MV(img) } else { set image $MV($person.icon) } set MV($person.moving) 1 set sspeed [expr $speed * 3] #puts "DoTheMove $x $y $xx $yy $speed $nametag $delete_flag" if {[expr $x - $xx] > 0} {set xdir 1} else {set xdir -1} if {[expr $y - $yy] > 0} {set ydir 1} else {set ydir -1} if {[expr $y - $yy] == 0} {set ydir 0} if {[expr $x - $xx] == 0} {set xdir 0} set xinc $xdir set yinc $ydir if {$xdir && $sspeed != 2} { set xinc [expr $xdir * 1] set xxx $xx while { $xxx != $x && $xinc != [expr $sspeed * $xdir]} { set xxx $xx incr xinc [expr $xdir * 1] incr xxx $xinc } } if {$ydir && $sspeed != 2} { set yinc [expr $ydir * 1] set yyy $yy while { $yyy != $y && $yinc != [expr $sspeed * $ydir]} { set yyy $yy incr yinc [expr $ydir * 1] incr yyy $yinc } } .top.c move $image $xinc $yinc set xx [expr $xx + $xinc] set yy [expr $yy + $yinc] set MV($person.current_x) $xx set MV($person.current_y) $yy if {$nametag && $MV(names)} { KillName $person ShowName $person } if {$x != $xx || $y != $yy} { set newlist "$x $y $xx $yy $speed $nametag 0" } else { set newlist "$x $y $xx $yy $speed $nametag 1" } set MV($person.moves) [lreplace $MV($person.moves) 0 0 $newlist] # Process Plugins! # foreach plugin $MV(plugin.traps.MoveTo.Post) { $MV(plugin.traps.MoveTo.Post.$plugin) $x $y } } proc MoveAvatars {loop_var} { global MV if {$MV(moving) && !$loop_var} {return} set MV(moving) 1 # Info needed for movement. # # X position to move to. # Y position to move to. # XX Original X position # YY Original Y position # Speed at which we move. # Nametag replacement (should we move the nametag) # The image name to move. set anymove 0 set moveusers {} if {[llength $MV($MV(nick).moves)]} { lappend moveusers $MV(nick) } else { set MV($MV(nick).moving) 0 } foreach person $MV(people) { if {[llength $MV($person.moves)]} { lappend moveusers $person } else { set MV($person.moving) 0 } } foreach user $moveusers { DoTheMove $user set info [split [lindex $MV($user.moves) 0] " "] set delete_flag [lindex $info 6] if $delete_flag { set MV($user.moves) [lreplace $MV($user.moves) 0 0] } if {[llength $MV($user.moves)]} { set anymove 1 } else { set MV($user.moving) 0 } } update idletasks if $anymove { # # NOTE: PERFORMANCE! # # What you see below is a great performance enhancer. It # causes this function to return now instead of later and # prevents unnescary nesting. # after 1 "MoveAvatars 1" } else { set MV(moving) 0 } return } proc ChangeUserAvatar {who what x y size bx by} { global MV if {[lsearch -exact $MV(people) $who] == -1} {return} if {[TestNum $x] || [TestNum $y] || [TestPosNum $size] || \ [TestNum $bx] || [TestNum $by]} { DebugIt "ChangeUserAvatar: Invalid Parameters" other return } set MV($who.avatar) $what set MV($who.name_x_offset) $x set MV($who.name_y_offset) $y set MV($who.baloon_x) $bx set MV($who.baloon_y) $by if $MV(names) { KillName $who ShowName $who } if {![string compare $what "default.gif"]} { image create photo OpenVerse_User_Image_$who -file "$MV(images)/default.gif" return } if {![file exists "$MV(rem_images)/$what"]} { if {[lsearch -exact $MV(downloads) $what] == -1} { DebugIt "I do not have $what ([file exists \"$MV(rem_images)/$what\"])" other if $MV(download_avatars) { SendToServer "DCCSENDAV $what" set MV($who.downloading) 1 } } } else { if {[file size "$MV(rem_images)/$what"] != $size} { if {[lsearch -exact $MV(downloads) $what] == -1} { DebugIt "size mismatch for $what" other catch {file delete "$MV(rem_images)/$what"} if $MV(download_avatars) { SendToServer "DCCSENDAV $what" set MV($who.downloading) 1 } } } else { catch {image create photo OpenVerse_User_Image_$who -file "$MV(rem_images)/$what"} err if {[string compare $err OpenVerse_User_Image_$who]} { image create photo OpenVerse_User_Image_$who -file "$MV(images)/default.gif" } } } # # Process Plugins! # foreach plugin $MV(plugin.traps.ChangeUserAvatar) { if {![$MV(plugin.traps.ChangeUserAvatar.$plugin) $who $what $x $y $size $bx $by]} {return} } } proc MoveUser {who x y speed} { global MV if {![string compare $who $MV(nick)]} {return} if {[lsearch -exact $MV(people) $who] == -1} {return} if $MV($who.nomoremove) {return} if {[TestNum $x] || [TestNum $y] || [TestNum $speed]} { DebugIt "MoveUser: Invalid Parameters" other return } # # Process Plugins! # foreach plugin $MV(plugin.traps.MoveUser.Pre) { if {![$MV(plugin.traps.MoveUser.Pre.$plugin) $who $x $y $speed]} {return} } if {![string compare $speed ""]} {set speed 1} set string "$x $y $MV($who.x) $MV($who.y) $speed 1 0" set MV($who.x) $x set MV($who.y) $y update idletasks lappend MV($who.moves) $string MoveAvatars 0 # # Process Plugins! # foreach plugin $MV(plugin.traps.MoveUser.Post) { if {![$MV(plugin.traps.MoveUser.Post.$plugin) $who $x $y $speed]} {return} } } proc AvatarEffect {who what} { global MV if {![string compare $who $MV(nick)]} { set image $MV(img) } else { set image $MV($who.icon) } set x $MV($who.x) set y $MV($who.y) DebugIt "(Effect) - $who $what $x $y" other switch -- [string tolower $what] { "shiver" { set dir 0 for {set c 0} {$c < 50} {incr c} { if $dir { set dir 0 set xx [expr $x - 15] } else { set dir 1 set xx [expr $x + 15] } lappend MV($who.moves) "$xx $y $x $y 12 0 0" lappend MV($who.moves) "$x $y $xx $y 12 0 0" } MoveAvatars 0 } "jump" { set dir 0 for {set c 0} {$c < 50} {incr c} { switch -- $dir { "0" { set dir 1 set yy [expr $y - 15] } "1" { set dir 2 set yy [expr $y - 30] } "2" { set dir 3 set yy [expr $y - 45] } "3" { set dir 4 set yy [expr $y - 30] } "4" { set dir 5 set yy [expr $y - 15] } "5" { set dir 0 set yy $y } } lappend MV($who.moves) "$x $yy $x $y 3 0 0" lappend MV($who.moves) "$x $y $x $yy 3 0 0" } MoveAvatars 0 } } }