Questlog 3.0
~ von Caesar ~
Inhalt
1. Was ist das Questlog?......................................................................................................................3
1.1. Neues in Version 3....................................................................................................................3
2. Verwendung.................................................................................................................................... 4
2.1. Einfügen und Entfernen von Quests......................................................................................... 4
2.1. Parameter................................................................................................................................. 4
2.1.1. INSERT_AT_TOP............................................................................................................4
2.1.2. LINE_HEIGHT.................................................................................................................4
2.1.3. WINDOWSKIN................................................................................................................4
2.1.4. HEADER_TEXT.............................................................................................................. 4
2.1.5. SCROLL_SPEED............................................................................................................. 5
2.1.6. STYLES........................................................................................................................... 5
2.1.7. ON_CLOSE...................................................................................................................... 5
2.2. Tags..........................................................................................................................................5
2.2.1. <br>..................................................................................................................................6
2.2.2. <b>Text</b>..................................................................................................................... 6
2.2.3. <i>Text</i>....................................................................................................................... 6
2.2.4. <u>Text</u>..................................................................................................................... 6
2.2.5. <color=X>Text</color>....................................................................................................6
2.2.6 <size=X>Text</size>.........................................................................................................7
2.2.7. <small>Text</small>........................................................................................................7
2.2.8. <big>Text</big>............................................................................................................... 7
2.2.9. <font=X>Text</font>....................................................................................................... 7
2.2.10. <shadow>Text</shadow>...............................................................................................7
2.2.11. <icon=X>........................................................................................................................ 7
2.2.12. <image=X>..................................................................................................................... 7
2.2.13. <line>............................................................................................................................. 7
2.2.14. <down=X>...................................................................................................................... 7
2.2.15. <space=X>...................................................................................................................... 7
2.2.16. <if=X>Text<else>Anderer Text</if>............................................................................. 7
2.2.17. <var=X>..........................................................................................................................8
2.2.18. <eval={X}>.....................................................................................................................8
2.2.19. <style=X>Text</style>................................................................................................... 8
2.3. Beispiel.................................................................................................................................... 8
3. Einbau..............................................................................................................................................9
1. Was ist das Questlog?
Das Questlog ist ein RGSS (Ruby Game Scripting System) geschriebenes Script für den RPG
Maker XP1. Es erweitert RPGs um die Möglichkeit, Aufgaben des Spielers in einem Buch zu
verwalten.
1.1. Neues in Version 3
Die erste Version war sehr statisch. Optional konnten für den Titel ein Icon und für die Beschreibung ein Bild verwendet werden, ansonsten war keine Formatierung möglich. Version 2.0 behob einige Fehler und erweiterte das Questlog um Formatierungsmöglichkeiten in Form von HTML-ähnlichen Tags. Diese Formatierung war ein Schritt in die richtige Richtung (die Inhalte
dynamisch zu gestalten), sah aber nur Formatierung des Textes vor (Schriftfarbe, Schriftart, kursive und fette Schrift, Schatten, Unterstreichung...). Außerdem war der Platz für die Questbeschreibung
auf 268 × 328 Pixel beschränkt. Die wesentliche Neuerung in Version 3.0 ist die HTML-Rendering- Engine, die den Spielemacher befähigt, selbst komplexe Dokumentstrukturen abzubilden. Die (Pseudo-)HTML-Tags wurden um viele neue erweitert, so dass neben bekannten Textformatierungen auch eingebettete Bilder und Icons, Einrückungen, Absätze, Trennlinien und
dynamisch erzeugter Inhalt möglich sind. Außerdem ist der Platz der Beschreibung nun theoretisch unbegrenzt, denn das rechte Fenster lässt sich nun mit den Tasten Pageup und Pagedown vertikal scrollen. Des weiteren wurden zwei Bugs behoben: (Eventgescriptete) Bilder werden nun nicht
mehr über dem Questlog angezeigt; und wer das Questlog einbaut und einen älteren Spielstand lädt, der das Questlog noch nicht enthält, bekommt keine Fehlermeldung, sondern ein leeres Questlog wird neu erstellt. Auch sind nun viele Eigenschaften des Scripts nicht mehr tief im Code verankert,
sondern als Parameter an zentraler Stelle konfigurierbar.
_________________________________________________________________
1 Der RPG Maker XP ist ein Tool der Firma Enterbrain, das es ermöglicht, eigene Rollenspiele (RPGs) ohne
Programmierkenntnis zu erstellen. Neuerungen:
● HTML-Rendering-Engine
● Unbegrenzte Höhe der Beschreibung durch Scrollen
● Konfiguration per Scriptparameter
Bugfixes:
● Bilder nun unter Questlog
● Beim Laden eines Spielstandes ohne Questlog keine
Fehlermeldung mehr
2. Verwendung
Allgemein wird das Questlog aufgerufen durch Ausführung des folgenden RGSS-Codes:
$scene = Scene_Questlog.new
Dies kann ein einem Call-Script aufgerufen werden, im Menü oder auf Knopfdruck auf der Map. Der Aufruf per Knopfdruck wird unter Einbau beschrieben. Die Möglichkeit, Questtitel per „disable“ auszugrauen, ist in dieser Version entfallen, kann aber bei etwas Mehraufwand mit HTML-Tags umgesetzt werden.
2.1. Einfügen und Entfernen von Quests
Da Bilder und Icons nun über HTML-Tags eingefügt werden können, ist die Möglichkeit, beim Einfügen von Quests ein Icon und ein Bild anzugeben, obsolet. Der Aufruf enthält daher nur noch zwei Parameter: den Titel und die Beschreibung. Bei beiden ist HTML-Formatierung möglich, beim Titel selbstverständlich nur einzeilig. Der Code zum Einfügen neuer Quests sieht daher wie folgt aus:
Questlog.add("Titel", "Beschreibung")
Zum Löschen von Quests wird der Titel benötigt. Er muss genau mit dem übereinstimmen, der beim Einfügen des Quests angegeben wurde, einschließlich der HTML-Tags:
Questlog.remove("Titel")
2.1. Parameter
Ganz oben im Script lassen sich viele Funktionen des Scripts konfigurieren. Im Folgenden beschreibe ich die einzelnen Parameter.
2.1.1. INSERT_AT_TOP
Dieser boolesche Wert (true oder false) bestimmt, ob neu eingefügte Quests im Questlog ganz oben oder ganz unten erscheinen. Wenn der Wert true ist werden, neue Quests oben eingefügt, wenn er false ist, werden sie unten eingefügt.
2.1.2. LINE_HEIGHT
Wie der Name schon sagt, beschreibt dieser Integer-Wert die Zeilenhöhe der Beschreibungen in Pixeln. Je höher dieser Wert ist, desto größer ist der Zeilenabstand.
2.1.3. WINDOWSKIN
In den alten Versionen wurde für das Questlog immer der in der Database eingestellte Standardwindowskin des Spiels verwendet. In der Version 3.0 kann ein alternativer Windowskin festgelegt werden, der das Aussehen des Questlogs bestimmt. Die Variable WINDOWSKIN enthält per Default den Wert nil, d.h. der Standardwindowskin wird verwendet. Wenn ein anderer Windowskin benutzt werden soll, muss die Variable den Namen des importierten) Windowskins als String enthalten.
2.1.4. HEADER_TEXT
In dem kleinen Fenster oben im Questlog-Interface steht normalerweise der Text „Questlog“, aber dies kann mit dieser Variable auch geändert werden.
2.1.5. SCROLL_SPEED
Wie schon oben beschrieben, können Questbeschreibungen eine theoretisch unbegrenzte Höhe haben, da man mit den Tasten Page-Up und Page-Down (Bild rauf und Bild runter) vertikal scrollen kann. Wie schnell gescrollt wird (Default: 7), lässt sich in dieser Variable festlegen. Die Einheit ist
Pixel pro Frame.
2.1.6. STYLES
Ein besonderes Schmankerl der HTML-Rendering-Engine sind die vordefinierten Styles. Angenommen, alle Questbeschreibungen enthalten Überschriften. Man könnte jetzt für jede Überschrift die entsprechenden Tags setzen, fett, unterstrichen, Schriftgröße, Schriftart, Zeilenabstand etc. Will man jetzt aber alle Überschriften um einen Grad größer machen, hat man ganz schön Probleme, denn man muss für jede Überschrift die Tags ändern. Hier kommt das so genannte Semantische Tagging zum Einsatz: Alle Styles werden an zentraler Stelle definiert und die einzelnen Überschriften werden nur anhand ihrer Semantik bezeichnet, d.h. anhand ihrer Funktion im Dokument (z.B. Überschrift). Im Idealfall enthält das Dokument selbst dann gar keine absoluten Formatierungen mehr. Genau das gleiche Prinzip kommt bei der Gestaltung von Webseiten zum Einsatz, wenn die Formatierungen in Cascading Style Sheets (CSS) definiert werden. Die STYLESVariable
entspricht insofern dem Stylesheet. Die Variable ist ein Hash. Die Schlüssel entsprechen den Namen der Styles und die Werte enthalten die Informationen zur Formatierung. An der Stelle des senkrechten Striches (|) wird später der
getaggte Text eingefügt. Beispiel: Ein Style enthält Informationen zur Formatierung von Überschriften. Wir verwenden die Schriftgröße 45, die Schriftart Cambria, stellen den Text fett dar und lassen einen Zeilenabstand von 40 Pixeln zur nächsten Zeile. Der Style sieht demnach wie folgt aus:
<size=45><font=Cambria><b>|</b></font></size><down=40>
Die einzelnen Tags werden unten genauer beschrieben.
2.1.7. ON_CLOSE
Diese Variable enthält einen Process, der aufgerufen wird, sobald das Questlog geschlossen wird. Per Default gelangt man zurück auf die Map („$scene = Scene_Map.new“), aber baut man das Questlog beispielsweise ins Menü ein, möchte man bei Schließen des Questlogs zurück ins Menü.
In diesem Fall kann hier der Proces geändert werden, z.B. zu „$scene = Scene_Menu.new(4)“ (Zahl in Klammern = Index der Questlog-Auswahl).
2.2. Tags
Generell sind die Tags HTML nachempfunden, dennoch sind selbstverständlich nicht alle HTMLTags im Questlog verwendbar und umgekehrt existieren nicht alle Questlog-Tags auch in HTML. Die Tags sind außerdem nicht XML-konform, d.h. es gibt auch Tags die nicht geschlossen werden.
Schande über mein Haupt, aber was soll's ;-) Leider habe ich es nicht hinbekommen, zentrierte und rechtsbündige Ausrichtung zu
implementieren; außerdem ist es zuweilen etwas mühselig, die richtigen Stellen der Zeilenumbrüche herauszufinden, da hilft meist nur Ausprobieren.
Questtitel kann man übrigens mit Formatierungen gut kategorisieren, beispielsweise in Haupt- und Nebenquests. Und die Einbindung von Variablen, der If-Tag und die Code-Evaluation ermöglichen in der Questbeschreibung eine (dynamisch erzeugte) Übersicht über den Fortschritt des Quests, wie
auch auf den Demoscreens zu sehen ist.
Es existieren die folgenden Tags:
● <br>
● <b>Text</b>
● <i>Text</i>
● <u>Text</u>
● <color=X>Text</color>
● <size=X>Text</size>
● <small>Text</small>
● <big>Text</big>
● <font=X>Text</font>
● <shadow>Text</shadow>
● <icon=X>
● <image=X>
● <line>
● <down=X>
● <space=X>
● <if=X>Text<else>Anderer Text</if>
● <var=X>
● <eval={X}>
● <style=X>Text</style>
2.2.1. <br>
Zeilenumbruch
2.2.2. <b>Text</b>
Fetter Text
2.2.3. <i>Text</i>
Kursiver Text
2.2.4. <u>Text</u>
Unterstrichener Text
2.2.5. <color=X>Text</color>
Farbiger Text
Für X muss einer der folgenden Parameter eingesetzt werden:
a) Ein Farbcode in Hexadezimalschreibweise mit vorangestelltem #, z.B. #ffffff = weiß. Die gleichen Farbcodes können in HTML bzw. CSS verwendet werden, daher gibt es im Internet viele Farbtabellen für diese Hexcodes.
b) Ein Farbwort, dabei sind folgende möglich: normal_color (weiß), system_color (blau), disabled_color (grau), crisis_color (gelb), knockout_color (rot), white, black, red, green, blue, yellow, cyan, magenta, light_gray, gray, dark_gray, pink, orange.
c) Ein Message-Farbcode, der auch beim Messagecode \c[X] verwendet wird, also eine Zahl von 0-7.
2.2.6 <size=X>Text</size>
Der Text wird in der angegebenen Schriftgröße dargestellt.
2.2.7. <small>Text</small>
Kleinerer Text
2.2.8. <big>Text</big>
Größerer Text
2.2.9. <font=X>Text</font>
[FONT="Comic Sans MS"]Der Text wird in der angegebenen Schriftart dargestellt.[/FONT]
2.2.10. <shadow>Text</shadow>
Der Text wirft einen Schatten.
2.2.11. <icon=X>
Ein Icon wird (innerhalb der Zeile) gezeichnet. Für X ist der Name des (importierten) Icons einzusetzen.
2.2.12. <image=X>
Ein Bild wird zentriert in einer neuen Zeile gezeichnet. Für X ist der Name des (importierten) Bildes einzusetzen.
2.2.13. <line>
Zeichnet eine Trennlinie, entspricht <hr> aus HTML.
2.2.14. <down=X>
Wie Zeilenumbruch, aber Zeilenabstand ist einstellbar. Für X ist der vertikale Versatz in Pixeln einzusetzen.
2.2.15. <space=X>
Lässt eine (horizontale) Lücke von X Pixeln. Z.B. für Einrückung am Zeilenanfang zu gebrauchen.
2.2.16. <if=X>Text<else>Anderer Text</if>
Schalterabhängiger Text. Für X ist die ID eines Switches einzusetzen. Wenn der Switch an ist, wird „Text“ dargestellt, ansonsten der „Andere Text“.
2.2.17. <var=X>
Wert der Variable mit der ID X.
2.2.18. <eval={X}>
Hiermit kann beliebiger RGSS-Code eingebettet werden, der erst zum Zeitpunkt der Darstellung evaluiert wird. Die Tags <if> und <var> sind im Grunde nur Spezialformen dieser dynamischen Inhaltserzeugung. Mit dem Eval-Tag können so spezielle Variablen wie Heldennamen, Statuswerte und Systemvariablen eingebunden werden.
2.2.19. <style=X>Text</style>
Eines der wichtigsten Tags: das Style-Tag. Wie schon bei den Parametern beschrieben, werden die konkreten Formatierungen idealerweise zentral (bei den Parametern) definiert und die Dokumente semantisch getaggt. Dieses Semantische Tagging geschieht durch den Style-Tag. Für X ist der
Name des Styles einzusetzen, der natürlich im Styles-Parameter definiert sein muss.
2.3. Beispiel
Zur Verdeutlichung zeige ich im Folgenden ein Beispiel mit Code und Screenshot. Das Call Script zum Einfügen des Quests sieht wie folgt aus:
Questlog.add("Fischfang", "Kaufe dir eine Angel, lass dich <br>vom Angler unterweisen und
<br>fange mindestens 10 Fische.<br><image=fish><down=8><space=20><style=system>Bereits gefangen:
</style><var=1>/10<br><space=20><style=system>Ort:
</style>Grindmoore<br><space=20><style=system>Belohnung: </style>100 $")
3. Einbau
Da die HTML-Rendering-Engine prinzipiell auch in anderen Scripts einsetzbar ist, wird sie als ein
Extra-Script in den Script-Editor eingefügt. Der Code:
Code:
#///////////////////////HTML-Rendering-Engine/////////////////////////////////
#~~~~~~~~~~~~~~~~by Caesar~~~~~~~~~~~~~~~~~~~
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
class Bitmap
def draw_shadow_text(x, y, width, height, str, align=0)
color = font.color.dup
font.color = Color.new(192, 192, 192, 156)
draw_text(x+2, y+2, width, height, str, align)
font.color = color
draw_text(x, y, width, height, str, align)
end
#----------------
def draw_html(x, y, width, height, str)
# remember string and font variables
str = str.dup
color = font.color.dup
bold = font.bold
italic = font.italic
size = font.size
name = font.name.dup
#::::::::::
shadow = false
underlined = false
opacity = 255
str.gsub!(/<if=([0-9]+)>(.+?)<else>(.+?)<\/if>/) {$game_switches[$1.to_i] ? $2 : $3}
str.gsub!(/<var=([0-9]+)>/) {$game_variables[$1.to_i].to_s}
str.gsub!(/<eval={(.+?)}>/) {eval $1}
str.gsub!(/<style=([A-Za-z0-9_-]+)>(.+?)<\/style>/) {
STYLES.has_key?($1) ? STYLES[$1].sub("|", $2) : ""
} if defined?(STYLES)
str.gsub!(/<br>/) {"\n"}
str.gsub!(/\\\\/) {"\00"}
str.gsub!(/<b>/) {"\01"}
str.gsub!(/<\/b>/) {"\02"}
str.gsub!(/<i>/) {"\03"}
str.gsub!(/<\/i>/) {"\04"}
str.gsub!(/<color=(#?[0-9a-z_]+)>/) {"\05[#{$1}]"}
str.gsub!(/<\/color>/) {"\06"}
str.gsub!(/<shadow>/) {"\16"}
str.gsub!(/<\/shadow>/) {"\17"}
str.gsub!(/<small>/) {"\20"}
str.gsub!(/<\/small>/) {"\21"}
str.gsub!(/<big>/) {"\23"}
str.gsub!(/<\/big>/) {"\21"}
str.gsub!(/<size=([0-9]+)>/) {"\24[#{$1}]"}
str.gsub!(/<\/size>/) {"\21"}
str.gsub!(/<font=([A-Za-z0-9\s]+)>/) {"\25[#{$1}]"}
str.gsub!(/<\/font>/) {"\26"}
str.gsub!(/<u>/) {"\27"}
str.gsub!(/<\/u>/) {"\30"}
str.gsub!(/<icon=([_A-Za-z0-9-]+)>/) {"\11[#{$1}]"}
str.gsub!(/<image=([_A-Za-z0-9-]+)>/) {"\31[#{$1}]"}
str.gsub!(/<down=([0-9]+)>/) {"\22[#{$1}]"}
str.gsub!(/<space=([0-9]+)>/) {"\100[#{$1}]"}
str.gsub!(/<line>/) {"\07"}
ix = 0
iy = 0
while ((c = str.slice!(/./m)) != nil)
if c == "\00" # \\
c = "\\"
end
if c == "\01" # <b>
font.bold = true
end
if c == "\02" #</b>
font.bold = bold
end
if c == "\03" # <i>
font.italic = true
end
if c == "\04" # </i>
font.italic = false
end
if c == "\05" # <color=xxx>
str.sub!(/\[(#?[0-9a-z_]+)\]/, "")
if $1[0] == 35
col = Color.decode($1)
elsif $1.to_i != 0
col = Window_Base.text_color($1.to_i)
else
col = Color.get($1)
end
font.color = col
end
if c == "\06" # </color>
font.color = color
end
if c == "\16" # <shadow>
shadow = true
end
if c == "\17" # </shadow>
shadow = false
end
if c == "\20" # <small>
font.size -= 5 if font.size > 10
end
if c == "\21" # </small> </big> </size>
font.size = size
end
if c == "\23" # <big>
font.size += 5 if font.size < 92
end
if c == "\24" # <size=xx>
str.sub!(/\[([0-9]+)\]/, "")
newsize = $1.to_i
font.size = newsize if newsize > 5 and newsize < 97
end
if c == "\25" # <font=xxx>
str.sub!(/\[([A-Za-z0-9\s]+)\]/, "")
font.name = $1 if Font.exist?($1)
end
if c == "\26" # </font>
font.name = name
end
if c == "\27" # <u>
underlined = true
end
if c == "\30" # </u>
underlined = false
end
if c == "\11" #<icon=xxx>
str.sub!(/\[([_A-Za-z0-9-]+)\]/, "")
icon = RPG::Cache.icon($1)
blt(ix + 8, iy + LINE_HEIGHT/2 - 12, icon, Rect.new(0, 0, 24, 24))
ix += 24
end
if c == "\31" # <image=xxx>
str.sub!(/\[([_A-Za-z0-9-]+)\]/, "")
image = RPG::Cache.picture($1)
iy += LINE_HEIGHT
blt((width-image.rect.width)/2, iy, image, image.rect)
iy += image.rect.height
ix = 0
end
if c == "\22" # <down=xxx>
str.sub!(/\[([0-9]+)\]/, "")
iy += $1.to_i
ix = 0
end
if c == "\100" # <space=xxx>
str.sub!(/\[([0-9]+)\]/, "")
ix += $1.to_i
c = ""
end
if c == "\07" # <line>
iy += LINE_HEIGHT + 3
fill_rect(16, iy, width-32, 2, font.color)
fill_rect(16, iy, width-32, 2, Color.new(192, 192, 192, 156)) if shadow
iy += 5
ix = 0
end
if c == "\n"
iy += LINE_HEIGHT
ix = 0
end
#:::::::::
if shadow
draw_shadow_text(x+ix+4, y+iy, 40, font.size, c)
else
draw_text(x+ix+4, y+iy, 40, font.size, c)
end
w = text_size(c).width
if underlined
fill_rect(x+ix+4, y+iy+text_size("T").height+3, w, 2, font.color)
end
ix += w
end
#::::::::::
#reset font variables
font.color = color
font.bold = bold
font.italic = italic
font.size = size
font.name = name
#return height of the bitmap
return iy + LINE_HEIGHT
end
end
#==============
class Color
def Color.get(s)
eval "Color.#{s}" rescue Color.white
end
#------------
def Color.decode(hex)
return Color.decode(hex[1..hex.length]) if hex[0] == 35
hex.downcase!
red = hex[0..1].hex
green = hex[2..3].hex
blue = hex[4..5].hex
alpha = hex.length == 8 ? hex[6..7].hex : 255
return Color.new(red, green, blue, alpha)
end
#------------
def Color.normal_color
return Color.new(255, 255, 255, 255)
end
#-----------
def Color.disabled_color
return Color.new(255, 255, 255, 128)
end
#-----------
def Color.system_color
return Color.new(192, 224, 255, 255)
end
#-----------
def Color.crisis_color
return Color.new(255, 255, 64, 255)
end
#-----------
def Color.knockout_color
return Color.new(255, 64, 0)
end
#------------
def Color.white(alpha=255)
return Color.new(255, 255, 255, alpha)
end
#-----------
def Color.black(alpha=255)
return Color.new(0, 0, 0, alpha)
end
#----------
def Color.red(alpha=255)
return Color.new(255, 0, 0, alpha)
end
#----------
def Color.green(alpha=255)
return Color.new(0, 255, 0, alpha)
end
#---------
def Color.blue(alpha=255)
return Color.new(0, 0, 255, alpha)
end
#----------
def Color.yellow(alpha=255)
return Color.new(255, 255, 0, alpha)
end
#----------
def Color.cyan(alpha=255)
return Color.new(0, 255, 255, alpha)
end
#----------
def Color.magenta(alpha=255)
return Color.new(255, 255, 0, alpha)
end
#----------
def Color.light_gray(alpha=255)
return Color.new(192, 192, 192, alpha)
end
#-----------
def Color.gray(alpha=255)
return Color.new(128, 128, 128, alpha)
end
#-----------
def Color.dark_gray(alpha=255)
return Color.new(64, 64, 64, alpha)
end
#-----------
def Color.pink(alpha=255)
return Color.new(255, 175, 175, alpha)
end
#-----------
def Color.orange(alpha=255)
return Color.new(255, 200, 0, alpha)
end
end
#=====================
class Window_Base < Window
# redefine text colors for static context
def self.text_color(n)
case n
when 0
return Color.new(255, 255, 255, 255)
when 1
return Color.new(128, 128, 255, 255)
when 2
return Color.new(255, 128, 128, 255)
when 3
return Color.new(128, 255, 128, 255)
when 4
return Color.new(128, 255, 255, 255)
when 5
return Color.new(255, 128, 255, 255)
when 6
return Color.new(255, 255, 128, 255)
when 7
return Color.new(192, 192, 192, 255)
else
return Color.white
end
end
end
Der Code für das eigentliche Questlog, ebenfalls einzufügen in einem neuen Script über Main:
Code:
#//////////////////////////////////Questlog 3.0/////////////////////////////////
#~~~~~~~~~~~~~~~~~~by Caesar~~~~~~~~~~~~~~~~~
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#===================Parameter==================
# Wenn true, werden neue Quests oben eingefügt, ansonsten unten
INSERT_AT_TOP = true
# Zeilenhöhe in der Questbeschreibung
LINE_HEIGHT = 24
# Windowskin der Questlog-Fenster (nil = default)
WINDOWSKIN = nil
# "Überschrift" des Questlogs
HEADER_TEXT = "Questlog"
# Geschwindigkeit beim Scrollen (Pixel / Frame)
SCROLL_SPEED = 7
# Styles für die Beschreibungen der Quests
STYLES = {
"h1" => "<size=45><font=Cambria><b>|</b></font></size><down=40>",
"h2" => "<big><b><font=Cambria>|</font></b></big><down=32>",
"disabled" => "<color=disabled_color>|</color>",
"highlight" => "<color=#eeee32>|</color>",
"system" => "<color=system_color>|</color>"
}
# Dieser Process wird ausgeführt, sobald das Questlog geschlossen wird;
# (Default: Spieler kommt wieder auf die Map)
ON_CLOSE = Proc.new {$scene = Scene_Map.new}
#============================================
class Scene_Questlog
def main
@window_header = Window_Help.new
@window_header.x = 65
@window_header.y = 28
@window_header.z = 500
@window_header.width = 510
@window_header.windowskin = RPG::Cache.windowskin(WINDOWSKIN) unless
WINDOWSKIN.nil?
@window_header.contents = Bitmap.new(478, 32)
@window_header.contents.font.size = 30
@window_header.contents.draw_text(0, 0, 510, 32, HEADER_TEXT, 1)
@window_titles = Window_Questlog_Titles.new
@window_titles.windowskin = RPG::Cache.windowskin(WINDOWSKIN) unless
WINDOWSKIN.nil?
@window_description = Window_Questlog_Description.new(
$game_system.questlog.quests.map{|q| q.description})
@window_description.windowskin = RPG::Cache.windowskin(WINDOWSKIN) unless
WINDOWSKIN.nil?
@index = @window_titles.index
spriteset = Spriteset_Map.new
Graphics.transition
loop do
Graphics.update
Input.update
update
if $scene != self
break
end
end
Graphics.freeze
@window_header.dispose
@window_titles.dispose
@window_description.dispose
spriteset.dispose
end
#----------------
def update
@window_titles.update
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
ON_CLOSE.call
return
end
if Input.press?(Input::R)
@window_description.scroll_down
elsif Input.press?(Input::L)
@window_description.scroll_up
end
if @index != @window_titles.index
@window_description.index = @index = @window_titles.index
end
end
end
#=============
class Quest
attr_reader :title
attr_reader :description
def initialize(title, description)
@title = title
@description = description
end
end
#============
class Questlog
attr_reader :quests
def initialize
@quests = []
end
#-----------
def add(quest, description="")
return add(Quest.new(quest, description)) unless quest.is_a?(Quest)
i = index(quest.title)
return @quests[i] = quest if i != nil
if INSERT_AT_TOP
# insert quest at top of the list
@quests.unshift(quest)
else
# insert quest at bottom of the list
@quests.push(quest)
end
end
#-----------
def remove(title)
@quests.delete_if{ |quest| quest.title == title}
end
#-----------
def count
return @quests.length
end
#------------
def index(title)
for i in 0..@quests.length-1
return i if @quests[i].title == title
end
return nil
end
#------------
def Questlog.add(title, description="")
$game_system.questlog.add(title, description)
end
#------------
def Questlog.remove(title)
$game_system.questlog.remove(title)
end
end
#=============
class Window_Questlog_Description < Window_Base
attr_reader :index
#------------------
def initialize(descriptions)
super(275, 92, 300, 360)
@descriptions = descriptions
@cache = Array.new(descriptions.size)
self.contents = Bitmap.new(width-32, height-32)
self.index = 0
self.z = 500
end
#-----------
def index=(index)
return if index == @index or @descriptions.empty?
@index = index
self.oy = 0
# bitmaps are only rendered once and than cached to reach more efficiency
if @cache[index].nil?
buffer = Bitmap.new(width-32, 2000)
docheight = buffer.draw_html(0, 0, 270, 2000, @descriptions[index])
@cache[index] = self.contents = Bitmap.new(width-32, docheight)
self.contents.blt(0, 0, buffer, Rect.new(0, 0, self.width-32, docheight))
else
self.contents = @cache[index]
end
end
#-----------
def scroll_down
self.oy += SCROLL_SPEED if self.height + self.oy - 32 < self.contents.height
end
#------------
def scroll_up
self.oy -= SCROLL_SPEED
self.oy = 0 if self.oy < 0
end
end
#=============
class Window_Questlog_Titles < Window_Base
attr_reader :index
def initialize
super(65, 92, 210, 360)
self.z = 500
@item_max = $game_system.questlog.count
self.contents = Bitmap.new(width-32, @item_max > 0 ? @item_max*32 : 32)
@index = 0
refresh
end
#-------------
def index=(index)
@index = index
update_cursor_rect
end
#-------------
def top_row=(row)
if row < 0
row = 0
end
if row > @item_max - 1
row = @item_max - 1
end
self.oy = row * 32
end
#-------------
def page_row_max
return (self.height - 32) / 32
end
#-------------
def page_item_max
return page_row_max * @column_max
end
#-------------
def update_cursor_rect
if @index < 0
self.cursor_rect.empty
return
end
row = @index
top_row = self.oy / 32
if row < top_row
self.top_row = row
end
if row > top_row + (self.page_row_max - 1)
self.top_row = row - (self.page_row_max - 1)
end
self.cursor_rect.set(0, @index * 32 - self.oy, self.width - 32, 32)
end
#-------------
def refresh
self.contents.clear
for i in 0...$game_system.questlog.count
quest = $game_system.questlog.quests[i]
y = i*32
self.contents.draw_html(4, y, 150, 32, quest.title)
end
end
#------------
def update
super
if self.active and @item_max > 0 and @index >= 0
if Input.repeat?(Input::DOWN) and
(Input.trigger?(Input::DOWN) or @index < @item_max - 1)
$game_system.se_play($data_system.cursor_se)
@index = (@index + 1) % @item_max
end
if Input.repeat?(Input::UP) and
(Input.trigger?(Input::UP) or @index > 0)
$game_system.se_play($data_system.cursor_se)
@index = (@index - 1 + @item_max) % @item_max
end
end
update_cursor_rect
end
end
#===========
class Scene_Map
def call_questlog
$game_temp.questlog_calling = false
$game_player.straighten
$scene = Scene_Questlog.new
end
end
#===========
class Game_System
attr_accessor :questlog
alias questlog_init initialize
def initialize
questlog_init
@questlog = Questlog.new
end
end
#===========
class Game_Temp
attr_accessor :questlog_calling
alias questlog_init initialize
def initialize
questlog_init
@questlog_calling = false
end
end
#========================
class Scene_Load < Scene_File
# if a game that does not yet contain the questlog is loaded
# a new (empty) questlog instance is created
alias questlog_read_save_data read_save_data
def read_save_data(file)
questlog_read_save_data(file)
$game_system.questlog = Questlog.new if $game_system.questlog.nil?
end
end
Wenn das Questlog auf der Map per Tastendruck aufrufbar sein soll, müssen im Script Scene_Map
ein paar Zeilen eingefügt werden. Was dies betrifft, hat sich zur alten Questlog-Version nichts
geändert. Wer also schon eine ältere Version des Questlogs eingebaut hat, muss in Scene_Map
nichts mehr ändern. Im folgenden ist beschrieben, wie das Questlog per F5 aufrufbar gemacht wird;
will man eine andere Taste (möglich sind z.B. auch F6-F8) verwenden, funktioniert dies analog zu
F5.
Man suche in Scene_Map die folgenden Zeilen (unter def update):
Code:
unless $game_player.moving?
if $game_temp.battle_calling
call_battle
elsif $game_temp.shop_calling
call_shop
elsif $game_temp.name_calling
call_name
elsif $game_temp.menu_calling
call_menu
elsif $game_temp.save_calling
call_save
elsif $game_temp.debug_calling
call_debug
end
end
Und ändere diesen Code durch Einfügen einiger Zeilen, so dass dann da steht:
Code:
#~~~~~~~~~~~~~
if Input.trigger?(Input::F5) # Questlog
$game_temp.questlog_calling = true
end
#~~~~~~~~~~~~~
unless $game_player.moving?
if $game_temp.battle_calling
call_battle
elsif $game_temp.shop_calling
call_shop
elsif $game_temp.name_calling
call_name
elsif $game_temp.menu_calling
call_menu
elsif $game_temp.save_calling
call_save
elsif $game_temp.debug_calling
call_debug
#~~~~~~~~~~~~
elsif $game_temp.questlog_calling
call_questlog
#~~~~~~~~~~~~
end
end