package GCE::Util; =head1 NAME GCE::Util - some utility functions =over 4 =cut use base 'Exporter'; use Crossfire; use Carp (); use Storable; use List::Util qw(min max); our @EXPORT = qw(insert_arch_stack_layer replace_arch_stack_layer); sub classify_arch_layer { my ($arch) = @_; if ($arch->{invisible}) { # just a heuristic for 'special' tiles (er. pedestals) return 'below'; } elsif ($arch->{monster}) { return 'top'; } else { # $arch->{is_floor} and all other arches are 'between' monsters and floor return 'between'; } } sub insert_arch_stack_layer { my ($stack, $arch) = @_; unless (@$stack) { return [ $arch ]; } my @outstack; my $l = classify_arch_layer ($Crossfire::ARCH{$arch->{_name}}); if ($l eq 'between') { # loop until we reached the first 'between' arch above 'below' arches and the floor while (my $a = shift @$stack) { unless ($Crossfire::ARCH{$a->{_name}}->{is_floor} or classify_arch_layer ($Crossfire::ARCH{$a->{_name}}) eq 'below') { unshift @$stack, $a; last; } push @outstack, $a; } # ignore duplicates # FIXME: Broken if non-floor are drawn (too tired to fix) return [ @outstack, @$stack ] if @outstack and $outstack[-1]->{_name} eq $arch->{_name}; push @outstack, ($arch, @$stack); } elsif ($l eq 'top') { # ignore duplicates return [ @$stack ] if $stack->[-1]->{_name} eq $arch->{_name}; @outstack = (@$stack, $arch); } else { # ignore duplicates return [ @$stack ] if $stack->[0]->{_name} eq $arch->{_name}; @outstack = ($arch, @$stack); } return \@outstack; } sub replace_arch_stack_layer { my ($stack, $arch) = @_; my @outstack; my $l = classify_arch_layer ($Crossfire::ARCH{$arch->{_name}}); if ($l eq 'between') { while (shift @$stack) { last unless $Crossfire::ARCH{$_->{_name}}->{is_floor}; push @outstack, $_; } if (@outstack and $Crossfire::ARCH{$outstack[-1]->{_name}}->{is_floor}) { pop @outstack; } push @outstack, ($arch, @$stack); } elsif ($l eq 'top') { @outstack = (@$stack, $arch); } else { @outstack = ($arch, @$stack); } return \@outstack; } =head1 AUTHOR Marc Lehmann http://home.schmorp.de/ Robin Redeker http://www.ta-sa.org/ =cut 1;