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.56 by root, Thu Mar 23 07:33:16 2006 UTC vs.
Revision 1.66 by root, Wed Jun 14 19:23:32 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines