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.57 by root, Thu Mar 23 08:55:54 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
55 59
56 name name_pl custom_name title race 60 name name_pl custom_name title race
57 slaying skill msg lore other_arch face 61 slaying skill msg lore other_arch face
58 #todo-events 62 #todo-events
59 animation is_animated 63 animation is_animated
60 Str Dex Con Wis Pow Cha Int 64 str dex con wis pow cha int
61 hp maxhp sp maxsp grace maxgrace 65 hp maxhp sp maxsp grace maxgrace
62 exp perm_exp expmul 66 exp perm_exp expmul
63 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
64 nrof level direction type subtype 68 nrof level direction type subtype attacktype
65 69
66 resist_physical resist_magic resist_fire resist_electricity 70 resist_physical resist_magic resist_fire resist_electricity
67 resist_cold resist_confusion resist_acid resist_drain 71 resist_cold resist_confusion resist_acid resist_drain
68 resist_weaponmagic resist_ghosthit resist_poison resist_slow 72 resist_weaponmagic resist_ghosthit resist_poison resist_slow
69 resist_paralyze resist_turn_undead resist_fear resist_cancellation 73 resist_paralyze resist_turn_undead resist_fear resist_cancellation
98 102
99 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
100 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
101)); 105));
102 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
103sub MOVE_WALK (){ 0x01 } 122sub MOVE_WALK (){ 0x01 }
104sub MOVE_FLY_LOW (){ 0x02 } 123sub MOVE_FLY_LOW (){ 0x02 }
105sub MOVE_FLY_HIGH (){ 0x04 } 124sub MOVE_FLY_HIGH (){ 0x04 }
106sub MOVE_FLYING (){ 0x06 } 125sub MOVE_FLYING (){ 0x06 }
107sub MOVE_SWIM (){ 0x08 } 126sub MOVE_SWIM (){ 0x08 }
108sub MOVE_BOAT (){ 0x10 } 127sub MOVE_BOAT (){ 0x10 }
128sub MOVE_KNOWN (){ 0x1f } # all of above
109sub MOVE_ALL (){ 0xff } 129sub MOVE_ALLBIT (){ 0x10000 }
130sub MOVE_ALL (){ 0x1001f } # very special value, more PITA
110 131
111sub load_ref($) { 132sub load_ref($) {
112 my ($path) = @_; 133 my ($path) = @_;
113 134
114 open my $fh, "<", $path 135 open my $fh, "<:raw:perlio", $path
115 or die "$path: $!"; 136 or die "$path: $!";
116 binmode $fh;
117 local $/; 137 local $/;
118 138
119 thaw <$fh> 139 thaw <$fh>
120} 140}
121 141
122sub save_ref($$) { 142sub save_ref($$) {
123 my ($ref, $path) = @_; 143 my ($ref, $path) = @_;
124 144
125 open my $fh, ">", "$path~" 145 open my $fh, ">:raw:perlio", "$path~"
126 or die "$path~: $!"; 146 or die "$path~: $!";
127 binmode $fh;
128 print $fh freeze $ref; 147 print $fh freeze $ref;
129 close $fh; 148 close $fh;
130 rename "$path~", $path 149 rename "$path~", $path
131 or die "$path: $!"; 150 or die "$path: $!";
132} 151}
133 152
153# object as in "Object xxx", i.e. archetypes
134sub normalize_object($) { 154sub normalize_object($) {
135 my ($ob) = @_; 155 my ($ob) = @_;
136 156
157 # nuke outdated or never supported fields
137 delete $ob->{$_} for qw( 158 delete $ob->{$_} for qw(
138 can_knockback can_parry can_impale can_cut can_dam_armour 159 can_knockback can_parry can_impale can_cut can_dam_armour
139 can_apply pass_thru can_pass_thru 160 can_apply pass_thru can_pass_thru
140 ); 161 );
141 162
142 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) {
143 next unless exists $ob->{$attr}; 165 next unless exists $ob->{$attr};
166
167 $ob->{$attr} = MOVE_ALL if $ob->{$attr} == 255; #d# compatibility
168
144 next if $ob->{$attr} =~ /^\d+$/; 169 next if $ob->{$attr} =~ /^\d+$/;
145 170
146 my $flags = 0; 171 my $flags = 0;
147 172
148 # assume list 173 # assume list
165 } 190 }
166 191
167 $ob->{$attr} = $flags; 192 $ob->{$attr} = $flags;
168 } 193 }
169 194
195 # convert outdated movement flags to new movement sets
170 if (defined (my $v = delete $ob->{no_pass})) { 196 if (defined (my $v = delete $ob->{no_pass})) {
171 $ob->{move_block} = $v ? MOVE_ALL : 0; 197 $ob->{move_block} = $v ? MOVE_ALL : 0;
172 } 198 }
173 if (defined (my $v = delete $ob->{slow_move})) { 199 if (defined (my $v = delete $ob->{slow_move})) {
174 $ob->{move_slow} |= MOVE_WALK; 200 $ob->{move_slow} |= MOVE_WALK;
175 $ob->{move_slow_penalty} = $v; 201 $ob->{move_slow_penalty} = $v;
176 } 202 }
177 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};
178 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_WALK 205 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_WALK
179 : $ob->{move_on} & ~MOVE_WALK; 206 : $ob->{move_on} & ~MOVE_WALK;
180 } 207 }
181 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};
182 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_WALK 210 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_WALK
183 : $ob->{move_off} & ~MOVE_WALK; 211 : $ob->{move_off} & ~MOVE_WALK;
184 } 212 }
185 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};
186 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_FLY_LOW 215 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_FLY_LOW
187 : $ob->{move_on} & ~MOVE_FLY_LOW; 216 : $ob->{move_on} & ~MOVE_FLY_LOW;
188 } 217 }
189 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};
190 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_FLY_LOW 220 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_FLY_LOW
191 : $ob->{move_off} & ~MOVE_FLY_LOW; 221 : $ob->{move_off} & ~MOVE_FLY_LOW;
192 } 222 }
193 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};
194 $ob->{move_type} = $v ? $ob->{move_type} | MOVE_FLY_LOW 225 $ob->{move_type} = $v ? $ob->{move_type} | MOVE_FLY_LOW
195 : $ob->{move_type} & ~MOVE_FLY_LOW; 226 : $ob->{move_type} & ~MOVE_FLY_LOW;
196 } 227 }
197 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
198 $ob 241 $ob
199} 242}
200 243
244# arch as in "arch xxx", ie.. objects
201sub normalize_arch($) { 245sub normalize_arch($) {
202 my ($ob) = @_; 246 my ($ob) = @_;
203 247
204 normalize_object $ob; 248 normalize_object $ob;
205 249
247sub read_pak($) { 291sub read_pak($) {
248 my ($path) = @_; 292 my ($path) = @_;
249 293
250 my %pak; 294 my %pak;
251 295
252 open my $fh, "<", $path 296 open my $fh, "<:raw:perlio", $path
253 or Carp::croak "$_[0]: $!"; 297 or Carp::croak "$_[0]: $!";
254 binmode $fh; 298 binmode $fh;
255 while (<$fh>) { 299 while (<$fh>) {
256 my ($type, $id, $len, $path) = split; 300 my ($type, $id, $len, $path) = split;
257 $path =~ s/.*\///; 301 $path =~ s/.*\///;
259 } 303 }
260 304
261 \%pak 305 \%pak
262} 306}
263 307
264sub read_arch($) { 308sub read_arch($;$) {
265 my ($path) = @_; 309 my ($path, $toplevel) = @_;
266 310
267 my %arc; 311 my %arc;
268 my ($more, $prev); 312 my ($more, $prev);
269 313
270 open my $fh, "<", $path 314 open my $fh, "<:raw:perlio:utf8", $path
271 or Carp::croak "$path: $!"; 315 or Carp::croak "$path: $!";
272 316
273 binmode $fh; 317 binmode $fh;
274 318
275 my $parse_block; $parse_block = sub { 319 my $parse_block; $parse_block = sub {
289 } elsif (/^msg$/i) { 333 } elsif (/^msg$/i) {
290 while (<$fh>) { 334 while (<$fh>) {
291 last if /^endmsg\s*$/i; 335 last if /^endmsg\s*$/i;
292 $arc{msg} .= $_; 336 $arc{msg} .= $_;
293 } 337 }
338 } elsif (/^anim$/i) {
339 while (<$fh>) {
340 last if /^mina\s*$/i;
341 chomp;
342 push @{ $arc{anim} }, $_;
343 }
294 } elsif (/^(\S+)\s*(.*)$/) { 344 } elsif (/^(\S+)\s*(.*)$/) {
295 $arc{lc $1} = $2; 345 $arc{lc $1} = $2;
296 } elsif (/^\s*($|#)/) { 346 } elsif (/^\s*($|#)/) {
297 # 347 #
298 } else { 348 } else {
327 } else { 377 } else {
328 push @{ $arc{arch} }, $arc; 378 push @{ $arc{arch} }, $arc;
329 } 379 }
330 $prev = $arc; 380 $prev = $arc;
331 $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 }
332 } elsif (/^\s*($|#)/) { 391 } elsif (/^\s*($|#)/) {
333 # 392 #
334 } else { 393 } else {
335 warn "$path: unparseable top-level line '$_'"; 394 die "$path: unparseable top-level line '$_'";
336 } 395 }
337 } 396 }
338 397
339 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.
340 399
347sub editor_archs { 406sub editor_archs {
348 my %paths; 407 my %paths;
349 408
350 for (keys %ARCH) { 409 for (keys %ARCH) {
351 my $arch = $ARCH{$_}; 410 my $arch = $ARCH{$_};
352 push @{$paths{$arch->{editor_folder}}}, \$arch; 411 push @{$paths{$arch->{editor_folder}}}, $arch;
353 } 412 }
354 413
355 \%paths 414 \%paths
356} 415}
357 416
422 my $type = $obj->{type} || $arch->{type}; 481 my $type = $obj->{type} || $arch->{type};
423 482
424 if ($type > 0) { 483 if ($type > 0) {
425 $root = $Crossfire::Data::ATTR{$type}; 484 $root = $Crossfire::Data::ATTR{$type};
426 } 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 {
427 $root = $Crossfire::Data::TYPE{Misc}; 497 $root = $Crossfire::Data::TYPE{Misc};
428
429 type:
430 for (@Crossfire::Data::ATTR0) {
431 my $req = $_->{required}
432 or die "internal error: ATTR0 without 'required'";
433
434 keys %$req;
435 while (my ($k, $v) = each %$req) {
436 next type
437 unless $obj->{$k} == $v || $arch->{$k} == $v;
438 }
439
440 $root = $_;
441 } 498 }
442 } 499 }
443 500
444 my @import = ($root); 501 my @import = ($root);
445 502
619 cache_file "$LIB/crossfire.0", "$VARDIR/tilecache.pst", sub { 676 cache_file "$LIB/crossfire.0", "$VARDIR/tilecache.pst", sub {
620 $TILE = new_from_file Gtk2::Gdk::Pixbuf "$VARDIR/tilecache.png" 677 $TILE = new_from_file Gtk2::Gdk::Pixbuf "$VARDIR/tilecache.png"
621 or die "$VARDIR/tilecache.png: $!"; 678 or die "$VARDIR/tilecache.png: $!";
622 *FACE = $_[0]; 679 *FACE = $_[0];
623 }, sub { 680 }, sub {
624 require File::Temp;
625
626 my $tile = read_pak "$LIB/crossfire.0"; 681 my $tile = read_pak "$LIB/crossfire.0";
627 682
628 my %cache; 683 my %cache;
629 684
630 my $idx = 0; 685 my $idx = 0;
631 686
632 for my $name (sort keys %$tile) { 687 for my $name (sort keys %$tile) {
633 my ($fh, $filename) = File::Temp::tempfile (); 688 my $pb = new Gtk2::Gdk::PixbufLoader;
634 print $fh $tile->{$name}; 689 $pb->write ($tile->{$name});
635 close $fh; 690 $pb->close;
636 my $pb = new_from_file Gtk2::Gdk::Pixbuf $filename; 691 my $pb = $pb->get_pixbuf;
637 unlink $filename;
638 692
639 my $tile = $cache{$name} = { 693 my $tile = $cache{$name} = {
640 pb => $pb, 694 pb => $pb,
641 idx => $idx, 695 idx => $idx,
642 w => int $pb->get_width / TILESIZE, 696 w => int $pb->get_width / TILESIZE,
660 $pb, ($idx % 64) * TILESIZE, TILESIZE * int $idx / 64); 714 $pb, ($idx % 64) * TILESIZE, TILESIZE * int $idx / 64);
661 } 715 }
662 } 716 }
663 } 717 }
664 718
665 $pb->save ("$VARDIR/tilecache.png", "png"); 719 $pb->save ("$VARDIR/tilecache.png", "png", compression => 1);
666 720
667 \%cache 721 \%cache
668 }; 722 };
669} 723}
670 724

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines