ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/player-env.ext
Revision: 1.22
Committed: Sun Nov 11 02:24:51 2012 UTC (11 years, 6 months ago) by root
Branch: MAIN
Changes since 1.21: +1 -1 lines
Log Message:
preparations for external face data

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 root 1.22 # sort by size, smallest first, because it's the fastest to download...
51 root 1.18 [ 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 root 1.20 my $map = $ob->map;
69     my $rgn = $ob->region;
70    
71     my $id = join "\x00", $map->path, $rgn->name;
72 root 1.4
73 root 1.16 my $faces = delete $ns->{music_play_once};
74 root 1.20 $faces ||= $MUSIC_FACE_CACHE{$id} ||= do {
75 root 1.14 # 1. map-specific music info
76 root 1.18 parse_musiclist $map->{music}
77 root 1.14 or do {
78     # 2. fall back to region if no map-specific music
79 root 1.20 $rgn = $rgn->parent
80     while $rgn && !exists $rgn->{music};
81 root 1.3
82 root 1.20 parse_musiclist $rgn->{music}
83 root 1.3 }
84 root 1.14 ;
85     };
86 root 1.2
87 root 1.4 $faces
88     or next;
89    
90     my $facestr = join ",", @$faces;
91     $ns->{current_music_faces} ne $facestr
92     or next;
93    
94     $ns->{current_music_faces} = $facestr;
95    
96 root 1.6 my $pri = 0;
97 root 1.11 $ns->send_face ($_, --$pri - 110)
98     for @$faces;
99     $ns->flush_fx;
100 root 1.4
101 root 1.13 $ns->ext_msg (ambient_music => $faces);
102 root 1.2 }
103     Coro::schedule unless %MUSIC_QUEUE;
104     }
105     };
106    
107 root 1.1 cf::player->attach (
108     on_region_change => sub {
109     my ($pl, $new, $old) = @_;
110    
111     $pl->ob->message ("You are now " . $new->longname . ". H<Use whereami for more details.>", $new->longname);
112 root 1.2
113 root 1.16 undef $MUSIC_QUEUE{$pl->ob->name};
114 root 1.2 $MUSIC_SCHEDULER->ready;
115     },
116     on_map_change => sub {
117     my ($pl, $new) = @_;
118    
119 root 1.16 undef $MUSIC_QUEUE{$pl->ob->name};
120 root 1.2 $MUSIC_SCHEDULER->ready;
121 root 1.1 },
122     );
123    
124 root 1.16 sub play_music_once {
125     my ($pl, $music) = @_;
126    
127 root 1.18 $pl->ns->{music_play_once} = parse_musiclist $music;
128 root 1.16
129     undef $MUSIC_QUEUE{$pl->ob->name};
130     $MUSIC_SCHEDULER->ready;
131     }
132 root 1.1