--- deliantra/server/ext/player-env.ext 2007/07/11 16:26:26 1.2 +++ deliantra/server/ext/player-env.ext 2007/09/19 21:56:30 1.15 @@ -3,28 +3,74 @@ # this extension provides "environmental effects", # meaning mostly background music and region messages right now. +sub parse_facelist($$) { + my ($prefix, $list) = @_; + + return undef + unless defined $list; + + #TODO, sort by size (smallest first...) + [ + sort { (cf::face::get_data_size $a) <=> (cf::face::get_data_size $b) } + grep $_, + map +(cf::face::find "$prefix$_" or ((warn "unable to find music file $_"), undef)), + split /\s*,\s*/, $list + ] +} + our %MUSIC_QUEUE; +our %MUSIC_FACE_CACHE; # cleared by reload_facedata our $MUSIC_SCHEDULER = cf::async_ext { + $Coro::current->{desc} = "music scheduler"; + while () { for (keys %MUSIC_QUEUE) { delete $MUSIC_QUEUE{$_}; - my $pl = cf::player::find_active $_ - or next; - my $map = $pl->ob->map + cf::get_slot 0.01, -10, "music scheduler"; + + my $pl = cf::player::find_active $_ or next; + $pl->ob->active or next; + my $ns = $pl->ns or next; + $ns->extcmd or next; + my $map = $pl->ob->map or next; + + my $faces = $MUSIC_FACE_CACHE{$map} ||= do { + # 1. map-specific music info + parse_facelist "music/", $map->{music} + or do { + # 2. fall back to region if no map-specific music + my $rgn = $pl->ob->region + or next; + + my $par = $rgn; + while () { + last if exists $par->{music}; + $par = $par->parent + or last; + } + + parse_facelist "music/", $par->{music} + } + ; + }; + + $faces or next; - # 1. update map-specific music info - unless (exists $map->{music}) { + my $facestr = join ",", @$faces; + $ns->{current_music_faces} ne $facestr + or next; - } + $ns->{current_music_faces} = $facestr; - # 2. fall back to region if no map-specific music - unless ($map->{music}) { - } + my $pri = 0; + $ns->send_face ($_, --$pri - 110) + for @$faces; + $ns->flush_fx; - cf::cede_to_tick; + $ns->ext_msg (ambient_music => $faces); } Coro::schedule unless %MUSIC_QUEUE; }