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