-
strelokhalfer
-
-
Вне сайта
-
Архитектор Миров
-
-
Знатный грамотей
- Сообщений: 1640
- Спасибо получено: 1078
-
-
|
Представляю вам один, несомненно интересный скрипт под названием
Tile Swap
Он позволяет менять тайлы посредством вызова скрипта в событии.
Но для начала немного ТЕОРИИ
Тайлсеты в Ace
Тайлсеты в RMVX Ace разделяются на пять категорий, а именно A, B, C, D, E.
В свою очередь, "А" подразделяется ещё на пять категорий: А1, А2, А3, А4, А5.
Слои в Ace
Может принимать значения от 0 до 2.
0 - нижний слой, 2 - верхний слой.
Тайлсеты "A1", "A2", "A3", и "A4" располагаются на слоях 0 и 1, а "A5", "B", "C", "D", и "E" соответственно на 2.
[Прим.переводчика]
Я не понял логики работы слоя в скриптах, то не надо указывать, то надо гадать, какую цифру поставить.
Возможно с 1 по 4 столбец это нулевой слой, а с 5 по 8 соответственно первый слой.
Указывать надо, если тайлы из разных слоев(указывать слой на котором меняют)
Как рассчитать tileID?
Этот скрипт использует понятие "tile ID", оно определяет тайл в
вашем тайлсете.
Каждый tile ID начинается с буквы, далее идет номер.
Буквы указывают на раздела тайлсета, а именно(можно строчными):
A, B, C, D, E
Номер означает позицию тайла в тайлсете.
Для примера, "A1" означает первый файл в тайлсете A, а
"B12" означает двенадцатый тайл в тайлсете B.
Узнать номер ID очень легко: просто считаем с права-на-лево.
Пример:
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
и так далее.
Лично я использую(переводчик) формулу, так как иногда считать не удобно.
((x-1)*8)+y
"x" - номер ряда
"y" - номер столбца
Пример: На тайлстете "Карта мира" ищем id облака
((2-1)*8)+8=16 {Хотя посчитать вручную было проще, но это же пример!}
Часть сообщения скрыта для гостей. Пожалуйста, авторизуйтесь или зарегистрируйтесь, чтобы увидеть его.
=begin
================================================================================
Название: Tile Swap
Авторы: Hime, Rycochet
Первод: strelokhalfer для rpg-maker.info
Последнее обновление: Июнь 11, 2014
--------------------------------------------------------------------------------
** История версий
3.3ru
- Русификация.
3.3
- Поддержка автотайлов для второго слоя
3.2 Июнь 8, 2014
- мелкие правки
3.1 Январь 16, 2014
- флаг переименован в "need_refresh_tiles"
3.0 --- РВП
-СДЕЛАТЬ автослой из "A13"
-СДЕЛАТЬ новую документацию, включая метод Map_Mask
(Не сделали, а я разбирайся - П\п)
3.0b1 Сентябрь 20 2013 - Rycochet
-Добавлен Map_Mask и сопутствующие функции - может заменить всё,
кроме определйнных позиций, если это необходимо
-Различные правки и оптимизация
2.5 Сентябрь 19 2013 - Rycochet
-И опять оптимизация с исправлениями.
-Исправлена ошибка в конвертации
2.4 Сентябрь 17 2013 - Rycochet
-оптимизация и правки
2.3: 5 Мая
-Поправлен баг с A5 автотайлами.
2.2: 4 Мая
-Добавлена поддержка оверей-карт
2.1: 11 Апреля
-Поправлен баг со слоями B-E
2.0: 17 Февраля
-теперь новые тайлы не берутся с других карт
-поправлен баг, игнорировалась последняя строка A4 тайлов
-изменена команда скрипта
-замена автотайлов
1.2: 22 Января, 2013
-исправлен баг с неправильной заменой тайлов
1.1: 20 Мая
-Добавлена возможность откатить изменения
1.0: 16 Мая, 2012
-Первая версия
--------------------------------------------------------------------------------
** Условия использования
* Бесплатное использования для некоммерческих проектов.
* Для коммерческих требуется разрешение
* Предоставляется "как есть"
* Не обещается совместимость с другими скриптами
* Не удалять этот заголовок
--------------------------------------------------------------------------------
** Описание
Позволяет заменять любые тайлы и возвращать все назад.
--------------------------------------------------------------------------------
** Совместимость
Должна быть с большинством скриптов.
--------------------------------------------------------------------------------
** Как использовать
Используйте команды, указанные ниже. Параметры слоя и карты указывать не обязательно.
Вы должны знать, что такое tileId и как вызывать скрипт в событии.
map_id - номер карты, смотреть в мейкере.
ВСЕ tileID указывать в кавычках!
Слой: от 0 до 2(0-пол, 1-на уровне ГГ, 2-над игроком)
(Прим.Пер.)
Как показал опыт, слой все же нужно указывать в некоторых случаях.
С "А1" по "А4" - от 0 до 1
С "А5" по "В" - 2
Всего четыре шага:
1. Изменить по tile id
-Все тайлы имеющий такой ID будут заменены другими.
Использование: tile_swap(старый_tileID, новый_tileID, слой, map_id)
Последние два не обязательны.
2. Изменить по id региона
-Все тайлы отмеченные определённым ID региона буду изменены.
Использование: region_swap(regionID, tileID, слой, map_id)
Последние два не обязательны.
3. Изменить по координатам
-Измениться тайл, указанный на координате.
Использование: pos_swap(x, y, tileID, слой, map_id)
4. Использовать маску.
(гайд в процессе)
Вы можете отменить каждую команду или отменить все сразу.
tile_revert(tileid, слой, map_id)
pos_revert(x, y, tileid, слой, map_id)
region_revert(regionid, слой, map_id)
revert_all(map_id)
--------------------------------------------------------------------------------
** Пояснения
Этот скрипт использует понятие "tile ID", оно определяет тайл в
вашем тайлсете.
Каждый tile ID начинается с буквы, далее идет номер.
Буквы указывают на раздела тайлсета, а именно(можно строчными):
A, B, C, D, E
Номер означает позицию тайла в тайлсете.
Для примера, "A1" означает первый файл в тайлсете A, а
"B12" означает двенадцатый тайл в тайлсете B.
Узнать номер ID очень легко: просто считаем с права-на-лево.
Пример:
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
и так далее.
Лично я(переводчик) использую формулу, так как иногда считать не удобно.
((x-1)*8)+y
"x" - номер ряда
"y" - номер столбца
Пример: На тайлстете "Карта мира" ищем id облака
((2-1)*8)+8=16 {Хотя посчитать вручную было проще, но это же пример!}
--------------------------------------------------------------------------------
** Благодарности
KilloZapit, за отличный код генерации автотайлов.
================================================================================
=end
$imported = {} if $imported.nil?
$imported["TH_TileSwap"] = true
#===============================================================================
# ** Сам скрипт.
#===============================================================================
class Game_System
attr_accessor :swapped_tiles, :swapped_pos_tiles, :swapped_region_tiles, :swapped_mask_tiles
#-----------------------------------------------------------------------------
# Новый. Конвертирует мой tileID в игровой tile ID.
#-----------------------------------------------------------------------------
def convert_tid(tileID, layer=0)
return $game_map.tile_id(tileID[0], tileID[1], layer) if tileID.kind_of?(Array)
page = tileID[0].upcase
tid = tileID[1..-1].to_i - 1
if page == 'A'
# страница A содержит автотайлы
return tid * 48 + 2048 if tid < 128
return tid - 128 + 1536
end
# страницы B, C, D, и E содержат 256 иконок на страницу.
return tid if page == 'B'
return tid + 256 if page == 'C' # 1 x 256
return tid + 512 if page == 'D' # 2 x 256
return tid + 768 if page == 'E' # 3 x 256
end
#==============================================================================
# ■ Тайлы
#==============================================================================
#-----------------------------------------------------------------------------
# Новый.
#-----------------------------------------------------------------------------
def initialize_tile_list(map_id, layer)
@swapped_tiles = [] if @swapped_tiles.nil?
@swapped_tiles[map_id] = [] if @swapped_tiles[map_id].nil?
@swapped_tiles[map_id][layer] = [] if @swapped_tiles[map_id][layer].nil?
end
#-----------------------------------------------------------------------------
# Новый.
#-----------------------------------------------------------------------------
def add_tile_id(map_id, layer, old_tid, new_tid)
initialize_tile_list(map_id, layer)
old_tid = convert_tid(old_tid, layer)
new_tid = convert_tid(new_tid, layer)
@swapped_tiles[map_id][layer][old_tid] = new_tid
$game_map.load_new_map_data
end
#-----------------------------------------------------------------------------
# Новый.
#-----------------------------------------------------------------------------
def has_swap_tiles?(map_id, layer)
return false if @swapped_tiles.nil?
return false if @swapped_tiles[map_id].nil? || @swapped_tiles[map_id].empty?
return false if @swapped_tiles[map_id][layer].nil? || @swapped_tiles[map_id][layer].empty?
return true
end
#-----------------------------------------------------------------------------
# Новый. Возвращает старые тайлы.
#-----------------------------------------------------------------------------
def revert_tile(map_id, layer, tid)
initialize_tile_list(map_id, layer)
tid = convert_tid(tid, layer)
@swapped_tiles[map_id][layer].delete_at(tid)
$game_map.reload_map
end
#==============================================================================
# ■ Позиция
#==============================================================================
#-----------------------------------------------------------------------------
# Новый.
#-----------------------------------------------------------------------------
def initialize_pos_list(map_id, layer)
@swapped_pos_tiles = [] if @swapped_pos_tiles.nil?
@swapped_pos_tiles[map_id] = [] if @swapped_pos_tiles[map_id].nil?
@swapped_pos_tiles[map_id][layer] = [] if @swapped_pos_tiles[map_id][layer].nil?
end
#-----------------------------------------------------------------------------
# Новый.
#-----------------------------------------------------------------------------
def add_position_tile(map_id, x, y, layer, tid)
initialize_pos_list(map_id, layer)
tid = convert_tid(tid, layer)
@swapped_pos_tiles[map_id][layer][y] = [] if @swapped_pos_tiles[map_id][layer][y].nil?
@swapped_pos_tiles[map_id][layer][y][x] = tid
$game_map.load_new_map_data
end
#-----------------------------------------------------------------------------
# Новый.
#-----------------------------------------------------------------------------
def has_swap_pos?(map_id, layer)
return false if @swapped_pos_tiles.nil?
return false if @swapped_pos_tiles[map_id].nil? || @swapped_pos_tiles[map_id].empty?
return false if @swapped_pos_tiles[map_id][layer].nil? || @swapped_pos_tiles[map_id][layer].empty?
return true
end
#-----------------------------------------------------------------------------
# Новый. Возвращает старые тайлы.
#-----------------------------------------------------------------------------
def revert_pos(map_id, x, y, layer)
initialize_pos_list(map_id, layer)
unless @swapped_pos_tiles[map_id][layer][y].nil?
@swapped_pos_tiles[map_id][layer][y][x] = nil
@swapped_pos_tiles[map_id][layer].delete_at(y) if @swapped_pos_tiles[map_id][layer][y].empty?
end
$game_map.reload_map
end
#==============================================================================
# ■ Регионы
#==============================================================================
#-----------------------------------------------------------------------------
# Новый.
#-----------------------------------------------------------------------------
def initialize_region_list(map_id, layer)
@swapped_region_tiles = [] if @swapped_region_tiles.nil?
@swapped_region_tiles[map_id] = [] if @swapped_region_tiles[map_id].nil?
@swapped_region_tiles[map_id][layer] = [] if @swapped_region_tiles[map_id][layer].nil?
end
#-----------------------------------------------------------------------------
# Новый.
#-----------------------------------------------------------------------------
def add_region_tile(map_id, rid, layer, tid)
initialize_region_list(map_id, layer)
tid = convert_tid(tid, layer)
@swapped_region_tiles[map_id][layer][rid] = tid
$game_map.load_new_map_data
end
#-----------------------------------------------------------------------------
# Новый.
#-----------------------------------------------------------------------------
def has_swap_region?(map_id, layer)
return false if @swapped_region_tiles.nil?
return false if @swapped_region_tiles[map_id].nil? || @swapped_region_tiles[map_id].empty?
return false if @swapped_region_tiles[map_id][layer].nil? || @swapped_region_tiles[map_id][layer].empty?
return true
end
#-----------------------------------------------------------------------------
# Новый. Возвращает старые тайлы.
#-----------------------------------------------------------------------------
def revert_region(map_id, layer, rid)
initialize_region_list(map_id, layer)
@swapped_region_tiles[map_id][layer].delete_at(rid)
$game_map.reload_map
end
#==============================================================================
# ■ Маска
#==============================================================================
#-----------------------------------------------------------------------------
# Новый.
#-----------------------------------------------------------------------------
def initialize_mask_list(map_id, layer)
@swapped_mask_tiles = [] if @swapped_mask_tiles.nil?
@swapped_mask_tiles[map_id] = [] if @swapped_mask_tiles[map_id].nil?
@swapped_mask_tiles[map_id][layer] = {} if @swapped_mask_tiles[map_id][layer].nil?
end
#-----------------------------------------------------------------------------
# Новый.
#-----------------------------------------------------------------------------
def add_mask_tile(map_id, mask, layer, tid)
initialize_mask_list(map_id, layer)
tid = convert_tid(tid, layer)
@swapped_mask_tiles[map_id][layer][mask] = tid
$game_map.load_new_map_data
end
#-----------------------------------------------------------------------------
# Новый.
#-----------------------------------------------------------------------------
def has_swap_mask?(map_id, layer)
return false if @swapped_mask_tiles.nil?
return false if @swapped_mask_tiles[map_id].nil? || @swapped_mask_tiles[map_id].empty?
return false if @swapped_mask_tiles[map_id][layer].nil? || @swapped_mask_tiles[map_id][layer].empty?
return true
end
#-----------------------------------------------------------------------------
# Новый. Возвращает старые тайлы.
#-----------------------------------------------------------------------------
def revert_mask(map_id, layer, mask)
initialize_mask_list(map_id, layer)
@swapped_mask_tiles[map_id][layer].delete(mask)
$game_map.reload_map
end
#==============================================================================
# ■ Вернуть всё
#==============================================================================
#-----------------------------------------------------------------------------
# Новый. Возвращает старые тайлы.
#-----------------------------------------------------------------------------
def revert_all(map_id)
@swapped_tiles[map_id] = nil unless @swapped_tiles.nil?
@swapped_pos_tiles[map_id] = nil unless @swapped_pos_tiles.nil?
@swapped_mask_tiles[map_id] = nil unless @swapped_mask_tiles.nil?
@swapped_region_tiles[map_id] = nil unless @swapped_region_tiles.nil?
$game_map.reload_map
end
end
class Map_Mask
attr_accessor :width, :height, :priority
#attr @mask # array, each row is in reverse order, bit 0 is the left-most bit
#attr @mask_width # 0b1111111 - a mask to & with a row to ensure it stays within the width
def initialize(max_width, max_height, priority = 0)
@width = max_width
@height = max_height
@priority = priority
@mask_width = (1 << max_width) - 1
clear!
end
#--------------------------------------------------------------------------
# * !! Для отладки !!
#--------------------------------------------------------------------------
def debug
print "Текущая маска:\n"
for y in 0...@height
print "#{(@mask[y] || 0).to_s(2).reverse}\n"
end
end
#--------------------------------------------------------------------------
# * update
# Обновляет карту
#--------------------------------------------------------------------------
def update
# $game_map.load_new_map_data
$game_map.reload_map
end
#--------------------------------------------------------------------------
# * valid?(x, y)
# Проверяет корректность координат
#--------------------------------------------------------------------------
def valid?(x, y)
return x >= 0 && x < @width && y >= 0 && y < @height
end
#--------------------------------------------------------------------------
# * empty?
# Пуста ли маска
#--------------------------------------------------------------------------
def empty?
return true if @mask.empty?
for y in 0...@height
return false if @mask[y]
end
return true
end
#--------------------------------------------------------------------------
# * clear!
# Очистить маску
#--------------------------------------------------------------------------
def clear!
@mask = []
end
#--------------------------------------------------------------------------
# * []=(x, y)
# Marks or clears a single coordinate in the mask
# Access as an array, but with a true/false value type
#--------------------------------------------------------------------------
def []=(x, y, set)
return unless valid?(x, y)
if set
@mask[y] = ((@mask[y] || 0) | (1 << x)) & @mask_width
else
@mask[y] = (@mask[y] || 0) & (@mask_width ^ (1 << x))
end
end
#--------------------------------------------------------------------------
# * [](x, y)
# Проверяет координату с маске
#--------------------------------------------------------------------------
def [](x, y)
return (@mask[y] || 0) & (1 << x) != 0
end
#--------------------------------------------------------------------------
# * **(y)
# Получить данные с одной строки
#--------------------------------------------------------------------------
def **(y)
return (@mask[y] || 0)
end
#--------------------------------------------------------------------------
# * or(mask)
# Делает логическую операцию OR(ИЛИ) с другой маской,
# по сути, объединяет две маски.
#--------------------------------------------------------------------------
def or(mask)
for y in 0...[mask.height, @height].min
@mask[y] = ((@mask[y] || 0) | (mask ** y)) & @mask_width
end
end
#--------------------------------------------------------------------------
# * xor(mask)
# Делает логическую операцию XOR(Исключающее ИЛИ) с другой маской,
# останутся только те тайлы, что содержаться только в ОДНОЙ маске.
#--------------------------------------------------------------------------
def xor(mask)
for y in 0...[mask.height, @height].min
@mask[y] = ((@mask[y] || 0) ^ (mask ** y)) & @mask_width
end
end
#--------------------------------------------------------------------------
# * and(mask)
# Делает логическую операцию AND(И) с другой маской, останутся только те
# тайлы, что были в ОБЕИХ масках
#--------------------------------------------------------------------------
def and(mask)
for y in 0...[mask.height, @height].min
@mask[y] = ((@mask[y] || 0) & (mask ** y)) & @mask_width
end
end
#--------------------------------------------------------------------------
# * invert
# Инвертирует маску
#--------------------------------------------------------------------------
def invert
for y in 0...@height
@mask[y] = (@mask[y] || 0) ^ @mask_width
end
end
#--------------------------------------------------------------------------
# * copy(mask)
# Скопировать маску
#--------------------------------------------------------------------------
def copy(mask)
clear!
for y in 0...[mask.height, @height].min
@mask[y] = (mask ** y) & @mask_width
end
end
#--------------------------------------------------------------------------
# * from_region(rid)
# Копирует с региона карты
#--------------------------------------------------------------------------
def from_region(rid)
for y in 0...[@height, $game_map.height].min
for x in 0...[@width, $game_map.width].min
if rid == $game_map.data[x, y, 3] >> 8
@mask[y] = ((@mask[y] || 0) | (1 << x)) # @mask[x,y] = true
end
end
end
end
#--------------------------------------------------------------------------
# * from_tile(tid)
# Copy a tile mask from the current map - uses autotile generic tiles
#--------------------------------------------------------------------------
def from_tile(tid, layer = 0)
tid = $game_system.convert_tid(tid)
for y in 0...[@height, $game_map.height].min
for x in 0...[@width, $game_map.width].min
old_tid = $game_map.data[x, y, layer]
old_tid = old_tid - ((old_tid - 2048) % 48) if old_tid >= 2048
if tid == old_tid
@mask[y] = ((@mask[y] || 0) | (1 << x)) # @mask[x,y] = true
end
end
end
end
#--------------------------------------------------------------------------
# * rectangle(width, height, left, top)
# Draw a rectangle in the mask
#--------------------------------------------------------------------------
def rectangle(width, height, left = 0, top = 0)
mask = (((1 << (width + 1)) - 1) << left) & @mask_width
for y in top...[(top + width), @height].min
@mask[y] = (@mask[y] || 0) | mask
end
end
#--------------------------------------------------------------------------
# * shift(right, down)
# Shift a mask, use negative numbers for left / up
#--------------------------------------------------------------------------
def shift(right, down)
mask = []
for y in 0...@height
if @mask[y + down]
if !right
mask[y] = @mask[y + down]
elsif right < 0
mask[y] = @mask[y + down] >> -right
elsif right > 0
mask[y] = (@mask[y + down] << right) & @mask_width
end
end
end
@mask = mask
end
#--------------------------------------------------------------------------
# * grow
# Grow the outline of a mask, every filled coordinate is surrounded in a
# 3x3 grid
#--------------------------------------------------------------------------
def grow
mask = []
for y in 0...@height
if @mask[y]
mask[y] = @mask[y] |= (@mask[y] << 1) | (@mask[y] >> 1)
end
if y > 0
mask[y-1] = (mask[y-1] || 0) | @mask[y] unless @mask[y].nil?
mask[y] = (mask[y] || 0) | @mask[y-1] unless @mask[y-1].nil?
end
end
@mask = mask
end
#--------------------------------------------------------------------------
# * shrink
# Shrink the outline of a mask, will reduce the size of a mask in a * shape
#--------------------------------------------------------------------------
def shrink
invert
grow
invert
end
#--------------------------------------------------------------------------
# * blur
# Similar to grow, but doesn't grow diagonally
#--------------------------------------------------------------------------
def blur
mask = []
for y in 0...@height
if @mask[y]
mask[y] = @mask[y] | (@mask[y] << 1) | (@mask[y] >> 1)
end
if y > 0
mask[y-1] = (mask[y-1] || 0) | @mask[y] unless @mask[y].nil?
mask[y] = (mask[y] || 0) | @mask[y-1] unless @mask[y-1].nil?
end
end
@mask = mask
end
#--------------------------------------------------------------------------
# * unblur
# Shrink the outline of a mask, will reduce the size of a mask in a + shape
#--------------------------------------------------------------------------
def unblur
invert
blur
invert
end
#--------------------------------------------------------------------------
# * each {|x, y, valid_left, valid_top, valid_right, valid_bottom| ... }
# Perform operations on every valid square in the mask, the valid_*
# variables state whether the coordinate is against the edge (in a more
# efficient manner)
#--------------------------------------------------------------------------
def each
for y in 0...@height
next if !@mask[y]
valid_top = y > 0
valid_bottom = y < @height-1
val = @mask[y]
for x in 0...@width
break if !val
unless val & 1 == 0
valid_left = x > 0
valid_right = x < @width-1
yield x, y, valid_left, valid_top, valid_right, valid_bottom
end
val >>= 1
end
end
end
end
class Game_Map
attr_reader :need_refresh_tiles
#-----------------------------------------------------------------------------
# Псевдоним. Загрузка новых данных после загрузки оригинальных
#-----------------------------------------------------------------------------
alias :tsuki_tile_swap_setup_map :setup
def setup(map_id)
tsuki_tile_swap_setup_map(map_id)
@updated_tiles = Map_Mask.new(width, height)
load_new_map_data
end
#-----------------------------------------------------------------------------
# Новый. Загрузка оригинальных данных
#-----------------------------------------------------------------------------
def reload_map
new_map = load_data(sprintf("Data/Map%03d.rvdata2", @map_id))
@map.data = new_map.data
load_new_map_data
end
#-----------------------------------------------------------------------------
# Новый. Загруска новыйх данных на карту
#-----------------------------------------------------------------------------
def load_new_map_data
@need_refresh_tiles = true
end
#-----------------------------------------------------------------------------
# Новый. Смена тайлов по tile ID
#-----------------------------------------------------------------------------
def perform_load_new_map_data
@need_refresh_tiles = false
for z in 0...3
@updated_tiles.clear!
tiles = $game_system.has_swap_tiles?(@map_id, z) ? $game_system.swapped_tiles[map_id][z] : nil
regions = $game_system.has_swap_region?(@map_id, z) ? $game_system.swapped_region_tiles[map_id][z] : nil
masks = $game_system.has_swap_mask?(@map_id, z) ? $game_system.swapped_mask_tiles[map_id][z] : nil
position_tiles = $game_system.has_swap_pos?(@map_id, z) ? $game_system.swapped_pos_tiles[map_id][z] : nil
next unless tiles or masks or regions or position_tiles
for y in 0...height
positions = position_tiles.nil? ? nil : position_tiles[y]
for x in 0...width
new_tile = nil
if positions
new_tile = positions[x]
end
if new_tile.nil? and masks
priority = nil
masks.each {|mask, tid|
if (priority.nil? or mask.priority > priority) and mask[x,y]
new_tile = tid
priority = mask.priority
end
}
end
if new_tile.nil? and regions
new_tile = regions[tile_id(x, y, 3) >> 8] # region_id(x,y) - но без проверки valid?(x,y)
end
if new_tile.nil? and tiles
old_tid = tile_id(x, y, z)
old_tid = old_tid - ((old_tid - 2048) % 48) if old_tid >= 2048
new_tile = tiles[old_tid]
end
next if new_tile.nil?
old_tid = tile_id(x, y, z)
old_tid = old_tid - ((old_tid - 2048) % 48) if old_tid >= 2048
next if new_tile == old_tid # так быстрее
@map.data[x, y, z] = new_tile
@updated_tiles[x, y] = true
end
end
@updated_tiles.grow
#-----------------------------------------------------------------------------
# Основан на коде генераций от KilloZapit
#-----------------------------------------------------------------------------
@updated_tiles.each { |x, y, valid_left, valid_top, valid_right, valid_bottom|
autotile = (tile_id(x, y, z) - 2048) / 48
next if autotile < 0
index = 0
if autotile == 5 or autotile == 7 or autotile == 9 or autotile == 11 or autotile == 13 or autotile == 15
# водопад
index |= 1 if valid_left && autotile_edge(autotile, x - 1, y, z)
index |= 2 if valid_right && autotile_edge(autotile, x + 1, y, z)
elsif autotile >= 48 and autotile <= 79 or autotile >= 88 and autotile <= 95 or autotile >= 104 and autotile <= 111 or autotile >= 120 and autotile <= 127
# стена
index |= 1 if valid_left && autotile_wall_edge(autotile, x - 1, y, z)
index |= 2 if valid_top && autotile_edge(autotile, x, y - 1, z)
index |= 4 if valid_right && autotile_wall_edge(autotile, x + 1, y, z)
index |= 8 if valid_bottom && autotile_edge(autotile, x, y + 1, z)
else
# обычный
edge = 0
edge |= 1 if valid_left && autotile_edge(autotile, x - 1, y, z)
edge |= 2 if valid_top && autotile_edge(autotile, x, y - 1, z)
edge |= 4 if valid_right && autotile_edge(autotile, x + 1, y, z)
edge |= 8 if valid_bottom && autotile_edge(autotile, x, y + 1, z)
if edge == 0 # -
index |= 1 if valid_top && valid_left && autotile_edge(autotile, x - 1, y - 1, z)
index |= 2 if valid_top && valid_right && autotile_edge(autotile, x + 1, y - 1, z)
index |= 4 if valid_bottom && valid_right && autotile_edge(autotile, x + 1, y + 1, z)
index |= 8 if valid_bottom && valid_left && autotile_edge(autotile, x - 1, y + 1, z)
elsif edge == 1 # l
index |= 1 if valid_top && valid_right && autotile_edge(autotile, x + 1, y - 1, z)
index |= 2 if valid_bottom && valid_right && autotile_edge(autotile, x + 1, y + 1, z)
index |= 16
elsif edge == 2 # u
index |= 1 if valid_bottom && valid_right && autotile_edge(autotile, x + 1, y + 1, z)
index |= 2 if valid_bottom && valid_left && autotile_edge(autotile, x - 1, y + 1, z)
index |= 20
elsif edge == 3 # lu
index = valid_bottom && valid_right && autotile_edge(autotile, x + 1, y + 1, z) ? 35 : 34
elsif edge == 4 # r
index |= 1 if valid_bottom && valid_left && autotile_edge(autotile, x - 1, y + 1, z)
index |= 2 if valid_top && valid_left && autotile_edge(autotile, x - 1, y - 1, z)
index |= 24
elsif edge == 5 # lr
index = 32
elsif edge == 6 # ur
index = valid_bottom && valid_left && autotile_edge(autotile, x - 1, y + 1, z) ? 37 : 36
elsif edge == 7 # lur
index = 42
elsif edge == 8 # d
index |= 1 if valid_top && valid_left && autotile_edge(autotile, x - 1, y - 1, z)
index |= 2 if valid_top && valid_right && autotile_edge(autotile, x + 1, y - 1, z)
index |= 28
elsif edge == 9 # ld
index = valid_top && valid_right && autotile_edge(autotile, x + 1, y - 1, z) ? 41 : 40
elsif edge == 10 # ud
index = 33
elsif edge == 11 # lud
index = 43
elsif edge == 12 # rd
index = valid_top && valid_left && autotile_edge(autotile, x - 1, y - 1, z) ? 39 : 38
elsif edge == 13 # lrd
index = 44
elsif edge == 14 # urd
index = 45
elsif edge == 15 # lurd
index = 46
else # wtf
index = 47
end
end
@map.data[x, y, z]= 2048 + (48 * autotile) + index
}
end
end
#-----------------------------------------------------------------------------
# Псевдоним. Обновляет карту.
#-----------------------------------------------------------------------------
alias :tsuki_tile_swap_update_map :update
def update(main = false)
if @need_refresh_tiles
perform_load_new_map_data
end
tsuki_tile_swap_update_map(main)
end
# Логика подземелий о_О
# Что бы оверлейная трава росла на стенах.
def autotile_edge(autotile, x, y, z)
return autotile != (tile_id(x, y, z) - 2048) / 48
end
def autotile_wall_edge(autotile, x, y, z)
return false if autotile & 8 and (tile_id(x, y, z) - 2048) / 48 + 8 == autotile
return autotile_edge(autotile, x, y, z)
end
end
class Game_Interpreter
def tile_swap(old_tid, new_tid, layer=0, map_id=$game_map.map_id)
$game_system.add_tile_id(map_id, layer, old_tid, new_tid)
end
def pos_swap(x, y, tid, layer=0, map_id=$game_map.map_id)
$game_system.add_position_tile(map_id, x, y, layer, tid)
end
def region_swap(rid, tid, layer=0, map_id=$game_map.map_id)
$game_system.add_region_tile(map_id, rid, layer, tid)
end
def mask_swap(mask, tid, layer=0, map_id=$game_map.map_id)
$game_system.add_mask_tile(map_id, mask, layer, tid)
end
def tile_revert(tid, layer=0, map_id=$game_map.map_id)
$game_system.revert_tile(map_id, layer, tid)
end
def pos_revert(x, y, layer=0, map_id=$game_map.map_id)
$game_system.revert_pos(map_id, x, y, layer)
end
def region_revert(rid, layer=0, map_id=$game_map.map_id)
$game_system.revert_region(map_id, layer, rid)
end
def mask_revert(mask, layer=0, map_id=$game_map.map_id)
$game_system.revert_mask(map_id, layer, mask)
end
def revert_all(map_id=$game_map.map_id)
$game_system.revert_all(map_id)
end
end
#-------------------------------------------------------------------------------
# Адон для Overlay Maps
#-------------------------------------------------------------------------------
if $imported["TH_OverlayMaps"]
class Game_Map
alias :th_overlay_maps_load_new_map_data :load_new_map_data
def load_new_map_data
th_overlay_maps_load_new_map_data
@overlay_maps.each {|map| map.load_new_map_data} unless self.is_a?(Game_OverlayMap)
end
end
end
Как всегда, дэмо прилагается.
Ссылка на демо - Архив ZIP 1.4мб
|