ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/player-env.ext
Revision: 1.18
Committed: Fri May 14 22:56:47 2010 UTC (14 years ago) by root
Branch: MAIN
Changes since 1.17: +43 -12 lines
Log Message:
music groups, music conf file, post_init async

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