Tentaculon
Member
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:
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.
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.