ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra/Deliantra.pm
(Generate patch)

Comparing deliantra/Deliantra/Deliantra.pm (file contents):
Revision 1.60 by root, Mon Mar 27 17:23:35 2006 UTC vs.
Revision 1.68 by elmex, Sun Jul 30 17:29:29 2006 UTC

4 4
5=cut 5=cut
6 6
7package Crossfire; 7package Crossfire;
8 8
9our $VERSION = '0.1'; 9our $VERSION = '0.8';
10 10
11use strict; 11use strict;
12 12
13use base 'Exporter'; 13use base 'Exporter';
14 14
102 102
103 body_range body_arm body_torso body_head body_neck body_skill 103 body_range body_arm body_torso body_head body_neck body_skill
104 body_finger body_shoulder body_foot body_hand body_wrist body_waist 104 body_finger body_shoulder body_foot body_hand body_wrist body_waist
105)); 105));
106 106
107our %EVENT_TYPE = (
108 apply => 1,
109 attack => 2,
110 death => 3,
111 drop => 4,
112 pickup => 5,
113 say => 6,
114 stop => 7,
115 time => 8,
116 throw => 9,
117 trigger => 10,
118 close => 11,
119 timer => 12,
120);
121
107sub MOVE_WALK (){ 0x01 } 122sub MOVE_WALK (){ 0x01 }
108sub MOVE_FLY_LOW (){ 0x02 } 123sub MOVE_FLY_LOW (){ 0x02 }
109sub MOVE_FLY_HIGH (){ 0x04 } 124sub MOVE_FLY_HIGH (){ 0x04 }
110sub MOVE_FLYING (){ 0x06 } 125sub MOVE_FLYING (){ 0x06 }
111sub MOVE_SWIM (){ 0x08 } 126sub MOVE_SWIM (){ 0x08 }
115sub MOVE_ALL (){ 0x1001f } # very special value, more PITA 130sub MOVE_ALL (){ 0x1001f } # very special value, more PITA
116 131
117sub load_ref($) { 132sub load_ref($) {
118 my ($path) = @_; 133 my ($path) = @_;
119 134
120 open my $fh, "<", $path 135 open my $fh, "<:raw:perlio", $path
121 or die "$path: $!"; 136 or die "$path: $!";
122 binmode $fh;
123 local $/; 137 local $/;
124 138
125 thaw <$fh> 139 thaw <$fh>
126} 140}
127 141
128sub save_ref($$) { 142sub save_ref($$) {
129 my ($ref, $path) = @_; 143 my ($ref, $path) = @_;
130 144
131 open my $fh, ">", "$path~" 145 open my $fh, ">:raw:perlio", "$path~"
132 or die "$path~: $!"; 146 or die "$path~: $!";
133 binmode $fh;
134 print $fh freeze $ref; 147 print $fh freeze $ref;
135 close $fh; 148 close $fh;
136 rename "$path~", $path 149 rename "$path~", $path
137 or die "$path: $!"; 150 or die "$path: $!";
138} 151}
139 152
153# object as in "Object xxx", i.e. archetypes
140sub normalize_object($) { 154sub normalize_object($) {
141 my ($ob) = @_; 155 my ($ob) = @_;
142 156
157 # nuke outdated or never supported fields
143 delete $ob->{$_} for qw( 158 delete $ob->{$_} for qw(
144 can_knockback can_parry can_impale can_cut can_dam_armour 159 can_knockback can_parry can_impale can_cut can_dam_armour
145 can_apply pass_thru can_pass_thru 160 can_apply pass_thru can_pass_thru
146 ); 161 );
147 162
163 # convert movement strings to bitsets
148 for my $attr (keys %FIELD_MOVEMENT) { 164 for my $attr (keys %FIELD_MOVEMENT) {
149 next unless exists $ob->{$attr}; 165 next unless exists $ob->{$attr};
150 166
151 $ob->{$attr} = MOVE_ALL if $ob->{$attr} == 255; #d# compatibility 167 $ob->{$attr} = MOVE_ALL if $ob->{$attr} == 255; #d# compatibility
152 168
174 } 190 }
175 191
176 $ob->{$attr} = $flags; 192 $ob->{$attr} = $flags;
177 } 193 }
178 194
195 # convert outdated movement flags to new movement sets
179 if (defined (my $v = delete $ob->{no_pass})) { 196 if (defined (my $v = delete $ob->{no_pass})) {
180 $ob->{move_block} = $v ? MOVE_ALL : 0; 197 $ob->{move_block} = $v ? MOVE_ALL : 0;
181 } 198 }
182 if (defined (my $v = delete $ob->{slow_move})) { 199 if (defined (my $v = delete $ob->{slow_move})) {
183 $ob->{move_slow} |= MOVE_WALK; 200 $ob->{move_slow} |= MOVE_WALK;
184 $ob->{move_slow_penalty} = $v; 201 $ob->{move_slow_penalty} = $v;
185 } 202 }
186 if (defined (my $v = delete $ob->{walk_on})) { 203 if (defined (my $v = delete $ob->{walk_on})) {
204 $ob->{move_on} = MOVE_ALL unless exists $ob->{move_on};
187 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_WALK 205 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_WALK
188 : $ob->{move_on} & ~MOVE_WALK; 206 : $ob->{move_on} & ~MOVE_WALK;
189 } 207 }
190 if (defined (my $v = delete $ob->{walk_off})) { 208 if (defined (my $v = delete $ob->{walk_off})) {
209 $ob->{move_off} = MOVE_ALL unless exists $ob->{move_off};
191 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_WALK 210 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_WALK
192 : $ob->{move_off} & ~MOVE_WALK; 211 : $ob->{move_off} & ~MOVE_WALK;
193 } 212 }
194 if (defined (my $v = delete $ob->{fly_on})) { 213 if (defined (my $v = delete $ob->{fly_on})) {
214 $ob->{move_on} = MOVE_ALL unless exists $ob->{move_on};
195 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_FLY_LOW 215 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_FLY_LOW
196 : $ob->{move_on} & ~MOVE_FLY_LOW; 216 : $ob->{move_on} & ~MOVE_FLY_LOW;
197 } 217 }
198 if (defined (my $v = delete $ob->{fly_off})) { 218 if (defined (my $v = delete $ob->{fly_off})) {
219 $ob->{move_off} = MOVE_ALL unless exists $ob->{move_off};
199 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_FLY_LOW 220 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_FLY_LOW
200 : $ob->{move_off} & ~MOVE_FLY_LOW; 221 : $ob->{move_off} & ~MOVE_FLY_LOW;
201 } 222 }
202 if (defined (my $v = delete $ob->{flying})) { 223 if (defined (my $v = delete $ob->{flying})) {
224 $ob->{move_type} = MOVE_ALL unless exists $ob->{move_type};
203 $ob->{move_type} = $v ? $ob->{move_type} | MOVE_FLY_LOW 225 $ob->{move_type} = $v ? $ob->{move_type} | MOVE_FLY_LOW
204 : $ob->{move_type} & ~MOVE_FLY_LOW; 226 : $ob->{move_type} & ~MOVE_FLY_LOW;
205 } 227 }
206 228
229 # convert idiotic event_xxx things into objects
230 while (my ($event, $subtype) = each %EVENT_TYPE) {
231 if (exists $ob->{"event_${event}_plugin"}) {
232 push @{$ob->{inventory}}, {
233 _name => "event_$event",
234 title => delete $ob->{"event_${event}_plugin"},
235 slaying => delete $ob->{"event_${event}"},
236 name => delete $ob->{"event_${event}_options"},
237 };
238 }
239 }
240
207 $ob 241 $ob
208} 242}
209 243
244# arch as in "arch xxx", ie.. objects
210sub normalize_arch($) { 245sub normalize_arch($) {
211 my ($ob) = @_; 246 my ($ob) = @_;
212 247
213 normalize_object $ob; 248 normalize_object $ob;
214 249
256sub read_pak($) { 291sub read_pak($) {
257 my ($path) = @_; 292 my ($path) = @_;
258 293
259 my %pak; 294 my %pak;
260 295
261 open my $fh, "<", $path 296 open my $fh, "<:raw:perlio", $path
262 or Carp::croak "$_[0]: $!"; 297 or Carp::croak "$_[0]: $!";
263 binmode $fh; 298 binmode $fh;
264 while (<$fh>) { 299 while (<$fh>) {
265 my ($type, $id, $len, $path) = split; 300 my ($type, $id, $len, $path) = split;
266 $path =~ s/.*\///; 301 $path =~ s/.*\///;
268 } 303 }
269 304
270 \%pak 305 \%pak
271} 306}
272 307
273sub read_arch($) { 308sub read_arch($;$) {
274 my ($path) = @_; 309 my ($path, $toplevel) = @_;
275 310
276 my %arc; 311 my %arc;
277 my ($more, $prev); 312 my ($more, $prev);
278 313
279 open my $fh, "<", $path 314 open my $fh, "<:raw:perlio:utf8", $path
280 or Carp::croak "$path: $!"; 315 or Carp::croak "$path: $!";
281 316
282 binmode $fh; 317# binmode $fh;
283 318
284 my $parse_block; $parse_block = sub { 319 my $parse_block; $parse_block = sub {
285 my %arc = @_; 320 my %arc = @_;
286 321
287 while (<$fh>) { 322 while (<$fh>) {
298 } elsif (/^msg$/i) { 333 } elsif (/^msg$/i) {
299 while (<$fh>) { 334 while (<$fh>) {
300 last if /^endmsg\s*$/i; 335 last if /^endmsg\s*$/i;
301 $arc{msg} .= $_; 336 $arc{msg} .= $_;
302 } 337 }
338 } elsif (/^anim$/i) {
339 while (<$fh>) {
340 last if /^mina\s*$/i;
341 chomp;
342 push @{ $arc{anim} }, $_;
343 }
303 } elsif (/^(\S+)\s*(.*)$/) { 344 } elsif (/^(\S+)\s*(.*)$/) {
304 $arc{lc $1} = $2; 345 $arc{lc $1} = $2;
305 } elsif (/^\s*($|#)/) { 346 } elsif (/^\s*($|#)/) {
306 # 347 #
307 } else { 348 } else {
336 } else { 377 } else {
337 push @{ $arc{arch} }, $arc; 378 push @{ $arc{arch} }, $arc;
338 } 379 }
339 $prev = $arc; 380 $prev = $arc;
340 $more = undef; 381 $more = undef;
382 } elsif ($toplevel && /^(\S+)\s+(.*)$/) {
383 if ($1 eq "lev_array") {
384 while (<$fh>) {
385 last if /^endplst\s*$/;
386 push @{$toplevel->{lev_array}}, $_+0;
387 }
388 } else {
389 $toplevel->{$1} = $2;
390 }
341 } elsif (/^\s*($|#)/) { 391 } elsif (/^\s*($|#)/) {
342 # 392 #
343 } else { 393 } else {
344 warn "$path: unparseable top-level line '$_'"; 394 die "$path: unparseable top-level line '$_'";
345 } 395 }
346 } 396 }
347 397
348 undef $parse_block; # work around bug in perl not freeing $fh etc. 398 undef $parse_block; # work around bug in perl not freeing $fh etc.
349 399
356sub editor_archs { 406sub editor_archs {
357 my %paths; 407 my %paths;
358 408
359 for (keys %ARCH) { 409 for (keys %ARCH) {
360 my $arch = $ARCH{$_}; 410 my $arch = $ARCH{$_};
361 push @{$paths{$arch->{editor_folder}}}, \$arch; 411 push @{$paths{$arch->{editor_folder}}}, $arch;
362 } 412 }
363 413
364 \%paths 414 \%paths
365} 415}
366 416
431 my $type = $obj->{type} || $arch->{type}; 481 my $type = $obj->{type} || $arch->{type};
432 482
433 if ($type > 0) { 483 if ($type > 0) {
434 $root = $Crossfire::Data::ATTR{$type}; 484 $root = $Crossfire::Data::ATTR{$type};
435 } else { 485 } else {
486 my %a = (%$arch, %$obj);
487
488 if ($a{is_floor} && !$a{alive}) {
489 $root = $Crossfire::Data::TYPE{Floor};
490 } elsif (!$a{is_floor} && $a{alive} && !$a{tear_down}) {
491 $root = $Crossfire::Data::TYPE{"Monster & NPC"};
492 } elsif (!$a{is_floor} && !$a{alive} && $a{move_block}) {
493 $root = $Crossfire::Data::TYPE{Wall};
494 } elsif (!$a{is_floor} && $a{alive} && $a{tear_down}) {
495 $root = $Crossfire::Data::TYPE{"Weak Wall"};
496 } else {
436 $root = $Crossfire::Data::TYPE{Misc}; 497 $root = $Crossfire::Data::TYPE{Misc};
437
438 type:
439 for (@Crossfire::Data::ATTR0) {
440 my $req = $_->{required}
441 or die "internal error: ATTR0 without 'required'";
442
443 keys %$req;
444 while (my ($k, $v) = each %$req) {
445 next type
446 unless $obj->{$k} == $v || $arch->{$k} == $v;
447 }
448
449 $root = $_;
450 } 498 }
451 } 499 }
452 500
453 my @import = ($root); 501 my @import = ($root);
454 502

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines