[XP] wraptile (ingame autotile chainer)

Started by Poe, February 23, 2012, 10:46:21 am

Previous topic - Next topic

Poe

February 23, 2012, 10:46:21 am Last Edit: February 25, 2012, 05:16:30 pm by Poe
Wraptile
Authors: Poe
Version: 1.1
Type: Autotile chainer
Key Term: Misc System



Introduction

a small script that allows you to replace tiles ingame while still chaining the autotiles like in the map creator.


Features


  • tile substitution with automatic rechaining of autotiles ingame

  • changes to the map are saved




Screenshots

None.


Demo/Minigame

http://dl.dropbox.com/u/56282677/rmxp/wraptile%20v1.1.rar


Script

Spoiler: ShowHide

#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#: WRAPTILE v1.1 by Poe
#:
#: INFO:
#: this script allows you to replace tiles ingame while still chaining the
#: autotiles like in the map creator. changes to the map are also saved now.
#:
#: HOWTO:
#: place this script anywhere. there shouldn't be any compatibility issues.
#: to use it, put this inside a script box:
#:
#:    $game_map.wraptile(x,y,z,*newtile_x,*newtile_y)
#:
#:    - x,y = location on the map.
#:    - z = layer (0,1,2)
#:    - newtile_x/y =
#:            * x and y location the replacement tile is at in the tileset grid.
#:            * for autotiles, newtile_y is always 0 (may be omitted).
#:            * to only remove a tile, you can omit both newtile_x and newtile_y.
#:            * you can also use a specific tileid for newtile_x.
#:
#: NOTE:
#: please let me know if you get the "too many outcomes" error message,
#: in that case i probably made a typo in the numbers somewhere.:)
#:
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Game_Map
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 def wraptile(x,y,z,newtile_x=0,newtile_y=nil)
 
   # remove former wrapping.
   former_tile = data[x,y,z]
   if former_tile < 383
     # tile is part of an autotile: remove wrapping.
     former_tile = set_autotile_start(former_tile)
     data[x,y,z] = 0
     set_wrapping(x,y,z,former_tile)
   end
   
   # set the new autotile.
   if newtile_y == nil && newtile_x < 384
     case newtile_x
     when 0
       newtile = 0
     when 1
       newtile = 48
     when 2
       newtile = 96
     when 3
       newtile = 144
     when 4
       newtile = 192
     when 5
       newtile = 240
     when 6
       newtile = 288
     when 7
       newtile = 336
     else
       newtile = set_autotile_start(newtile_x)
     end
     
     # set new wrapping.
     data[x,y,z] = newtile
     set_wrapping(x,y,z,newtile)
     
   elsif newtile_x >= 384
   # not an autotile, set tile without wrapping.
     data[x,y,z] = newtile_x
   else
     newtile_y = 0 if newtile_y == nil
     data[x,y,z] = 376 + (newtile_y * 8) + newtile_x
   end
   
   # save changed data.
   $wraptile_data[$game_map.map_id] = $game_map.data

 end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 def set_autotile_start(tile)
   return 0 if tile.between?(0,47)
   return 48 if tile.between?(48,95)
   return 96 if tile.between?(96,143)
   return 144 if tile.between?(144,191)
   return 192 if tile.between?(192,239)
   return 240 if tile.between?(240,287)
   return 288 if tile.between?(288,335)
   return 336 if tile.between?(336,383)
 end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 def set_wrapping(start_x,start_y,z,base_tile)
   # using a process of exclusion, determines what the surrounding tiles will be.
   
   for firstlayer in 0..8
     case firstlayer
     when 0 # NW of middle tile.
       x = start_x-1
       y = start_y-1
     when 1 # N of middle tile.
       x = start_x
       y = start_y-1
     when 2 # NE of middle tile.
       x = start_x+1
       y = start_y-1
     when 3 # W of middle tile.
       x = start_x-1
       y = start_y
     when 4 # middle tile.
       x = start_x
       y = start_y
     when 5 # E of middle tile.
       x = start_x+1
       y = start_y
     when 6 # SW of middle tile.
       x = start_x-1
       y = start_y+1
     when 7 # S of middle tile.
       x = start_x
       y = start_y+1
     when 8 # SE of middle tile.
       x = start_x+1
       y = start_y+1
     end
     
     # skip if outside of map.
     next if valid?(x, y) == false
     # skip if not part of the autotile.
     next if data[x,y,z].between?(base_tile,base_tile+47) == false
     
     # adding all possibilities to the list.
     del_list = []
     possible_tiles = []
     for i in 0..47
       possible_tiles.push i
     end
     
     # check the surrounding tiles.
     for secondlayer in 0..7
       case secondlayer
       when 0
       # second layer NW.
         if valid?(x-1,y-1) &&
           data[x-1,y-1,z].between?(base_tile,base_tile+47) == false
           # not part of the autotile.
           del_list.push 0,2,4,6,8,10,12,14,24,25,28,30,38
         else
           # if any surrounding tile is part of autotile,
           # this tile will never be lone.
           del_list.push 1,3,5,7,9,11,13,15,26,27,29,31,39,46,47
         end
       when 1
       # second layer N.
         if valid?(x,y-1) &&  
           data[x,y-1,z].between?(base_tile,base_tile+47) == false
           del_list.push 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,24,
             25,26,27,28,29,30,31,32,38,39,40,41,44
         else
           del_list.push 20,21,22,23,33,34,35,36,37,42,43,45,46,47
         end
       when 2
       # second layer NE.
         if valid?(x+1,y-1) &&
           data[x+1,y-1,z].between?(base_tile,base_tile+47) == false
           del_list.push 0,1,4,5,8,9,12,13,16,18,28,29,40
         else
           del_list.push 2,3,6,7,10,11,14,15,17,19,30,31,41,46,47
         end
       when 3
       # second layer W.
         if valid?(x-1,y) &&
           data[x-1,y,z].between?(base_tile,base_tile+47) == false
           del_list.push 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,20,21,22,23,24,
           25,26,27,28,29,30,31,33,36,37,38,39,45
         else
           del_list.push 16,17,18,19,32,34,35,40,41,42,43,44,46,47
         end
       when 4
       # second layer E.
         if valid?(x+1,y) &&
           data[x+1,y,z].between?(base_tile,base_tile+47) == false
           del_list.push 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
           21,22,23,28,29,30,31,33,34,35,40,41,43
         else
           del_list.push 24,25,26,27,32,36,37,38,39,42,44,45,46,47
         end
       when 5
       # second layer SW.
         if valid?(x-1,y+1) &&
           data[x-1,y+1,z].between?(base_tile,base_tile+47) == false
           del_list.push 0,1,2,3,4,5,6,7,20,21,24,26,36
         else
           del_list.push 8,9,10,11,12,13,14,15,22,23,25,27,37,46,47
         end
       when 6
       # second layer S.
         if valid?(x,y+1) &&
           data[x,y+1,z].between?(base_tile,base_tile+47) == false
           del_list.push 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
           21,22,23,24,25,26,27,32,34,35,36,37,42
         else
           del_list.push 28,29,30,31,33,38,39,40,41,43,44,45,46,47
         end
       when 7
       # second layer SE.
         if valid?(x+1,y+1) &&
           data[x+1,y+1,z].between?(base_tile,base_tile+47) == false
           del_list.push 0,1,2,3,8,9,10,11,16,17,20,22,34
         else
           del_list.push 4,5,6,7,12,13,14,15,18,19,21,23,35,46,47
         end          
       end
     end
     
     # do the check.
     possible_tiles.each { |i|
     possible_tiles.delete_if{|i| del_list.include?(i)}
     }
     
     # set the result,
     # else (no possibilities are left), set to the lone tile.
     if possible_tiles.size == 1
       data[x,y,z] = possible_tiles.pop + base_tile
     elsif possible_tiles.size > 2
       # here be a typo check.
       p "WRAPTILE ERROR: too many outcomes for ("+x.to_s+","+y.to_s+")"
       data[x,y,z] = 0
     else
       data[x,y,z] = 46 + base_tile
     end
   end
 end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 alias wraptile_ini initialize unless $@
 def initialize
   $wraptile_data = []
   wraptile_ini
 end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 alias wraptile_setup setup unless $@
 def setup(map_id)
   wraptile_setup(map_id)
   # load saved wraptile data instead.
   @map.data = $wraptile_data[@map_id] if $wraptile_data[@map_id] != nil
 end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
end



Instructions

in the script.


Compatibility

any.


Credits and Thanks


  • Poe (myself)

  • all the scripters that came before me for teaching me stuff:)




Author's Notes

please let me know if a "too many outcomes" error message pops up. lots of numbers makes for easy typos.

Wizered67

Wow, this is pretty interesting. I don't see how this could be useful in most games, but this could really help mine! I already have stuff set up for placing tiles, but I never got around to getting autotiles to work. I will probably end up using some of the code from this. Thanks!

Poe

you're welcome^^

well it can be very useful in minigames like i showed in the demo, or in random dungeon generators, or anything using changing maps like growing towns, or... i'm using this in my own game to randomly make grass grow on sand tiles. you can do a lot of things with it if you get creative.:)

LiTTleDRAgo

this is kind of useful,

is there any way to save edited tiles to save games?

Poe

February 25, 2012, 04:58:27 pm #4 Last Edit: February 25, 2012, 04:59:37 pm by Poe
Quote from: LiTTleDRAgo on February 25, 2012, 12:20:15 pm
this is kind of useful,

is there any way to save edited tiles to save games?

edited tiles are now saved in savegames as well as in transfer to different map.