ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/player-env.ext
Revision: 1.20
Committed: Sun May 16 01:58:50 2010 UTC (14 years ago) by root
Branch: MAIN
CVS Tags: rel-3_0
Changes since 1.19: +9 -13 lines
Log Message:
fix music scheduler

File Contents

# User Rev Content
1 root 1.1 #! perl # mandatory
2    
3     # this extension provides "environmental effects",
4     # meaning mostly background music and region messages right now.
5    
6 root 1.18 our %MUSIC_GROUP;
7 root 1.19 our %MUSIC_FACE_CACHE; # cleared by reload_facedata
8 root 1.18
9     sub reload {
10     cf::trace "loading music config from $DATADIR/music\n";
11    
12     0 < Coro::AIO::aio_load "$DATADIR/music", my $data
13     or die "$DATADIR/music $!";
14    
15     my $conf = JSON::XS->new->utf8->relaxed->decode ($data);
16     %MUSIC_GROUP = %{ $conf->{group} };
17 root 1.19 %MUSIC_FACE_CACHE = ();
18 root 1.18 }
19    
20     cf::post_init {
21     $_[0] ? cf::async { reload } : reload
22     };
23    
24     sub parse_musiclist($) {
25     my ($list) = @_;
26 root 1.3
27     return undef
28     unless defined $list;
29    
30 root 1.18 my @name = split /\s*,\s*/, $list;
31     my @face;
32    
33     while (@name) {
34     my $name = shift @name;
35    
36     if ($name =~ /^\@(.*)$/) {
37     my $group = $MUSIC_GROUP{$1}
38     or cf::error "music group $1 does not exist (referenced in '$list')";
39    
40     unshift @name, @$group;
41     } else {
42     my $face = cf::face::find "music/$name"
43     or "unable to find music face $name (referenced in '$list')";
44    
45     push @face, $face
46     if $face;
47     }
48     }
49    
50     # sort by size, smallest first, because it'S the fastest to download...
51     [ sort { (cf::face::get_data_size $a) <=> (cf::face::get_data_size $b) } @face ]
52 root 1.3 }
53    
54 root 1.2 our %MUSIC_QUEUE;
55    
56     our $MUSIC_SCHEDULER = cf::async_ext {
57 root 1.15 $Coro::current->{desc} = "music scheduler";
58    
59 root 1.2 while () {
60     for (keys %MUSIC_QUEUE) {
61     delete $MUSIC_QUEUE{$_};
62 root 1.4
63 root 1.9 cf::get_slot 0.01, -10, "music scheduler";
64 root 1.8
65 root 1.6 my $pl = cf::player::find_active $_ or next;
66 root 1.20 my $ob = $pl->ob;
67 root 1.6 my $ns = $pl->ns or next;
68     $ns->extcmd or next;
69 root 1.20 my $map = $ob->map;
70     my $rgn = $ob->region;
71    
72     my $id = join "\x00", $map->path, $rgn->name;
73 root 1.4
74 root 1.16 my $faces = delete $ns->{music_play_once};
75 root 1.20 $faces ||= $MUSIC_FACE_CACHE{$id} ||= do {
76 root 1.14 # 1. map-specific music info
77 root 1.18 parse_musiclist $map->{music}
78 root 1.14 or do {
79     # 2. fall back to region if no map-specific music
80 root 1.20 $rgn = $rgn->parent
81     while $rgn && !exists $rgn->{music};
82 root 1.3
83 root 1.20 parse_musiclist $rgn->{music}
84 root 1.3 }
85 root 1.14 ;
86     };
87 root 1.2
88 root 1.4 $faces
89     or next;
90    
91     my $facestr = join ",", @$faces;
92     $ns->{current_music_faces} ne $facestr
93     or next;
94    
95     $ns->{current_music_faces} = $facestr;
96    
97 root 1.6 my $pri = 0;
98 root 1.11 $ns->send_face ($_, --$pri - 110)
99     for @$faces;
100     $ns->flush_fx;
101 root 1.4
102 root 1.13 $ns->ext_msg (ambient_music => $faces);
103 root 1.2 }
104     Coro::schedule unless %MUSIC_QUEUE;
105     }
106     };
107    
108 root 1.1 cf::player->attach (
109     on_region_change => sub {
110     my ($pl, $new, $old) = @_;
111    
112     $pl->ob->message ("You are now " . $new->longname . ". H<Use whereami for more details.>", $new->longname);
113 root 1.2
114 root 1.16 undef $MUSIC_QUEUE{$pl->ob->name};
115 root 1.2 $MUSIC_SCHEDULER->ready;
116     },
117     on_map_change => sub {
118     my ($pl, $new) = @_;
119    
120 root 1.16 undef $MUSIC_QUEUE{$pl->ob->name};
121 root 1.2 $MUSIC_SCHEDULER->ready;
122 root 1.1 },
123     );
124    
125 root 1.16 sub play_music_once {
126     my ($pl, $music) = @_;
127    
128 root 1.18 $pl->ns->{music_play_once} = parse_musiclist $music;
129 root 1.16
130     undef $MUSIC_QUEUE{$pl->ob->name};
131     $MUSIC_SCHEDULER->ready;
132     }
133 root 1.1