#!/usr/bin/perl use strict; use warnings; use lib "../adv"; use include; # CONFIGURATION my $unit_size = 10; # [small], [large] my $area = "halls"; # beard, halls, squiggle my $formation = "flank"; # line, troop, flank my $mode = "single"; # single, multi # SET UP UI use HexedUI; my $ui = create HexedUI { Main => { Type => "Map", At => [0, 0], Size => ["100%", "100%"], Border => 1, Render => sub { my $tile = shift; my ($char, $color); if (ref $tile->{_}) { ($char, $color) = $tile->{_}->symbol; } elsif ($tile->{color}) { $char = $tile->{_}; $color = $tile->{color}; } else { $char = $tile->{_}; $color = { "#" => "orange", "." => "grey" }->{$char}; $color ||= "yellow"; } return ord($char) | HexedUI::paint($color); } }, }; GAME->{UI} = $ui; # SET UP MAP use BDSM::Transform; my $map = loadmap("../maps/$area"); $ui->{Main}->setup($map); $map->{OnChange} = sub { my ($map, $y, $x, $new) = @_; $ui->{Main}->_mod($y, $x, $map->{Map}[$y][$x]); }; use Highway; preprock($map); sub run { # Initialize units use Unit; my @units; # Rnd Starting Positions: CONFIG->rndload($file); GAME->{UnitSize} = $unit_size; # leader needs to know to make room foreach (1 .. $unit_size) { my $unit = GAME->{Classes}{Unit}->new(Map => $map, Num => $_); if ($_ == 1) { $unit->{Magnet}{Last} = "h"; } else { $unit->{Magnet}{Buddy} = $units[$_ - 2]; # Whilst assembling, just form a line. $unit->{Magnet}{Dir} = [0, 1]; } push @units, $unit; } # PART ONE: Assembly # Single: Find the highway and then our buddy, then give control to next unit. # Multi: Everybody find the highway at once. If our buddy is on too, find # them; otherwise wait. my %found; while (1) { my $cntr = 0; foreach my $unit (@units) { if ($mode eq "single") { 1 until $unit->gethi; 1 until $unit->assemble == 42 and $unit->{Laster} = [$unit->{Y}, $unit->{X}]; $cntr++; } else { $unit->gethi and $found{ $unit->{Num} }++ unless $found{ $unit->{Num} }; next unless $found{ $unit->{Num} }; $unit->assemble == 42 and $unit->{Laster} = [$unit->{Y}, $unit->{X}] and $cntr++; } } last if $cntr == @units; } # INTERMISSION if ($formation eq "flank") { # We had to assemble normally in a line. But now we need to reassign # buddies cause this formation is really funky. # #2 is an anchor. So is another. Just assign group numbers. my $mid = int($#units / 2) + 1; # My magic number. foreach my $num (1 .. $#units) { if ($num < $mid) { $units[$num]->{Magnet}{Group} = 1; } elsif ($num == $mid) { # We're the 2nd anchor. $units[$num]->{Magnet}{Group} = 2; $units[$num]->{Magnet}{Buddy} = $units[0]; } else { $units[$num]->{Magnet}{Group} = 2; } } } # PART TWO: Movement # Single & Multi: Follow our buddy until everybody reaches the destination. while (1) { GAME->{UI}{Main}->draw; foreach my $unit (@units) { ($unit->{Num} == 1) ? ctrl(@units) : $unit->magnet(); } } } sub ctrl { my $me = shift; my @units = @_; my $in = lc GAME->{UI}->input; return if $in eq "x"; return unless $in =~ m/[hjklyubn]/; my ($y, $x) = ($me->{Y}, $me->{X}); $x-- if $in eq "h" or $in eq "y" or $in eq "b"; $y++ if $in eq "j" or $in eq "b" or $in eq "n"; $y-- if $in eq "k" or $in eq "y" or $in eq "u"; $x++ if $in eq "l" or $in eq "u" or $in eq "n"; $me->go($y, $x); # Update the vectors for the troops. if ($formation eq "line") { $_->{Magnet}{Dir} = { l => [0, -1], h => [0, +1], k => [+1, 0], j => [-1, 0], y => [+1, +1], u => [+1, -1], b => [-1, +1], n => [-1, -1], }->{$in} foreach @units; } elsif ($formation eq "troop") { # This is the anchor's $units[0]->{Magnet}{Dir} = { l => [-3, -5], h => [-3, +5], k => [+3, -5], j => [-3, -5], y => [-3, +10], u => [-3, -10], b => [-7, +5], n => [-5, +1], }->{$in}; # And these for the others $_->{Magnet}{Dir} = { l => [+1, 0], h => [+1, 0], k => [0, +1], j => [0, +1], y => [+1, -1], u => [+1, +1], b => [+1, +1], n => [+1, -1], }->{$in} foreach @units[1 .. $#units]; } elsif ($formation eq "flank") { foreach (@units) { $_->{Magnet}{Dir} = { l => [-1, -1], h => [-1, +1], k => [+1, -1], j => [-1, -1], y => [-1, +1], u => [-1, -1], b => [-1, -1], n => [-1, +1] }->{$in} if $_->{Magnet}{Group} == 1; $_->{Magnet}{Dir} = { l => [+1, -1], h => [+1, +1], k => [+1, +1], j => [-1, +1], y => [+1, -1], u => [+1, +1], b => [+1, +1], n => [+1, -1] }->{$in} if $_->{Magnet}{Group} == 2; } } } run;