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.83 by root, Wed Feb 7 00:14:48 2007 UTC vs.
Revision 1.93 by root, Sat Mar 3 19:38:06 2007 UTC

58 qw(move_type move_block move_allow move_on move_off move_slow); 58 qw(move_type move_block move_allow move_on move_off move_slow);
59 59
60# same as in server save routine, to (hopefully) be compatible 60# same as in server save routine, to (hopefully) be compatible
61# to the other editors. 61# to the other editors.
62our @FIELD_ORDER_MAP = (qw( 62our @FIELD_ORDER_MAP = (qw(
63 file_format_version
63 name attach swap_time reset_timeout fixed_resettime difficulty region 64 name attach swap_time reset_timeout fixed_resettime difficulty region
64 shopitems shopgreed shopmin shopmax shoprace 65 shopitems shopgreed shopmin shopmax shoprace
65 darkness width height enter_x enter_y msg maplore 66 darkness width height enter_x enter_y msg maplore
66 unique template 67 unique template
67 outdoor temp pressure humid windspeed winddir sky nosmooth 68 outdoor temp pressure humid windspeed winddir sky nosmooth
138sub MOVE_FLY_HIGH (){ 0x04 } 139sub MOVE_FLY_HIGH (){ 0x04 }
139sub MOVE_FLYING (){ 0x06 } 140sub MOVE_FLYING (){ 0x06 }
140sub MOVE_SWIM (){ 0x08 } 141sub MOVE_SWIM (){ 0x08 }
141sub MOVE_BOAT (){ 0x10 } 142sub MOVE_BOAT (){ 0x10 }
142sub MOVE_KNOWN (){ 0x1f } # all of above 143sub MOVE_KNOWN (){ 0x1f } # all of above
143sub MOVE_ALLBIT (){ 0x10000 }
144sub MOVE_ALL (){ 0x1001f } # very special value, more PITA 144sub MOVE_ALL (){ 0x10000 } # very special value
145
146our %MOVE_TYPE = (
147 walk => MOVE_WALK,
148 fly_low => MOVE_FLY_LOW,
149 fly_high => MOVE_FLY_HIGH,
150 flying => MOVE_FLYING,
151 swim => MOVE_SWIM,
152 boat => MOVE_BOAT,
153 all => MOVE_ALL,
154);
155
156our @MOVE_TYPE = qw(all walk flying fly_low fly_high swim boat);
157
158{
159 package Crossfire::MoveType;
160
161 use overload
162 '=' => sub { bless [@{$_[0]}], ref $_[0] },
163 '""' => \&as_string,
164 '>=' => sub { $_[0][0] & $MOVE_TYPE{$_[1]} ? $_[0][1] & $MOVE_TYPE{$_[1]} : undef },
165 '+=' => sub { $_[0][0] |= $MOVE_TYPE{$_[1]}; $_[0][1] |= $MOVE_TYPE{$_[1]}; &normalise },
166 '-=' => sub { $_[0][0] |= $MOVE_TYPE{$_[1]}; $_[0][1] &= ~$MOVE_TYPE{$_[1]}; &normalise },
167 '/=' => sub { $_[0][0] &= ~$MOVE_TYPE{$_[1]}; &normalise },
168 'x=' => sub {
169 my $cur = $_[0] >= $_[1];
170 if (!defined $cur) {
171 $_[0] += $_[1];
172 } elsif ($cur) {
173 $_[0] -= $_[1];
174 } else {
175 $_[0] /= $_[1];
176 }
177
178 $_[0]
179 },
180 'eq' => sub { "$_[0]" eq "$_[1]" },
181 'ne' => sub { "$_[0]" ne "$_[1]" },
182 ;
183}
184
185sub Crossfire::MoveType::new {
186 my ($class, $string) = @_;
187
188 my $mask;
189 my $value;
190
191 if ($string =~ /^\s*\d+\s*$/) {
192 $mask = MOVE_ALL;
193 $value = $string+0;
194 } else {
195 for (split /\s+/, lc $string) {
196 if (s/^-//) {
197 $mask |= $MOVE_TYPE{$_};
198 $value &= ~$MOVE_TYPE{$_};
199 } else {
200 $mask |= $MOVE_TYPE{$_};
201 $value |= $MOVE_TYPE{$_};
202 }
203 }
204 }
205
206 (bless [$mask, $value], $class)->normalise
207}
208
209sub Crossfire::MoveType::normalise {
210 my ($self) = @_;
211
212 if ($self->[0] & MOVE_ALL) {
213 my $mask = ~(($self->[1] & MOVE_ALL ? $self->[1] : ~$self->[1]) & $self->[0] & ~MOVE_ALL);
214 $self->[0] &= $mask;
215 $self->[1] &= $mask;
216 }
217
218 $self->[1] &= $self->[0];
219
220 $self
221}
222
223sub Crossfire::MoveType::as_string {
224 my ($self) = @_;
225
226 my @res;
227
228 my ($mask, $value) = @$self;
229
230 for (@Crossfire::MOVE_TYPE) {
231 my $bit = $Crossfire::MOVE_TYPE{$_};
232 if (($mask & $bit) == $bit && (($value & $bit) == $bit || ($value & $bit) == 0)) {
233 $mask &= ~$bit;
234 push @res, $value & $bit ? $_ : "-$_";
235 }
236 }
237
238 join " ", @res
239}
145 240
146sub load_ref($) { 241sub load_ref($) {
147 my ($path) = @_; 242 my ($path) = @_;
148 243
149 open my $fh, "<:raw:perlio", $path 244 open my $fh, "<:raw:perlio", $path
225 ice => 68, 320 ice => 68,
226 stone => 70, 321 stone => 70,
227 stone => 80, 322 stone => 80,
228 cloth => 136, 323 cloth => 136,
229 ironwood => 144, 324 ironwood => 144,
325 adamantium => 258,
326 glacium => 260,
230 blood => 544, 327 blood => 544,
231; 328;
232 329
233# object as in "Object xxx", i.e. archetypes 330# object as in "Object xxx", i.e. archetypes
234sub normalize_object($) { 331sub normalize_object($) {
265 362
266 # convert movement strings to bitsets 363 # convert movement strings to bitsets
267 for my $attr (keys %FIELD_MOVEMENT) { 364 for my $attr (keys %FIELD_MOVEMENT) {
268 next unless exists $ob->{$attr}; 365 next unless exists $ob->{$attr};
269 366
270 $ob->{$attr} = MOVE_ALL if $ob->{$attr} == 255; #d# compatibility 367 $ob->{$attr} = new Crossfire::MoveType $ob->{$attr};
271
272 next if $ob->{$attr} =~ /^\d+$/;
273
274 my $flags = 0;
275
276 # assume list
277 for my $flag (map lc, split /\s+/, $ob->{$attr}) {
278 $flags |= MOVE_WALK if $flag eq "walk";
279 $flags |= MOVE_FLY_LOW if $flag eq "fly_low";
280 $flags |= MOVE_FLY_HIGH if $flag eq "fly_high";
281 $flags |= MOVE_FLYING if $flag eq "flying";
282 $flags |= MOVE_SWIM if $flag eq "swim";
283 $flags |= MOVE_BOAT if $flag eq "boat";
284 $flags |= MOVE_ALL if $flag eq "all";
285
286 $flags &= ~MOVE_WALK if $flag eq "-walk";
287 $flags &= ~MOVE_FLY_LOW if $flag eq "-fly_low";
288 $flags &= ~MOVE_FLY_HIGH if $flag eq "-fly_high";
289 $flags &= ~MOVE_FLYING if $flag eq "-flying";
290 $flags &= ~MOVE_SWIM if $flag eq "-swim";
291 $flags &= ~MOVE_BOAT if $flag eq "-boat";
292 $flags &= ~MOVE_ALL if $flag eq "-all";
293 }
294
295 $ob->{$attr} = $flags;
296 } 368 }
297 369
298 # convert outdated movement flags to new movement sets 370 # convert outdated movement flags to new movement sets
299 if (defined (my $v = delete $ob->{no_pass})) { 371 if (defined (my $v = delete $ob->{no_pass})) {
300 $ob->{move_block} = $v ? MOVE_ALL : 0; 372 $ob->{move_block} = new Crossfire::MoveType $v ? "all" : "";
301 } 373 }
302 if (defined (my $v = delete $ob->{slow_move})) { 374 if (defined (my $v = delete $ob->{slow_move})) {
303 $ob->{move_slow} |= MOVE_WALK; 375 $ob->{move_slow} += "walk";
304 $ob->{move_slow_penalty} = $v; 376 $ob->{move_slow_penalty} = $v;
305 } 377 }
306 if (defined (my $v = delete $ob->{walk_on})) { 378 if (defined (my $v = delete $ob->{walk_on})) {
307 $ob->{move_on} = MOVE_ALL unless exists $ob->{move_on}; 379 $ob->{move_on} ||= new Crossfire::MoveType; if ($v) { $ob->{move_on} += "walk" } else { $ob->{move_on} -= "walk" }
308 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_WALK
309 : $ob->{move_on} & ~MOVE_WALK;
310 } 380 }
311 if (defined (my $v = delete $ob->{walk_off})) { 381 if (defined (my $v = delete $ob->{walk_off})) {
312 $ob->{move_off} = MOVE_ALL unless exists $ob->{move_off}; 382 $ob->{move_off} ||= new Crossfire::MoveType; if ($v) { $ob->{move_off} += "walk" } else { $ob->{move_off} -= "walk" }
313 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_WALK
314 : $ob->{move_off} & ~MOVE_WALK;
315 } 383 }
316 if (defined (my $v = delete $ob->{fly_on})) { 384 if (defined (my $v = delete $ob->{fly_on})) {
317 $ob->{move_on} = MOVE_ALL unless exists $ob->{move_on}; 385 $ob->{move_on} ||= new Crossfire::MoveType; if ($v) { $ob->{move_on} += "fly_low" } else { $ob->{move_on} -= "fly_low" }
318 $ob->{move_on} = $v ? $ob->{move_on} | MOVE_FLY_LOW
319 : $ob->{move_on} & ~MOVE_FLY_LOW;
320 } 386 }
321 if (defined (my $v = delete $ob->{fly_off})) { 387 if (defined (my $v = delete $ob->{fly_off})) {
322 $ob->{move_off} = MOVE_ALL unless exists $ob->{move_off}; 388 $ob->{move_off} ||= new Crossfire::MoveType; if ($v) { $ob->{move_off} += "fly_low" } else { $ob->{move_off} -= "fly_low" }
323 $ob->{move_off} = $v ? $ob->{move_off} | MOVE_FLY_LOW
324 : $ob->{move_off} & ~MOVE_FLY_LOW;
325 } 389 }
326 if (defined (my $v = delete $ob->{flying})) { 390 if (defined (my $v = delete $ob->{flying})) {
327 $ob->{move_type} = MOVE_ALL unless exists $ob->{move_type}; 391 $ob->{move_type} ||= new Crossfire::MoveType; if ($v) { $ob->{move_type} += "fly_low" } else { $ob->{move_type} -= "fly_low" }
328 $ob->{move_type} = $v ? $ob->{move_type} | MOVE_FLY_LOW
329 : $ob->{move_type} & ~MOVE_FLY_LOW;
330 } 392 }
331 393
332 # convert idiotic event_xxx things into objects 394 # convert idiotic event_xxx things into objects
333 while (my ($event, $subtype) = each %EVENT_TYPE) { 395 while (my ($event, $subtype) = each %EVENT_TYPE) {
334 if (exists $ob->{"event_${event}_plugin"}) { 396 if (exists $ob->{"event_${event}_plugin"}) {
565 627
566 my $inv = delete $a{inventory}; 628 my $inv = delete $a{inventory};
567 my $more = delete $a{more}; # arches do not support 'more', but old maps can contain some 629 my $more = delete $a{more}; # arches do not support 'more', but old maps can contain some
568 my $anim = delete $a{anim}; 630 my $anim = delete $a{anim};
569 631
632 if ($a{_atype} eq 'object') {
633 $str .= join "\n", "anim", @$anim, "mina\n"
634 if $anim;
635 }
636
570 my @kv; 637 my @kv;
571 638
572 for ($a{_name} eq "map" 639 for ($a{_name} eq "map"
573 ? @Crossfire::FIELD_ORDER_MAP 640 ? @Crossfire::FIELD_ORDER_MAP
574 : @Crossfire::FIELD_ORDER) { 641 : @Crossfire::FIELD_ORDER) {
585 my ($k, $v) = @$_; 652 my ($k, $v) = @$_;
586 653
587 if (my $end = $Crossfire::FIELD_MULTILINE{$k}) { 654 if (my $end = $Crossfire::FIELD_MULTILINE{$k}) {
588 $v =~ s/\n$//; 655 $v =~ s/\n$//;
589 $str .= "$k\n$v\n$end\n"; 656 $str .= "$k\n$v\n$end\n";
590 } elsif (exists $Crossfire::FIELD_MOVEMENT{$k}) {
591 if ($v & ~Crossfire::MOVE_ALL or !$v) {
592 $str .= "$k $v\n";
593
594 } elsif ($v & Crossfire::MOVE_ALLBIT) {
595 $str .= "$k all";
596
597 $str .= " -walk" unless $v & Crossfire::MOVE_WALK;
598 $str .= " -fly_low" unless $v & Crossfire::MOVE_FLY_LOW;
599 $str .= " -fly_high" unless $v & Crossfire::MOVE_FLY_HIGH;
600 $str .= " -swim" unless $v & Crossfire::MOVE_SWIM;
601 $str .= " -boat" unless $v & Crossfire::MOVE_BOAT;
602
603 $str .= "\n";
604
605 } else {
606 $str .= $k;
607
608 $str .= " walk" if $v & Crossfire::MOVE_WALK;
609 $str .= " fly_low" if $v & Crossfire::MOVE_FLY_LOW;
610 $str .= " fly_high" if $v & Crossfire::MOVE_FLY_HIGH;
611 $str .= " swim" if $v & Crossfire::MOVE_SWIM;
612 $str .= " boat" if $v & Crossfire::MOVE_BOAT;
613
614 $str .= "\n";
615 }
616 } else { 657 } else {
617 $str .= "$k $v\n"; 658 $str .= "$k $v\n";
618 } 659 }
619 } 660 }
620 661
621 if ($inv) { 662 if ($inv) {
622 $append->($_) for @$inv; 663 $append->($_) for @$inv;
623 }
624
625 if ($a{_atype} eq 'object') {
626 $str .= join "\n", "anim", @$anim, "mina\n"
627 if $anim;
628 } 664 }
629 665
630 $str .= "end\n"; 666 $str .= "end\n";
631 667
632 if ($a{_atype} eq 'object') { 668 if ($a{_atype} eq 'object') {
793 ]; 829 ];
794 830
795 $attr 831 $attr
796} 832}
797 833
798sub arch_edit_sections {
799# if (edit_type == IGUIConstants.TILE_EDIT_NONE)
800# edit_type = 0;
801# else if (edit_type != 0) {
802# // all flags from 'check_type' must be unset in this arch because they get recalculated now
803# edit_type &= ~check_type;
804# }
805#
806# }
807# if ((check_type & IGUIConstants.TILE_EDIT_MONSTER) != 0 &&
808# getAttributeValue("alive", defarch) == 1 &&
809# (getAttributeValue("monster", defarch) == 1 ||
810# getAttributeValue("generator", defarch) == 1)) {
811# // Monster: monsters/npcs/generators
812# edit_type |= IGUIConstants.TILE_EDIT_MONSTER;
813# }
814# if ((check_type & IGUIConstants.TILE_EDIT_WALL) != 0 &&
815# arch_type == 0 && getAttributeValue("no_pass", defarch) == 1) {
816# // Walls
817# edit_type |= IGUIConstants.TILE_EDIT_WALL;
818# }
819# if ((check_type & IGUIConstants.TILE_EDIT_CONNECTED) != 0 &&
820# getAttributeValue("connected", defarch) != 0) {
821# // Connected Objects
822# edit_type |= IGUIConstants.TILE_EDIT_CONNECTED;
823# }
824# if ((check_type & IGUIConstants.TILE_EDIT_EXIT) != 0 &&
825# arch_type == 66 || arch_type == 41 || arch_type == 95) {
826# // Exit: teleporter/exit/trapdoors
827# edit_type |= IGUIConstants.TILE_EDIT_EXIT;
828# }
829# if ((check_type & IGUIConstants.TILE_EDIT_TREASURE) != 0 &&
830# getAttributeValue("no_pick", defarch) == 0 && (arch_type == 4 ||
831# arch_type == 5 || arch_type == 36 || arch_type == 60 ||
832# arch_type == 85 || arch_type == 111 || arch_type == 123 ||
833# arch_type == 124 || arch_type == 130)) {
834# // Treasure: randomtreasure/money/gems/potions/spellbooks/scrolls
835# edit_type |= IGUIConstants.TILE_EDIT_TREASURE;
836# }
837# if ((check_type & IGUIConstants.TILE_EDIT_DOOR) != 0 &&
838# arch_type == 20 || arch_type == 23 || arch_type == 26 ||
839# arch_type == 91 || arch_type == 21 || arch_type == 24) {
840# // Door: door/special door/gates + keys
841# edit_type |= IGUIConstants.TILE_EDIT_DOOR;
842# }
843# if ((check_type & IGUIConstants.TILE_EDIT_EQUIP) != 0 &&
844# getAttributeValue("no_pick", defarch) == 0 && ((arch_type >= 13 &&
845# arch_type <= 16) || arch_type == 33 || arch_type == 34 ||
846# arch_type == 35 || arch_type == 39 || arch_type == 70 ||
847# arch_type == 87 || arch_type == 99 || arch_type == 100 ||
848# arch_type == 104 || arch_type == 109 || arch_type == 113 ||
849# arch_type == 122 || arch_type == 3)) {
850# // Equipment: weapons/armour/wands/rods
851# edit_type |= IGUIConstants.TILE_EDIT_EQUIP;
852# }
853#
854# return(edit_type);
855#
856#
857}
858
859sub cache_file($$&&) { 834sub cache_file($$&&) {
860 my ($src, $cache, $load, $create) = @_; 835 my ($src, $cache, $load, $create) = @_;
861 836
862 my ($size, $mtime) = (stat $src)[7,9] 837 my ($size, $mtime) = (stat $src)[7,9]
863 or Carp::croak "$src: $!"; 838 or Carp::croak "$src: $!";

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines