Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Implementation of Near Fantastica's Dynamic Maps Script

I'm creating a small harvest moon sim, and I wanted to use a system that would allow just about any of the "ground" around the farm to be plowed, have seeds planted in it, watered, and etc.  Ultimately, this leads to a lot of different tiles in one area that have to be very dynamic.  Thus, instead of spreading around literally hundreds of events, it seems much wiser to implement a system that makes the map itself dynamic--the same sort of engine that one might consider for customized player housing.

For this reason, it made the most sense to turn to Near Fantastica's Dynamic Maps script, which I found after a few cursory searches:

Code:
#==============================================================================
# ** Dynamic Maps
#==============================================================================
# Near Fantastica
# Version 3
# 02.10.05
#==============================================================================

#------------------------------------------------------------------------------
# * SDK Log Script
#------------------------------------------------------------------------------
SDK.log("Dynamic Maps", "Near Fantastica", 3, "02.10.05")

#------------------------------------------------------------------------------
# * Begin SDK Enable Test
#------------------------------------------------------------------------------
if SDK.state("Dynamic Maps") == true

module Map
  #----------------------------------------------------------------------------
  @items = []
  @dynamic = false
  @map_data = {}
  @map_id = 0
  @data = []
  #============================================================================
  class Item
    #--------------------------------------------------------------------------
    attr_accessor :name
    attr_accessor :x
    attr_accessor :y
    attr_accessor :width
    attr_accessor :height
    attr_accessor :z
    attr_accessor :id
    #--------------------------------------------------------------------------
    def initialize(name, id, x, y, width, height, layer = 2)
      @name = name
      @id = id
      @x = x
      @y = y
      @width = width
      @height = height
      @z = layer - 1
    end
  end
  #============================================================================
  class Map_Data
    #--------------------------------------------------------------------------
    attr_accessor :map
    #--------------------------------------------------------------------------
    def initialize
      @map = 0
    end
  end
  #---------------------------------------------------------------------------- 
  def Map.set_map(map, map_id)
    @map_data[map_id] = map
  end
  #----------------------------------------------------------------------------  
  def Map.data(map_id)
    return @map_data[map_id]
  end
  #----------------------------------------------------------------------------
  def Map.setup_map(map_id)
    @dynamic = true
    @map_id = map_id
    @data = []
    map = load_data(sprintf("Data/Map%03d.rxdata", map_id))
    list = map.events[1].pages[0].list
    for item in list
      break if item.parameters[0] == nil
      eval(item.parameters[0]) 
    end
    data = []
    for item in @items
      data.push(item) if $game_party.item_number(item.id) != 0
    end
    @items = data
    return
  end
  #----------------------------------------------------------------------------
  def Map.clear
    @items = []
    @dynamic = false
    @map_id = 0
    return
  end
  #----------------------------------------------------------------------------
  def Map.mapdata
    return @data
  end
  #----------------------------------------------------------------------------
  def Map.dynamic
    return @dynamic
  end
  #----------------------------------------------------------------------------
  def Map.items
    return @items
  end
  #----------------------------------------------------------------------------
  def Map.remove_item(item)
    @items.delete(item)
  end
  #----------------------------------------------------------------------------
  def Map.map_id
    return @map_id
  end
  #----------------------------------------------------------------------------
  def Map.draw(sz, tz, xo, yo, sx, sy, width, height)
    map = load_data(sprintf("Data/Map%03d.rxdata", @map_id))
    a,b = 0,0
    x,y = sx,sy
    width.times do |w|
      height.times do |h|
        $game_map.map.data[xo+w, yo+h, tz] = map.data[x+w, y+h, sz]
      end
    end
  end
end


class Game_Map
  #----------------------------------------------------------------------------
  attr_accessor :map
  #----------------------------------------------------------------------------
  alias nf_dm_game_map_setup setup
  #----------------------------------------------------------------------------
  def setup(map_id)
    save_map(@map_id)
    if Map.data(map_id) == nil
      nf_dm_game_map_setup(map_id)
    else
      nf_dm_game_map_setup(map_id)
      load_map(map_id)
    end
  end
  #----------------------------------------------------------------------------
  def load_map(map_id)
    map_data = Map.data(map_id)
    @map = map_data.map
  end
  #----------------------------------------------------------------------------
  def save_map(map_id)
    return if map_id == 0
    map_data = Map::Map_Data.new
    map_data.map = @map
    Map.set_map(map_data, map_id)
  end
end

class Scene_Map
  #----------------------------------------------------------------------------
  alias nf_dm_scene_map_update update
  #----------------------------------------------------------------------------
  def update
    if Input.trigger?(Input::L) and Map.dynamic
      $scene = Scene_Placment.new
    end
    nf_dm_scene_map_update
  end
end

class Scene_Placment
  #--------------------------------------------------------------------------
  def main
    @z = 1
    @item = nil
    @place = false
    @move = false
    @remove = false
    @draw = false
    @cursor = Sprite.new
    @cursor.x = 0
    @cursor.y = 0
    @cursor.z = 5000
    @cursor.opacity = 160
    @spriteset = Spriteset_Map.new
    s1 = "Place"
    s2 = "Move"
    s3 = "Remove"
    s4 = "Exit"
    @command_window = Window_Command.new(192, [s1, s2, s3, s4])
    @command_window.back_opacity = 160
    @command_window.height = 480
    @command_window.disable_item(0) if Map.items == []
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    Graphics.freeze
    @spriteset.dispose
    @command_window.dispose
  end
  #--------------------------------------------------------------------------
  def update
    @command_window.update
    @spriteset.update
    if @draw == true
      cursor
    elsif @place == true
      placement
    elsif @move == true
      movement
    elsif @remove == true
      removement
    elsif Input.trigger?(Input::C)
      case @command_window.index
      when 0
        return if Map.items == []
        $game_system.se_play($data_system.decision_se)
        @place = true
        @command_window.visible = false
        data = []
        for item in Map.items
          data.push(item.name)
        end
        @placement_window = Window_Command.new(192, data)
        @placement_window.back_opacity = 160
        @placement_window.height = 480
      when 1
        return if Map.mapdata == []
        $game_system.se_play($data_system.decision_se)
        @move = true
        @command_window.visible = false
        data = []
        for item in Map.mapdata
          data.push(item.name)
        end
        @moveement_window = Window_Command.new(192, data)
        @moveement_window.back_opacity = 160
        @moveement_window.height = 480
      when 2
        $game_system.se_play($data_system.decision_se)
        @remove = true
        @command_window.visible = false
        data = []
        for item in Map.mapdata
          data.push(item.name)
        end
        @removeement_window = Window_Command.new(192, data)
        @removeement_window.back_opacity = 160
        @removeement_window.height = 480
      when 3
        $game_system.se_play($data_system.decision_se)
        $scene = Scene_Map.new
      end
    elsif Input.trigger?(Input::B)
      $game_system.se_play($data_system.decision_se)
      $scene = Scene_Map.new
    end
  end
  #--------------------------------------------------------------------------
  def cursor
    if @place == true
      @cursor.y += 32 if Input.trigger?(Input::DOWN)
      @cursor.x -= 32 if Input.trigger?(Input::LEFT)
      @cursor.x += 32 if Input.trigger?(Input::RIGHT)
      @cursor.y -= 32 if Input.trigger?(Input::UP)
      if Input.trigger?(Input::L)
        @z = 1
        color = Color.new(0, 255, 0) 
        @cursor.bitmap.fill_rect(0, 0, @item.width * 32, @item.height * 32, color) 
      end
      if Input.trigger?(Input::R)
        @z = 2
        color = Color.new(0, 0, 255) 
        @cursor.bitmap.fill_rect(0, 0, @item.width * 32, @item.height * 32, color) 
      end
      @cursor.update
      if Input.trigger?(Input::B)
        @draw = false
        @cursor.bitmap.dispose
        @placement_window.visible = true
      end
      if Input.trigger?(Input::C)
        x = @cursor.x/32
        y = @cursor.y /32
        Map.draw(@item.z, @z, x, y, @item.x, @item.y, @item.width, @item.height)
        $game_system.se_play($data_system.decision_se)
        $game_party.lose_item(@item.id, 1)
        Map.remove_item(@item) if $game_party.item_number(@item.id) == 0
        item = Map::Item.new(@item.name, @item.id, x, y, @item.width, @item.height, @z+1)
        Map.mapdata.push(item)
        @cursor.bitmap.dispose
        $scene = Scene_Map.new
      end
    elsif @move == true
      @cursor.y += 32 if Input.trigger?(Input::DOWN)
      @cursor.x -= 32 if Input.trigger?(Input::LEFT)
      @cursor.x += 32 if Input.trigger?(Input::RIGHT)
      @cursor.y -= 32 if Input.trigger?(Input::UP)
      if Input.trigger?(Input::L)
        @z = 1
        color = Color.new(0, 255, 0) 
        @cursor.bitmap.fill_rect(0, 0, @item.width * 32, @item.height * 32, color) 
      end
      if Input.trigger?(Input::R)
        @z = 2
        color = Color.new(0, 0, 255) 
        @cursor.bitmap.fill_rect(0, 0, @item.width * 32, @item.height * 32, color) 
      end
      @cursor.update
      if Input.trigger?(Input::C)
        data = nil
        for item in Map.items
          if item.name == @item.name
            data = item
            break
          end  
        end
        x = @cursor.x/32
        y = @cursor.y /32
        Map.draw(data.z, @z, x, y, data.x, data.y, data.width, data.height)
        $game_system.se_play($data_system.decision_se)
        $game_party.lose_item(data.id, 1)
        Map.remove_item(data) if $game_party.item_number(data.id) == 0
        Map.mapdata.delete(@item)
        item = Map::Item.new(data.name, data.id, x, y, data.width, data.height, @z)
        Map.mapdata.push(item)
        @cursor.bitmap.dispose
        $scene = Scene_Map.new
      end
      if Input.trigger?(Input::B)
        @draw = false
        @cursor.bitmap.dispose
        @placement_window.visible = true
      end
    elsif @remove == true
      if Input.trigger?(Input::C)
        @cursor.bitmap.dispose
        $scene = Scene_Map.new
      end
      if Input.trigger?(Input::B)
        @cursor.bitmap.dispose
        $scene = Scene_Map.new
      end
    end
  end
  #--------------------------------------------------------------------------
  def placement
    @placement_window.update
    if Input.trigger?(Input::B)
      @place = false
      @placement_window.dispose
      @command_window.visible = true
    elsif Input.trigger?(Input::C)
      @draw = true
      @placement_window.visible = false
      @item = Map.items[@placement_window.index]
      @cursor.bitmap = Bitmap.new(@item.width * 32, @item.height * 32)
      color = Color.new(0, 255, 0) 
      @cursor.bitmap.fill_rect(0, 0, @item.width * 32, @item.height * 32, color) 
      @z = 1
    end
  end
  #--------------------------------------------------------------------------
  def movement
    @moveement_window.update
    if Input.trigger?(Input::B)
      @move = false
      @moveement_window.dispose
      @command_window.visible = true
    elsif Input.trigger?(Input::C)
      @draw = true
      @moveement_window.visible = false
      @item = Map.mapdata[@moveement_window.index]
      @z = @item.z
      @cursor.bitmap = Bitmap.new(@item.width * 32, @item.height * 32)
      if @z == 1
        color = Color.new(0, 255, 0) 
        @cursor.bitmap.fill_rect(0, 0, @item.width * 32, @item.height * 32, color) 
      elsif @z == 2
        color = Color.new(0, 0, 255) 
        @cursor.bitmap.fill_rect(0, 0, @item.width * 32, @item.height * 32, color) 
      end
      @cursor.x = @item.x*32
      @cursor.y = @item.y*32
      $game_party.gain_item(@item.id, 1)
      x,y = @item.x,@item.y
      @item.width.times do |w|
        @item.height.times do |h|
          $game_map.map.data[x+w, y+h, @z] = 0
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  def removement
    @removeement_window.update
    if Input.trigger?(Input::B)
      @remove = false
      @removeement_window.dispose
      @command_window.visible = true
    elsif Input.trigger?(Input::C)
      @draw = true
      @removeement_window.visible = false
      @item = Map.mapdata[@removeement_window.index]
      @z = @item.z
      @cursor.bitmap = Bitmap.new(@item.width * 32, @item.height * 32)
      color = Color.new(255, 0, 0) 
      @cursor.bitmap.fill_rect(0, 0, @item.width * 32, @item.height * 32, color)  
      @cursor.x = @item.x*32
      @cursor.y = @item.y*32
      $game_party.gain_item(@item.id, 1)
      x,y = @item.x,@item.y
      @item.width.times do |w|
        @item.height.times do |h|
          $game_map.map.data[x+w, y+h, @z] = 0
        end
      end
    end
  end
end

#------------------------------------------------------------------------------
# * End SDK Enable Test
#------------------------------------------------------------------------------
end

I have some basic understanding of reading Ruby, but I haven't worked too long with the RGSS.  Furthermore, Fantastica's script comes with no comments and no documentation; a number of google searches still leave me fruitless.

My question, then, is this: is anyone particularly familiar with the script?  Can anyone help me with its implementation?

Ultimately, I'd like one particular kind of ground (which I imagine I would specify with a type of Terrain) to be 'plowable', changing it into a different kind of tile.  After plowing it, watering and/or planting seeds would further modify the tile into something else.  It seems like the best way to do it in the context of this script would be to specify each type of land as a different 'item,' which is then placed in-map accordingly.  Still, I'm wondering how I can actually keybind the player's use of plow/watering can tools to make these changes occur.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top