ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra/bin/cfmap-tagify
Revision: 1.7
Committed: Sat May 15 00:22:27 2010 UTC (14 years ago) by root
Branch: MAIN
CVS Tags: rel-2_01, rel-2_0, HEAD
Changes since 1.6: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #!/opt/bin/perl
2    
3     # read through the whole maps at .=/ and replace all exits by
4     # tags that point to one of the maps given on the commandline
5     # (which must be relative paths starting at .!)
6    
7 root 1.7 use common::sense;
8 root 1.1
9 root 1.5 use Deliantra;
10     use Deliantra::Map;
11 root 1.1 use Tie::Cache;
12 root 1.4 use Errno;
13 root 1.1
14     {
15     package mapcache;
16    
17     use base Tie::Cache::;
18    
19     sub read {
20 root 1.4 my $map = eval {
21 root 1.5 new_from_file Deliantra::Map $_[1]
22 root 1.4 };
23    
24     if ($@) {
25     die unless $@ =~ /No such file or directory/;
26     warn $@;
27     }
28    
29     $map
30    
31 root 1.1 }
32    
33     sub write {
34     my ($self, $path, $map) = @_;
35 root 1.4 $map or return;
36 root 1.1 warn "writing $path\n";#d#
37     $map->write_file ($path);
38     }
39     }
40    
41     our %map;
42     tie %map, mapcache::, 100, { Debug => 0, WriteSync => 0 }
43     or die;
44    
45 root 1.5 Deliantra::load_archetypes;
46 root 1.1
47     sub expand {
48     my ($path, $base) = @_;
49    
50     $path =~ s/\.map$//;
51    
52     return +(substr $path, 1) . ".map" if $path =~ /^\//;
53    
54     defined $base
55     or die "relative path without base";
56    
57     $path = "$base/../$path.map";
58    
59     1 while $path =~ s/\/+[^\/]*\/+\.\./\//;
60     1 while $path =~ s/\/\//\//;
61    
62     $path
63     }
64    
65     my %is_exit = ( 41 => 1, 57 => 1, 66 => 1 );
66    
67     sub gen_tag {
68     my ($path, $suffix, $x, $y) = @_;
69    
70     # create a tag name
71     my $tag = $path;
72     $tag =~ s/\.map$//;
73     $tag =~ s/\//_/g;
74     $tag .= $suffix;
75     $tag .= $x <= 0 || $y <= 0 ? "_entrance" : "+${x}+${y}";
76    
77     1 while $tag =~ s/\b([^_]+)_\1\b/$1/;
78    
79     lc $tag
80     }
81    
82     sub patch_exit {
83     my ($from, $fx, $fy, $path, $x, $y) = @_;
84    
85     my $map = $map{$path}
86     or return;
87    
88     my $tag;
89    
90     my $tag =
91     $path =~ /world/ && $from !~ /world/
92     ? gen_tag $from, "_exit", $fx, $fy
93     : gen_tag $path, "", $x, $y;
94    
95     $x = $map->{info}{enter_x} if $x <= 0;
96     $y = $map->{info}{enter_y} if $y <= 0;
97    
98     $x >= 0 && $y >= 0
99     or ((warn "invalid x,y"), return);
100    
101     # 1. try to find an existing tag
102     my $os = $map->{map}[$x][$y] ||= [];
103     if (my ($tagged) = grep exists $_->{tag}, @$os) {
104     return $tagged->{tag};
105     }
106    
107     # 2. find an existing exit
108     if (my ($exit) = grep $is_exit{$_->{type} || $ARCH{$_->{_name}}{type}}, @$os) {
109     $exit->{tag} = $tag;
110     $map{$path} = $map;
111     return $tag;
112     }
113    
114     # 3. add a tag object to the bottom
115     unshift @$os, { _atype => "arch", _name => "tag", tag => $tag };
116     $map{$path} = $map;
117     $tag
118     }
119    
120     open my $fh, "find * -name '*.map' -type f -print0 |"
121     or die "find: $!";
122    
123     my %target;
124    
125     for (@ARGV) {
126     s/\.map$//;
127     s/^\///;
128     s/\/\/+/\//g;
129     $_ .= ".map";
130    
131     $target{$_} = 1;
132     }
133    
134     while (defined (my $path = do { local $/ = "\x00"; <$fh> })) {
135     chop $path;
136     my $map = $map{$path};
137    
138     for my $fx (0 .. $map->{info}{width} - 1) {
139 root 1.3 for my $fy (0 .. $map->{info}{height} - 1) {
140 root 1.1 my $space = $map->{map}[$fx][$fy]
141     or next;
142    
143     for my $o (@$space) {
144 root 1.5 my $a = $Deliantra::ARCH{$o->{_name}}
145 root 1.1 or next;
146    
147     if ($is_exit{$o->{type} || $a->{type}}) {
148     my ($exit, $x, $y) = ($o->{slaying}, $o->{hp}, $o->{sp});
149 root 1.3 if ($exit =~ /^[\/0-9a-zA-Z\.]/ && $exit ne "/!") {
150 root 1.1 $exit = expand $exit, $path;
151 root 1.6 if ($exit ne $path && $target{$exit}) {
152 root 1.1 if (my $tag = patch_exit $path, $fx, $fy, $exit, $x, $y) {
153     delete $o->{sp};
154     delete $o->{hp};
155     $o->{slaying} = "*$tag";
156     $map{$path} = $map;
157    
158     warn "$path: found exit $exit $x $y => *$tag\n";#d#
159     } else {
160     warn "$path: $exit $o->{hp} $o->{sp} unpatchable\n";
161     }
162     }
163     }
164     }
165     }
166     }
167     }
168     }
169    
170     %map = ();
171