Implemented GameData::Metadata and GameData::MapMetadata

This commit is contained in:
Maruno17
2020-11-15 18:59:07 +00:00
parent d8476d1fa4
commit 52ffae9e8a
45 changed files with 803 additions and 540 deletions

View File

@@ -166,7 +166,7 @@ def pbDebugMenuCommands(showall=true)
commands.add("main","editorsmenu",_INTL("Information editors..."),
_INTL("Edit information in the PBS files, terrain tags, battle animations, etc."))
commands.add("editorsmenu","setmetadata",_INTL("Edit Metadata"),
_INTL("Edit global and map-specific metadata."))
_INTL("Edit global and map metadata."))
commands.add("editorsmenu","mapconnections",_INTL("Edit Map Connections"),
_INTL("Connect maps using a visual interface. Can also edit map encounters/metadata."))
commands.add("editorsmenu","terraintags",_INTL("Edit Terrain Tags"),
@@ -679,7 +679,7 @@ def pbDebugMenuActions(cmd="",sprites=nil,viewport=nil)
when "setplayer"
limit = 0
for i in 0...8
meta = pbGetMetadata(0,Metadata::PLAYER_A+i)
meta = GameData::Metadata.get_player(i)
if !meta
limit = i; break
end

View File

@@ -553,27 +553,85 @@ end
#===============================================================================
# Metadata editor
#===============================================================================
def pbMetadataScreen(defaultMapId=nil)
metadata = nil
mapinfos = pbLoadRxData("Data/MapInfos")
metadata = pbLoadMetadata
map = defaultMapId ? defaultMapId : 0
def pbMetadataScreen(map_id = 0)
loop do
map = pbListScreen(_INTL("SET METADATA"),MapLister.new(map,true))
break if map<0
mapname = (map==0) ? _INTL("Global Metadata") : mapinfos[map].name
data = []
properties = (map==0) ? MapScreenScene::GLOBALMETADATA : MapScreenScene::LOCALMAPS
for i in 0...properties.length
data.push((metadata[map]) ? metadata[map][i+1] : nil)
end
pbPropertyList(mapname,data,properties)
for i in 0...properties.length
metadata[map] = [] if !metadata[map]
metadata[map][i+1] = data[i]
end
map_id = pbListScreen(_INTL("SET METADATA"), MapLister.new(map_id, true))
break if map_id < 0
pbEditMetadata(map_id)
end
end
def pbEditMetadata(map_id = 0)
mapinfos = pbLoadRxData("Data/MapInfos")
data = []
if map_id == 0 # Global metadata
map_name = _INTL("Global Metadata")
metadata = GameData::Metadata.get
properties = GameData::Metadata.editor_properties
else # Map metadata
map_name = mapinfos[map_id].name
metadata = GameData::MapMetadata.get(map_id)
properties = GameData::MapMetadata.editor_properties
end
properties.each do |property|
data.push(metadata.property_from_string(property[0]))
end
if pbPropertyList(map_name, data, properties, true)
if map_id == 0 # Global metadata
# Construct metadata hash
metadata_hash = {
:id => map_id,
:home => data[0],
:wild_battle_BGM => data[1],
:trainer_battle_BGM => data[2],
:wild_victory_ME => data[3],
:trainer_victory_ME => data[4],
:wild_capture_ME => data[5],
:surf_BGM => data[6],
:bicycle_BGM => data[7],
:player_A => data[8],
:player_B => data[9],
:player_C => data[10],
:player_D => data[11],
:player_E => data[12],
:player_F => data[13],
:player_G => data[14],
:player_H => data[15]
}
# Add metadata's data to records
GameData::Metadata::DATA[map_id] = GameData::Metadata.new(metadata_hash)
GameData::Metadata.save
else # Map metadata
# Construct metadata hash
metadata_hash = {
:id => map_id,
:outdoor_map => data[0],
:announce_location => data[1],
:can_bicycle => data[2],
:always_bicycle => data[3],
:teleport_destination => data[4],
:weather => data[5],
:town_map_position => data[6],
:dive_map_id => data[7],
:dark_map => data[8],
:safari_map => data[9],
:snap_edges => data[10],
:random_dungeon => data[11],
:battle_background => data[12],
:wild_battle_BGM => data[13],
:trainer_battle_BGM => data[14],
:wild_victory_ME => data[15],
:trainer_victory_ME => data[16],
:wild_capture_ME => data[17],
:town_map_size => data[18],
:battle_environment => data[19]
}
# Add metadata's data to records
GameData::MapMetadata::DATA[map_id] = GameData::MapMetadata.new(metadata_hash)
GameData::MapMetadata.save
end
pbSaveMetadata
end
pbSerializeMetadata(metadata,mapinfos) if metadata
end
@@ -638,8 +696,7 @@ def pbItemEditor
itm.type,
itm.move || 0
]
save = pbPropertyList(itm.id.to_s, data, items, true)
if save
if pbPropertyList(itm.id.to_s, data, items, true)
# Construct item hash
item_hash = {
:id_number => itm.id_number,

View File

@@ -184,44 +184,47 @@ end
#===============================================================================
# Save metadata data to PBS file
#===============================================================================
def pbSerializeMetadata(metadata,mapinfos)
save_data(metadata,"Data/metadata.dat")
def pbSaveMetadata
File.open("PBS/metadata.txt","wb") { |f|
f.write(0xEF.chr)
f.write(0xBB.chr)
f.write(0xBF.chr)
f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file."))
f.write("\r\n")
for i in 0...metadata.length
next if !metadata[i]
# Write global metadata
f.write("\#-------------------------------\r\n")
f.write("[000]\r\n")
metadata = GameData::Metadata.get
schema = GameData::Metadata::SCHEMA
keys = schema.keys.sort {|a, b| schema[a][0] <=> schema[b][0] }
for key in keys
record = metadata.property_from_string(key)
next if record.nil?
f.write(sprintf("%s = ", key))
pbWriteCsvRecord(record, f, schema[key])
f.write("\r\n")
end
# Write map metadata
map_infos = pbLoadRxData("Data/MapInfos")
schema = GameData::MapMetadata::SCHEMA
keys = schema.keys.sort {|a, b| schema[a][0] <=> schema[b][0] }
GameData::MapMetadata.each do |map_data|
f.write("\#-------------------------------\r\n")
f.write(sprintf("[%03d]\r\n",i))
if i==0
types = Metadata::SCHEMA
else
if mapinfos && mapinfos[i]
f.write(sprintf("# %s\r\n",mapinfos[i].name))
end
types = MapMetadata::SCHEMA
f.write(sprintf("[%03d]\r\n", map_data.id))
if map_infos && map_infos[map_data.id]
f.write(sprintf("# %s\r\n", map_infos[map_data.id].name))
end
for key in types.keys
schema = types[key]
record = metadata[i][schema[0]]
next if record==nil
f.write(sprintf("%s = ",key))
pbWriteCsvRecord(record,f,schema)
for key in keys
record = map_data.property_from_string(key)
next if record.nil?
f.write(sprintf("%s = ", key))
pbWriteCsvRecord(record, f, schema[key])
f.write("\r\n")
end
end
}
end
def pbSaveMetadata
data = load_data("Data/metadata.dat") rescue nil
return if !data
pbSerializeMetadata(data,pbLoadRxData("Data/MapInfos"))
end
#===============================================================================

View File

@@ -240,83 +240,6 @@ end
# Visual Editor (map connections)
#===============================================================================
class MapScreenScene
GLOBALMETADATA=[
["Home",MapCoordsFacingProperty,
_INTL("Map ID and X and Y coordinates of where the player goes if no Pokémon Center was entered after a loss.")],
["WildBattleBGM",BGMProperty,
_INTL("Default BGM for wild Pokémon battles.")],
["TrainerBattleBGM",BGMProperty,
_INTL("Default BGM for Trainer battles.")],
["WildVictoryME",MEProperty,
_INTL("Default ME played after winning a wild Pokémon battle.")],
["TrainerVictoryME",MEProperty,
_INTL("Default ME played after winning a Trainer battle.")],
["WildCaptureME",MEProperty,
_INTL("Default ME played after catching a Pokémon.")],
["SurfBGM",BGMProperty,
_INTL("BGM played while surfing.")],
["BicycleBGM",BGMProperty,
_INTL("BGM played while on a bicycle.")],
["PlayerA",PlayerProperty,
_INTL("Specifies player A.")],
["PlayerB",PlayerProperty,
_INTL("Specifies player B.")],
["PlayerC",PlayerProperty,
_INTL("Specifies player C.")],
["PlayerD",PlayerProperty,
_INTL("Specifies player D.")],
["PlayerE",PlayerProperty,
_INTL("Specifies player E.")],
["PlayerF",PlayerProperty,
_INTL("Specifies player F.")],
["PlayerG",PlayerProperty,
_INTL("Specifies player G.")],
["PlayerH",PlayerProperty,
_INTL("Specifies player H.")]
]
LOCALMAPS = [
["Outdoor",BooleanProperty,
_INTL("If true, this map is an outdoor map and will be tinted according to time of day.")],
["ShowArea",BooleanProperty,
_INTL("If true, the game will display the map's name upon entry.")],
["Bicycle",BooleanProperty,
_INTL("If true, the bicycle can be used on this map.")],
["BicycleAlways",BooleanProperty,
_INTL("If true, the bicycle will be mounted automatically on this map and cannot be dismounted.")],
["HealingSpot",MapCoordsProperty,
_INTL("Map ID of this Pokémon Center's town, and X and Y coordinates of its entrance within that town.")],
["Weather",WeatherEffectProperty,
_INTL("Weather conditions in effect for this map.")],
["MapPosition",RegionMapCoordsProperty,
_INTL("Identifies the point on the regional map for this map.")],
["DiveMap",MapProperty,
_INTL("Specifies the underwater layer of this map. Use only if this map has deep water.")],
["DarkMap",BooleanProperty,
_INTL("If true, this map is dark and a circle of light appears around the player. Flash can be used to expand the circle.")],
["SafariMap",BooleanProperty,
_INTL("If true, this map is part of the Safari Zone (both indoor and outdoor). Not to be used in the reception desk.")],
["SnapEdges",BooleanProperty,
_INTL("If true, when the player goes near this map's edge, the game doesn't center the player as usual.")],
["Dungeon",BooleanProperty,
_INTL("If true, this map has a randomly generated layout. See the wiki for more information.")],
["BattleBack",StringProperty,
_INTL("PNG files named 'XXX_bg', 'XXX_base0', 'XXX_base1', 'XXX_message' in Battlebacks folder, where XXX is this property's value.")],
["WildBattleBGM",BGMProperty,
_INTL("Default BGM for wild Pokémon battles on this map.")],
["TrainerBattleBGM",BGMProperty,
_INTL("Default BGM for trainer battles on this map.")],
["WildVictoryME",MEProperty,
_INTL("Default ME played after winning a wild Pokémon battle on this map.")],
["TrainerVictoryME",MEProperty,
_INTL("Default ME played after winning a Trainer battle on this map.")],
["WildCaptureME",MEProperty,
_INTL("Default ME played after catching a wild Pokémon on this map.")],
["MapSize",MapSizeProperty,
_INTL("The width of the map in Town Map squares, and a string indicating which squares are part of this map.")],
["Environment",EnvironmentProperty,
_INTL("The default battle environment for battles on this map.")]
]
def getMapSprite(id)
if !@mapsprites[id]
@mapsprites[id]=Sprite.new(@viewport)
@@ -405,7 +328,7 @@ class MapScreenScene
ret.compact!
end
# Returns the maps within _keys_ that are directly connected to this map, _map_.
# Returns the maps within _keys_ that are directly connected to this map, _map_.
def getDirectConnections(keys,map)
thissprite=getMapSprite(map)
thisdims=MapFactoryHelper.getMapDims(map)
@@ -520,7 +443,6 @@ class MapScreenScene
for c in conns
@mapconns.push(c.clone)
end
@metadata=pbLoadMetadata
if $game_map
@currentmap=$game_map.map_id
else
@@ -532,27 +454,10 @@ class MapScreenScene
def setTopSprite(id)
for i in @mapsprites.keys
if i==id
@mapsprites[i].z=1
else
@mapsprites[i].z=0
end
@mapsprites[i].z = (i == id) ? 1 : 0
end
end
def getMetadata(mapid,metadataType)
return @metadata[mapid][metadataType] if @metadata[mapid]
end
def setMetadata(mapid,metadataType,data)
@metadata[mapid]=[] if !@metadata[mapid]
@metadata[mapid][metadataType]=data
end
def serializeMetadata
pbSerializeMetadata(@metadata,@mapinfos)
end
def helpWindow
helptext=_INTL("A: Add map to canvas\r\n")
helptext+=_INTL("DEL: Delete map from canvas\r\n")
@@ -578,19 +483,6 @@ class MapScreenScene
title.dispose
end
def propertyList(map,properties)
infos=load_data("Data/MapInfos.rxdata")
mapname=(map==0) ? _INTL("Global Metadata") : infos[map].name
data=[]
for i in 0...properties.length
data.push(getMetadata(map,i+1))
end
pbPropertyList(mapname,data,properties)
for i in 0...properties.length
setMetadata(map,i+1,data[i])
end
end
def getMapRect(mapid)
sprite=getMapSprite(mapid)
if sprite
@@ -605,16 +497,12 @@ class MapScreenScene
end
end
def onDoubleClick(mapid)
if mapid>=0
propertyList(mapid,LOCALMAPS)
else
propertyList(0,GLOBALMETADATA)
end
def onDoubleClick(map_id)
pbEditMetadata(map_id)
end
def onClick(mapid,x,y)
if @lastclick>0 && Graphics.frame_count-@lastclick<15
if @lastclick>0 && Graphics.frame_count - @lastclick < Graphics.frame_rate * 0.5
onDoubleClick(mapid)
@lastclick=-1
else
@@ -718,7 +606,7 @@ class MapScreenScene
onMouseOver(hitmap,mousepos[0],mousepos[1])
@lasthitmap=hitmap
end
if @oldmousex!=mousepos[0]||@oldmousey!=mousepos[1]
if @oldmousex!=mousepos[0] || @oldmousey!=mousepos[1]
onMouseMove(hitmap,mousepos[0],mousepos[1])
@oldmousex=mousepos[0]
@oldmousey=mousepos[1]
@@ -727,26 +615,22 @@ class MapScreenScene
end
if Input.press?(Input::UP)
for i in @mapsprites
next if !i
i[1].y+=4
i[1].y += 4 if i
end
end
if Input.press?(Input::DOWN)
for i in @mapsprites
next if !i
i[1].y-=4
i[1].y -= 4 if i
end
end
if Input.press?(Input::LEFT)
for i in @mapsprites
next if !i
i[1].x+=4
i[1].x += 4 if i
end
end
if Input.press?(Input::RIGHT)
for i in @mapsprites
next if !i
i[1].x-=4
i[1].x -= 4 if i
end
end
if Input.triggerex?("A"[0])
@@ -791,9 +675,8 @@ class MapScreenScene
if Input.trigger?(Input::B)
if pbConfirmMessage(_INTL("Save changes?"))
serializeConnectionData
serializeMetadata
save_data(@encdata,"Data/encounters.dat")
# TODO: Only need to reload connections, metadata, encounter data.
# TODO: Only need to reload connections and encounter data.
pbClearData
pbSaveEncounterData
end