#============================================================================== # ■ Auto_MazeWalls #------------------------------------------------------------------------------ # 自动生成迷宫的墙壁,默认支持的迷宫种类有: # 农村内部(24)、教会内部(29)、城寨内部(38)、塔内部(40)、魔物城堡内部 # (42)、土之洞窟(43)、炎之洞窟(44)、冰之洞窟(45)、水之洞窟(46)、矿山 # (47)、体内(49),也就是不能用自动元件画墙壁的所有图块。 # 使用方法: # 绘制一张只有一层(F5)层的地图,并只绘制地面的部分(即人可以走到的部分), # 其他位置全部留空——注意是留空,不要用别的东西填充了 # 插入本脚本到Game_Temp(注意不是Main)之前,然后在末尾添加 # # $auto_fill = Auto_MazeWalls.new(地图编号) # $auto_fill = fill_wall(墙壁高度) # $auto_fill.save # exit # # 运行完毕后请重新打开工程或相关地图。 # 注释掉本脚本末尾的四行可以屏蔽该功能正常测试游戏。 # 注: # 1) 地图编号不存在的话,脚本将无效直接关闭 # 2) 部分图块锁定了墙高(24、29、38),墙壁高度填写任何值都是无效的 # 3) 墙壁高度如填写为负数,则会生成悬空式迷宫,但前提是图块支持这种迷宫 # 4) 如果有多张地图需要生成墙壁,请分别执行 # 5) 如果地形有冲突(如墙高度不够),图块会重叠或空白,请手工修改冲突的地方 #============================================================================== class Auto_MazeWalls #-------------------------------------------------------------------------- # ● 初始化对像 #-------------------------------------------------------------------------- def initialize(map_id) @filename = sprintf("Data/Map%03d.rxdata", map_id) if FileTest.exist?(@filename) @map = load_data(@filename) @width = @map.width @height = @map.height setup(@map.tileset_id) else exit end end #-------------------------------------------------------------------------- # ● 保存地图 #-------------------------------------------------------------------------- def save save_data(@map, @filename) end #-------------------------------------------------------------------------- # ● 根据图块ID获得填涂ID表 #-------------------------------------------------------------------------- def setup(tileset_id) case tileset_id when 24 # 农村 内部 @force_height = 2 @floor = 384 @dark = 396 @covers = [387, 388, 389] @walls_low = [-419, 420, -421] @walls_med = [411, 412, 413] @walls_top = [403, 404, 405] @line_l = 395 @line_r = 397 @corner_lu = 390 @corner_ru = 391 @corner_lb = 398 @corner_rb = 399 @d_corner1 = 0 @d_corner2 = 0 @allow_deep = false @shades = {384 => 385, 404 => 404, 412 => 401, 420 => 409} when 29 # 教会 内部 @force_height = 3 @floor = 384 @dark = 409 @covers = [400, 401, 402] @walls_low = [440, 441, 442] @walls_med = [432, 433, 434] @walls_rim = [424, 425, 426] @walls_top = [416, 417, 418] @line_l = 408 @line_r = 410 @corner_lu = 403 @corner_ru = 404 @corner_lb = 411 @corner_rb = 412 @d_corner1 = 0 @d_corner2 = 0 @allow_deep = false @shades = {384 => 385, 417 => 417, 425 => 427, 433 => 435, 441 => 443} when 38 # 城寨 内部 @force_height = 2 @floor = 384 @dark = 409 @covers = [400, 401, 402] @walls_low = [-432, 433, -434] @walls_med = [424, 425, 426] @walls_top = [416, 417, 418] @line_l = 408 @line_r = 410 @corner_lu = 403 @corner_ru = 404 @corner_lb = 411 @corner_rb = 412 @d_corner1 = 0 @d_corner2 = 0 @allow_deep = false @shades = {384 => 386, 417 => 417, 425 => 419, 433 => 427} when 40 # 塔 内部 @force_height = 0 @floor = 384 @dark = 409 @covers = [400, 401, 402] @walls_low = [432, 433, 434] @walls_med = [424, 425, 426] @walls_top = [416, 417, 418] @line_l = 408 @line_r = 410 @corner_lu = 403 @corner_ru = 404 @corner_lb = 411 @corner_rb = 412 @d_corner1 = 0 @d_corner2 = 0 @allow_deep = false @shades = {384 => 385, 417 => 417, 425 => 427, 433 => 435} when 42 # 魔物城堡 内部 @force_height = 0 @floor = 384 @dark = 409 @covers = [400, 401, 402] @walls_low = [432, 433, 434] @walls_med = [424, 425, 426] @walls_top = [416, 417, 418] @line_l = 408 @line_r = 410 @corner_lu = 403 @corner_ru = 404 @corner_lb = 411 @corner_rb = 412 @d_corner1 = 0 @d_corner2 = 0 @allow_deep = true @depths = [437, 438, 439, 445, 446, 447, 453, 454, 455, 461, 462, 463, 469, 470, 471] @void = 393 @flat_top = [405, 406, 407] @flat_l = 413 @flat_r = 415 @flat_bottom = [421, 422, 423] @d_flat1 = 0 @d_flat2 = 0 @flat_lu = 419 @flat_ru = 420 @flat_lb = 427 @flat_rb = 428 @shades = {384 => 385, 417 => 440, 425 => 448, 433 => 456} when 43..46 # 属性洞穴 @force_height = 0 @floor = 384 @dark = 425 @covers = [416, 417, 418] @walls_low = [448, 449, 450] @walls_med = [440, 441, 442] @walls_top = [432, 433, 434] @line_l = 424 @line_r = 426 @corner_lu = 419 @corner_ru = 420 @corner_lb = 427 @corner_rb = 428 @d_corner1 = 435 @d_corner2 = 436 @allow_deep = true @depths = [488, 489, 490, 496, 497, 498, 504, 505, 506, 512, 513, 514, 520, 521, 522, 528, 529, 530] @void = 425 @flat_top = [421, 422, 423] @flat_l = 429 @flat_r = 431 @flat_bottom = [437, 438, 439] @d_flat1 = 443 @d_flat2 = 444 @flat_lu = 451 @flat_ru = 452 @flat_lb = 459 @flat_rb = 460 @shades = {384 => 96, 433 => 445, 441 => 453, 449 => 461} when 47 # 矿山 @force_height = 0 @floor = 384 @dark = 409 @covers = [400, 401, 402] @walls_low = [-432, -433, -434] @walls_med = [424, 425, 426] @walls_top = [416, 417, 418] @line_l = 408 @line_r = 410 @corner_lu = 403 @corner_ru = 404 @corner_lb = 411 @corner_rb = 412 @d_corner1 = 0 @d_corner2 = 0 @allow_deep = true @depths = [429, 430, 431, 437, 438, 439, 445, 446, 447, 453, 454, 455, 461, 462, 463, 469, 470, 471] @void = 409 @flat_top = [405, 406, 407] @flat_l = 413 @flat_r = 415 @flat_bottom = [421, 422, 423] @d_flat1 = 0 @d_flat2 = 0 @flat_lu = 419 @flat_ru = 420 @flat_lb = 427 @flat_rb = 428 @shades = {384 => 385, 417 => 464, 425 => 472, 433 => 480} when 49 # 体内 @force_height = 0 @floor = 384 @dark = 433 @covers = [424, 425, 426] @walls_low = [-456, -457, -458] @walls_med = [448, 449, 450] @walls_top = [440, 441, 442] @line_l = 432 @line_r = 434 @corner_lu = 435 @corner_ru = 436 @corner_lb = 443 @corner_rb = 444 @d_corner1 = 0 @d_corner2 = 0 @allow_deep = true @depths = [461, 462, 463, 469, 470, 471, 477, 478, 479, 485, 486, 487, 493, 494, 495] @void = 433 @flat_top = [429, 430, 431] @flat_l = 437 @flat_r = 439 @flat_bottom = [445, 446, 447] @d_flat1 = 0 @d_flat2 = 0 @flat_lu = 451 @flat_ru = 452 @flat_lb = 459 @flat_rb = 460 @shades = {384 => 385, 441 => 464, 449 => 472, 457 => 480} end end #-------------------------------------------------------------------------- # ● 填涂墙壁 # wall_height: 墙壁高度(负值为悬空式,可能会被图块锁定) #-------------------------------------------------------------------------- def fill_wall(wall_height = 2) # 检查深渊地形 if wall_height < 0 if @allow_deep fill_depth return else # 图块没有深渊地形的情况下,按2格默认高度填涂墙壁 wall_height = [2, @force_height].max end end # 强制墙高生效 wall_height = @force_height if @force_height != 0 # 勾勒地板边缘 tile_data = Table.new(@width, @height) for i in 0...@width for j in 0...@height tile_data[i, j] = get_border_tile(i, j) end end # 填涂地板边缘和F5层(背板遮挡填在F6层) for i in 0...@width for j in 0...@height unless @covers.include?(tile_data[i, j]) if tile_data[i, j] > 0 @map.data[i, j, 0] = tile_data[i, j] else @map.data[i, j, 0] = @floor @map.data[i, j, 1] = -tile_data[i, j] end else @map.data[i, j - 1, 1] = tile_data[i, j] if j > 0 case tile_data[i, j] when @covers[0] if j < @height - 1 and tile_data[i, j + 1] == @dark @map.data[i, j, 0] = @corner_lu else @map.data[i, j, 0] = @line_l end when @covers[1] @map.data[i, j, 0] = @dark when @covers[2] if j < @height - 1 and tile_data[i, j + 1] == @dark @map.data[i, j, 0] = @corner_ru else @map.data[i, j, 0] = @line_r end end end end end # 墙高及纵向墙线的增长 wall_data = {} for i in 0...@width for j in 0...@height index = @walls_low.index(@map.data[i, j, 0]) index = @walls_low.index([email]-@map.data[/email][i, j, 1]) if index == nil if index != nil # 不是固定墙高3的情况下 unless @force_height == 3 (wall_height - 1).times do |n| wall_data[[i, j - n - 1]] = @walls_med[index] if j > n end else wall_data[[i, j - 1]] = @walls_med[index] if j > 0 wall_data[[i, j - 2]] = @walls_rim[index] if j > 1 end wall_data[[i, j - wall_height]] = @walls_top[index] if j >= wall_height elsif @map.data[i, j, 0] == @line_l and @map.data[i, j - 1, 0] == @dark (wall_height - 1).times do |n| wall_data[[i, j - n - 1]] = @line_l if j > n end # 交角处理 if j >= wall_height if @map.data[i, j - wall_height, 0] == @corner_ru wall_data[[i, j - wall_height]] = @d_corner2 else wall_data[[i, j - wall_height]] = @corner_lb end end elsif @map.data[i, j, 0] == @line_r and @map.data[i, j - 1, 0] == @dark (wall_height - 1).times do |n| wall_data[[i, j - n - 1]] = @line_r if j > n end # 交角处理 if j >= wall_height if @map.data[i, j - wall_height, 0] == @corner_lu wall_data[[i, j - wall_height]] = @d_corner1 else wall_data[[i, j - wall_height]] = @corner_rb end end end end end # 填涂墙壁 wall_data.each do |k, v| @map.data[k[0], k[1], 0] = v end # 末行处理 for i in 0...@width if @map.data[i, @height - 1, 0] == @floor @map.data[i, @height - 1, 1] = @covers[1] end end # 阴影处理 @width.times do |n| i = @width - n for j in 0...@height # 地板的阴影 if @map.data[i, j, 0] == @floor unless @map.data[i - 1, j - 1, 0] == @floor or @map.data[i - 1, j, 0] == @floor or (@map.data[i - 1, j + 1, 0] == @floor and @map.data[i - 1, j + 1, 1] != -@walls_low[2]) @map.data[i, j, 0] = @shades[@floor] end end # 墙壁的阴影 if @map.data[i, j, 0] == @walls_top[1] if @map.data[i - 1, j + 1, 0] == @line_r for k in 0..wall_height if j + k < @height @map.data[i, j + k, 0] = @shades[@map.data[i, j + k, 0]] if @map.data[i, j + k, 1] == -@walls_low[1] @map.data[i, j + k, 1] = @shades[@map.data[i, j + k, 1]] end end end end end end end end #-------------------------------------------------------------------------- # ● 获得勾勒墙壁图块 # x: 地图的 x 坐标 # y: 地图的 y 坐标 #-------------------------------------------------------------------------- def get_border_tile(x, y) s = @map.data[x, y, 0] return s if s != 0 case neighbor_data(x, y) when 0, 2, 128 return @dark when 1, 3, 129, 131 return @covers[1] when 16, 24, 48, 56 return @walls_low[1] when 4, 6 return @corner_ru when 64, 192 return @corner_lu when 8, 12, 14 return @line_r when 32, 96, 224 return @line_l when 80, 88, 112, 120, 208, 216, 240, 248 return @walls_low[0] when 20, 22, 28, 30, 52, 54, 60, 62 return @walls_low[2] when 65, 67, 97, 99, 193, 195, 225, 227 return @covers[0] when 5, 7, 13, 15, 133, 135, 141, 143 return @covers[2] else return 0 end end #-------------------------------------------------------------------------- # ● 填涂深渊 #-------------------------------------------------------------------------- def fill_depth # 勾勒地板边缘 tile_data = Table.new(@width, @height) for i in 0...@width for j in 0...@height tile_data[i, j] = get_depth_tile(i, j) end end # 填涂地板边缘和F5层(高台遮挡填在F6层) for i in 0...@width for j in 0...@height unless @flat_top.include?(tile_data[i, j]) @map.data[i, j, 0] = tile_data[i, j] else @map.data[i, j, 1] = tile_data[i, j] @map.data[i, j, 0] = @void end end end # 深渊的增长 for i in 0...@width for j in 0...@height index = @flat_bottom.index(@map.data[i, j, 0]) if index != nil for k in [email]0...@depths.length[/email] / 3 break if @map.data[i, j + k + 1, 0] != @void or j + k + 1 >= @height @map.data[i, j + k + 1, 0] = @depths[k * 3 + index] end end end end end #-------------------------------------------------------------------------- # ● 获得勾勒深渊图块 # x: 地图的 x 坐标 # y: 地图的 y 坐标 #-------------------------------------------------------------------------- def get_depth_tile(x, y) s = @map.data[x, y, 0] return s if s != 0 case neighbor_data(x, y) when 0 return @void when 2 return @flat_bottom[0] when 1, 3, 129, 131 return @flat_bottom[1] when 128 return @flat_bottom[2] when 8 return @flat_top[0] when 16, 24, 48, 56 return @flat_top[1] when 32 return @flat_top[2] when 4, 6, 12, 14 return @flat_l when 64, 96, 192, 224 return @flat_r when 65, 67, 97, 99, 193, 195, 225, 227 return @flat_rb when 5, 7, 13, 15, 133, 135, 141, 143 return @flat_lb when 80, 88, 112, 120, 208, 216, 240, 248 return @flat_ru when 20, 22, 28, 30, 52, 54, 60, 62 return @flat_lu else return 0 end end #-------------------------------------------------------------------------- # ● 获得图块的邻近值 # x: 地图的 x 坐标 # y: 地图的 y 坐标 #-------------------------------------------------------------------------- def neighbor_data(x, y) neighbor = [0, 0, 0, 0, 0, 0, 0, 0] neighbor[0] = @map.data[x-1, y-1, 0] if x > 0 and y > 0 neighbor[1] = @map.data[x-1, y, 0] if x > 0 neighbor[2] = @map.data[x-1, y+1, 0] if x > 0 and y < @height - 1 neighbor[3] = @map.data[x, y+1, 0] if y < @height - 1 neighbor[4] = @map.data[x+1, y+1, 0] if x < @width - 1 and y < @height - 1 neighbor[5] = @map.data[x+1, y, 0] if x < @width - 1 neighbor[6] = @map.data[x+1, y-1, 0] if x < @width - 1 and y > 0 neighbor[7] = @map.data[x, y-1, 0] if y > 0 neighbor.collect!{|n| n > 0 ? 1 : 0} return neighbor.inject(0) {|v, n| v = v * 2 + n} end end # 以下为使用脚本,发布前请删除或注释 $auto_fill = Auto_MazeWalls.new(1) $auto_fill.fill_wall $auto_fill.save exit
yang1zhi 发表于 2016-1-26 10:16
先收下了。
QQ图片20160523021840.jpg (22.12 KB, 下载次数: 33)
欢迎光临 Project1 (https://rpg.blue/) | Powered by Discuz! X3.1 |