Kategorien
Benutzer:Three Of Twelve/npcmap.pl
Zur Navigation springen
Zur Suche springen
use strict; use GD; # 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 }; # Argumente auswerten my $sourceimg; my $maplist; my $npclist; my $tilesize; 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; } } 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) 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); # 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); # 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 @bounds = (400, 400, 2, 2); while (<MAP>) { my ($gebiet, $betretbar, $x, $y, $npcname) = split(/;/); next if ($x < 2 || $y < 2 || $x > 400 || $y > 400); $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]); # 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}); } } } # Kartenfeld-Groesse errechnen my $width = $map->width() / ($bounds[2] - $bounds[0] + 1); $tilesize = int($width * 0.6 + 0.5) if (!$tilesize); 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->colorAllocate($r, $g, $b); printf STDERR "%x %x %x = %x\n", $r, $g, $b, $colors->{$key}; } foreach my $x(keys(%mapcolor)) { next if ($x < 2 || $x > 400); foreach my $y(keys(%{$mapcolor{$x}})) { next if ($y < 2 || $x > 400); my $ax = ($x - $bounds[0]) * $width + ($width - $tilesize) / 2; my $ay = ($y - $bounds[1]) * $width + ($width - $tilesize) / 2; $map->filledRectangle($ax, $ay, $ax + $tilesize - 1, $ay + $tilesize - 1, $colors->{$mapcolor{$x}->{$y}->[0]}); if (defined($mapcolor{$x}->{$y}->[1])) { my $poly = new GD::Polygon(); $poly->addPt($ax + $tilesize - 1, $ay); $poly->addPt($ax + $tilesize - 1, $ay + $tilesize - 1); $poly->addPt($ax, $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->colorExact(($rgb1[0] + $rgb2[0]) / 2, ($rgb1[1] + $rgb2[1]) / 2, ($rgb1[2] + $rgb2[2]) / 2); $intermediate = $map->colorAllocate(($rgb1[0] + $rgb2[0]) / 2, ($rgb1[1] + $rgb2[1]) / 2, ($rgb1[2] + $rgb2[2]) / 2) if ($intermediate == -1); $map->line($ax + $tilesize - 1, $ay, $ax, $ay + $tilesize - 1, $intermediate); } } } print $map->png; # NPCs in eine Klasse von 1 (schwach) bis 9 (stark) einordnen. # Geschieht hier einfach durch eine Betrachtung des Produkts # 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; }
Diese Artikel wurde von ihrem Urheberrechtsinhaber in die Gemeinfreiheit („public domain“) übergeben. Dies gilt weltweit und zeitlich unbeschränkt.
Für den Fall, dass dies nach lokaler Rechtslage nicht möglich ist, wie beispielsweise in Deutschland: |