Hi, ist schon ein bisschen länger her, dass ich hier im Forum was geposted habe. Gestern kam ich endlich mal wieder zum Scripten und habe mich an einen Code begeben, den ich schon lange (genau gesagt seit meinem Erfolgs-Script, welches ebenfalls hier im Forum zu finden ist) vor habe.
Wer mein Erfolgs-Script kennt, weiß, dass dieses bereits die Möglichkeit besaß, sich selbstständig in ein Menü einzubetten und das Menü auch ein wenig umzugestalten. Allerdings hatte dies noch einige Fehler, beispielsweise, wenn man weniger Elemente im Menü hatte als sechs. Darum und aus ein paar anderen Gründen habe ich nun begonnen, die Möglichkeiten der Menü-Gestaltung in einem neuen Script zu überarbeiten und mit ein paar neuen Möglichkeiten zu veröffentlichen:
Was macht das Script?
Das Script ersetzt lediglich ein paar Methoden der Menü-Szene und bestimmter Klassen, welche darauf zugreifen. Dies ermöglicht eine relativ einfache Umgestaltung des Menüs, ohne nennenswerte Kenntnisse in RGSS2 zu besitzen.
Auf diese Art kann man mit ein paar kleinen Handgriffen neue Befehle ins Menü setzen, ihre Namen ändern, ihnen Icons zuweisen, sie nach Belieben ein- oder ausblenden (per Switches) oder ihre Reihenfolge verändern.
Außerdem habe ich noch die aus Tales-of-Titeln bekannte Gruppenführer-Option hinzugeschaltet, welche es einem erlaubt, die Spielfigur, welche auf der Map herumläuft, frei im Menü auszuwählen (lässt sich auch deaktivieren).
Des Weiteren werden im Menü auf Wunsch auch Spielzeit und Name der Map, auf der man sich gerade befindet, eingeblendet.
Was wird noch kommen?
Die Anordnung der Fenster im Menü soll noch freier gestaltet werden. Außerdem möchte ich noch Optionsmöglichkeiten zum Actor-Screen einbauen. Später soll es noch ein paar Komfortabilitätserweiterungen zur Verwendung von mir erstellter Scripte erhalten und in der Lage sein, auch Common Events als Menü-Befehle einzubauen.
Für weitere Vorschläge, was ich in mein Script einbauen könnte, bin ich natürlich jederzeit offen. ;)
#===============================================================================
# ____ ____ ___________ ____ __ __ __
# | \ / || || \ | || | | |
# | | \ / | || ________|| | \ | || | | |
# | |\ \/ /| || |___ | |\ \ | || | | |
# | | \ / | || ___| | | \ \| || | | |
# | | \__/ | || |________ | | \ | || | | |
# | | | || || | \ | \ \___/ /
# |__| |__||___________||__| \___| \_______/
#
#===============================================================================
#
# MK3 - Phoenix Power Productions Presents: Custom-Menu V 1.0
# Credits: An Michael Funkel
# Letztes Update: Donnerstag, 04.02.2010
# Level: Leicht, Normal
#
# Das Script ermöglicht eine leichte Bearbeitung der Befehle im Menü, darüber
# hinaus gibt es auch zahlreiche Optionen, die das Aussehen verändern können.
# Für die volle Ausschöpfung der Möglichkeiten sind jedoch Grundkenntnisse im
# Verwenden von Parametern von Nöten.
#
#===============================================================================
# Updates:
# ----------------------------------------------------------------------------
# o 04.02.2010 - Beginn und Fertigstellung des Basis-Projekts auf V 1.0
# o 05.02.2010 - Bugfixing und Einbau des Location-Fensters (V 1.11)
#===============================================================================
# Installation und Anleitung
#===============================================================================
#
# Platziere das Script unter Material und über Main.
# Scrolle runter bis zu "module MK3", dort kannst du verschiedene Einstellungen
# treffen. In MENU_LIST kannst du einstellen, welche Befehle im Menü angezeigt
# werden sollen, in MENU_SORT kannst du deren Reihenfolge festlegen (das ist
# ganz wichtig! Was nicht in MENU_SORT drinsteht, wird im Spiel nicht angezeigt).
# Jeder Befehl, der eine Actor-Auswahl erfordert (zum Beispiel Equip), muss auch
# noch einmal extra in CHAR_WAHL angegeben werden, damit anschließend die Actor-
# Auswahl getroffen werden kann.
# Außer, dass nun völlig frei Befehle ins Menü eingebettet werden können (wie ge-
# nau das funktioniert wird ausführlich bei MENU_LIST weiter unten erklärt),
# können nun auch alle Befehle Icons erhalten, auch dies wird in MENU_LIST genau
# beschrieben. Ob und welche Befehle Icons erhalten, kann man mit SHOW_ICONS
# ausschalten.
# Des Weiteren kann man mit dem Befehl SHOW_TIME ein Zeitfenster im Menü einblen-
# den, welches die bisherige Spielzeit in hh:mm:ss darstellt.
# Die Steuerung des Menüs wurde darüber hinaus noch erweitert:
# - Mit Rechts kann man vom Befehlsfenster zum Actor-Screen wechseln
# - Mit Links kann man vom Actor-Screen zum Befehlsfenster wechseln
# - Ist ALLOW_LEADER aktiv, so kann man mit der in LEADER_BUTTON bestimmten Taste
# den Leader bestimmen, solange der Actor-Screen aktiv ist.
# Der Leader ist eine spezielle Neuerung, basierend auf der Gruppenführer-Option
# aus verschiedenen Tales of - Titeln. Es bedeutet nichts anderes als die Figur,
# welche der Spieler auf der Map steuert. Dadurch muss man nun nicht mehr extra
# die Reihenfolge des Teams wechseln, nur um eine andere Figur zu steuern.
# Das Icon, welches den Leader markiert, wird durch LEADER_ICON bestimmt.
# Das Script wird (teils durch Add-Ons) später noch erweitert, Vorschläge für
# neue Optionen werden jederzeit gerne angenommen.
#
#===============================================================================
#
# Kompatibilität
# - Alias: $game_player: initialize
# - Alias: Window_MenuStatus: refresh
# - Alias: Scene_Menu: terminate, update
# - Attribut: Game_Actor: actor_id (reader)
# - Attribut: $game_player: leader(accessor)
# - Attribut: Window_MenuStatus: index(accessor)
# - Erweitert: Scene_Base: get_index_re
# - Erweitert: Scene_Menu: game_time
# - Overwrite: Game_Player: refresh
# - Overwrite: Window_MenuStatus: initialize
# - Overwrite: Scene_Menu: start, update_command_selection, create_command_window,
# update_actor_selection
# - Overwrite: Scene_Item: return_scene
# - Overwrite: Scene_Skill: return_scene
# - Overwrite: Scene_Status: return_scene
# - Overwrite: Scene_File: return_scene
# - Overwrite: Scene_End: return_scene
# - Hinzugefügt: Class: Window_MenuCommand
# - Hinzugefügt: Class: Window_MapName
# - Hinzugefügt: Class: Window_Time
#
#===============================================================================
#
# Freigegeben für jede nicht-kommerzielle Verwendung, bei kommerzieller Verwen-
# dung möchte ich informiert werden.
# Kontakt: rpgvx.net, unter Nick Michael Funkel
# Dieses Script darf nicht auf anderen Websites angeboten werden, als jenen, auf
# denen ich es ausstelle.
#
#===============================================================================
module MK3
module MENU
# In MENU_LIST werden sämtliche Menü-Befehle gehandhabt. Dies funktioniert
# immer nach demselben Schema (sämtliche "" beim Eintippen ignorieren):
# Jeder Befehl wird einer ID zugeordnet und beinhaltet 5 Angaben
# 1. Switch, hiermit wird bestimmt, ob der Befehl nur im Menü angezeigt
# wird, wenn der Switch mit der entsprechenden ID auf "On" steht. Ist
# als ID des Switches "nil" eingetragen, so wird der Befehl immer an-
# gezeigt (vorausgesetzt natürlich, er ist in MENU_SORT enthalten).
# 2. Icon, dieser Wert bestimmt die Icon-ID, welche dem Menü-Befehl voran-
# gestellt werden soll. Ist "nil" eingetragen, so wird für diesen Be-
# fehl kein Icon angezeigt. Um gar keine Icons anzuzeigen, einfach
# SHOW_ICON auf "false" setzen.
# 3. Scene, die Scene, welche aufgerufen werden soll, wenn der Spieler den
# jeweiligen Befehl im Menü anwählt. Hierfür muss man den Namen der je-
# weiligen Class angeben (beispielsweise die class "Scene_Item" für den
# Aufruf des Inventars). Wichtig ist hierbei, dass die "" gesetzt werden
# müssen und man keine "Extras" hinzuschreiben darf (wie zum Beispiel
# ".new" oder "(a,x,v,)"...).
# 4. Name, diese Einträge werden jeweils im Menü angezeigt. Schreibt man
# beispielsweise "Item", so steht im Menü an der jeweiligen Stelle
# "Item", schreibt man hingegen "Inventar", so steht im Menü "Inventar".
# Auch hier müssen die "" gesetzt werden.
# 5. Parameter, der letzte Punkt erfordert ein wenig Programmier-Kenntnisse.
# Manche Scenes benötigen beim Aufruf Parameter, sind keine angegeben,
# so können sie damit nicht arbeiten. Die zu übergebenden Parameter fin-
# det man unter "def initialize(...)" bei der jeweiligen Scene, die "..."
# sind die zu übergebenden Parameter. Steht hinter initialize kein (...),
# so benötigt die Scene auch keine Parameter (und darf noch nicht einmal
# welche bekommen, sonst stürzt es ab). Von den sechs Standard-Befehlen
# des Menüs ist "Save" der einzige, der Parameter benötigt, auch diese
# werden mit "" in die Liste geschrieben, verwendet man keine, so schreibt
# man einfach "nil" (in dem Fall aber ohne "").
MENU_LIST = {
# ID Switch Icon Scene Name Parameter
1 => [nil, 144, "Scene_Item", "Item", nil],
2 => [nil, 133, "Scene_Skill", "Skill", nil],
3 => [nil, 40, "Scene_Equip", "Equip", nil],
4 => [ 1, 137, "Scene_Status", "Status", nil],
5 => [nil, 176, "Scene_File", "Save", "(true, false, false)"],
6 => [nil, 112, "Scene_End", "Shutdown", nil],
}
# In dem Array unter diesem Kommentar werden die Aufrufe in der Reihenfolge
# eingegeben, wie sie im Menü erscheinen sollen. Sie müssen hierbei exakt
# mit den IDs in MENU_LIST übereinstimmen.
MENU_SORT = [1, 3, 2, 4, 5, 6]
# Dieser Schalter bestimmt, ob die bisherige Spielzeit im Menü angezeigt wird.
# Funktioniert nur, wenn "MENU_ACCESS = true".
SHOW_TIME = true
# Dieser Schalter bestimmt, ob der Name der jeweiligen Map im Menü angezeigt
# wird. In "[...]" gesetzte Zeichen werden dabei ignoriert.
SHOW_MAPNAME = true
# Dieser Schalter bestimmt, ob Icons dargestellt werden sollen oder nicht.
SHOW_ICON = true
# In diesem Array müssen alle Scenes stehen, bei welchen man zuvor eine
# Actor-Auswahl im Menü-Status machen möchte. Standardmäßig sind dies 2 für
# Skill, 3 für Equip und 4 für Status.
# Dieses Feature ist noch nicht fertig ausgebaut und unterstützt deshalb nur
# Skill, Equip und Status, die ID muss mit der in MENU_LIST übereinstimmen.
CHAR_WAHL = [2, 3, 4]
# Dieser Schalter erlaubt es, in der Actor-Auswahl den Gruppenführer zu be-
# stimmen. Dies hat keinen anderen Effekt, als dass diese Figur als gesteuerte
# Figur auf der Map herumläuft.
ALLOW_LEADER = true
# Hiermit wird die Taste bestimmt, welche in der Actor-Auswahl gedrückt wer-
# den muss, damit die jeweilige Figur zum Leader ernannt wird.
LEADER_BUTTON = Input::X
# Dies gibt die Icon-ID des Icons an, mit welchem der Leader angezeigt wird.
LEADER_ICON = 26
end
end # Module MK3::MENU
#===============================================================================
# MK3 Phoenix Power Productions übernimmt keinerlei Haftung für sämtliche Schä-
# den, die an Material oder Personen entstehen, wenn die Zeilen unterhalb dieses
# Kommentars verändert werden.
#===============================================================================
$imported = {} if $imported == nil
$imported["MK3_Custom_Menu"] = true
#===============================================================================
#
# * Dies ermöglicht das Auslesen der Actor-ID eines Actors.
#
#===============================================================================
class Game_Actor < Game_Battler
attr_reader :actor_id
end # Game_Actor
#===============================================================================
#
# * Dies erweitert $game_map um das neue Attribut "map".
#
#===============================================================================
class Game_Map
attr_reader :map
end
#===============================================================================
#
# * Dies erweitert $game_player um das Accessor-Attribut "leader"
#
#===============================================================================
class Game_Player < Game_Character
attr_accessor :leader # Ermöglicht die Bestimmung eines Leaders (=> Graphic)
alias mk_custmenu_initialize initialize
def initialize
@leader = 0
mk_custmenu_initialize
end
def refresh
if $game_party.members.size == 0
@character_name = ""
@character_index = 0
else
actor = $game_party.members[@leader]
@character_name = actor.character_name
@character_index = actor.character_index
end
end
end # Game_Player
#===============================================================================
#
# * Dieser Code macht die Darstellung des Actor-Screens im Menü dynamischer. Ist
# allerdings noch nicht fertiggestellt.
# Des Weiteren führt es das Leader-Symbol ein.
#
#===============================================================================
class Window_MenuStatus < Window_Selectable
attr_accessor :index
alias mk_custmenu_refresh refresh
def initialize(x, y)
super(x, y, 544 - x, 416 - y)
refresh
self.active = false
self.index = -1
end
def refresh
mk_custmenu_refresh
leader = $game_player.leader
leader = 0 if leader == nil
draw_icon(MK3::MENU::LEADER_ICON, 180, 96 * leader, true) if MK3::MENU::ALLOW_LEADER
end
end # Window_MenuStatus
#===============================================================================
#
# * Dieser Code führt ein neues Command_Window ein, welches vom Menü genutzt wird.
#
#===============================================================================
class Window_MenuCommand < Window_Selectable
attr_reader :commands
def initialize(width, commands, column_max = 1, row_max = 0, spacing = 32)
if row_max == 0
row_max = (commands.size + column_max - 1) / column_max
end
x = 0
y = 0
super(x, y, width, row_max * WLH + 32, spacing)
@commands = commands
@item_max = commands.size
@column_max = column_max
@spacing = spacing
refresh
self.index = 0
end
def refresh
@from = MK3::MENU::MENU_SORT
self.contents.clear
for i in 0...@item_max
draw_item(i)
end
end
def get_key(index)
MK3::MENU::MENU_LIST.each_value do |val|
if val.include?(@commands[index])
return val[1]
end
end
end
def draw_item(index, enabled = true)
rect = item_rect(index)
rect.x += MK3::MENU::SHOW_ICON ? 25 : 0
rect.width -= 8
self.contents.clear_rect(rect)
self.contents.font.color = normal_color
self.contents.font.color.alpha = enabled ? 255 : 128
self.contents.draw_text(rect, @commands[index])
if MK3::MENU::SHOW_ICON
icon_id = get_key(index)
draw_icon(icon_id, 0, 25 * index, enabled) if icon_id != nil
end
end
end # Window_MenuCommand
#===============================================================================
#
# * Definiert das Zeit-Window.
#
#===============================================================================
class Window_Time < Window_Base
def update(text)
self.create_contents
self.contents.draw_text(0, 0, 128, 24, text, 1)
end
end # Window_Time
#===============================================================================
#
# * Dies führt das neue Map-Name-Window ein.
#
#===============================================================================
class Window_MapName < Window_Base
def initialize(x = 0, y = 244, width = 160, height = 56)
super(x, y, width, height)
refresh
end
def map_name
data = load_data("Data/MapInfos.rvdata")
text = data[$game_map.map_id].name.gsub(/\[.*\]/) { "" }
return text
end
def refresh
self.contents.clear
text = map_name
self.contents.draw_text(0, 0, contents.width, contents.height, text, 1)
end
end # Window_MapName
#===============================================================================
#
# * Dieser Code ermöglicht es jeder Scene, ihren Index im Menü zu bestimmen und
# so den Cursor bei Rückkehr an diese Stelle zu setzen.
#
#===============================================================================
class Scene_Base
def get_menu_index(scene)
liste = []
MK3::MENU::MENU_SORT.each do |id|
name = MK3::MENU::MENU_LIST[id]
if name[0] == nil or $game_switches[name[0]] == true
liste << id
end
end
MK3::MENU::MENU_LIST.each do |key, val|
if val.include?(scene)
x = liste.index(key)
return x
end
end
return 0
end
end # Scene_Base
#===============================================================================
#
# * Dieser Code definiert das Menü neu unter Verwendung der im Modul getroffenen
# Einstellungen.
#
#===============================================================================
class Scene_Menu < Scene_Base
alias mk_custmenu_terminate terminate
alias mk_custmenu_update update
def start
super
create_menu_background
create_command_window
@gold_window = Window_Gold.new(0, 360)
@status_window = Window_MenuStatus.new(MK3::MENU::SHOW_ICON ? 160 : 160, 0)
@status_window.index = 0
@map_window = Window_MapName.new if MK3::MENU::SHOW_MAPNAME
end
def update
mk_custmenu_update
text = game_time
@time_window.update(text)
if Input.trigger?(Input::RIGHT) and @command_window.active
@command_window.active = false
@status_window.active = true
@status_window.index = 0 if @status_window.index < 0
elsif Input.trigger?(Input::LEFT) and @status_window.active
@status_window.active = false
@command_window.active = true
end
end
def terminate
mk_custmenu_terminate
@time_window.dispose if MK3::MENU::SHOW_TIME
@map_window.dispose if MK3::MENU::SHOW_MAPNAME
end
def game_time(modificate = false)
@gametime = Graphics.frame_count / Graphics.frame_rate
hours = @gametime / 3600
minutes = @gametime / 60 % 60
seconds = @gametime % 60
if modificate then
result = sprintf("%d%02d%02d", hours, minutes, seconds)
else
result = sprintf("%d:%02d:%02d", hours, minutes, seconds)
end
return result
end
def create_command_window
if MK3::MENU::SHOW_TIME
@time_window = Window_Time.new(0, 300, 160, 60)
@time_window.contents.clear
@time_window.create_contents
text = game_time
@time_window.contents.draw_text(0, 0, 24, 128, text, 1)
end
@liste = []
@command = []
MK3::MENU::MENU_SORT.each do |id|
name = MK3::MENU::MENU_LIST[id]
if name[0] == nil or $game_switches[name[0]] == true
@command << name[3]
@liste << id
end
end
@command_window = Window_MenuCommand.new(MK3::MENU::SHOW_ICON ? 160 : 160, @command)
@command_window.index = @menu_index
if $game_party.members.size == 0 # If number of party members is 0
@command_window.draw_item(0, false) # Disable item
@command_window.draw_item(1, false) # Disable skill
@command_window.draw_item(2, false) # Disable equipment
@command_window.draw_item(3, false) # Disable status
end
if $game_system.save_disabled # If save is forbidden
@command_window.draw_item(4, false) # Disable save
end
end
def update_command_selection
if Input.trigger?(Input::B)
Sound.play_cancel
$scene = Scene_Map.new
elsif Input.trigger?(Input::C)
Sound.play_decision
aufruf = MK3::MENU::MENU_LIST[@liste[@command_window.index]]
x = get_menu_index(aufruf[2])
if MK3::MENU::CHAR_WAHL.include?(@liste[x])
start_actor_selection
return
end
scene = aufruf[2] + ".new"
scene += aufruf[4] if aufruf[4] != nil
$scene = eval(scene)
end
end
def update_actor_selection
if Input.trigger?(Input::B)
Sound.play_cancel
end_actor_selection
elsif Input.trigger?(Input::C)
$game_party.last_actor_index = @status_window.index
Sound.play_decision
position = @liste[@command_window.index]
from = MK3::MENU::MENU_LIST[position]
if Input.trigger?(Input::C)
case from[2]
when "Scene_Skill" # skill
$scene = Scene_Skill.new(@status_window.index)
when "Scene_Equip" # equipment
$scene = Scene_Equip.new(@status_window.index)
when "Scene_Status" # status
$scene = Scene_Status.new(@status_window.index)
else
scene = from[2] + ".new"
scene += from[4] if from[4] != nil
$scene = eval(scene) if MK3::MENU::CHAR_WAHL.include?(position)
end
end
end
if MK3::MENU::ALLOW_LEADER
if Input.trigger?(MK3::MENU::LEADER_BUTTON)
Sound.play_decision
name = $data_actors[$game_party.members[@status_window.index].actor_id].character_name
index = $data_actors[$game_party.members[@status_window.index].actor_id].character_index
$game_player.set_graphic(name, index)
$game_player.leader = @status_window.index
@status_window.refresh
end
end
end
end # Scene_Menu
#===============================================================================
#
# * Dieser Code ermöglicht die fehlerfreie Rückkehr ins Menü vom Itemscreen.
#
#===============================================================================
class Scene_Item < Scene_Base
def return_scene
x = get_menu_index("Scene_Item")
$scene = Scene_Menu.new(x)
end
end # Scene_Item
#===============================================================================
#
# * Dieser Code ermöglicht die fehlerfreie Rückkehr ins Menü vom Skillscreen.
#
#===============================================================================
class Scene_Skill < Scene_Base
def return_scene
x = get_menu_index("Scene_Skill")
$scene = Scene_Menu.new(x)
end
end # Scene_Skill
#===============================================================================
#
# * Dieser Code ermöglicht die fehlerfreie Rückkehr ins Menü vom Equipscreen.
#
#===============================================================================
class Scene_Equip < Scene_Base
def return_scene
x = get_menu_index("Scene_Equip")
$scene = Scene_Menu.new(x)
end
end # Scene_Equip
#===============================================================================
#
# * Dieser Code ermöglicht die fehlerfreie Rückkehr ins Menü vom Statusscreen.
#
#===============================================================================
class Scene_Status < Scene_Base
def return_scene
x = get_menu_index("Scene_Status")
$scene = Scene_Menu.new(x)
end
end # Scene_Status
#===============================================================================
#
# * Dieser Code ermöglicht die fehlerfreie Rückkehr ins Menü vom Speicherscreen.
#
#===============================================================================
class Scene_File < Scene_Base
def return_scene
if @from_title
$scene = Scene_Title.new
elsif @from_event
$scene = Scene_Map.new
else
x = get_menu_index("Scene_File")
$scene = Scene_Menu.new(x)
end
end
end # Scene_File
#===============================================================================
#
# * Dieser Code ermöglicht die fehlerfreie Rückkehr ins Menü vom Endescreen.
#
#===============================================================================
class Scene_End < Scene_Base
def return_scene
x = get_menu_index("Scene_End")
$scene = Scene_Menu.new(x)
end
end # Scene_End
#===============================End of Script==================================#
Derzeit befinden sich auch noch ein paar weitere Scripte bei mir in der Mache. Sobald alle fertig sind, plane ich, eine Demo rauszubringen, welche allesamt zusammenfasst und ingame vorstellt.
Edit:
Habe ein paar kleine Bugfixes (hauptsächlich bezüglich des Gruppenleaders) vorgenommen. Darum hier das erste Update: Version 1.11 (habe den alten Code dagegen ersetzt).