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

# Content
1 =head1 NAME
2
3 Crossfire - Crossfire maphandling
4
5 =cut
6
7 package Crossfire;
8
9 our $VERSION = '0.1';
10
11 use strict;
12
13 use base 'Exporter';
14
15 use Storable;
16
17 our @EXPORT = qw(read_pak read_arch arch2map $ARCH TILESIZE);
18
19 our $LIB = $ENV{CROSSFIRE_LIBDIR}
20 or die "\$CROSSFIRE_LIBDIR must be set\n";
21
22 sub TILESIZE (){ 32 }
23
24 our $ARCH;
25
26 sub read_pak($;$) {
27 my ($path, $cache) = @_;
28
29 eval {
30 defined $cache
31 && -M $cache < -M $path
32 && Storable::retrieve $cache
33 } 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 Storable::nstore \%pak, $cache
45 if defined $cache;
46
47 \%pak
48 }
49 }
50
51 sub read_arch($;$) {
52 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
65 my $parse_block; $parse_block = sub {
66 my %arc = @_;
67
68 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
93 \%arc
94 };
95
96 while (<$fh>) {
97 s/\s+$//;
98 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 }
109 $prev = $arc;
110 $more = undef;
111 } elsif (/^arch (\S+)$/i) {
112 push @{ $arc{arch} }, $parse_block->(_name => $1);
113 } elsif (/^\s*($|#)/) {
114 #
115 } else {
116 warn "$path: unparseable top-level line '$_'";
117 }
118 }
119
120 undef $parse_block; # work around bug in perl not freeing $fh etc.
121
122 Storable::nstore \%arc, $cache
123 if defined $cache;
124
125 \%arc
126 }
127 }
128
129 sub arch2map($;$) {
130 my ($mapa) = @_;
131
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 $meta{map} = $map;
160
161 \%meta
162 }
163
164 sub init($) {
165 my ($cachedir) = @_;
166
167 $ARCH = read_arch "$LIB/archetypes", "$cachedir/archetypes.pst";
168 }
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
180 1