--- deliantra/server/ext/player-env.ext 2007/07/12 19:36:57 1.7 +++ deliantra/server/ext/player-env.ext 2010/04/29 07:52:02 1.17 @@ -13,51 +13,49 @@ [ 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)), + map +(cf::face::find "$prefix$_" or ((cf::error "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{$_}; + 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; + my $faces = delete $ns->{music_play_once}; + $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; + } - # 1. update map-specific music info - unless (exists $map->{music_faces}) { - $map->{music_faces} = parse_facelist "music/", $map->{music}; - } - - my $faces = $map->{music_faces}; - - # 2. fall back to region if no map-specific music - unless ($faces) { - my $rgn = $pl->ob->region - or next; - - unless (exists $rgn->{music_faces}) { - my $par = $rgn; - while () { - last if exists $par->{music}; - $par = $par->parent - or last; + parse_facelist "music/", $par->{music} } - - $rgn->{music_faces} = parse_facelist "music/", $par->{music}; - } - - $faces = $rgn->{music_faces}; - } + ; + }; $faces or next; @@ -68,17 +66,12 @@ $ns->{current_music_faces} = $facestr; - my $msg = { - play => $faces, - }; - my $pri = 0; - push @{$msg->{faces}}, [$_, $pri++, cf::face::get_chksum $_] - for grep $ns->must_send_face ($_), @$faces; - - $ns->ext_event (music => %$msg); + $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; } @@ -90,15 +83,23 @@ $pl->ob->message ("You are now " . $new->longname . ". H", $new->longname); - $MUSIC_QUEUE{$pl->ob->name} = undef; + undef $MUSIC_QUEUE{$pl->ob->name}; $MUSIC_SCHEDULER->ready; }, on_map_change => sub { my ($pl, $new) = @_; - $MUSIC_QUEUE{$pl->ob->name} = undef; + undef $MUSIC_QUEUE{$pl->ob->name}; $MUSIC_SCHEDULER->ready; }, ); +sub play_music_once { + my ($pl, $music) = @_; + + $pl->ns->{music_play_once} = parse_facelist "music/", $music; + + undef $MUSIC_QUEUE{$pl->ob->name}; + $MUSIC_SCHEDULER->ready; +}