ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/player-env.ext
Revision: 1.19
Committed: Fri May 14 23:47:37 2010 UTC (14 years ago) by root
Branch: MAIN
Changes since 1.18: +2 -1 lines
Log Message:
*** empty log message ***

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