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.55 by root, Thu Mar 23 07:06:17 2006 UTC vs.
Revision 1.69 by root, Thu Aug 3 10:51:26 2006 UTC

4 4
5=cut 5=cut
6 6
7package Crossfire; 7package Crossfire;
8 8
9our $VERSION = '0.1'; 9our $VERSION = '0.9';
10 10
11use strict; 11use strict;
12 12
13use base 'Exporter'; 13use base 'Exporter';
14 14
37 msg => "endmsg", 37 msg => "endmsg",
38 lore => "endlore", 38 lore => "endlore",
39 maplore => "endmaplore", 39 maplore => "endmaplore",
40); 40);
41 41
42# movement bit type, PITA
43our %FIELD_MOVEMENT = map +($_ => undef),
44 qw(move_type move_block move_allow move_on move_off move_slow);
45
42# same as in server save routine, to (hopefully) be compatible 46# same as in server save routine, to (hopefully) be compatible
43# to the other editors. 47# to the other editors.
48our @FIELD_ORDER_MAP = (qw(
49 name swap_time reset_timeout fixed_resettime difficulty region
50 shopitems shopgreed shopmin shopmax shoprace
51 darkness width height enter_x enter_y msg maplore
52 unique template
53 outdoor temp pressure humid windspeed winddir sky nosmooth
54 tile_path_1 tile_path_2 tile_path_3 tile_path_4
55));
56
44our @FIELD_ORDER = (qw( 57our @FIELD_ORDER = (qw(
58 elevation
59
45 name name_pl custom_name title race 60 name name_pl custom_name title race
46 slaying skill msg lore other_arch face 61 slaying skill msg lore other_arch face
47 #events 62 #todo-events
48 animation is_animated 63 animation is_animated
49 Str Dex Con Wis Pow Cha Int 64 str dex con wis pow cha int
50 hp maxhp sp maxsp grace maxgrace 65 hp maxhp sp maxsp grace maxgrace
51 exp perm_exp expmul 66 exp perm_exp expmul
52 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
53 nrof level direction type subtype 68 nrof level direction type subtype attacktype
54 69
55 resist_physical resist_magic resist_fire resist_electricity 70 resist_physical resist_magic resist_fire resist_electricity
56 resist_cold resist_confusion resist_acid resist_drain 71 resist_cold resist_confusion resist_acid resist_drain
57 resist_weaponmagic resist_ghosthit resist_poison resist_slow 72 resist_weaponmagic resist_ghosthit resist_poison resist_slow
58 resist_paralyze resist_turn_undead resist_fear resist_cancellation 73 resist_paralyze resist_turn_undead resist_fear resist_cancellation
87 102
88 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
89 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
90)); 105));
91 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
92sub MOVE_WALK (){ 0x01 } 122sub MOVE_WALK (){ 0x01 }
93sub MOVE_FLY_LOW (){ 0x02 } 123sub MOVE_FLY_LOW (){ 0x02 }
94sub MOVE_FLY_HIGH (){ 0x04 } 124sub MOVE_FLY_HIGH (){ 0x04 }
95sub MOVE_FLYING (){ 0x06 } 125sub MOVE_FLYING (){ 0x06 }
96sub MOVE_SWIM (){ 0x08 } 126sub MOVE_SWIM (){ 0x08 }
97sub MOVE_BOAT (){ 0x10 } 127sub MOVE_BOAT (){ 0x10 }
128sub MOVE_KNOWN (){ 0x1f } # all of above
98sub MOVE_ALL (){ 0xff } 129sub MOVE_ALLBIT (){ 0x10000 }
130sub MOVE_ALL (){ 0x1001f } # very special value, more PITA
99 131
100sub load_ref($) { 132sub load_ref($) {
101 my ($path) = @_; 133 my ($path) = @_;
102 134
103 open my $fh, "<", $path 135 open my $fh, "<:raw:perlio", $path
104 or die "$path: $!"; 136 or die "$path: $!";
105 binmode $fh;
106 local $/; 137 local $/;
107 138
108 thaw <$fh> 139 thaw <$fh>
109} 140}
110 141
111sub save_ref($$) { 142sub save_ref($$) {
112 my ($ref, $path) = @_; 143 my ($ref, $path) = @_;
113 144
114 open my $fh, ">", "$path~" 145 open my $fh, ">:raw:perlio", "$path~"
115 or die "$path~: $!"; 146 or die "$path~: $!";
116 binmode $fh;
117 print $fh freeze $ref; 147 print $fh freeze $ref;
118 close $fh; 148 close $fh;
119 rename "$path~", $path 149 rename "$path~", $path
120 or die "$path: $!"; 150 or die "$path: $!";
121} 151}
122 152
153# object as in "Object xxx", i.e. archetypes
123sub normalize_object($) { 154sub normalize_object($) {
124 my ($ob) = @_; 155 my ($ob) = @_;
125 156
157 # nuke outdated or never supported fields
126 delete $ob->{$_} for qw( 158 delete $ob->{$_} for qw(
127 can_knockback can_parry can_impale can_cut can_dam_armour 159 can_knockback can_parry can_impale can_cut can_dam_armour
128 can_apply pass_thru can_pass_thru 160 can_apply pass_thru can_pass_thru
129 ); 161 );
130 162
131 for my $attr (qw(move_type move_block move_allow move_on move_off move_slow)) { 163 # convert movement strings to bitsets
164 for my $attr (keys %FIELD_MOVEMENT) {
132 next unless exists $ob->{$attr}; 165 next unless exists $ob->{$attr};
166
167 $ob->{$attr} = MOVE_ALL if $ob->{$attr} == 255; #d# compatibility
168
133 next if $ob->{$attr} =~ /^\d+$/; 169 next if $ob->{$attr} =~ /^\d+$/;
134 170
135 my $flags = 0; 171 my $flags = 0;
136 172
137 # assume list 173 # assume list
154 } 190 }
155 191
156 $ob->{$attr} = $flags; 192 $ob->{$attr} = $flags;
157 } 193 }
158 194
195 # convert outdated movement flags to new movement sets
159 if (defined (my $v = delete $ob->{no_pass})) { 196 if (defined (my $v = delete $ob->{no_pass})) {
160 $ob->{move_block} = $v ? MOVE_ALL : 0; 197 $ob->{move_block} = $v ? MOVE_ALL : 0;
161 } 198 }
162 if (defined (my $v = delete $ob->{slow_move})) { 199 if (defined (my $v = delete $ob->{slow_move})) {
163 $ob->{move_slow} |= MOVE_WALK; 200 $ob->{move_slow} |= MOVE_WALK;
164 $ob->{move_slow_penalty} = $v; 201 $ob->{move_slow_penalty} = $v;
165 } 202 }
166 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};
167 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_WALK 205 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_WALK
168 : $ob->{move_on} & ~MOVE_WALK; 206 : $ob->{move_on} & ~MOVE_WALK;
169 } 207 }
170 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};
171 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_WALK 210 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_WALK
172 : $ob->{move_off} & ~MOVE_WALK; 211 : $ob->{move_off} & ~MOVE_WALK;
173 } 212 }
174 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};
175 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_FLY_LOW 215 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_FLY_LOW
176 : $ob->{move_on} & ~MOVE_FLY_LOW; 216 : $ob->{move_on} & ~MOVE_FLY_LOW;
177 } 217 }
178 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};
179 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_FLY_LOW 220 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_FLY_LOW
180 : $ob->{move_off} & ~MOVE_FLY_LOW; 221 : $ob->{move_off} & ~MOVE_FLY_LOW;
181 } 222 }
182 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};
183 $ob->{move_type} = $v ? $ob->{move_type} | MOVE_FLY_LOW 225 $ob->{move_type} = $v ? $ob->{move_type} | MOVE_FLY_LOW
184 : $ob->{move_type} & ~MOVE_FLY_LOW; 226 : $ob->{move_type} & ~MOVE_FLY_LOW;
185 } 227 }
186 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
187 $ob 241 $ob
188} 242}
189 243
244# arch as in "arch xxx", ie.. objects
190sub normalize_arch($) { 245sub normalize_arch($) {
191 my ($ob) = @_; 246 my ($ob) = @_;
192 247
193 normalize_object $ob; 248 normalize_object $ob;
194 249
221 delete $ob->{$k}; 276 delete $ob->{$k};
222 } 277 }
223 } 278 }
224 } 279 }
225 280
281 # a speciality for the editor
282 if (exists $ob->{attack_movement}) {
283 my $am = delete $ob->{attack_movement};
284 $ob->{attack_movement_bits_0_3} = $am & 15;
285 $ob->{attack_movement_bits_4_7} = $am & 240;
286 }
287
226 $ob 288 $ob
227} 289}
228 290
229sub read_pak($) { 291sub read_pak($) {
230 my ($path) = @_; 292 my ($path) = @_;
231 293
232 my %pak; 294 my %pak;
233 295
234 open my $fh, "<", $path 296 open my $fh, "<:raw:perlio", $path
235 or Carp::croak "$_[0]: $!"; 297 or Carp::croak "$_[0]: $!";
236 binmode $fh; 298 binmode $fh;
237 while (<$fh>) { 299 while (<$fh>) {
238 my ($type, $id, $len, $path) = split; 300 my ($type, $id, $len, $path) = split;
239 $path =~ s/.*\///; 301 $path =~ s/.*\///;
241 } 303 }
242 304
243 \%pak 305 \%pak
244} 306}
245 307
246sub read_arch($) { 308sub read_arch($;$) {
247 my ($path) = @_; 309 my ($path, $toplevel) = @_;
248 310
249 my %arc; 311 my %arc;
250 my ($more, $prev); 312 my ($more, $prev);
251 313
252 open my $fh, "<", $path 314 open my $fh, "<:raw:perlio:utf8", $path
253 or Carp::croak "$path: $!"; 315 or Carp::croak "$path: $!";
254 316
255 binmode $fh; 317# binmode $fh;
256 318
257 my $parse_block; $parse_block = sub { 319 my $parse_block; $parse_block = sub {
258 my %arc = @_; 320 my %arc = @_;
259 321
260 while (<$fh>) { 322 while (<$fh>) {
271 } elsif (/^msg$/i) { 333 } elsif (/^msg$/i) {
272 while (<$fh>) { 334 while (<$fh>) {
273 last if /^endmsg\s*$/i; 335 last if /^endmsg\s*$/i;
274 $arc{msg} .= $_; 336 $arc{msg} .= $_;
275 } 337 }
338 } elsif (/^anim$/i) {
339 while (<$fh>) {
340 last if /^mina\s*$/i;
341 chomp;
342 push @{ $arc{anim} }, $_;
343 }
276 } elsif (/^(\S+)\s*(.*)$/) { 344 } elsif (/^(\S+)\s*(.*)$/) {
277 $arc{lc $1} = $2; 345 $arc{lc $1} = $2;
278 } elsif (/^\s*($|#)/) { 346 } elsif (/^\s*($|#)/) {
279 # 347 #
280 } else { 348 } else {
300 } 368 }
301 $prev = $arc; 369 $prev = $arc;
302 $more = undef; 370 $more = undef;
303 } elsif (/^arch (\S+)$/i) { 371 } elsif (/^arch (\S+)$/i) {
304 my $name = $1; 372 my $name = $1;
305 my $arc = normalize_object $parse_block->(_name => $name); 373 my $arc = normalize_arch $parse_block->(_name => $name);
306 374
307 if ($more) { 375 if ($more) {
308 $more->{more} = $arc; 376 $more->{more} = $arc;
309 } else { 377 } else {
310 push @{ $arc{arch} }, $arc; 378 push @{ $arc{arch} }, $arc;
311 } 379 }
312 $prev = $arc; 380 $prev = $arc;
313 $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 }
314 } elsif (/^\s*($|#)/) { 391 } elsif (/^\s*($|#)/) {
315 # 392 #
316 } else { 393 } else {
317 warn "$path: unparseable top-level line '$_'"; 394 die "$path: unparseable top-level line '$_'";
318 } 395 }
319 } 396 }
320 397
321 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.
322 399
329sub editor_archs { 406sub editor_archs {
330 my %paths; 407 my %paths;
331 408
332 for (keys %ARCH) { 409 for (keys %ARCH) {
333 my $arch = $ARCH{$_}; 410 my $arch = $ARCH{$_};
334 push @{$paths{$arch->{editor_folder}}}, \$arch; 411 push @{$paths{$arch->{editor_folder}}}, $arch;
335 } 412 }
336 413
337 \%paths 414 \%paths
338} 415}
339 416
404 my $type = $obj->{type} || $arch->{type}; 481 my $type = $obj->{type} || $arch->{type};
405 482
406 if ($type > 0) { 483 if ($type > 0) {
407 $root = $Crossfire::Data::ATTR{$type}; 484 $root = $Crossfire::Data::ATTR{$type};
408 } 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 {
409 $root = $Crossfire::Data::TYPE{Misc}; 497 $root = $Crossfire::Data::TYPE{Misc};
410
411 type:
412 for (@Crossfire::Data::ATTR0) {
413 my $req = $_->{required}
414 or die "internal error: ATTR0 without 'required'";
415
416 keys %$req;
417 while (my ($k, $v) = each %$req) {
418 next type
419 unless $obj->{$k} == $v || $arch->{$k} == $v;
420 }
421
422 $root = $_;
423 } 498 }
424 } 499 }
425 500
426 my @import = ($root); 501 my @import = ($root);
427 502
601 cache_file "$LIB/crossfire.0", "$VARDIR/tilecache.pst", sub { 676 cache_file "$LIB/crossfire.0", "$VARDIR/tilecache.pst", sub {
602 $TILE = new_from_file Gtk2::Gdk::Pixbuf "$VARDIR/tilecache.png" 677 $TILE = new_from_file Gtk2::Gdk::Pixbuf "$VARDIR/tilecache.png"
603 or die "$VARDIR/tilecache.png: $!"; 678 or die "$VARDIR/tilecache.png: $!";
604 *FACE = $_[0]; 679 *FACE = $_[0];
605 }, sub { 680 }, sub {
606 require File::Temp;
607
608 my $tile = read_pak "$LIB/crossfire.0"; 681 my $tile = read_pak "$LIB/crossfire.0";
609 682
610 my %cache; 683 my %cache;
611 684
612 my $idx = 0; 685 my $idx = 0;
613 686
614 for my $name (sort keys %$tile) { 687 for my $name (sort keys %$tile) {
615 my ($fh, $filename) = File::Temp::tempfile (); 688 my $pb = new Gtk2::Gdk::PixbufLoader;
616 print $fh $tile->{$name}; 689 $pb->write ($tile->{$name});
617 close $fh; 690 $pb->close;
618 my $pb = new_from_file Gtk2::Gdk::Pixbuf $filename; 691 my $pb = $pb->get_pixbuf;
619 unlink $filename;
620 692
621 my $tile = $cache{$name} = { 693 my $tile = $cache{$name} = {
622 pb => $pb, 694 pb => $pb,
623 idx => $idx, 695 idx => $idx,
624 w => int $pb->get_width / TILESIZE, 696 w => int $pb->get_width / TILESIZE,
642 $pb, ($idx % 64) * TILESIZE, TILESIZE * int $idx / 64); 714 $pb, ($idx % 64) * TILESIZE, TILESIZE * int $idx / 64);
643 } 715 }
644 } 716 }
645 } 717 }
646 718
647 $pb->save ("$VARDIR/tilecache.png", "png"); 719 $pb->save ("$VARDIR/tilecache.png", "png", compression => 1);
648 720
649 \%cache 721 \%cache
650 }; 722 };
651} 723}
652 724

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines