gat_to_fld2.pl.svn-base
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:3k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. #!/usr/bin/perl
  2. # See http://www.openkore.com/wiki/index.php/Field2_file_format
  3. # for information about the file formats.
  4. # gat_to_fld2
  5. use strict;
  6. use constant {
  7. TILE_NOWALK => 0,
  8. TILE_WALK => 1,
  9. TILE_SNIPE => 2,
  10. TILE_WATER => 4,
  11. TILE_CLIFF => 8,
  12. };
  13. # conversion (ex. $TILE_TYPE[0] = TILE_WALK = 1), (ex. $TILE_TYPE[1] = TILE_NOWALK = 0)
  14. my @TILE_TYPE = ( TILE_WALK, # 0) Walkable
  15. TILE_NOWALK, # 1) Non-walkable
  16. TILE_WATER, # 2) Non-walkable water
  17. TILE_WALK|TILE_WATER, # 3) Walkable water
  18. TILE_WATER|TILE_SNIPE, # 4) Non-walkable water (snipable)
  19. TILE_CLIFF|TILE_SNIPE, # 5) Cliff (snipable)
  20. TILE_CLIFF); # 6) Cliff (not snipable)
  21. my $i = 0;
  22. foreach my $name (sort(listMaps("."))) {
  23. $i++;
  24. gat_to_fld2("$name.gat", "$name.fld2", readWaterLevel("$name.rsw"));
  25. }
  26. sub listMaps {
  27. my ($dir) = @_;
  28. my $handle;
  29. opendir($handle, $dir);
  30. my @list = grep { /.gat$/i && -f $_ } readdir $handle;
  31. closedir $handle;
  32. foreach my $file (@list) {
  33. $file =~ s/.gat$//i;
  34. }
  35. return @list;
  36. }
  37. ##
  38. # float readWaterLevel(String rswFile)
  39. #
  40. # Read the map's water level from the corresponding RSW file.
  41. sub readWaterLevel {
  42. my ($rswFile) = @_;
  43. my ($f, $buf);
  44. if (!open($f, "<", $rswFile)) {
  45. print "Cannot open $rswFile for reading.n";
  46. exit 1;
  47. }
  48. seek $f, 166, 0;
  49. read $f, $buf, 4;
  50. close $f;
  51. return unpack("f", $buf);
  52. }
  53. ##
  54. # void gat_to_fld2(String gat, String fld2, float waterLevel)
  55. #
  56. # Convert a GAT file to the specified FLD2 file.
  57. sub gat_to_fld2 {
  58. my ($gat, $fld2, $waterLevel) = @_;
  59. my ($in, $out, $data);
  60. if (!open $in, "<", $gat) {
  61. print "Cannot open $gat for reading.n";
  62. exit 1;
  63. }
  64. if (!open $out, ">", $fld2) {
  65. print "Cannot open $fld2 for writing.n";
  66. exit 1;
  67. }
  68. binmode $in;
  69. binmode $out;
  70. # Read header. Yes we're assuming that maps are never
  71. # larger than 2^16-1 blocks.
  72. read($in, $data, 14);
  73. my ($width, $height) = unpack("V2", substr($data, 6, 8));
  74. my $size = $width * $height;
  75. # when y = height, we variate x from 0 to width
  76. # thus, we variate block offset from size - width to size
  77. my $max_Y = $size - $width;
  78. #print $out pack("v", $index);
  79. print $out pack ("v2", $width, $height);
  80. my ($y, $x) = (1, 1);
  81. while (read($in, $data, 20)) {
  82. my ($a, $b, $c, $d) = unpack("f4", $data);
  83. my $type = unpack("C", substr($data, 16, 1));
  84. my $averageDepth = ($a + $b + $c + $d) / 4;
  85. # warn us for unknown/new block types
  86. if ($type > $#TILE_TYPE) {
  87. print "An unknown blocktype($type) was found, please report this to the OpenKore devs.n";
  88. exit 1;
  89. # make upper blocks unwalkable
  90. } elsif ($y > $max_Y ) {
  91. print $out pack("C", TILE_NOWALK);
  92. # make rightern blocks unwalkable
  93. } elsif ($y == $x * $width) {
  94. $x++;
  95. print $out pack("C", TILE_NOWALK);
  96. # In contrast to what the elsif-condition tells you,
  97. # we're actually checking whether this block
  98. # is below the map's water level.
  99. # Block is below water level.
  100. } elsif ($averageDepth > $waterLevel) {
  101. # add bitflag water to non-water blocks
  102. print $out pack("C", (($TILE_TYPE[$type] & TILE_WATER) == TILE_WATER) ? $TILE_TYPE[$type] : $TILE_TYPE[$type]|TILE_WATER);
  103. # Block is above water level
  104. } else {
  105. print $out pack("C", $TILE_TYPE[$type]);
  106. }
  107. $y++;
  108. }
  109. close $in;
  110. close $out;
  111. }