ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra/Deliantra.pm
Revision: 1.6
Committed: Sun Feb 5 00:28:09 2006 UTC (18 years, 3 months ago) by elmex
Branch: MAIN
Changes since 1.5: +2 -0 lines
Log Message:
put exporter in

File Contents

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