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.58 by root, Thu Mar 23 20:15:08 2006 UTC vs.
Revision 1.67 by root, Sun Jul 30 16:05:11 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
59 59
60 name name_pl custom_name title race 60 name name_pl custom_name title race
61 slaying skill msg lore other_arch face 61 slaying skill msg lore other_arch face
62 #todo-events 62 #todo-events
63 animation is_animated 63 animation is_animated
64 Str Dex Con Wis Pow Cha Int 64 str dex con wis pow cha int
65 hp maxhp sp maxsp grace maxgrace 65 hp maxhp sp maxsp grace maxgrace
66 exp perm_exp expmul 66 exp perm_exp expmul
67 food dam luck wc ac x y speed speed_left move_state attack_movement 67 food dam luck wc ac x y speed speed_left move_state attack_movement
68 nrof level direction type subtype 68 nrof level direction type subtype attacktype
69 69
70 resist_physical resist_magic resist_fire resist_electricity 70 resist_physical resist_magic resist_fire resist_electricity
71 resist_cold resist_confusion resist_acid resist_drain 71 resist_cold resist_confusion resist_acid resist_drain
72 resist_weaponmagic resist_ghosthit resist_poison resist_slow 72 resist_weaponmagic resist_ghosthit resist_poison resist_slow
73 resist_paralyze resist_turn_undead resist_fear resist_cancellation 73 resist_paralyze resist_turn_undead resist_fear resist_cancellation
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 {
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
628 cache_file "$LIB/crossfire.0", "$VARDIR/tilecache.pst", sub { 676 cache_file "$LIB/crossfire.0", "$VARDIR/tilecache.pst", sub {
629 $TILE = new_from_file Gtk2::Gdk::Pixbuf "$VARDIR/tilecache.png" 677 $TILE = new_from_file Gtk2::Gdk::Pixbuf "$VARDIR/tilecache.png"
630 or die "$VARDIR/tilecache.png: $!"; 678 or die "$VARDIR/tilecache.png: $!";
631 *FACE = $_[0]; 679 *FACE = $_[0];
632 }, sub { 680 }, sub {
633 require File::Temp;
634
635 my $tile = read_pak "$LIB/crossfire.0"; 681 my $tile = read_pak "$LIB/crossfire.0";
636 682
637 my %cache; 683 my %cache;
638 684
639 my $idx = 0; 685 my $idx = 0;
640 686
641 for my $name (sort keys %$tile) { 687 for my $name (sort keys %$tile) {
642 my ($fh, $filename) = File::Temp::tempfile (); 688 my $pb = new Gtk2::Gdk::PixbufLoader;
643 print $fh $tile->{$name}; 689 $pb->write ($tile->{$name});
644 close $fh; 690 $pb->close;
645 my $pb = new_from_file Gtk2::Gdk::Pixbuf $filename; 691 my $pb = $pb->get_pixbuf;
646 unlink $filename;
647 692
648 my $tile = $cache{$name} = { 693 my $tile = $cache{$name} = {
649 pb => $pb, 694 pb => $pb,
650 idx => $idx, 695 idx => $idx,
651 w => int $pb->get_width / TILESIZE, 696 w => int $pb->get_width / TILESIZE,
669 $pb, ($idx % 64) * TILESIZE, TILESIZE * int $idx / 64); 714 $pb, ($idx % 64) * TILESIZE, TILESIZE * int $idx / 64);
670 } 715 }
671 } 716 }
672 } 717 }
673 718
674 $pb->save ("$VARDIR/tilecache.png", "png"); 719 $pb->save ("$VARDIR/tilecache.png", "png", compression => 1);
675 720
676 \%cache 721 \%cache
677 }; 722 };
678} 723}
679 724

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines