FreewarWiki:Bot/Skripts/npcmap.pl

aus FreewarWiki, der Referenz für Freewar
Version vom 16. Februar 2009, 19:03 Uhr von Three Of Twelve (Diskussion | Beiträge)
(Unterschied) ← Nächstältere Version | ↑ Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen

use strict; use GD;

  1. Farbdefinition fuer die NPC-Klassen

my $colors = {

   "1" => 0x4db34d,
   "2" => 0x33e53f,
   "3" => 0x7ae533,
   "4" => 0xaae533,
   "5" => 0xd9e533,
   "6" => 0xe5c433,
   "7" => 0xe59833,
   "8" => 0xe56b33,
   "9" => 0xe53f33

};

  1. Argumente auswerten

my $sourceimg; my $maplist; my $npclist; my $tilesize; my $alpha = 0; my %args = @ARGV; while (my ($key, $val) = each(%args)) {

   if ($key eq "-source")   { $sourceimg = $val; }
   if ($key eq "-maplist")  { $maplist = $val; }
   if ($key eq "-npclist")  { $npclist = $val; }
   if ($key eq "-tilesize") { $tilesize = $val; }
   if ($key eq "-alpha")    { $alpha = $val; }

}

die(" Aufruf: perl npcmap.pl [Optionen] > Zieldatei.png

Moegliche Optionen:

   -source Karten-Quelldatei
               Name der Karten-Quelldatei (erforderlich)
   -maplist Kartenfeldliste
               Name der Datei mit der Kartenfeldliste im Format
               Gebiet;Begehbarkit;X;Y;NPCs;Bild-URL
               (erforderlich)
   -npclist NPC-Liste
               Name der Datei mit der NPC-Liste im Format
               NPC-Name;Staerke;LP;XP;GM;Vorkommen;Drops
               (erforderlich)
   -tilesize Zahl
               Groesse des eingefaerbten Teils pro Feld (optional,
               Standard: 60% der Kartenfeldgroesse)
   -alpha Zahl
               Alphakanal der Farbkacheln, Wert zwischen 0 und 127.
               0 ist undurchsichtig, 127 vollstaendig transparent.
               Halbtransparenz bspw. wird also durch 63 erzielt.
               (optional, Standard: 0, also deckend)

Beispiel:

   perl npclist.pl -source Karte.jpg -maplist maplist.txt -npclist npclist.txt > NPC-Karte.png

") if (not $sourceimg or not $maplist or not $npclist);

  1. Bild-Objekt erstellen

my $mapsource = GD::Image->new($sourceimg); my $map = GD::Image->new($mapsource->width, $mapsource->height, 1); $map->copy($mapsource, 0, 0, 0, 0, $map->width, $map->height);

  1. Farbzuordnung und Grenzen ermitteln

open (NPC, $npclist); my %npc; while (<NPC>) {

   my ($name, $atk, $lp, $xp, $gm) = split(/;/);
   $npc{$name}->{"atk"} = $atk;
   $npc{$name}->{"lp"} = $lp;
   $npc{$name}->{"xp"} = $xp;
   $npc{$name}->{"gm"} = $gm;

} close(NPC);

open (MAP, $maplist); my %mapcolor;

my $min_x = 2; my $min_y = 2; my $max_x = 400; my $max_y = 400; my @bounds = ($max_x, $max_y, $min_x, $min_y); while (<MAP>) {

   my ($gebiet, $betretbar, $x, $y, $npcnames, $img, $passagen) = split(/;/);
   next if ($x < $min_x || $y < $min_y || $x > $max_x || $y > $max_y);
   $bounds[0] = $x if ($x < $bounds[0]);
   $bounds[1] = $y if ($y < $bounds[1]);
   $bounds[2] = $x if ($x > $bounds[2]);
   $bounds[3] = $y if ($y > $bounds[3]);
   foreach my $npcname(split(/\//, $npcnames)) {
   # es folgt eine Bastelheuristik, die die in der Kartenliste
   # auftretenden NPC-Namen mit denen aus der NPC-Liste in Ein-
   # klang bringt (Worttrennung entfernen usw.)
   my $tmpname = $npcname;
   $tmpname =~ s/- //g;
   if (!defined($npc{$tmpname})) {
       $tmpname = $npcname;
       $tmpname =~ s/- /-/g;
       if (!defined($npc{$tmpname})) {
           $tmpname = ucfirst($npcname);
           $tmpname =~ s/- //g;
           if (!defined($npc{$tmpname})) {
               $tmpname = ucfirst($npcname);
               $tmpname =~ s/- /-/g;

$tmpname = $npcname if (!defined($npc{$tmpname}));

           }
       }
   }
   if (!defined($npc{$tmpname})) {
       print STDERR "NPC $npcname auf $x/$y nicht gefunden\n" unless ($npcname eq "" or $npcname eq "none");
   } else {
       if (defined($mapcolor{$x}->{$y}->[0])) {

if (npcclass($npc{$tmpname}) > $mapcolor{$x}->{$y}->[0]) { $mapcolor{$x}->{$y}->[1] = npcclass($npc{$tmpname}); } elsif (npcclass($npc{$tmpname}) != $mapcolor{$x}->{$y}->[0]) { $mapcolor{$x}->{$y}->[1] = $mapcolor{$x}->{$y}->[0]; $mapcolor{$x}->{$y}->[0] = npcclass($npc{$tmpname}); } } else { $mapcolor{$x}->{$y}->[0] = npcclass($npc{$tmpname}); }}

   }

}

  1. Kartenfeld-Groesse errechnen

my $width = $map->width() / ($bounds[2] - $bounds[0] + 1); $tilesize = int($width * 0.6 + 0.5) if (!$tilesize);

$map->alphaBlending(1); foreach my $key(keys(%{$colors})) {

   my $v = $colors->{$key};
   printf STDERR "$key: %x->", $v;
   my $b = $v & 0xff;
   $v = $v >> 8;
   my $g = $v & 0xff;
   $v = $v >> 8;
   my $r = $v & 0xff;
   $colors->{$key} = $map->colorAllocateAlpha($r, $g, $b, $alpha);
   printf STDERR "%x %x %x = %x\n", $r, $g, $b,  $colors->{$key};

}

foreach my $x(keys(%mapcolor)) {

   next if ($x < $min_x || $x > $max_x);
   foreach my $y(keys(%{$mapcolor{$x}})) {
       next if ($y < $min_y || $y > $max_y);
       my $ax = ($x - $bounds[0]) * $width + ($width - $tilesize) / 2;

my $ay = ($y - $bounds[1]) * $width + ($width - $tilesize) / 2; if (defined($mapcolor{$x}->{$y}->[1])) { my $poly = new GD::Polygon(); $poly->addPt($ax, $ay); $poly->addPt($ax + $tilesize - 2, $ay); $poly->addPt($ax, $ay + $tilesize - 2); $map->filledPolygon($poly, $colors->{$mapcolor{$x}->{$y}->[0]});

           $poly = new GD::Polygon();
           $poly->addPt($ax + $tilesize - 1, $ay + 1);
           $poly->addPt($ax + $tilesize - 1, $ay + $tilesize - 1);
           $poly->addPt($ax + 1, $ay + $tilesize - 1);

$map->filledPolygon($poly, $colors->{$mapcolor{$x}->{$y}->[1]});

           # Gleichheit der Farben! ;-)
           # Der "Fairness" halber wird die Mittellinie mit der Mischfarbe gezeichnet.
           # Naja, eigentlich sieht's einfach besser aus.

my @rgb1 = $map->rgb($colors->{$mapcolor{$x}->{$y}->[0]}); my @rgb2 = $map->rgb($colors->{$mapcolor{$x}->{$y}->[1]}); my $intermediate = $map->colorAllocateAlpha(($rgb1[0] + $rgb2[0]) / 2, ($rgb1[1] + $rgb2[1]) / 2, ($rgb1[2] + $rgb2[2]) / 2, $alpha); $map->line($ax + $tilesize - 1, $ay, $ax, $ay + $tilesize - 1, $intermediate); } else { $map->filledRectangle($ax, $ay, $ax + $tilesize - 1, $ay + $tilesize - 1, $colors->{$mapcolor{$x}->{$y}->[0]}); }

   }

}

print $map->png;

  1. NPCs in eine Klasse von 1 (schwach) bis 9 (stark) einordnen.
  2. Geschieht hier einfach durch eine Betrachtung des Produkts
  3. aus LP und A.

sub npcclass {

   my ($npc) = @_;
   my $i = $npc->{"lp"} * $npc->{"atk"};
   return 1 if ($i <      8);
   return 2 if ($i <     18);
   return 3 if ($i <     31);
   return 4 if ($i <     51);
   return 5 if ($i <    201);
   return 6 if ($i <   2001);
   return 7 if ($i <  10001);
   return 8 if ($i < 100001);
   return 9;

}