ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra/Deliantra.pm
Revision: 1.8
Committed: Sun Feb 5 02:29:13 2006 UTC (18 years, 3 months ago) by root
Branch: MAIN
Changes since 1.7: +1 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 elmex 1.1 =head1 NAME
2    
3     Crossfire - Crossfire maphandling
4    
5     =cut
6    
7 root 1.4 package Crossfire;
8    
9 elmex 1.3 our $VERSION = '0.1';
10 elmex 1.1
11     use strict;
12    
13 root 1.7 use base 'Exporter';
14    
15 elmex 1.1 use Storable;
16    
17 root 1.7 our @EXPORT = qw(read_pak read_arch arch2map $ARCH TILESIZE);
18    
19 root 1.4 our $LIB = $ENV{CROSSFIRE_LIBDIR}
20 elmex 1.1 or die "\$CROSSFIRE_LIBDIR must be set\n";
21    
22 root 1.7 sub TILESIZE (){ 32 }
23 elmex 1.1
24 root 1.4 our $ARCH;
25 elmex 1.1
26 root 1.4 sub read_pak($;$) {
27     my ($path, $cache) = @_;
28 elmex 1.1
29     eval {
30 root 1.4 defined $cache
31     && -M $cache < -M $path
32     && Storable::retrieve $cache
33 elmex 1.1 } or do {
34     my %pak;
35    
36     open my $fh, "<:raw", $path
37     or die "$_[0]: $!";
38     while (<$fh>) {
39     my ($type, $id, $len, $path) = split;
40     $path =~ s/.*\///;
41     read $fh, $pak{$path}, $len;
42     }
43    
44 root 1.4 Storable::nstore \%pak, $cache
45     if defined $cache;
46 elmex 1.1
47     \%pak
48     }
49     }
50    
51     sub read_arch($;$) {
52 root 1.4 my ($path, $cache) = @_;
53    
54     eval {
55     defined $cache
56     && -M $cache < -M $path
57     && Storable::retrieve $cache
58     } or do {
59     my %arc;
60     my ($more, $prev);
61    
62     open my $fh, "<:raw", $path
63     or die "$path: $!";
64 elmex 1.1
65 root 1.4 my $parse_block; $parse_block = sub {
66     my %arc = @_;
67 elmex 1.2
68 root 1.4 while (<$fh>) {
69     s/\s+$//;
70     if (/^end$/i) {
71     last;
72     } elsif (/^arch (\S+)$/) {
73     push @{ $arc{inventory} }, $parse_block->(_name => $1);
74     } elsif (/^lore$/) {
75     while (<$fh>) {
76     last if /^endlore\s*$/i;
77     $arc{lore} .= $_;
78     }
79     } elsif (/^msg$/) {
80     while (<$fh>) {
81     last if /^endmsg\s*$/i;
82     $arc{msg} .= $_;
83     }
84     } elsif (/^(\S+)\s*(.*)$/) {
85     $arc{lc $1} = $2;
86     } elsif (/^\s*($|#)/) {
87     #
88     } else {
89     warn "$path: unparsable line '$_' in arch $arc{_name}";
90     }
91     }
92 elmex 1.1
93 root 1.4 \%arc
94     };
95 elmex 1.1
96     while (<$fh>) {
97     s/\s+$//;
98 root 1.4 if (/^more$/i) {
99     $more = $prev;
100     } elsif (/^object (\S+)$/i) {
101     my $name = $1;
102     my $arc = $parse_block->(_name => $name);
103    
104     if ($more) {
105     $more->{more} = $arc;
106     } else {
107     $arc{$name} = $arc;
108 elmex 1.1 }
109 root 1.4 $prev = $arc;
110     $more = undef;
111     } elsif (/^arch (\S+)$/i) {
112     push @{ $arc{arch} }, $parse_block->(_name => $1);
113 elmex 1.1 } elsif (/^\s*($|#)/) {
114     #
115     } else {
116 root 1.4 warn "$path: unparseable top-level line '$_'";
117 elmex 1.1 }
118     }
119    
120 root 1.4 undef $parse_block; # work around bug in perl not freeing $fh etc.
121 elmex 1.2
122 root 1.4 Storable::nstore \%arc, $cache
123     if defined $cache;
124 elmex 1.1
125 root 1.4 \%arc
126 elmex 1.2 }
127 elmex 1.1 }
128    
129 root 1.4 sub arch2map($;$) {
130     my ($mapa) = @_;
131 elmex 1.1
132     my %meta;
133    
134     my ($mapx, $mapy);
135    
136     my $map;
137    
138     for (@{ $mapa->{arch} }) {
139     my ($x, $y) = ($_->{x}, $_->{y});
140    
141     if ($_->{_name} eq "map") {
142     $meta{info} = $_;
143    
144     $mapx = $_->{width} || $x;
145     $mapy = $_->{height} || $y;
146     } else {
147     push @{ $map->[$x][$y] }, $_;
148    
149     # arch map is unreliable w.r.t. width and height
150     $mapx = $x + 1 if $mapx <= $x;
151     $mapy = $y + 1 if $mapy <= $y;
152     #$mapx = $a->{x} + 1, warn "$mapname: arch '$a->{_name}' outside map width at ($a->{x}|$a->{y})\n" if $mapx <= $a->{x};
153     #$mapy = $a->{y} + 1, warn "$mapname: arch '$a->{_name}' outside map height at ($a->{x}|$a->{y})\n" if $mapy <= $a->{y};
154     }
155     }
156    
157     $meta{width} = $mapx;
158     $meta{height} = $mapy;
159 root 1.8 $meta{map} = $map;
160 elmex 1.1
161     \%meta
162     }
163    
164 root 1.4 sub init($) {
165     my ($cachedir) = @_;
166 elmex 1.1
167 root 1.4 $ARCH = read_arch "$LIB/archetypes", "$cachedir/archetypes.pst";
168 elmex 1.1 }
169    
170     =head1 AUTHOR
171    
172     Marc Lehmann <schmorp@schmorp.de>
173     http://home.schmorp.de/
174    
175     Robin Redeker <elmex@ta-sa.org>
176     http://www.ta-sa.org/
177    
178     =cut
179 root 1.4
180     1