ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra/Deliantra.pm
(Generate patch)

Comparing deliantra/Deliantra/Deliantra.pm (file contents):
Revision 1.23 by root, Thu Feb 23 02:52:51 2006 UTC vs.
Revision 1.39 by root, Sun Mar 12 23:35:03 2006 UTC

11use strict; 11use strict;
12 12
13use base 'Exporter'; 13use base 'Exporter';
14 14
15use Carp (); 15use Carp ();
16use Storable;
17use File::Spec; 16use File::Spec;
18use List::Util qw(min max); 17use List::Util qw(min max);
19 18use Storable;
20#XXX: The map_* procedures scream for a map-object
21 19
22our @EXPORT = 20our @EXPORT =
23 qw(read_pak read_arch %ARCH TILESIZE $TILE %FACE editor_archs arch_extents); 21 qw(read_pak read_arch %ARCH TILESIZE $TILE %FACE editor_archs arch_extents);
24 22
25our $LIB = $ENV{CROSSFIRE_LIBDIR} 23our $LIB = $ENV{CROSSFIRE_LIBDIR}
26 or Carp::croak "\$CROSSFIRE_LIBDIR must be set\n"; 24 or Carp::croak "\$CROSSFIRE_LIBDIR must be set\n";
27 25
28sub TILESIZE (){ 32 } 26sub TILESIZE (){ 32 }
29 27
30our $CACHEDIR; 28our $VARDIR;
31our %ARCH; 29our %ARCH;
32our %FACE; 30our %FACE;
33our $TILE; 31our $TILE;
34 32
35our %FIELD_MULTILINE = ( 33our %FIELD_MULTILINE = (
44sub MOVE_FLY_LOW (){ 0x2 } 42sub MOVE_FLY_LOW (){ 0x2 }
45sub MOVE_FLY_HIGH (){ 0x4 } 43sub MOVE_FLY_HIGH (){ 0x4 }
46sub MOVE_FLYING (){ 0x6 } 44sub MOVE_FLYING (){ 0x6 }
47sub MOVE_SWIM (){ 0x8 } 45sub MOVE_SWIM (){ 0x8 }
48sub MOVE_ALL (){ 0xf } 46sub MOVE_ALL (){ 0xf }
47
48sub load_ref($) {
49 my ($path) = @_;
50
51 open my $fh, "<", $path
52 or die "$path: $!";
53 binmode $fh;
54 local $/;
55
56 Storable::thaw <$fh>
57}
58
59sub save_ref($$) {
60 my ($ref, $path) = @_;
61
62 open my $fh, ">", "$path~"
63 or die "$path~: $!";
64 binmode $fh;
65 print $fh Storable::freeze $ref;
66 close $fh;
67 rename "$path~", $path
68 or die "$path: $!";
69}
49 70
50sub normalize_arch($) { 71sub normalize_arch($) {
51 my ($ob) = @_; 72 my ($ob) = @_;
52 73
53 my $arch = $ARCH{$ob->{_name}} 74 my $arch = $ARCH{$ob->{_name}}
114 my ($path, $cache) = @_; 135 my ($path, $cache) = @_;
115 136
116 eval { 137 eval {
117 defined $cache 138 defined $cache
118 && -M $cache < -M $path 139 && -M $cache < -M $path
119 && Storable::retrieve ($cache) 140 && load_ref $cache
120 } or do { 141 } or do {
121 my %pak; 142 my %pak;
122 143
123 open my $fh, "<:raw", $path 144 open my $fh, "<", $path
124 or Carp::croak "$_[0]: $!"; 145 or Carp::croak "$_[0]: $!";
146 binmode $fh;
125 while (<$fh>) { 147 while (<$fh>) {
126 my ($type, $id, $len, $path) = split; 148 my ($type, $id, $len, $path) = split;
127 $path =~ s/.*\///; 149 $path =~ s/.*\///;
128 read $fh, $pak{$path}, $len; 150 read $fh, $pak{$path}, $len;
129 } 151 }
130 152
131 Storable::nstore (\%pak, $cache) 153 save_ref \%pak, $cache
132 if defined $cache; 154 if defined $cache;
133 155
134 \%pak 156 \%pak
135 } 157 }
136} 158}
139 my ($path, $cache) = @_; 161 my ($path, $cache) = @_;
140 162
141 eval { 163 eval {
142 defined $cache 164 defined $cache
143 && -M $cache < -M $path 165 && -M $cache < -M $path
144 && Storable::retrieve ($cache) 166 && load_ref $cache
145 } or do { 167 } or do {
146 my %arc; 168 my %arc;
147 my ($more, $prev); 169 my ($more, $prev);
148 170
149 open my $fh, "<:raw", $path 171 open my $fh, "<", $path
150 or Carp::croak "$path: $!"; 172 or Carp::croak "$path: $!";
173
174 binmode $fh;
151 175
152 my $parse_block; $parse_block = sub { 176 my $parse_block; $parse_block = sub {
153 my %arc = @_; 177 my %arc = @_;
154 178
155 while (<$fh>) { 179 while (<$fh>) {
204 } 228 }
205 } 229 }
206 230
207 undef $parse_block; # work around bug in perl not freeing $fh etc. 231 undef $parse_block; # work around bug in perl not freeing $fh etc.
208 232
209 Storable::nstore (\%arc, $cache) 233 save_ref \%arc, $cache
210 if defined $cache; 234 if defined $cache;
211 235
212 \%arc 236 \%arc
213 } 237 }
214} 238}
263 287
264 } else { 288 } else {
265 # single face 289 # single face
266 return (0, 0, 0, 0); 290 return (0, 0, 0, 0);
267 } 291 }
268}
269
270sub init($) {
271 my ($cachedir) = @_;
272
273 return if %ARCH;
274
275 mkdir $cachedir, 0777;
276 *ARCH = read_arch "$LIB/archetypes", "$cachedir/archetypes.pst";
277} 292}
278 293
279=item $type = arch_attr $arch 294=item $type = arch_attr $arch
280 295
281Returns a hashref describing the object and its attributes. It can contain 296Returns a hashref describing the object and its attributes. It can contain
294sub arch_attr($) { 309sub arch_attr($) {
295 my ($arch) = @_; 310 my ($arch) = @_;
296 311
297 require Crossfire::Data; 312 require Crossfire::Data;
298 313
299 my $attr; 314 my $root;
300 315
301 if ($arch->{type} > 0) { 316 if ($arch->{type} > 0) {
302 $attr = $Crossfire::Data::ATTR{$arch->{type}+0}; 317 $root = $Crossfire::Data::ATTR{$arch->{type}+0};
303 } else { 318 } else {
304 $attr = $Crossfire::Data::TYPE{Misc}; 319 $root = $Crossfire::Data::TYPE{Misc};
305 320
306 type: 321 type:
307 for (@Crossfire::Data::ATTR0) { 322 for (@Crossfire::Data::ATTR0) {
308 my $req = $_->{required} 323 my $req = $_->{required}
309 or die "internal error: ATTR0 without 'required'"; 324 or die "internal error: ATTR0 without 'required'";
310 325
326 keys %$req;
311 while (my ($k, $v) = each %$req) { 327 while (my ($k, $v) = each %$req) {
312 next type 328 next type
313 unless $arch->{$k} == $v; 329 unless $arch->{$k} == $v;
314 } 330 }
315 331
316 $attr = $_; 332 $root = $_;
333 }
334 }
335
336 my $attr = { };
337
338 my @import = ($root, \%Crossfire::Data::DEFAULT_ATTR);
339 my (%ignore);
340 my (@section_order, %section, @attr_order);
341
342 while (my $type = shift @import) {
343 push @import, @{$type->{import} || []};
344
345 $attr->{$_} ||= $type->{$_}
346 for qw(name desc use);
347
348 for (@{$type->{ignore} || []}) {
349 $ignore{$_}++ for ref $_ ? @$_ : $_;
350 }
351
352 for ([general => ($type->{attr} || {})], @{$type->{section} || []}) {
353 my ($name, $attr) = @$_;
354 push @section_order, $name;
355 for (@$attr) {
356 my ($k, $v) = @$_;
357 push @attr_order, $k;
358 $section{$name}{$k} ||= $v;
317 } 359 }
360 }
318 } 361 }
319 362
320 $attr || \%Crossfire::Data::DEFAULT_ATTR; 363 $attr->{section} = [
364 map !exists $section{$_} ? () : do {
365 my $attr = delete $section{$_};
366
367 [
368 $_,
369 map exists $attr->{$_} && !$ignore{$_}
370 ? [$_ => delete $attr->{$_}] : (),
371 @attr_order
372 ]
373 },
374
375 exists $section{$_} ? [$_ => delete $section{$_}] : (),
376 @section_order
377 ];
378
379 use PApp::Util;
380 warn PApp::Util::dumpval $attr;
381
382 $attr
321} 383}
322 384
323sub arch_edit_sections { 385sub arch_edit_sections {
324# if (edit_type == IGUIConstants.TILE_EDIT_NONE) 386# if (edit_type == IGUIConstants.TILE_EDIT_NONE)
325# edit_type = 0; 387# edit_type = 0;
379# return(edit_type); 441# return(edit_type);
380# 442#
381# 443#
382} 444}
383 445
446sub init($) {
447 my ($cachedir) = @_;
448
449 return if %ARCH;
450
451 mkdir $cachedir, 0777;
452 *ARCH = read_arch "$LIB/archetypes", "$cachedir/archetypes.pst";
453}
454
384$CACHEDIR ||= $ENV{HOME} ? "$ENV{HOME}/.crossfire" : File::Spec->tmpdir; 455$VARDIR ||= $ENV{HOME} ? "$ENV{HOME}/.crossfire" : File::Spec->tmpdir . "/crossfire";
385 456
386init $CACHEDIR; 457init $VARDIR;
387 458
388=head1 AUTHOR 459=head1 AUTHOR
389 460
390 Marc Lehmann <schmorp@schmorp.de> 461 Marc Lehmann <schmorp@schmorp.de>
391 http://home.schmorp.de/ 462 http://home.schmorp.de/

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines