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