Verschiedenste Arten ziviler Wasserquellen!
REFMAP-Brunnen01.png REFMAP-Brunnen02.png
Nächtliche Versionen des kleineren Sprudlers und des Schöpfbrunnens sowie vertrocknete Wasserspielorte, etc sind von mir drangedichtet.
~炬燵あ
Verschiedenste Arten ziviler Wasserquellen!
REFMAP-Brunnen01.png REFMAP-Brunnen02.png
Nächtliche Versionen des kleineren Sprudlers und des Schöpfbrunnens sowie vertrocknete Wasserspielorte, etc sind von mir drangedichtet.
~炬燵あ
Möchte anmerken, dass die bisher mitgeschleiften und oben geposteten CharSets um einiges älter sind und mitunter nicht ganz korrekte Farben enthalten können. Ich hab die letzten Tage nun alle offiziellen alten ursprünglichen CharSets und ChipSets von REFMAP/FSM nochmal durchwühlt sowie zerlegt und werde versuchen das was dabei herauskam halbwegs zu sortieren, hin und wieder was auf Basis davon zu basteln oder andere ältere Sachen zu überprüfen / anzupassen / neuzumachen, es liegt noch vieles tief vergraben herum.
Hebel und Schalter kann man nie genug haben!
REFMAP-Switch01.png REFMAP-Switch02.png
~炬燵あ
Simple Keyboard Input
(RPG Maker XP/VX/Ace)
by KotatsuAkira / AkiraKotatsuhime
Einführung
Dieses Script habe ich letztes Jahr infolge einer Anfrage aus einem Spiel, an dem ich hin und wieder bastel, rausgeschnitten und diese Version nun spontan wiedergefunden. Es ermöglicht eine einfache Abfrage der kompletten Tastatur in jeder Version der RGSS-Engine (nicht in Ersatz-Engines), allerdings muss im Fall von RPGXP/VX .force_encoding("ASCII-8BIT") aus Zeile #17 entfernt werden.
Features
Wie beim gewöhnlichen Inputmodul der RGSS-Engine verfügt Keyboard über die Funktionen press?, trigger?, repeat?, dir4 und dir8, die den exakten Zweck ihres jeweiligen Vorbildes erfüllen sollen. Als Parameter bei den drei erstgenannten werden VirtualKey-Nummern anstelle von Input-IDs/Konstanten oder Symbolen verwendet.
Neu hinzu kommen die Funktionen toggle?, caps_lock?, num_lock? und scroll_lock?, die überprüfen, ob sich eine beliebige bzw. eine der drei wirklich dafür sinnvollen Tasten gerade im aktivierten Zustand befindet.
Praktische Anwendung
Die Nutzung geschieht vollständig auf eigene Gefahr und ist für Leute mit Script-Erfahrung gedacht, die eigenen Code schreiben wollen, in dem es zum Einsatz kommen soll. Um das Script anzuwenden, muss, nachdem es oberhalb von Main an einer passenden Position eingefügt wurde, an Codestellen, wo Eingaben in einem Frame-Update eingeholt werden sollen, Keyboard.update aufgerufen werden, der Rest geschieht wie gewohnt.
FAQ
Q: Wer kommt in die Credits dafür?
A: Na ich natürlich. Das Script darf auch jederzeit alleinstehend kostenfrei weitergegeben werden, solange alle Hinweise am oberen Rand des Codeblocks dabei intakt bleiben.
Q: Ist es kompatibel mit (Scripte hier einfügen)?
A: Keine Ahnung, eigentlich sollte es mit allen RPGXP-/-VX-/-Ace-Spielen funktionieren und kein anderes Modul in sich haben, das zufällig auch "Keyboard" heißt. Dann wäre es aber sehr wahrscheinlich, dass dieses oder ein anderes Script redundant ist.
Q: Win32API existiert nicht, was soll ich tun?
A: Wie schon oben klargestellt, funktioniert dieses Script nicht mit einer Ersatz-Engine. Diese sind nämlich für gewöhnlich nicht exklusiv auf Windows ausgerichtet, wovon diese Funktionalität jedoch direkt abhängig ist.
Q: Mein Computer ist explodiert!
A: Das ist nichtmal eine Frage. Und habe ich schon erwähnt, dass Nutzung auf eigene Gefahr geschieht?
Der Code
#==============================================================================
# ** Simple Keyboard Input
#------------------------------------------------------------------------------
# © 2022 KotatsuAkira / AkiraKotatsuhime
# Redistribute only with this copyright notice intact.
#==============================================================================
module Keyboard
#--------------------------------------------------------------------------
# * Module Constants
#--------------------------------------------------------------------------
KeyboardState = Win32API.new('user32', 'GetKeyboardState', 'P', 'L')
#--------------------------------------------------------------------------
# * Module Variables
#--------------------------------------------------------------------------
@@result = nil
@@data = ("\0" * 256).force_encoding("ASCII-8BIT")
@@states = Hash.new {|sh, sk| sh[sk] = 0 }
@@pressed_keys = [false] * 256
@@press_order = []
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def self.update
@@result = KeyboardState.call(@@data)
@@pressed_keys = (0..255).select do |sk|
(@@states[sk] = @@data[sk].ord >= 128 ? @@states[sk] + 1 : 0).nonzero?
end
@@states.each_key {|sk| @@states[sk] -= 6 if @@states[sk] >= 30 }
@@pressed_keys.each {|sk| @@press_order.push_once(sk) }
@@states.each {|sk, sv| @@press_order.delete(sk) unless sv }
end
#--------------------------------------------------------------------------
# * Check if Key is pressed down
#--------------------------------------------------------------------------
def self.press?(si)
return @@states[si] > 0
end
#--------------------------------------------------------------------------
# * Check if Keypress started right now
#--------------------------------------------------------------------------
def self.trigger?(si)
return @@states[si] == 1
end
#--------------------------------------------------------------------------
# * Check if Keypress has interval
#--------------------------------------------------------------------------
def self.repeat?(si)
st = @@states[si]
return st == 1 || st > 23 && st % 6 == 0
end
#--------------------------------------------------------------------------
# * Check if toggleable Key is active
#--------------------------------------------------------------------------
def self.toggle?(si)
return @@data[si].ord & 1 == 1
end
#--------------------------------------------------------------------------
# * Check if CapsLock is active
#--------------------------------------------------------------------------
def self.caps_lock?
return toggle?(0x14)
end
#--------------------------------------------------------------------------
# * Check if NumLock is active
#--------------------------------------------------------------------------
def self.num_lock?
return toggle?(0x90)
end
#--------------------------------------------------------------------------
# * Check if ScrollLock is active
#--------------------------------------------------------------------------
def self.scroll_lock?
return toggle?(0x91)
end
#--------------------------------------------------------------------------
# * Get even direction Keypress
#--------------------------------------------------------------------------
def self.dir4(su=0x26, sd=0x28, sl=0x25, sr=0x27)
s1 = @@press_order.index(su) || -1
s2 = @@press_order.index(sd) || -1
s3 = @@press_order.index(sl) || -1
s4 = @@press_order.index(sr) || -1
return 8 if s1 > s2 && s1 > s3 && s1 > s4
return 2 if s2 > s1 && s2 > s3 && s2 > s4
return 4 if s3 > s1 && s3 > s2 && s3 > s4
return 6 if s4 > s1 && s4 > s2 && s4 > s3
return 5
end
#--------------------------------------------------------------------------
# * Get even or diagonal direction Keypress
#--------------------------------------------------------------------------
def self.dir8(su=0x26, sd=0x28, sl=0x25, sr=0x27)
s1 = @@press_order.index(su) || -1
s2 = @@press_order.index(sd) || -1
s3 = @@press_order.index(sl) || -1
s4 = @@press_order.index(sr) || -1
if s1 > s2
return s3 > s4 ? 7 : s4 > s3 ? 9 : 8
elsif s2 > s1
return s3 > s4 ? 1 : s4 > s3 ? 3 : 2
else
return s3 > s4 ? 4 : s4 > s3 ? 6 : 5
end
return 5
end
#--------------------------------------------------------------------------
# * Inspect Object
#--------------------------------------------------------------------------
def self.inspect
return "#<Keyboard {#{@@pressed_keys.join(',')}}>"
end
end
Alles anzeigen
~炬燵あ
EasyRTP-Werkstatt 200X+
Holerö!~
Dieser Thread soll fortan als Experiment herhalten, eine alte Tradition aus einem anderen Forum, die für eine beachtlich lange Zeit wirklich gut funktionierte, hierher zu übertragen, auch wenn ich dem noch nicht die allergrößten Chancen beimesse. Kurzum geht es darum, einen gemeinschaftlichen Ort zu schaffen, an dem alle, die möchten, an neuen Grafiken aller Art unter der Vorgabe eines etablierten Stils basteln, diese anschließend hier unterbringen und bestenfalls auch für andere in die freie Wildbahn zur Weiternutzung entlassen.
Wie ist der Plan und wer macht mit?
Um den Einstieg nicht zu schwierig zu machen, fällt auch, besonders wenn es um Charakter-Laufgrafiken sowie Objekte und Tiles geht, die Wahl auf einen Stil, der nicht zu komplex daherkommt, selbstverfreilich rede ich von... nein, diesmal nicht vom RPG-Maker-2000-RTP, sondern vom Ersatz für ebenjenes (und für das von RPG2003), das zu EasyRPG gehört.
Möchte behaupten, alle, die auch nur ein paar Pixel präzise mit Geduld setzen können, können sich da reinfinden. Ob gerade erst angefangen oder schon lange gemeistert, jedes Level an Können ist willkommen!
Warum überhaupt ein RTP-Ersatz?
Jedes offizielle RTP unterliegt strengen Lizenzbeschränkungen, auch mit der Redistribution dieser Inhalte sieht es sehr kompliziert aus. Da EasyRPG anstrebt, die komplette RPG_RT-Engine vom RPG Maker 2000/2003 nachzubilden und damit Spiele auf vielen Plattformen zur Verfügung zu stellen, sind viele Inhalte, die damit wiedergegeben werden wollen, an ein solches RTP gebunden, an das man häufig erstmal separat gelangen muss.
Mit einem eigenen Paket an unter CreativeCommons-Lizenzen herausgegebenen Materialien, das inhaltlich genau darauf abgestimmt ist, kann sich EasyRPG langfristig von jeglichen Beschränkungen des Herstellers der Vorlage unabhängig machen.
Gibt es sonstige Dinge zu beachten?
Nichts weiter als eine kleine Hausregel, um gewisse Prozesse zu vereinfachen. Wenn ihr Grafiken erstellt und sie hier reinpostet, werden sie, sofern ihr es nicht anders angebt, zur korrekt creditierten, kostenfreien Weiternutzung, bspw. (aber nicht nur) in Spielen oder auf Webseiten, freigegeben. Oder kurz: Standardmäßig CC-BY, gerne auch CC0. Ihr könnt auch einfach so posten, woran ihr passend zum Stil arbeitet und weitere Verwertung verbieten, das würde jedoch den Sinn dieses Threads verfehlen.
Da der RTP-Ersatz selbst gegenwärtig noch lange nicht fertiggestellt ist, könnt ihr natürlich auch zur Stilfindung und Komplettierung in einigen Bereichen beitragen oder den Charakterbauteile-Pool für EasyChar (unten verlinkt) erweitern. Auch das Zusammenstecken vorhandener Tiles zu brauchbaren ChipSets oder Teilen von thematisch passenden Screenshots (bzw. Maps) sind gern gesehen.
Bitte nur reine PNGs in einfacher, nicht hochskalierter Größe posten und nach Möglichkeit direkt die Anhangsfunktion verwenden.
Was brauche ich um loszulegen?
Ein einfaches Grafikprogramm, das dich mit Pixelgrafiken hantieren lässt, ein bisschen gutlaunige Motivation, die ein oder andere lustige Idee und natürlich die Basisgrafiken, nach deren Vorbildern hier alles entstehen soll. Anbei hier also eine (sicher noch ausbaufähige) Liste an Anlaufstellen zur Beschaffung von Ausgangsmaterialien und sonstigen wichtigen oder hilfreichen Links.
Das allgemeine EasyRPG-RTP-Repo: https://github.com/EasyRPG/RTP
Basis-ChipSets von finalbossblues [CC0]: https://finalbossblues.itch.io/openrtp-tiles
EasyAdditions TileSheet#0000 [CC0]: https://kotatsuakira.itch.io/easyadd-tilesheet0000
Charakterbaukasten EasyChar: https://jetrotal.github.io/EasyChar/
~炬燵あ
Achtung!: Die nachfolgenden Dateien sind archivierte Überbleibsel aus älteren Großprojekten sowie REFMAP-Threads und enthalten möglicherweise Material unbekannten Ursprungs, das nicht genutzt werden sollte. Bitte nutzt stattdessen Sets aus dem Deko-Projekt!
Lagerungsgeschmeiß! In leerer Form sowie mit Zwiebeln!
REFMAP-Lagerung0001-Leer.png REFMAP-Lagerung0001-Zwiebel1.png REFMAP-Lagerung0001-Zwiebel2.png
Marmeladengebäck oder so ähnlich!
REFMAP-Marmeladengebaeck01.png
Jede Menge Fusel! Gift ohne Ende!
Formbearbeitete Banner zum Aufhängen!
Kleinigkeiten die jede Küche so braucht!
Und jetzt ist es Zeit für ein großes Festmahl!
REFMAP-Serviervorschlag01.png REFMAP-Serviervorschlag02.png
~炬燵あ
Achtung!: Die nachfolgenden Dateien sind archivierte Überbleibsel aus älteren Großprojekten sowie REFMAP-Threads und enthalten möglicherweise Material unbekannten Ursprungs, das nicht genutzt werden sollte. Bitte nutzt stattdessen Sets aus dem Deko-Projekt!
Alles voller Fisch!
REFMAP-Fisch0001.png REFMAP-Fisch0002.png REFMAP-Fisch0003.png
Käse, Fleisch und Brot!
REFMAP-Kaese0001.png REFMAP-Fleisch0001.png REFMAP-Brot0001.png
Bunte Pilze! Vorsicht, möglicherweise berauschend!
REFMAP-Kinoko01.png REFMAP-Kinoko02.png
~炬燵あ
Holerö!~
Damals vor mittlerweile ~10 Jahren arbeiteten diverse Leute, darunter auch Koshi und ich, an einer Vielzahl von CharSets für den RPG Maker 2000/2003, die zusätzliche praktische sowie dekorative Objekte für allerlei Umgebungen, Räumlichkeiten und Situationen auf Maps im Stil von REFMAP / First Seed Material bereitstellen sollten. Vieles davon lagert noch immer irgendwo tief vergraben und wartet darauf, ordentlich angeordnet und herausgebracht zu werden.
Dieser Thread soll nun dazu dienlich sein, all das und noch mehr, auch Sachen von euch, zusammenzutragen, zur (soweit das möglich ist) Übersicht und kostenfreien Weiterverwertung innerhalb der REFMAP-RPG2000-Lizenzbedingungen, auf dass die Maps noch mehr vor Lebendigkeit nur so sprießen mögen als jemals zu vor.
Und aufgepasst, die ersten kleinen Grafikschübe werden auch gleich im Anschluss folgen! °▽°
Das große Deko-Projekt!
Alle CharSets, die ich hier seit dem 8. Mai 2023 im Rahmen des palettenreinen Dekorations-Projektes REFMAP Extended poste, werden auch (mit abweichenden Dateinamen) auf der extra dafür eingerichteten Seite auf MakerDev Library mit weiteren Daten und Infos sowie einem Aktivitätenlog untergebracht. Lest die Seite hinter dem nachfolgenden Link unbedingt sorgfältig, sie beinhaltet auch sämtliche Quellen, die anständig mit Credits versehen werden müssen, solltet ihr etwas von diesen Sachen zu verwenden gedenken.
★ dev.makerpendium.de/materials/projects/refmap-extended
~炬燵あ
Holerö!~
Der nachfolgende Text ist eine Archivierung eines Threads, den ich ursprünglich am 30. März 2020 im alten MVde-Forum erstellt habe. Leider habe ich seitdem aber auch keine neuen Bilder dieser Art mehr erstellt.
Ich verspüre gerade die spontane Laune, hier einfach mal eine Serie an Bildern vorzustellen, die ich derzeit in superschwankenden Zeitabständen ab und an um einen neuen Eintrag erweitere, wann immer mir etwas Passendes einfällt.
"MöhrchenDice", Erklärung zum Namen im Spoilerblock zum ersten Bild, ist eine Ansammlung von besonders tollen Wörtern, die auf eine unerwartete Art bebildert, falsch geschrieben, falsch ausgesprochen, falsch verstanden oder tatsächlich echt sind und einfach so mit irgendeinem Gag verbunden werden.
Die Gelegenheiten für neue Bilder sind leider rar gesät, aber dafür mit der feinsten Auslese meiner humoristischen Vorlieben für stumpfe und besonders schlechte Gags ausgewählt. Und glaubt mir, einigen Menschen tun solche flachen Witze aktiv weh, ihr seid hiermit gewarnt.
Hiermit fing alles an. Ich schaute am 13. April 2019 nichtsahnend ein Video (fragt nicht, welches, so genau weiß ich das nicht mehr), in dem das Wort "Merchandise" entweder sehr komisch ausgesprochen wurde oder ich mich so richtig verhört habe, wahrscheinlich ein bisschen was von beidem. Was dann anschließend daraus entsprang, könnt ihr hier betrachten.
Ich habe vor Anlegen dieses Threads jenes Bild selber gar nicht als Teil von MöhrchenDice wahrgenommen, ich werde es aber trotzdem hier mit aufnehmen. Das Wort dieses Bildes basiert auf einen wirklich amüsanten Schreibfehler in einem steinalten RPG-Maker-Spiel (das auch allgemein nicht besonders gut ist), wenn ich nur gerade wüsste, welches. Dafür erinnere ich mich an die passende Umschreibung eines Streamers umso besser: "Das ist, wenn man so hart auf die Entfernen-Taste drückt, dass sie anfängt zu brennen!".
Weiter ging es mit einem altbekannten Problem, das man beim Schreiben so einiger Wörter öfters mal haben kann. Doppelt aufeinanderfolgende Buchstabenketten, wie bspw. in diesem Fall "PF-PF". Lässt man einen Teil davon weg, dann... wird's interessant. Ich präsentiere: Die Topf-Lanze! Vergesst Waffenläden und Schmieden, jetzt gibt es Zengarten-RPG-Ausrüstung zum Selbstzüchten. Nur echt mit Sonne in der Ecke.
Wie ich hierauf gekommen bin, weiß ich irgendwie gar nicht mehr. Aber Pyramüde hat bestimmt irgendwas damit zu tun, dass mancheiner das Y gern mal näher am Ü ausspricht, als gesund wäre. Und ne Mütze voll Schlaf gibt's gleich obendrauf. Schaut nur, sie träumt von lauter ZZZ2weien.
Das hier ist das Bild, für das ich bisher am finstersten angeguckt wurde. Selbst für meine Verhältnisse war ein gezinkter Würfel mit den chemischen Daten für Zink einfach nicht lustig, aber vielleicht gefällt's ja doch wem... hm, nicht? Naja, egal.
Der "Zweiffel"-Part im nachdenklichen "Zweiffelturm" ist kein Fehler, sondern kommt selbstverfreilich vom Eiffelturm. Ich habe zu jener Zeit extra nochmal nachgeschaut, wie der nun eigentlich geschrieben wird. Kurz nach dem Bild lieferte man mir mit "Verzweiffelturm" eine noch bessere Wortvariation, die ich jedoch nicht auch noch extra bebildert habe.
Am gestrigen Tage, ausgehend von der Erstellung dieses Threads, schaute ich abermals ein Video und stieß dabei auf eine unübliche Dativ-Form von "Gesetzbuch". Diese Vorlage war einfach viel zu gut, um sie ungenutzt zu lassen. Und da ist sie, die Gesetzbuche! Eigentlich hatte ich auch noch vor, §§Paragraphen§§ als Fruchtäquivalent an den Baum zu hängen, aber als mir das wieder einfiel, war bereits alles aufgeräumt und das Bild auch schon auf Twitter.
~炬燵あ
Holerö!~
In diesem Thread sammel ich von mir erstellte oder zumindest stark umgebaute IPS-Patches für RPG_RT.exe vom RPG Maker 2000 und 2003 (anwendbar mit Programmen wie bspw. Lunar IPS oder ipsXP), abseits von diesen gibt es noch einen ganzen Haufen mehr, ich empfehle einen Besuch in unserer Kategorie dafür auf Makerpendium oder unsere Patch-Sourcecode-Datenbank auf MakerDev Library.
Bedenkt beim Anwenden bitte stets, dass es keinerlei offizielle Regelungen für Modifikationsvorgänge an RPG_RT.exe außerhalb von 2003-1.10 bis 2003-1.12 gibt und ihr besonders dann damit in unklaren Gewässern fischt, falls es an eine kommerzielle Vermarktung eures Spiels geht. Möglicherweise auftretende Komplikationen in solchen Fällen müsst ihr alleine klären.
AccordVorbisPlayer
Ermöglicht in Version 2000-1.62 das Abspielen von OGG Vorbis anstelle von MP3. Die Funktionsweise setzt "accord.dll" von Maniac Patch für 2003-1.12 (getestet mit mp210414) voraus. BGM muss beim Basteln entweder temporär umbenannt oder der RPG Maker modifiziert werden, um OGG-Dateien auszuwählen. Probehören ist nicht möglich.
Verfügbar für
Encounter Randomness Alert
Aktiviert Switch #1018, sobald ein Zufallskampf starten würde und speichert die ID der ausgewählten Gegnergruppe in Variable #3355. Der Kampf selbst wird jedoch nicht mehr ausgelöst. Die MEPR-Version ermöglicht das Abfragen dieser Änderungen über Eventseiten, die normale Version führt an dieser Stelle nicht den üblichen Seitencheck durch (für CEs nicht benötigt).
Verfügbar für
EXtraFONT 96
Erweitert die Funktionalität der ExFont so, dass sie 96 (in früheren Experimenten 64 und 80) statt 52 Zeichen verwendet. Dabei werden aus Zeichensatz-technischen Gründen jedoch die Kleinbuchstaben herausgestrichen.
Standard:
$A | $B | $C | $D | $E | $F | $G | $H | $I | $J | $K | $L | $M |
$N | $O | $P | $Q | $R | $S | $T | $U | $V | $W | $X | $Y | $Z |
$a | $b | $c | $d | $e | $f | $g | $h | $i | $j | $k | $l | $m |
$n | $o | $p | $q | $r | $s | $t | $u | $v | $w | $x | $y | $z |
Erweitert:
$+ | $, | $- | $. | $/ | $0 | $1 | $2 | $3 | $4 | $5 | $6 | $7 | $8 | $9 | $: | $; | $< | $= | $> | $? | $@ | $A | $B |
$C | $D | $E | $F | $G | $H | $I | $J | $K | $L | $M | $N | $O | $P | $Q | $R | $S | $T | $U | $V | $W | $X | $Y | $Z |
$° | $± | $² | $³ | $´ | $µ | $¶ | $· | $¸ | $¹ | $º | $» | $¼ | $½ | $¾ | $¿ | $À | $Á | $Â | $Ã | $Ä | $Å | $Æ | $Ç |
$È | $É | $Ê | $Ë | $Ì | $Í | $Î | $Ï | $Ð | $Ñ | $Ò | $Ó | $Ô | $Õ | $Ö | $× | $Ø | $Ù | $Ú | $Û | $Ü | $Ý | $Þ | $ß |
Verfügbar für
FaceZeromizer
Zeigt bei allen Face-Grafiken jederzeit auch die Farbe auf Index 0 an, statt sie wegzulassen. Sorgt jedoch im Standard-Dateimenü auch dafür, dass alle freien Party-Slots durch schwarze Quadrate repräsentiert werden.
Verfügbar für
FlexibleWalker EX+α & BushPointer
Ersetzt die komplette Darstellungsfunktion für Charakter-Laufgrafiken auf der Map und berechnet deren jeweilige Größe aus den Abmessungen der geladenen Datei anstelle der festgeschriebenen Norm von 24×32 aus 288×256. Der Zusatzpatch BushPointer (FWEX wird voraussetzt) verändert die Sichtbarkeit von Eventoiden auf Terrains mit Busch-Eigenschaft. Beginnend mit Variable #1001 wird für Terrains ab #0001 festgelegt, wieviele Pixelzeilen (von unten gesehen) davon betroffen sind, ab Variable #2001, wie hoch die Sichtbarkeit dieser ist (0 bis 255, Standard: 128). Die Buscheigenschaft auf Maximum zu drehen, ignoriert die Variablen.
Verfügbar für
Game Over Teleport FTE
Teleportiert die Spielerfigur bei GameOver auf eine Position, die in den Variablen #3356 (Map), #3357 (X) und #3358 (Y) hinterlegt werden muss. Ist das Ziel ungültig, wird das Spiel crashen. Dieser Patch ist eine umfassende Abwandlung des ursprünglich von Cherry erstellten GOTP, der nur ein fest in den Code eingebranntes Ziel ansteuern konnte.
Verfügbar für
GameWindowSuperScale
Entfernt den Vollbildmodus aus der Engine, startet immer in (maximal) doppelt skalierter Auflösung und lässt per F5 (kleiner) und F6 (größer) die Skalierung auf das bis zu Achtfache schalten, falls das primäre Anzeigegerät genug Raum dafür bietet.
Verfügbar für
Keyboard Observator
Sobald im laufenden Spiel Variable #4256 oder höher mindestens einmal mit etwas beschrieben wurde, wird auf dem Mapbildschirm in jedem Frame ein komplettes Abbild der momentanen Tastatureingaben in den Variablen #4001 bis #4256 gespeichert, die Tasten entsprechen dem VirtualKey-Standard. Werte variieren zwischen 0 (nichts), 1 (aktiviert), 128 (wird gedrückt) und 129 (aktiviert und wird gedrückt), die Aktiviert-Zustände sind hauptsächlich für NumLock, CapsLock und ScrollLock relevant. Nicht gleichzeitig mit ExtendedKeyInput verwenden!
Verfügbar für
MenuReversed
Kehrt die Darstellung des Standardmenü-Hauptbildschirms horizontal um. Das bedeutet, die Auswahl und das Geldfenster wandern auf die rechte Seite. Enthält auch Patchdateien, die dies wieder rückgängig machen.
Verfügbar für
ModernEndScreen & RemoveQuitQuestion
MES ändert den Beenden-Frage-Screen im Standardmenü so ab, dass sie aussieht wie bei RPGXP/VX/Ace, damit man das Spiel auch von dort aus komplett schließen kann. Der Text des Shutdown-Befehls ist der gleiche wie auf dem Titelbildschirm. Falls RQQ-MES anschließend angewendet wird, wird das in erwähnten Versionen nicht vorhandene Fragefenster entfernt und der Text für Shutdown kann stattdessen im nun freigewordenen Frage-Vocabslot individualisiert werden. Das alleinstehende RQQ hingegen entfernt ausschließlich das Fragefenster, MES darf dazu allerdings nicht angewendet worden sein.
Verfügbar für
Party Knockout Alert
Verhindert ein GameOver, wenn die HP der gesamten Heldengruppe auf 0 fallen sollten und aktiviert stattdessen Switch #999. Die MEPR-Version ermöglicht das Abfragen dieser Änderung über Eventseiten, die normale Version führt an dieser Stelle nicht den üblichen Seitencheck durch (für CEs nicht benötigt). Nicht gleichzeitig mit KillSwitch verwenden!
Verfügbar für
RemoveAutoBattle
Entfernt die Option zum automatischen Bestreiten der nächsten Kampfrunde (RPG2000), bzw. des gesamten Kampfes bis zur manuellen Unterbrechung (RPG2003) aus dem Partybefehlsfenster des Standardkampfsystems.
Verfügbar für
Screen32
Verändert die Darstellung des Spielbildschirms von 16 auf 32bit und erhöht somit die Qualität von Farben, Verläufen und Animationen. Die vorgenommenen Änderungen sind extrem umfangreich, bei einigen anderen Patches muss darauf geachtet werden, diese erst danach und auch manchmal in einer speziell dafür angepassten Version anzuwenden, da es sonst zu Fehlern oder Crashes kommen kann.
Basiert auf einer Funktion im DestinyPatcher von Bananen-Joe für 2000-1.07, auch in ähnlicher Form von bugmenot für 2003-1.08 an anderer Stelle zu haben.
Verfügbar für
ShoppingShortcut
Ersetzt den Eventbefehl zum Öffnen des Standard-Shopbildschirms durch das Verändern diverser Switches und Variablen, um die im Befehl zuvor angegebenen Daten sowie das zusammengeklickte Sortiment anschließend in bspw. einem gecallten CommonEvent, das einen eigenen Shopbildschirm aufbaut und verwaltet, bequem nutzen zu können.
Verfügbar für
TextWidthEight
Verändert die Breite von Textzeichen, die auf dem Spielbildschirm dargestellt werden, was allerdings auch dazu führt, dass so ziemlich jeder Standard-Menübildschirm der Engine (einschließlich F9-Debug) sehr kaputt aussehen wird. Normale Zeichen werden von 6 auf 8px, breite Zeichen sowie EXFONT von 12 auf 16px und halbe Leerzeichen ( \_ ) von 3 auf 4px erweitert, die Höhe aller Textelemente wird bei 12 belassen. Um die EXFONT nachher noch richtig zu verwenden, sollte die in der EXE eingebaute Grafik für selbige durch ein Bild mit 208 statt 156px Breite ersetzt werden, außerdem ist für den vollen Genuss ein Wechsel der Fonts bzw Font-Referenzen notwendig.
Um den Patch zusammen mit EXtraFONT zu nutzen, muss die extra dafür angelegte XF96-Version angewendet werden.
Verfügbar für
TrickySoundPool
Erweitert über diverse Umleitungen die Vielzahl an von Standardsystemen nutzbaren Soundeffekten, die dann näher an RPGXP/VX/Ace dran sind. Dafür müssen jedoch diverse Sounds über den entsprechenden Eventbefehl sehr häufig bei laufendem Spiel ausgetauscht werden, um passend zu klingen, da sich die Menge an vorhandenen Slots nicht erhöht, sondern einige mehrere Zwecke erfüllen müssen.
Verfügbar für
VarTimerPos
Platziert den Timer auf den Koordinaten, die in den Variablen #3401 (X) und #3402 (Y) im Falle der Map, bzw. in #3403 (X) und #3404 (Y) beim Standardkampfsystem stehen. Bei RPG2003 gilt dies auch für den zweiten Timer von Variable #3405 bis #3408. Auf diese Weise kann ein Timer sich beliebig bewegen, sich an einem Event festklammern, wild durch die Gegend springen, Tennis spielen oder einfach nur vibrieren, die Möglichkeiten sind vielzählig.
Verfügbar für
~炬燵あ
Holerö!~
Mir gefallen solche Threads immer sehr, so auch der im alten MVde-Forum, der am 21. Februar 2021 von Boandlkramer eröffnet wurde.
Also erzählt doch mal, wie seid ihr, falls es euch betrifft, an die große weite Welt der RPG-Maker-Software geraten?
Ich nutze an der Stelle die Gelegenheit selbstverfreilich dazu, meine Antwort von damals zu zitieren und hoffe auch auf viele (alte und) neue Geschichten eurerseits dazu. °ω°
ZitatAlles anzeigenSommerurlaub 2002, in der noch vorher gekauften und mitgenommenen Screenfun-Ausgabe war ganz hinten in den Previews auf die 08-2002 ein kleiner Kasten zu RPG2000, der in selbiger dann behandelt werden sollte. Der kurze pupsige Text und das Vorschaubild, das ein Screenshot in RTP-Optik war, haben mich irgendwie angefixt, obwohl meine Erfahrung mit dem RPG-Genre recht begrenzt gewesen ist. Das Programm war dann zwar nicht auf der nächsten Disc drauf, aber ich hatte mehr Spaß mit Testfall, als gesund für mich war, aus Langeweile hab ich's auch ein paar Mal versucht ganz ohne Maker zu bearbeiten. Naja und VD gab's natürlich auch, aber das hab ich weggelegt, weil das Bürgermeister-Attentat nach wenigen Spielstunden einfach Schrott war und ich keine Lust mehr hatte.
Das erste, was ich richtig lang, ausführlich und (wie ich später feststellte nur fast) bis zum Ende gespielt hab, war Eternal Legends ab ungefähr April 2003 oder so, das war dann auch gleichzeitig mein erstes Spiel, das ich durch Nutzen von Bugs und Glitches ziemlich zerstört habe, die technische Katastrophe hinter dem Contentbiest habe ich mit der Zeit sogar ohne die geringste Makerkenntnis aufzuweisen bemerkt.
RPG2000 kannte ich zwar minimal durch die Crashkurse in den 08- und 09-2002-Heften, aber habe ihn erst ein paar Monate nach EL zum ersten Mal auch benutzen können. Den bekam ich zusammen mit einer Menge Arbeitsmaterial und Extrazeug von einem sehr coolen Menschen, momentan haben wir uns leider (mal wieder) aus den Augen verloren. Von dieser Person bekam ich dann auch das Programm und die Möglichkeiten richtig vorgeführt und wir hatten eine Menge Spaß dabei, das nicht gerade gute Dreamland 3 komplett zu zerlegen. Ja, ich hab beim Sezieren fremder Kreationen gelernt, das Ding zu bedienen. Kurz darauf fand dann auch Düsterburg seinen Weg auf meinen PC und zeigte, dass man auch was wirklich Gutes damit basteln kann, es war traumhaft.
~炬燵あ
~炬燵あ
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 5. November 2020 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar. Zudem wurde der Anfang leicht bearbeitet, ursprünglich war der Text eine Antwort auf einen Post von Zeder.
Es ist tatsächlich Panning (Raumausrichtung), das war mir irgendwie vorher nicht aufgefallen oder ich hab's gar nicht erst richtig gemacht. Wenn ich die auf die Extreme hin- und herschalte (ich nehm zumindest mal an, dass 0~127 stimmt), fällt es direkt auf.
Arbeitsweise ist schwer zu beschreiben, der Hex-Editor hat recht wenig Anteil momentan, wenn ich nicht irgendwas per Hack fixen muss. Die meiste Zeit verbring ich im Disassembler (zum Herumwühlen und Adressen-/Funktionen-Benennung in RPG_RT.exe) und im einfachen Notepad (letzteres für Assembler-Code für Destiny.dll, die Hilfedokumente und allerlei Datensammel-Listen), gefolgt vom RPG Maker, um obskure Tests in ihm zusammenzukleben, über temporär eingebaute Funktionen nehm ich dann auch mal hin und wieder direkt mit DestinyScript bei laufendem Spiel ein paar Sachen im Speicher auseinander.
Die neuste kleine Bastelei, von der ich berichten kann, hat erstmal nichts mehr mit Audio zu tun, sondern ist eine DestinyScript-Variante des Befehls zum Scrollen des sichtbaren Map-Ausschnitts um N Felder in eine beliebige Richtung mit den Standard-Tempoangaben. Die Koordinaten konnten zwar bereits geändert werden (und wenn man abseits von ganzen Feldern und der Tempowahl [1~6] arbeiten will, muss man das auch weiterhin direktbestimmend tun), ich wollte trotzdem eine Möglichkeit ohne die Nachteile von [Command] bieten, das klassische Feature zu nutzen. Das Zurückzentrieren auf die Spielerposition ist natürlich auch dabei, nur die WartenBisFertig-Einstellung nicht.
~炬燵あ
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 5. Dezember 2020 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
An die wenigen, die das hier oder etwas anderes von mir (zB MöhrchenDice-Bilder) interessiert: Rechnet in nächster Zeit besser mit nichts Neuem, ich habe heute alle meine laufenden Arbeiten an [Destiny for Maniacs] (inklusive Hilfe) sowie an allen Spielen/Experimenten (meine übrigen Anteile an [Elements Destiny] können nicht mehr viel im restlichen Team ausbremsen, also nicht verzagen, was dieses Spiel angeht) aufgrund der vorherrschenden Pandemie, aus der wir dank zu vieler sehr gefährlicher Menschen niemals herauskommen werden, zeitlich unbestimmt eingefroren, ich sehe mich momentan nicht dazu in der Lage.
Dies ist keine Protestaktion, sondern nerventechnisch für mich notwendig und kann schnell wieder vorüber sein oder sich lange hinziehen. Näher werde ich die Situation nicht erläutern, um meine Gesundheit muss sich hier allerdings niemand Sorgen machen. Das hier nur mal als kleines Update, das nicht viel zum Thema beiträgt, aber allen einen kleinen Infohappen bereithält, die sich fragen, ob oder wann hier noch was kommen möge.
Bis Baldrian, bleibt sicher und tragt Masken ordnungsgemäß, so viel es nur geht, um andere auch vor euch zu schützen. Mein kontaktloser Dank sei allen gewiss, die sich an einfachste Regeln zur Pandemiebekämpfung halten können, anstatt alles mit Protesten gegen "Freiheitsbeschränkung" zu verschlimmern.
Und wenn ihr mir einen großen Gefallen tun wollt: Schreibt bitte keine Antworten, nehmt es einfach zur Kenntnis und wendet euch Schönerem zu. Sobald jemand darauf hier in diesem Thread reagiert, würde jener garantiert sehr weit vom Gleis abkommen.
~炬燵あ
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 26. April 2021 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
Ich möchte nicht groß in Aussicht stellen, demnächst das Ding mal releasen zu können, denn so wirklich arbeite ich noch nicht wieder dran, aber es gibt endlich wieder klein wenig frischen Fortschritt.
Im Objekt [Message] können jetzt der Idle-Timer, die aktuelle Zeile, wie weit sie fortgeschritten ist und das DrawOffset für das nächste Zeichen abgefragt werden. Damit lässt sich bspw. eine Funktion schreiben, die automatisch, während die Dialogbox mit Text gefüllt wird, Sounds ausspuckt. Und da sich das grafisch nicht präsentieren lässt und ich jetzt auch nix aufnehmen will, gibt's hier jetzt stattdessen den Code dafür.
$
v[1301] = v[1201];
v[1302] = v[1202];
v[1201] = Message.CurrentLine;
v[1202] = Message.DrawOffset;
if(v[1201] < v[1301] || (v[1202] < v[1302] && v[1201] == 0))
v[1203] = 5;
endif;
if(v[1201] > v[1301] || v[1202] > v[1302])
v[1203] = (v[1203] + 1) % 6;
if(v[1203] == 0)
Harmony.Sound.PlaySystem(2, false, -1, Math.Rand(50, 150));
endif;
endif;
Alles anzeigen
Das Ganze packt man in ein Event mit [Parallel] und setzt noch ein [Wait 0] dahinter (sobald diese Version denn mal draußen ist). In diesem Beispiel schaltet Variable #1203 frameweise von 0 bis 5 durch, womit 10mal pro Sekunde ab dem Start eines Dialogtextes der Cancel-SystemSE mit einem zufälligen Pitch zwischen 50 und 150% abgespielt wird. Warum ausgerechnet der, wird man sich fragen. Äh... der fiel mir als erstbeste Möglichkeit ein, um mit dem RTP Tonfolgen zu erzeugen, die zu BanjoKazooie-Gibberish passen.
~炬燵あ
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 25. Mai 2021 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
Mittlerweile hat vor einer knappen Woche BingShan nach langer Zeit ein neues großes Update für MP rausgehauen, es wird also wahrscheinlich nun nochmal etwas länger dauern, bis ich DestinyForManiacs veröffentlichen kann, denn natürlich will ich schauen, ob ich es gleich dafür anpassen kann.
Wer sich für die wahnsinnig vielen neuen Änderungen von mp210519 (zB Spielbildschirmgröße ändern) interessiert, kann meine auf englisch verfasste Liste diesbezüglich im Forum von RMN lesen, mir ist gerade nicht danach, sie nochmal auf DE zu schreiben.
~炬燵あ
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 30. Mai 2021 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
Aus der Anpassung für mp210519 wird erstmal nichts. Wie es aussieht, wurde ein großer Teil der Engine restlos über den Haufen geworfen und from-scratch neugeschrieben. Klingt absolut unrealistisch? Ja, isses auch. Aber anders kann ich mir nicht mehr erklären, was mit RPG_RT.exe passiert ist und was die Changelog-Beschreibungen versuchen zu vermitteln. Das ist zwar der helle Wahnsinn, aber zu dem, was ich hier mache, absolut inkompatibel.
Das heißt allerdings noch lange nicht, dass es für Destiny jetzt aus ist, es wird nur wahrscheinlich gezwungenermaßen auf mp200128/210414 (und einigen weiteren RPG2000-/2003-Versionen, auch wenn es nicht bei allen von ihnen offiziell zugelassen ist) hängenbleiben.
Unterdessen habe ich noch eine neue Picture-Funktion zusammengestümpert, sie ist weder stabil noch fertig, aber mittlerweile halbwegs verwendbar. Mit ihr lässt sich über recht komplizierte Parameter Inhalt von einem AuroraSheet in ein anderes per Matrix kopieren (Wikipedia ➤ Affine Abbildung). Wenn man es Zeilenweise einzeln machen lässt, wie im nachfolgenden Beispiel, entsteht mit den richtigen Werteverschiebungen fast schon sowas wie Perspektive.
Oder kurz gesagt: Es funktioniert fast genau so wie Mode7 (SFC/SNES).
~炬燵あ
An dieser Stelle enden nun die archivierten Postings aus dem alten Thread.
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 27. Oktober 2020 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
Mittlerweile hab ich mit dem Tool "MEX", das eh niemand mehr kennt, eine Menge Eventbefehle per Windoof-Zwischenablage analysiert, inklusive der neuen ab RPG2003-1.10 und denen, die Maniac hinzuwirft. Es hilft schon sehr, den Aufbau zu kennen. Einige bestehende sind jetzt auch für RPG2003 im Objekt [Command] angepasst und funktionieren ebenda (z.B. Richtungsangabe beim Teleport oder dauerhaftes Screen-Flashen), vor manch anderen graut es mir sehr.
Ach, warum nochmal kümmer ich mich jetzt doch viel zu viel um den Command-Bereich, obwohl er ein übles Biest voller Funktionen ist, von denen so einige redundant und schlechter als ihre Pendants an anderer Stelle sind? Weiß es selber nicht.
Die DestinyScript-Hilfeseiten habe ich nach diesem vielen Gemache nun aber auch endlich angefangen, Die Grundlage zur Verwendung sowie Kommentare in Code einfügen und die Erklärung der Datentypen sind bislang geschrieben. Ausstehend: Zahlenformate, Strings, Operatoren, Verzweigungen, Schleifen, Sprungbefehle, Konstanten, Fehler, MessageLink, Debugger.
~炬燵あ
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 31. Oktober 2020 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
Die meisten Seiten der Hilfe sind "fertig", andere angefangen/lückenhaft und voller unerledigter Fleißdrecksarbeit, ich hab's auch endlich hinbekommen, den Eigenschaften von Objekten eindeutig beizufügen, ob sie schreibgeschützt sind oder nicht, musste dafür viele natürlich nochmal selbst im Code durchgehen und habe nebenher noch ein paar Dinge gefixt.
So langsam könnten wir uns also einem Fertigungsstadium nähern, in dem ich andere (vorzugsweise Programmier-Erfahrene und Makerkundige mit ausreichend Willen und Geduld, sich eine Scriptsprache anzueignen) an die aktuelle DLL lassen kann, um mit all den Sachen zu experimentieren, die DestinyScript ihnen so vor die Nase wirft, und zu schauen, wie gut die Hilfe ihren Zweck erfüllt. Und wann das passieren könnte, steht weiterhin in den Sternen.
Happy Halloween, so für die verbleibenden PFÜMPF Minuten.
~炬燵あ
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 1. November 2020 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
Eine Sache, die ich hier noch unbedingt teilen muss, ist, dass der Eventbefehls-Einschleuser für ShowPicture jetzt offenbar genau auf der absoluten Kotzgrenze von dem liegt, was der gute alte MASM32 bereit ist zu kompilieren. Einige Parameter, die durch Maniac Patch hinzugekommen sind, musste ich kürzen oder vereinfachen. Entsprechend ekelhaft sieht es an der entsprechenden Stelle auch in der aktuellen Version der Hilfe aus. Ich hab das Feature übrigens bisher nichtmal getestet, aber nur schonmal so am Rande:
Die Reihenfolge der Parameter ist nicht verhandelbar, die Anweisung muss auch in anderen Versionen weiterhin funktionieren.
~炬燵あ
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 3. November 2020 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
"Command.ShowPicture()" scheint, wie ich kurz darauf festgestellt habe, in RPG2003-1.12MP seine Funktion ordentlich zu erfüllen, sieht jedenfalls jetzt noch danach aus, Tests mit [Move] und [Delete] sind noch ausstehend.
Ein anderer Anschein hat mir dafür bis vorhin große Probleme bereitet, denn der MessageLink zum Ausführen von Code mitten in der Dialogtextbox hat, was ich ewig lange nicht gemerkt habe, alles an Text, abgesehen von aufgelösten Ergebniswerten in den jeweiligen Zeilen bei RPG2003-1.12MP plattradiert (ist halt blöd, wenn man nur isolierte Tests wie "\d[1]" macht, aber kein "Schinken \d[1] Käse"). Das Problem ist jetzt aber, ein paar hirnschmelzende Analysen und Experimente mit viel zu vielen offenen Programmfenstern später, aus der Welt.
Abseits davon schleichen sich, daher straucheln ausstehende Parts der Hilfe leider gerade extrem, immer noch neue Mini-Ergänzungen in den Fundus von DestinyScript ein, die viel zu viel Extra-Arbeit mit sich bringen, ich aber einfach nicht lassen kann. Die letzten zwei Tage betraf das den Lesezugriff auf einige Eigenschaften des RPG_RT-internen MIDI-Players (also wirklich nur für genau dieses BGM-Format) ab RPG2000-1.50 und RPG2003-1.05. Aus diesem gibt es jetzt die eingestellten Werte für Fade/Lautstärke/Pitch/Panning, den FadeIn-/FadeOut-Status, die Taktposition und ein paar entschlüsselte Eckdaten der laufenden Datei (Anzahl enthaltener Tracks, Abspieldauerangabe in Ticks, TimeDivision-Wert). Außerdem gibt es zwei Datensätze, die anscheinend mit den 16 MIDI-Kanälen zu tun haben, ich aber nicht ganz sicher zuordnen kann (die Defaults für die Werte darin sind bei jedem Kanal [100 (??Lautstärke??)] und [64]).
~炬燵あ
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 4. November 2020 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
Der eine MIDI-Kanäle-Datensatz hat sich mittlerweile wirklich als die jeweilige Lautstärke entpuppt, mit dem anderen von den beiden kann ich noch immer nichts anfangen. Wenn jemand Ahnung davon hat, bzw etwas weiß, das zum Dateiformat und zu einem Default-Wert von 64 passen würde, nur zu, ich bin neugierig. Wenn ich an den Werten herumdrehe, kann ich leider keinen Unterschied im Wiedergegebenen feststellen.
In der Zwischenzeit ist auch der MP3-Part (auch wenn ich dringlichst abrate, dieses Format jemals zu verwenden) vom Audiosystem halbwegs analysiert (Bei WAV sieht's währenddessen eher aus wie Krätze und die Betrachtung vom OGG-System, das Maniac Patch mitbringt, steht noch aus) und mit Zugriffsmöglichkeiten versehen.
Und hier ein paar neue Eventbefehls-Ersatzfunktionen, die beliebig in Scriptblöcke eingebaut werden können und teils mehr als ihre Vorlagen können:
~炬燵あ
Myau!~ °ω°
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 17. Oktober 2020 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
Es hat sich heute infolge einer spontanen Idee ergeben, dass sich ein weiteres neues Objekt zum Roster hinzugesellt, mit dem ihr vollständigen Lesezugriff auf die MapTree-Daten erhaltet. Der MapTree enthält Informationen, die von der Engine schnell gelesen können werden müssen, ohne betreffende Maps zu öffnen, das sind bei RPG2000/2003 eine ganze Menge (weswegen Spiele mit kaputter LMT nach Anwenden des Notfall-Tools MapTreeCreator was das angeht nur Dummy-Daten bieten können... immer noch besser als ein kaputtgebliebenes Spiel).
Ich präsentiere, aus dem Debugger heraus, einen Blick auf "TreeMap"! Wenn jemand einen besseren Bezeichner dafür auf Tasche haben sollte, immer raus damit, denn mir fiel nichts Besseres ein. Ebenfalls aufgeführt werden, wie man sehen kann, auch der symbolische "Ordner" sowie AREAs.
~炬燵あ
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 20. Oktober 2020 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
Neulich erwähnte ich in der Tabelle noch, dass ich, was das Mausrad betrifft, erstmal gucken muss, ob und wie ich an die Daten rankomme, die ManiacPatch da sich zusammenholt, schon hat's gestern Abend geklappt, "Input" von Destiny darauf Zugriff zu verschaffen.
Einen Teil der Nacht habe ich nun damit zugebracht, noch einen obendraufzusetzen, damit über die Version, wie sie für DestinyForManiacs gepatcht werden wird, auch horizontale Mausradeingaben in RPG2003-112MP erkannt und verarbeitet werden. Eine Sache, die kaum jemand jemals anwendet oder überhaupt kennt, kann das sein? Ein horizontales Rad existiert allerdings per Definition, bzw. lässt sich z.B. bei meiner Maus (und das ist eine der einfachsten, die es derzeit so gibt) dieses sogar benutzen, indem das normale Rad zur Seite gekippt wird. Ein Feature, das ich bei dem guten Dingchen überhaupt erst einige Zeit nach dem Kauf entdeckt habe, so unüblich kann's also nicht sein.
Und das war's auch schon an Neuigkeiten, abgesehen davon, dass auch bei der Hilfe die Inhalte noch immer halbwegs vorwärtskommen.
~炬燵あ
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 23. Oktober 2020 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
Die Hilfe kommt recht gut vorwärts, jedenfalls fehlen bei den Objekten nur noch ein paar wenige, die abgehandelt werden müssen, danach wird es daran gehen, endlich Sachen wie die Syntax zu erklären (ohje, ohje). Parallel dazu schaue ich mir noch immer die vor allem neueren Sachen von DestinyScript an und baue/benenne einige von ihnen noch um. So auch geschehen mit der Achsen-Erkennung von Joysticks/Gamepads, was in unveröffentlichten Versionen von 2016/2017 noch leicht komplizierter gewesen ist. Und damit es ein bisschen bunter hier wird, gibt's noch anbei einen Screen von einem GamepadInput-Test-Tool, das ich vorhin in einem Event zusammengeklebt habe.
~炬燵あ
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 25. Oktober 2020 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
Sämtliche Objekte, so wie sie jetzt existieren, sind abseits von Senf, den ich aussortieren werde, grob dokumentiert (offenkundige Schwachstelle, bei Funktionsparametern stehen bislang keine Datentypen). Vielleicht kann ich die unfertige Hilfe ja demnächst oder weißdergeierwann vorab irgendwo im Webseitenformat ausstellen, damit sich Interessierte schonmal vom gequetschten Inhalt überrumpeln lassen können, ist bisher nur ne Überlegung.
Jetzt stehen noch so einige aufregende Schritte an. Neben dem Kümmern um die Erklärung von DestinyScript ansich, da werd ich mich bestimmt sehr an der alten Hilfe orientieren, müssen einige Sachen noch funktionstechnisch in der DLL auf RPG2003, bzw 1.12, bzw. Maniacs ausgerichtet werden (ohne die Funktionalität bei anderen Versionen zu zerstören), seit vorhin ist das Laden von Pictures aus Dateien (ohne weitere Angaben), ohne den herkömmlichen Eventbefehl dafür direkt zu verwenden, fertig angepasst. Zumindest crasht es nicht.
Was das Command-Objekt zum Zwischenschieben eines (fast) beliebigen Eventbefehls angeht, würde ich mir in nächster Zeit bei RPG2003 erstmal keine große Hoffnung machen.
~炬燵あ
Achtung, der nachfolgende Text ist eine Archivierung eines Posts, der ursprünglich am 17. Oktober 2020 im Thread im alten MVde-Forum hinzugefügt wurde und stellt in keinster Weise den aktuellen Status dar.
Zeit für den ersten kleinen Zwischenstand, was die letzte Woche so zusammengekommen ist an Fortschritt.
Die meiste Arbeit nimmt neben ein paar kleinen Aufräumarbeiten und Neubenennungen, ansonsten tut sich funktionell erstmal wenig, derzeit die neue Hilfedokumentation ein, die bedeutend knapper ausfallen wird als die vorbildlichen, jedoch auch mitunter wahnsinnig ausführlichen Seiten der alten Destiny2-Hilfe, die sich immer mit nur einer Eigenschaft oder Methode/Funktion gleichzeitig, passendem Beispielcode und allem drum und dran auseinandersetzten.
Strukturell wird es sich mehr so verhalten, dass die Inhalte und Möglichkeiten eines ganzen Objektes jeweils auf einer Seite untereinander aufgeführt werden, ohne sich großartig viel mit Beispielen aufzuhalten, zumindest vorerst. Ich möchte in einem realistischen Zeit- und Aufwandsrahmen das Nötigste fertig haben, das man braucht, um mit DestinyScript mindestens halbwegs ordentlich zu arbeiten und nicht ewig an allem hängen.
Hier eine kleine Übersicht über die übergeordneten Objekte, die DestinyScript bietet, was sie ganz grob gesagt bedeuten und wie sie in der Hilfe momentan repräsentiert sind (alles was auf dieser groben Ebene neuer als 2012 ist, ist unterstrichen). Neben den Ausführungen zu diesen wird es allerdings auch noch andere Inhalte geben, wie eine Willkommensseite, Erklärungen zu Destiny, DestinyScript, der Syntax, Operatoren, Konstanten, Einschränkungen und solchen Dingen.
*.AuroraSheet | Einheitliche Grafikmanipulation für viele verschiedene Bereiche im Speicher: Kampfhintergrund, Gegnergrafiken, Eventlaufgrafiken, ExFont, Windowskin, Tileset, Dialogbox, Dialogface, Panorama, Pictures, Animation, Wetter | Angefangen |
a[], d[], f[] s[], v[] | Speicherbereiche für ANSI-Strings, Dwords und Floats sowie Zugriff auf Switches und Variablen | Dokumentiert |
Actor[] | Helden, Heldendatenbank | Dokumentiert |
Animation[] | Animationsdatenbank | Dokumentiert |
Battle | Kampfdaten, Aktuelle Gegnergruppe, Kampfeinstellungen | Dokumentiert |
Battler[] | Datenbanktab "Animations 2" (RPG2003) | Dokumentiert |
Client[] | Netzcode-Basis: Verbindung zu anderen Computersystemen | Angefangen |
Command | Ausführen eines Eventbefehls nach Abschluss des Scriptblocks (bisher nur RPG2000 bis 1.10) | Dokumentiert |
CommonEvent[] | CommonEvent-Datenbank | Dokumentiert |
Convert | Formatwandlung für verschiedene Arten von Werten. | Angefangen |
Destiny | Destiny-Basisdaten, Destiny-Speicherformat, Windows-MessageBox, Debugger, Konsolenfenster | Ausstehend |
Directory | Verzeichnisfunktionen innerhalb des Spielordners (Anlegen, Umbenennen/Verschieben, Löschen,...) | Ausstehend |
Element[] (LEGACY: Attribute[]) | Elementdatenbank (umbenannt, alte Bezeichnung weiterhin benutzbar) | Dokumentiert |
Enemy[] | Gegnerdatenbank | Dokumentiert |
Error[] | Einzelne Fehlermeldungen von Destiny | Dokumentiert |
Errors | Allgemeine Fehlereinstellungen von Destiny | Ausstehend |
Event[] | Events auf der Map, Indexiert per ID | Dokumentiert |
File[] | Dateifunktionen innerhalb des Spielordners (Erstellen, Lesen, Schreiben,...) | Ausstehend |
Game | Standard-Spielstandformat, Spiel verlassen, Parameter, Viele sonstige Datensätze die ich vielleicht noch umlagere | Ausstehend |
Harmony | Audiosystem von Harmony.dll (RPG2000 <1.50, RPG2003 <1.05) bzw. RPG_RT.exe | Ausstehend |
Input | Vollzugriff auf Daten der Engine-internen Ergebnisse von Tastenabfragen auf den Gamebuttons | Ausstehend |
Item[] | Gegenständedatenbank | Ausstehend |
Job[] | Jobklassendatenbank (RPG2003) | Ausstehend |
Joypad[] | Komplette Beschaffenheits-/Statusabfrage von allen Joysticks/Gamepads, die Windows-Multimedia erkennt (üblicherweise bis zu 16) | Ausstehend |
Keyboard | Tastenabfrage- und Kontrolle auf der Tastatur, Abfrage diverser Tastaturbeschaffenheitsdaten | Ausstehend |
Logic | Logische Schaltungen und Vergleiche (teils ein Relikt von Destiny 1.0) | Inhalt fertig |
Map | Aktuelle Map, Mapbildschirm, Mapeinstellungen, MapTree-Daten | Ausstehend |
MapEvent[] | Events auf der Map, Indexiert wie sie im Datensatz hintereinanderweg stehen | Dokumentiert |
Math | Komplexe mathematische Abläufe (größtenteils Winkelfunktionen in allen Varianten) | Inhalt fertig |
Message | Dialoge-Textbox, Textboxeinstellungen, Enthält das ehemals eigenständige Objekt "FaceSet" (als "Face", alte Bezeichnung weiterhin benutzbar) | Inhalt fertig |
Mouse | Zugriff auf Mausposition und diverse andere Eigenschaften, KEIN Mausrad (da Maniac es abfragen kann, kann ich diese Daten vielleicht für diese Version abgreifen lassen, bisher nur Theorie) | Ausstehend |
Panorama | Map-Panorama-Eigenschaften | Ausstehend |
Party | Heldengruppe/Spielerfigur, Inventar | Inhalt fertig |
Picture[] | Pictures, Picturemanipulation | Ausstehend |
Screen | Spielbildschirm, Animation, Wetter, Spielfenster | Ausstehend |
Server | Netzcode-Basis: Eingehende Verbindungen von anderen Computersystemen | Dokumentiert |
Skill[] | Skilldatenbank | Angefangen |
State[] (LEGACY: Condition[]) | Zustandsdatenbank (umbenannt, alte Bezeichnung weiterhin benutzbar) | Angefangen |
String | Analyse, Vergleich und Änderung von Zeichenketten | Dokumentiert |
Terrain[] | Terraindatenbank | Dokumentiert |
Tileset[] | Tilesetdatenbank | Dokumentiert |
Time | Aktuelle Uhrzeit, Aktuelles Datum, System-Tick, Zeitverschiebung, Sommerzeit | Dokumentiert |
Troop | Gegnergruppendatenbank | Dokumentiert |
~炬燵あ
Holerö!~
Achtung, der nachfolgende Text ist größtenteils am 10. Oktober 2020 für das alte MVde-Forum entstanden, es ist nicht mehr zwingend alles davon aktuell, auch wenn ich nochmal grob drübergeschaut und ein paar Details angepasst habe. Zudem... zu sagen, ich würde hierdran gerade eher sporadisch arbeiten, wär sogar noch zu optimistisch ausgedrückt.
Es ist viele Jahre her, da ersonn ein deutscher Programmierer mit dem klangvollen Namen Bananen-Joe die Erweiterung Destiny für den RPG Maker 2000, die neben einigen Patchfunktionen auch eine eigene Scriptsprache mitbrachte. Diese wurde bis Anfang des Jahres 2012 weiterentwickelt und schließlich mit der Veröffentlichung des Sourcecodes eingestellt.
Da mich dieses Addon schon von Anfang an sehr begeistert hat, ich viel damit gebastelt habe und schließlich beim Vorabtest für Version 2 sehr viel Energie reinfeuerte, begab es sich 2016, dass ich anfing, Destiny auf Basis des veröffentlichten Source, größtenteils in x86-Assembler (ja, wahnsinnig gruselig) verfasst, um einen Berg neuer Möglichkeiten zu erweitern, denn in vielen Punkten hatte der Umfang noch deutliche Lücken. Diese Nebenbastelarbeit hielt bis Ende 2017 an, als ich eine Pause von all diesem Zeug einlegen musste, um nicht verrückt zu werden. Viele dazugehörige Experimente liegen neben so einigem fertigen Stuff seitdem unvollendet oder kaputt herum.
Anfang Oktober 2020 hat mich der Wahnsinn erneut gefesselt, etwas daraus zu machen, diesmal jedoch mit Fokus auf den RPG Maker 2003 1.12! Auch wenn ich noch nie allzu sehr begeistert von diesem Programm war, da es das runde Produkt des Vorgängers mächtig zu zerpfuschen wusste, hat es besonders in jüngerer Vergangenheit einige neue Vorteile aus fähigen Händen geerntet, die man nicht ignorieren sollte. Doch was genau ist und kann dieses ominöse "Destiny" nun eigentlich? Dazu kommen wir jetzt.
[Wie war das damals eigentlich?]
Destiny kam ursprünglich in Form eines Patchers im Jahr 2008 heraus, der diverse Einstellungsmöglichkeiten mitbrachte. Das Herzstück war die Einbindung der Bibliothek "Destiny.dll", die Notizen und den sogenannten MessageLink als Scriptcode in einer eigenen Sprache verarbeiten kann. Weitere Einstellungen, von denen diverse erst gegen Ende der Entwicklung hinzukamen, waren unter anderem das Ändern von Fonts oder diversen Dateinamen, eine EnterHeroName-Reperatur sowie das Vertauschen der Zeichenebenen-Reihenfolge (Panorama, Above-Tiles, Pictures, Timer, etc.) auf dem Mapbildschirm. Ob und was alles von diesen Extras diesmal dabei sein wird, ist noch nicht entschieden, denn diese sind absolut nicht der Fokus.
[Hab gehört, es gibt Scripting?]
DestinyScript bietet eine Vielzahl an Datenlese- und -Manipulationsmöglichkeiten, eigene Speicherbereiche für Zahlen, Kommazahlen und Texte sowie das Ausführen von diversen Spielfunktionen, die nicht über Eventbefehle erreichbar sind. Dazu gehörten 2012 bereits Objekte wie Helden, Skills, Gegenstände, Attribute, Zustände, Events, Pictures, die Map, der Bildschirm und ein voller Tastenzugriff auf Tastatur und Maus. Die zuvor unveröffentlichte Erweiterung von ab 2016 gab vielen dieser Bereiche eine Menge weitere Inhalte, fügte allerdings auch Zugriff auf bspw. Animationen, Gegner, Gruppen, ChipSets, Terrains, System-BGM/-SE und Timer hinzu, es würde einfach zuviel werden, hier wirklich alles davon zu nennen. Ihr könnt außerdem diverse Syntax-Basics nutzen, die ungefähr jede Sprache mitbringt, jedoch beherrscht sie z.B. nicht das eigene Anlegen von benannten Konstanten oder Programmvariablen. Kurzum bekommt ihr eine Menge mehr Macht über die Engine, jedoch, das sei gesagt, NICHT im geradezu unendlichen Maße eines RPG Maker MZ.
[Ist das denn alles legal?]
Eine berechtigte Frage und was ältere Fassungen für RPG2000 angeht, so möchte ich dazu keinerlei Aussage treffen, diese sind hier nämlich nicht das Thema, zudem wurden dafür nie offizielle Regeln für Patches und dergleichen herausgegeben, auf die man sich stützen könnte. RPG2003 ab Version 1.10 jedoch verfügt über den Patchvertrag, der unter Erfüllung diverser Voraussetzungen das Verändern und Erweitern der Engine gestattet, ohne dass Entwickler die Berechtigung zur Verbreitung der damit geschaffenen Spiele riskieren. Ein populäres Beispiel hierfür ist Maniac Patch, prägt ihn euch gut ein, dieses gute Stück wird noch wichtig.
[Für welche Version nochmal gleich?]
Wie ich gerade sagte, ist Maniac Patch ein wichtiges Element hierbei, denn dieser wird für die Version, die ich hier hoffentlich irgendwann bereitstellen werde, in der Revision mp200128 oder mp210414 vorausgesetzt, das bedeutet, ihr müsst euren Maker sowie die RPG_RT 2003-1.12 eures Spiels bereits zuvor damit verarbeitet haben. Es lohnt sich, selbst wenn ihr Destiny nicht auch noch draufpacken wollt. Wenn euch interessiert, was der so kann, schaut mal in den oben verlinkten Artikel.
[Wie ist der Stand?]
Am gestrigen Tage habe ich mich nach einer guten Woche Vorarbeit, die größtenteils aus einer weitreichenden, supertrockenen Datenanalyse mit viel Drecksarbeit bestand, an die Einbindung von Destiny.dll in die RPG_RT.exe 2003-1.12 mit angewendetem Maniac Patch gesetzt und mittlerweile geht das Programm nicht mehr beim Testen in Flammen auf oder verweigert den Dienst. Die Verarbeitung des Scriptcodes funktioniert, womit ich mich nun langsam daran machen kann, die ganzen Datenzugriffsmöglichkeiten und Funktionen, die inhaltlich momentan in Destiny stecken, durchzuprüfen, zu fixen und zu erweitern.
[Brauch ich das?]
Keine Ahnung, aber wenn du in den alten Makerchen Menüs, Kampfsysteme, Nameneingaben oder viel abgefahrenere Dinge bauen willst, sind Maniac und Destiny eine enorm große Hilfe bei der Arbeit.
[Wie sieht der Funktionsumfang aus?]
DestinyScript for Maniacs verfügt über eine neue, deutlich kompaktere, jedoch noch ebenso unfertige Hilfedokumentation, die man sich derzeit bereits auf MakerDev Library anschauen kann.
[Kommt das auch für RPG2000?]
Wie bereits erwähnt, es könnte problematisch sein, da dafür nichts geregelt wurde. Allerdings werden neue Builds von Destiny.dll mit diversen Versionen kompatibel sein, darunter auch RPG2000 1.07 und 1.62. Wie es sich mit der Bereitstellung von allem dafür Wichtigen, damit man das nutzen kann, verhalten wird, sei erstmal dahingestellt.
[Wann kommt's raus?]
Sobald ich mir sicher bin, dass dieses Ungetüm auf die Menge losgelassen werden kann. Das kann noch lange dauern, ich hab auch noch andere Sachen vor als das hier.
[Darf ich testen?]
Möglicherweise wird irgendwann mal in die Runde gefragt, ob wer Lust dazu hat, momentan aber noch nicht.
[Soll ich hierauf warten bis ich was erstelle?]
Das wäre keine besonders schlaue Idee. Frohes Basteln! Hopp-hopp! Los, baut coole Sachen. =D
[Wird das denn überhaupt fertig?]
Finden wir's einfach mit der Zeit heraus. Hakuna Matata!
[Dein Lieblingsfeature?]
Picture-Manipulation all the Way!
[SCREENS BITTE!]
Momentan fällt mir nichts Aufregendes ein, das unmissverständlich in Standbildform die Macht von DestinyScript demonstriert und aus der Reverse-Engineering-Arbeit werde ich aus offensichtlichen Gründen nichts zeigen können. Also begnügt euch einfach mit einem winzigen Einblick darin, wie einfacher Testcode aus zweckentfremdeten Notizen und dem Messagelink ("\()") aussehen kann, mit dem ich mich vergewissere, dass die Verarbeitung klappt. Das hier ist nichtmal die Spitze der Spitze der Spitze des Eisbergs.
[DER DOWNLOAD, VERDAMMT!]
Ja, äh... hast du nur hier runtergescrollt, um was zu laden? Not ready yet. Ich hab noch nichtmal Patching-Tools bereit, damit ihr es so bequem wie möglich habt (wenn das überhaupt je passiert), geschweigedenn die Hilfedokumentation.
Nun denn, das soll's erstmal gewesen sein. °▽°
© 2006~2012 Bananen-Joe | Extended by KotatsuAkira
~炬燵あ
Event Exportexter for RPGXP
(rv20220318)
by KotatsuAkira / AkiraKotatsuhime
Einführung
Ich hatte mal wieder Laune auf ne kleine Programmierübung in Ruby und außerdem brauchte jemand aus dem RMWeb-Forum etwas, um Events im RPG Maker XP in eine Textdatei zu exportieren, also... hab ich einfach mal losgelegt. Hier ist mein neues kleines DevTool, das alle Events von allen Maps, alle CommonEvents und alle Troop-Seiten in einer einzigen TXT für Menschen lesbar verpackt.
Hauptsächlich getestet habe ich es bisher mit dem RPGXP-SampleGame KNight-Blade -Howling of Kerberos-, das Ergebnis davon, das als "EventExport.txt" im Spielordner hinterlassen wird, ist etwa 2MB groß, rechnet also beim Anwenden mit einer recht großen Datei, die besonders im Windows-eigenen Notepad zu öffnen SEHR lange dauern kann.
Features
Viel mehr gibt es auch schon gar nicht mehr im Vorfeld zu erklären. Das Textformat der Eventcodezeilen sieht fast exakt so aus wie in RPGXP selbst, nur dass die Farben fehlen und ich mir ein paar kleine Freiheiten gelassen habe, leichte Abwandlungen oder zusätzliche Infos einzufügen. Außerdem ist das "@>"-Präfix hässlich, daher gibt's das gute alte "<>" vor Befehlen.
Screens
Viel zu zeigen gibt's da nicht, aber so in etwa sollte es bei euch aussehen, während die Daten verarbeitet werden. Der schwarze Hintergrund ist durchlässig, also würde man mitten im Spiel ausgeführt da noch anderen Kram dahinter sehen.
Praktische Anwendung
Verwendung geschieht selbstverständlich auf eigene Gefahr, das sollte klar sein. Dieses DevTool wird in RGSS-Scriptform rausgegeben, daher müsst ihr es auch in das Spiel integrieren, in dem ihr es nutzen wollt, oder es auf anderweitige Art verknoten. Damit habe ich dann aber nix mehr zu tun. Platziert es irgendwo über "Main", am besten direkt darüber. Um den Exportexter zu verwenden, platziert an passender Stelle, zB in "Main" oder einem ScriptCall-Event die nachfolgende Zeile:
Wenn ihr dies dann ausführen lasst, wird der Exportexter euch nach einer Bestätigung fragen, damit es losgehen kann, die mit den GameButtons L+R bestätigt oder mit B abgebrochen werden kann. Danach werden alle MapEvents, dann CEs und schlussendlich alle Troops verarbeitet, der Fortschritt wird in drei respektiven grünen Balken am unteren Bildschirmrand dargestellt, siehe Bild oben.
FAQ
Q: Wer kommt in die Credits dafür?
A: Na ich natürlich, aber eigentlich wär's mir am liebsten, wenn ihr den Code nicht in Veröffentlichungen mit integriert, sondern ihn wieder entfernt, wenn er nicht mehr gebraucht wird. Es darf aber jederzeit alleinstehend kostenfrei weitergegeben werden, solange alle Hinweise am oberen Rand des Codeblocks dabei intakt bleiben.
Q: Ist es kompatibel mit (Scripte hier einfügen)?
A: Keine Ahnung, eigentlich sollte es mit allen RPGXP-Spielen funktionieren, die die Standard-Datenstrukturen (Datenbank und Maps) verwenden und kein anderes Modul in sich haben, das zufällig auch "Event_Exportexter" heißt.
Q: Kommt auch eine Version für (hier RPG Maker einfügen)?
A: Rechnet da mal besser nicht mit.
Q: Wieso sind da "Unknown Command"-Einträge in der Textdatei?
A: Seltsam, eigentlich sollten die nicht auftreten. Zeigt mir bitte, wo und wie sie passieren, aber nur falls die Eventdaten nicht generell manipuliert oder kaputt sind.
Q: Beim Verarbeiten ist ein Fehler aufgetreten, was ist da los?
A: Es kann immer sein, dass ich Patzer in meiner Syntax übersehen habe, informiert mich also bitte, welche Befehle betroffen sind, wenn sowas passiert.
Q: Mein Computer ist explodiert!
A: Das ist nichtmal eine Frage. Und habe ich schon erwähnt, dass Nutzung auf eigene Gefahr geschieht?
Der Code
#==============================================================================
# ** Event Exportexter for RPGXP (rv20220318)
#------------------------------------------------------------------------------
# Export event code content from all maps, CEs and troops to a textfile.
#------------------------------------------------------------------------------
# © 2022 KotatsuAkira
# This is a developer tool for temporary usage only.
# Do not include this with public demo or game releases.
# Redistribute only with this copyright notice intact.
#==============================================================================
module Event_Exportexter
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
TEXTOPTIONS_POS = ["Top", "Middle", "Bottom"]
TEXTOPTIONS_WINDOW = ["Show", "Hide"]
SWITCH_STATES = ["ON", "OFF"]
COMPARERS = ["==", ">=", "<=", ">", "<", "!="]
AMOUNT_OP = ["+", "-"]
MORE_LESS = ["or more", "or less"]
ACTOR_CONDITION = ["in the party", "applied", "learned", "equipped", "equipped", "inflicted"]
ENEMY_CONDITION = ["appeared", "inflicted"]
FACING_DIR = ["Down", "Left", "Right", "Up"]
GAME_BUTTONS = ["Down", "Left", "Right", "Up", "A", "B", "C", "X", "Y", "Z", "L", "R"]
OPERATORS = ["=", "+", "-", "*", "/", "%"]
VARIABLE_OP_ACTOR = ["Level", "EXP", "HP", "SP", "MaxHP", "MaxSP", "STR", "DEX", "AGI", "INT", "ATK", "PDEF", "MDEF", "EVA"]
VARIABLE_OP_ENEMY = ["HP", "SP", "MaxHP", "MaxSP", "STR", "DEX", "AGI", "INT", "ATK", "PDEF", "MDEF", "EVA"]
VARIABLE_OP_CHARACTER = ["Map X", "Map Y", "Direction", "Screen X", "Screen Y", "Terrain Tag"]
VARIABLE_OP_MISC = ["Map ID", "Party Members", "Gold", "Steps", "Play Time", "Timer", "Save Count"]
DISENABLERS = ["Disable", "Enable"]
TRANSFER_DIR = ["", ", Down", ", Left", ", Right", ", Up"]
TRANSFER_FADE = ["", ", No Fade"]
PLAYER_VISIBLE = ["Transparency", "Normal"]
ROUTE_STEPS = ["Move Down", "Move Left", "Move Right", "Move Up", "Move Lower Left", "Move Lower Right", "Move Upper Left", "Move Upper Right", "Move at Random", "Move toward Player", "Move away from Player", "1 Step Forward", "1 Step Backward"]
ROUTE_TURNS = ["Turn Down", "Turn Left", "Turn Right", "Turn Up", "Turn 90 Right", "Turn 90 Left", "Turn 180", "Turn 90 Right or Left", "Turn at Random", "Turn toward Player", "Turn away from Player"]
ROUTE_SWITCHES = ["Move Animation ON", "Move Animation OFF", "Stop Animation ON", "Stop Animation OFF", "Direction Fix ON", "Direction Fix OFF", "Through ON", "Through OFF", "Always on Top ON", "Always on Top OFF"]
BLENDINGS = ["Normal", "Add", "Sub"]
PIC_BASE = ["Upper Left", "Center"]
WEATHER = ["None", "Rain", "Storm", "Snow"]
LVSTAT = ["MaxHP", "MaxSP", "STR", "DEX", "AGI", "INT"]
EQUIPS = ["Weapon", "Shield", "Helmet", "Armor", "Accessory"]
FORCED_ACTIONS = ["Attack", "Defend", "Escape", "Do Nothing"]
FORCED_TARGETS = ["Last Target", "Random", "Index 1", "Index 2", "Index 3", "Index 4", "Index 5", "Index 6", "Index 7", "Index 8"]
FORCED_EXEC = ["", ", Execute Now"]
TRIGGER_TYPES = ["None", "Autorun", "Parallel"]
TROOP_SPAN = ["Battle", "Turn", "Moment"]
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.new_line
return "#{" " * @@indent}#{@@new_line}"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_base_name(so)
return so ? so.name : "???"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_actor(si)
return sprintf("[%.3d:%s]", si, get_base_name($data_actors[si]))
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_class(si)
return sprintf("[%.3d:%s]", si, get_base_name($data_classes[si]))
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_skill(si)
return sprintf("[%.3d:%s]", si, get_base_name($data_skills[si]))
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_item(si)
return sprintf("[%.3d:%s]", si, get_base_name($data_items[si]))
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_weapon(si)
return sprintf("[%.3d:%s]", si, get_base_name($data_weapons[si]))
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_armor(si)
return sprintf("[%.3d:%s]", si, get_base_name($data_armors[si]))
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_enemy(si)
return sprintf("[%.3d:%s]", si, get_base_name($data_enemies[si]))
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_troop(si)
return sprintf("[%.3d:%s]", si, get_base_name($data_troops[si]))
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_state(si)
return sprintf("[%.3d:%s]", si, get_base_name($data_states[si]))
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_animation(si)
return sprintf("[%.3d:%s]", si, get_base_name($data_animations[si]))
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_tileset(si)
return sprintf("[%.3d:%s]", si, get_base_name($data_tilesets[si]))
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_common_event(si)
return sprintf("[%.3d:%s]", si, get_base_name($data_common_events[si]))
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_map(si)
return sprintf("[%.3d:%s]", si, get_base_name($data_mapinfos[si]))
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_character(si)
return "Player" if si == -1
return "This Event" if si == 0
return sprintf("[%.3d:%s]", si, @@current_map ? get_base_name(@@current_map.events[si]) : "???")
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_switch(si)
return sprintf("[%.4d:%s]", si, $data_system.switches[si] || "???")
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_variable(si)
return sprintf("[%.4d:%s]", si, $data_system.variables[si] || "???")
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_switches(s1, s2)
return s1 == s2 ? get_switch(s1) : sprintf("[%.4d..%.4d]", s1, s2)
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_variables(s1, s2)
return s1 == s2 ? get_variable(s1) : sprintf("[%.4d..%.4d]", s1, s2)
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_actor_condition(sc, sp)
case sc
when 0
return ""
when 1
return "'#{sp}'"
when 2
return get_skill(sp)
when 3
return get_weapon(sp)
when 4
return get_armor(sp)
when 5
return get_state(sp)
end
return "???"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_enemy_condition(sc, sp)
return sc == 0 ? "" : sc == 1 ? get_state(sp) : "???"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.choice_cancel(si)
return si == 0 ? "" : si == 5 ? " (Cancel: Additional)" : " (Cancel: ##{si})"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.is_choice_cancel(si)
return si == @@choice_cancel ? " (Triggered by Cancel)" : ""
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_var_config(sc, st, sp)
case sc
when 0
return st.to_i
when 1
return get_variable(st)
when 2
return "Random No. (#{st}...#{sp})"
when 3
return "#{get_item(st)} in Inventory"
when 4
return "#{get_actor(st)}'s #{VARIABLE_OP_ACTOR[sp]}"
when 5
return "[#{st}. ]'s #{VARIABLE_OP_ENEMY[sp]}"
when 6
return "#{get_character(st)}'s #{VARIABLE_OP_CHARACTER[sp]}"
when 7
return VARIABLE_OP_MISC[st]
end
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.enemy_present(si)
return @@current_troop && @@current_troop.members[si]
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_troop_enemy(si)
return "[#{si}. #{enemy_present(si) ? get_enemy(@@current_troop.members[si].enemy_id) : ""}]"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_branch_content(*sp)
case sp[0]
when 0
return "Switch #{get_switch(sp[1])} == #{SWITCH_STATES[sp[2]]}"
when 1
return "Variable #{get_variable(sp[1])} #{COMPARERS[sp[4]]} #{sp[2] == 1 ? get_variable(sp[3]) : sp[3]}"
when 2
return "Self Switch #{sp[1]} == #{SWITCH_STATES[sp[2]]}"
when 3
return "Timer #{sp[1] / 60} min #{sp[1] % 60} sec #{MORE_LESS[sp[2]]}"
when 4
return "#{get_actor(sp[1])} is #{get_actor_condition(sp[2], sp[3])} #{ACTOR_CONDITION[sp[2]]}"
when 5
return "Enemy #{get_troop_enemy(sp[1])} is #{get_enemy_condition(sp[2], sp[3])} #{ENEMY_CONDITION[sp[2]]}"
when 6
return "#{get_character(sp[1])} is facing #{FACING_DIR[sp[2]]}"
when 7
return "Gold #{sp[1]} #{MORE_LESS[sp[2]]}"
when 8
return "Item #{get_item(sp[1])} in Inventory"
when 9
return "Weapon #{get_weapon(sp[1])} in Inventory"
when 10
return "Armor #{get_armor(sp[1])} in Inventory"
when 11
return "The #{GAME_BUTTONS[sp[1]]} button is being pressed"
when 12
return "Script: #{sp[1]}"
end
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_timer_data(st, sp)
return st == 1 ? "Stop" : "Startup (#{sp / 60} min. #{sp % 60} sec.)"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.value_or_var(st, sp)
return st == 0 ? sp.to_s : "Variable #{get_variable(sp)}"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_audio_file(sf)
return "'#{sf.name}', #{sf.volume}, #{sf.pitch}"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.map_or_var(st, sp)
return st == 0 ? get_map(sp) : sprintf("Variable [%.4d]", sp)
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.transfer_pos(st, sx, sy, sd, sf)
return sprintf(st == 0 ? " (%.3d,%.3d)" : "[%.4d][%.4d]", sx, sy) + TRANSFER_DIR[sd] + TRANSFER_FADE[sf]
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.set_location(st, sx, sy, sd)
return sprintf("(%.3d,%.3d)#{TRANSFER_DIR[sd]}", sx, sy) if st == 0
return sprintf("Variable [%.4d][%.4d]#{TRANSFER_DIR[sd]}", sx, sy) if st == 1
return "Switch with #{get_character(sx)}#{TRANSFER_DIR[sd]}"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.map_panorama(*sp)
return "Panorama = '#{sp[1]}', #{sp[2]}"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.map_fog(*sp)
return "Fog = '#{sp[1]}', #{sp[2]}, #{sp[3]}, #{BLENDINGS[sp[4]]}, #{sp[5]}, #{sp[6]}, #{sp[7]}"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.map_back(*sp)
return "Battleback = '#{sp[1]}'"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_color_data(sc)
return "(#{sc.red.to_i},#{sc.green.to_i},#{sc.blue.to_i},#{sc.alpha.to_i})"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_tone_data(st)
return "(#{st.red.to_i},#{st.green.to_i},#{st.blue.to_i},#{st.gray.to_i})"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.add_route_step(se, *sp)
case se
when 1..13
return "<>#{ROUTE_STEPS[se - 1]}"
when 14
return "<>Jump: #{sp[0]}, #{sp[1]}"
when 15
return "<>Wait: #{sp[0]} frame(s)"
when 16..26
return "<>#{ROUTE_TURNS[se - 16]}"
when 27
return "<>Switch ON: #{get_switch(sp[0])}"
when 28
return "<>Switch OFF: #{get_switch(sp[0])}"
when 29
return "<>Change Speed: #{sp[0]}"
when 30
return "<>Change Freq: #{sp[0]}"
when 31..40
return "<>#{ROUTE_SWITCHES[se - 31]}"
when 41
return "<>Graphic: '#{sp[0]}', #{sp[1]}, #{sp[2]}, #{sp[3]}"
when 42
return "<>Change Opacity: #{sp[0]}"
when 43
return "<>Change Blending: #{BLENDINGS[sp[0]]}"
when 44
return "<>SE: #{get_audio_file(sp[0])}"
when 45
return "<>Script: #{sp[0]}"
end
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.route_options(sr)
return new_line unless sr.repeat || sr.skippable
return " (Repeat Action)#{sr.list.empty? ? "" : new_line}" if sr.repeat && !sr.skippable
return " (Ignore If Can't Move)#{sr.list.empty? ? "" : new_line}" if sr.skippable && !sr.repeat
return " (Repeat Action, Ignore If Can't Move)#{sr.list.empty? ? "" : new_line}"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.step_indent
return "#{" " * @@indent}: : "
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.generate_route(sl)
sl.pop
return (sl.collect {|se| "#{step_indent}#{add_route_step(se.code, *se.parameters)}" }).join(new_line)
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.pic_pos(st, sx, sy)
return sprintf(st == 0 ? "%d,%d" : "Variable [%.4d][%.4d]", sx, sy)
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.pic_show(si, sn, sb, st, sx, sy)
return "#{si}, '#{sn}', #{PIC_BASE[sb]} (#{pic_pos(st, sx, sy)})"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.pic_move(si, sw, sb, st, sx, sy)
return "#{si}, @#{sw}, #{PIC_BASE[sb]} (#{pic_pos(st, sx, sy)})"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.set_weather(st, sp)
return st == 0 ? WEATHER[0] : "#{WEATHER[st]}, #{sp}"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.item_type(st)
return st == 1 ? "Weapon" : st == 2 ? "Armor" : "Item"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_item_by_type(st, sp)
return st == 1 ? get_weapon(sp) : st == 2 ? get_armor(sp) : get_item(sp)
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.add_shop_item(st, sp)
return "#{item_type(st)} #{get_item_by_type(st, sp)}"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.party_or_actor(si)
return si == 0 ? "Entire Party" : get_actor(si)
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.troop_or_enemy(si)
return si == 0 ? "Entire Troop" : get_troop_enemy(si)
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.knockout_possible(sf)
return sf == 1 ? ", Allow Knockout in Battle" : 0
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.change_hpsp(sk, so, st, sv, sf)
return "#{sk} #{AMOUNT_OP[so]} #{value_or_var(st, sv)}#{knockout_possible(sf)}"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_equip(sl, sp)
return sl == 0 ? get_weapon(sp) : get_armor(sp)
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_action(st, sp)
return st == 1 ? get_skill(sp) : FORCED_ACTIONS[sp]
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.get_target(so, se)
return "#{FORCED_TARGETS[so - 2]}#{FORCED_EXEC[se]}"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.actors_or_enemies(st, si)
return st == 1 ? troop_or_enemy(si) : party_or_actor(si)
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.troop_member(se, sx, sy, sh, si)
return "\n#{se} (X#{sx}, Y#{sy}#{sh ? ", HIDDEN" : ""}#{si ? ", IMMORTAL" : ""})"
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.write_command(si, sd, *sp)
case si
when 0
"<>"
when 101
"<>Show Text: #{sp[0]}"
when 401
": : #{sp[0]}"
when 102
@@choice_list = sp[0].dup
@@choice_cancel = sp[1]
"<>Show Choices: [#{@@choice_list.join("], [")}]#{choice_cancel(sp[1])}"
when 402
": When [#{@@choice_list[sp[0]]}]#{is_choice_cancel(sp[0] + 1)}"
when 403
": When Cancel"
when 404
": Branch End"
when 103
"<>Input Number: #{get_variable(sp[0])}, #{sp[1]} digit(s)"
when 104
"<>Change Text Options: #{TEXTOPTIONS_POS[sp[0]]}, #{TEXTOPTIONS_WINDOW[sp[1]]}"
when 105
"<>Button Input Processing: #{get_variable(sp[0])}"
when 106
"<>Wait: #{sp[0]} frame(s)"
when 108
"<>Comment: #{sp[0]}"
when 408
": : #{sp[0]}"
when 111
"<>Conditional Branch: #{get_branch_content(*sp)}"
when 411
": Else"
when 412
": Branch End"
when 112
"<>Loop"
when 413
": Repeat Above"
when 113
"<>Break Loop"
when 115
"<>Exit Event Processing"
when 116
"<>Erase Event"
when 117
"<>Call Common Event: #{get_common_event(sp[0])}"
when 118
"<>Label: #{sp[0]}"
when 119
"<>Jump to Label: #{sp[0]}"
when 121
"<>Control Switches: #{get_switches(sp[0], sp[1])} = #{SWITCH_STATES[sp[2]]}"
when 122
"<>Control Variables: #{get_variables(sp[0], sp[1])} OPERATORS[sp[2]] #{get_var_config(sp[3], sp[4], sp[5])}"
when 123
"<>Control Self Switch: #{sp[0]} = #{SWITCH_STATES[sp[1]]}"
when 124
"<>Control Timer: #{get_timer_data(sp[0], sp[1])}"
when 125
"<>Change Gold: #{AMOUNT_OP[sp[0]]} #{value_or_var(sp[1], sp[2])}"
when 126
"<>Change Items: #{get_item(sp[0])} #{AMOUNT_OP[sp[1]]} #{value_or_var(sp[2], sp[3])}"
when 127
"<>Change Weapons: #{get_weapon(sp[0])} #{AMOUNT_OP[sp[1]]} #{value_or_var(sp[2], sp[3])}"
when 128
"<>Change Armors: #{get_armor(sp[0])} #{AMOUNT_OP[sp[1]]} #{value_or_var(sp[2], sp[3])}"
when 129
"<>Change Party Member: #{AMOUNT_OP[sp[1]]} #{get_actor(sp[1])}#{sp[2] == 1 ? ", Initialize" : ""}"
when 131
"<>Change Windowskin: '#{sp[0]}'"
when 132
"<>Change Battle BGM: #{get_audio_file(sp[0])}"
when 133
"<>Change Battle End ME: #{get_audio_file(sp[0])}"
when 134
"<>Change Save Access: #{DISENABLERS[sp[0]]}"
when 135
"<>Change Menu Access: #{DISENABLERS[sp[0]]}"
when 136
"<>Change Encounter: #{DISENABLERS[sp[0]]}"
when 201
"<>Transfer Player: #{map_or_var(sp[0], sp[1])}, #{transfer_pos(sp[0], sp[2], sp[3], sp[4] / 2, sp[5])}"
when 202
"<>Set Event Location: #{get_character(sp[0])}, #{set_location(sp[1], sp[2], sp[3], sp[4] / 2)}"
when 203
"<>Scroll Map: #{FACING_DIR[sp[0] / 2]}, #{sp[1]}, #{sp[2]}"
when 204
"<>Change Map Settings: #{sp[0] == 0 ? map_panorama(*sp) : sp[0] == 1 ? map_fog(*sp) : map_back(*sp)}"
when 205
"<>Change Fog Color Tone: #{get_tone_data(sp[0])}, @#{sp[1]}"
when 206
"<>Change Fog Opacity: #{sp[0]}, @#{sp[1]}"
when 207
"<>Show Animation: #{get_character(sp[0])}, #{get_animation(sp[1])}"
when 208
"<>Change Transparent Flag: #{PLAYER_VISIBLE[sp[0]]}"
when 209
"<>Set Move Route: #{get_character(sp[0])}#{route_options(sp[1])}#{generate_route(sp[1].list)}"
when 509
return nil
when 210
"<>Wait for Move's Completion"
when 221
"<>Prepare for Transition"
when 222
"<>Execute Transition: '#{sp[0]}'"
when 223
"<>Change Screen Color Tone: #{get_tone_data(sp[0])}, @#{sp[1]}"
when 224
"<>Screen Flash: #{get_color_data(sp[0])}, @#{sp[1]}"
when 225
"<>Screen Shake: #{sp[0]}, #{sp[1]}, @#{sp[2]}"
when 231
"<>Show Picture: #{pic_show(*sp[0..5])}, (#{sp[6]}%,#{sp[7]}%), #{sp[8]}, #{BLENDINGS[sp[9]]}"
when 232
"<>Move Picture: #{pic_move(*sp[0..5])}, (#{sp[6]}%,#{sp[7]}%), #{sp[8]}, #{BLENDINGS[sp[9]]}"
when 233
"<>Rotate Picture: #{sp[0]}, #{sp[1] < 0 ? "" : "+"}#{sp[1]}"
when 234
"<>Change Picture Color Tone: #{sp[0]}, #{get_tone_data(sp[1])}, #{sp[2]}"
when 235
"<>Erase Picture: #{sp[0]}"
when 236
"<>Set Weather Effects: #{set_weather(sp[0], sp[1])}, @#{sp[2]}"
when 241
"<>Play BGM: #{get_audio_file(sp[0])}"
when 242
"<>Fade Out BGM: #{sp[0]} sec."
when 245
"<>Play BGS: #{get_audio_file(sp[0])}"
when 246
"<>Fade Out BGS: #{sp[0]} sec."
when 247
"<>Memorize BGM/BGS"
when 248
"<>Restore BGM/BGS"
when 249
"<>Play ME: #{get_audio_file(sp[0])}"
when 250
"<>Play SE: #{get_audio_file(sp[0])}"
when 251
"<>Stop SE"
when 301
"<>Battle Processing: #{get_troop(sp[0])}"
when 601
": If Win"
when 602
": If Escape"
when 603
": If Lose"
when 604
": Branch End"
when 302
"<>Shop Processing: #{add_shop_item(sp[0], sp[1])}"
when 605
": : #{add_shop_item(sp[0], sp[1])}"
when 303
"<>Name Input Processing: #{get_actor(sp[0])}, #{sp[1]} characters"
when 311
"<>Change HP: #{change_hpsp(party_or_actor(sp[0]), sp[1], sp[2], sp[3], sp[4])}"
when 312
"<>Change SP: #{change_hpsp(party_or_actor(sp[0]), sp[1], sp[2], sp[3], false)}"
when 313
"<>Change State: #{party_or_actor(sp[0])}, #{AMOUNT_OP[sp[1]]} #{get_state(sp[2])}"
when 314
"<>Recover All: #{party_or_actor(sp[0])}"
when 315
"<>Change EXP: #{party_or_actor(sp[0])}, #{AMOUNT_OP[sp[1]]} #{value_or_var(sp[2], sp[3])}"
when 316
"<>Change Level: #{party_or_actor(sp[0])}, #{AMOUNT_OP[sp[1]]} #{value_or_var(sp[2], sp[3])}"
when 317
"<>Change Parameters: #{get_actor(sp[0])}, #{LVSTAT[sp[1]]} #{AMOUNT_OP[sp[2]]} #{value_or_var(sp[3], sp[4])}"
when 318
"<>Change Skills: #{get_actor(sp[0])}, #{AMOUNT_OP[sp[1]]} #{get_skill(sp[2])}"
when 319
"<>Change Equipment: #{get_actor(sp[0])}, #{EQUIPS[sp[1]]} = #{get_equip(sp[1], sp[2])}"
when 320
"<>Change Actor Name: #{get_actor(sp[0])}, '#{sp[1]}'"
when 321
"<>Change Actor Class: #{get_actor(sp[0])}, #{get_class(sp[1])}"
when 322
"<>Change Actor Graphic: #{get_actor(sp[0])}, '#{sp[1]}', #{sp[2]}, '#{sp[3]}', #{sp[4]}"
when 331
"<>Change Enemy HP: #{change_hpsp(troop_or_enemy(sp[0]), sp[1], sp[2], sp[3], sp[4])}"
when 332
"<>Change Enemy SP: #{change_hpsp(troop_or_enemy(sp[0]), sp[1], sp[2], sp[3], false)}"
when 333
"<>Change Enemy State: #{troop_or_enemy(sp[0])}, #{AMOUNT_OP[sp[1]]} #{get_state(sp[2])}"
when 334
"<>Enemy Recover All: #{troop_or_enemy(sp[0])}"
when 335
"<>Enemy Appearance: #{get_troop_enemy(sp[0])}"
when 336
"<>Enemy Transform: #{get_troop_enemy(sp[0])}, #{get_enemy(sp[1])}"
when 337
"<>Show Battle Animation: #{actors_or_enemies(sp[0], sp[1])}, #{get_animation(sp[2])}"
when 338
"<>Deal Damage: #{actors_or_enemies(sp[0], sp[1])}, #{AMOUNT_OP[sp[2]]} #{value_or_var(sp[3], sp[4])}"
when 339
"<>Force Action: #{actors_or_enemies(sp[0], sp[1])}, #{get_action(sp[2], sp[3])}, #{get_target(sp[4], sp[5])}"
when 340
"<>Abort Battle"
when 351
"<>Call Menu Screen"
when 352
"<>Call Save Screen"
when 353
"<>Game Over"
when 354
"<>Return to Title Screen"
when 355
"<>Script: #{sp[0]}"
when 655
": : #{sp[0]}"
else
"<>Unknown Command ##{si} [#{sp.join(", ")}]"
end
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.add_command(sc, sr="")
@@indent = sc.indent
st = write_command(sc.code, sc.indent, *sc.parameters)
@@output += "#{" " * @@indent}#{st}\n#{sr}" if st
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.add_page_conditions(sc)
@@output += "\n\t\t\tSwitch #{get_switch(sc.switch1_id)} == ON" if sc.switch1_valid
@@output += "\n\t\t\tSwitch #{get_switch(sc.switch2_id)} == ON" if sc.switch2_valid
@@output += "\n\t\t\tVariable #{get_variable(sc.variable_id)} >= #{sc.variable_value}" if sc.variable_valid
@@output += "\n\t\t\tSelf Switch #{sc.self_switch_ch} == ON" if sc.self_switch_valid
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.add_event(si)
@@output += sprintf("\n\t\n\t\n\t[Event #%.3d: #{@@current_map.events[si].name}]\n\t\t\n\t\t", si)
@@current_map.events[si].pages.each_with_index do |sp, sj|
@@output += "\n\t\t\n\t\t[Page ##{sj + 1}]"
@@output += "\n\t\t\t\n\t\t\tCode Size: #{sp.list.size}\n\t\t\t"
add_page_conditions(sp.condition)
@@output += "\n\t\t\t\n\t\t\t\n\t\t\t[Code]\n\t\t\t\n\t\t\t"
sp.list.each {|sc| add_command(sc, "\t\t\t") }
end
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.progress_maps
return @@counter_maps.to_f / $data_mapinfos.keys.size.to_f
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.progress_ces
return @@counter_ces.to_f / ($data_common_events.size.to_f - 1)
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.progress_troops
return @@counter_troops.to_f / ($data_troops.size.to_f - 1)
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.add_map(si, so)
Graphics.update
@@counter_maps += 1
@@current_map = load_data(sprintf("Data/Map%03d.rxdata", si))
@@output += sprintf("\n\n\n\n[Map #%.3d: %s]", si, so.name)
@@output += " (#{@@current_map.width}×#{@@current_map.height})\n\n"
@@output += "Parent Map ID: #{so.parent_id}\nTree Order: #{so.order}"
@@current_map.events.keys.sort.each {|se| add_event(se) }
@@progressbar_maps.zoom_x = progress_maps * 640.0
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.add_common_event(si, so)
return unless so
Graphics.update
@@counter_ces += 1
@@current_ce = so
@@output += sprintf("\n\n\n\n[CE #%.3d: %s]\n\n", si, so.name)
@@output += "Trigger Type: #{TRIGGER_TYPES[so.trigger]}\nSwitch: #{get_switch(so.switch_id)}\n\t\n\t"
@@output += "\n\t\n\t\n\t[Code]\n\t\n\t"
@@current_ce.list.each {|sc| add_command(sc, "\t") }
@@progressbar_ces.zoom_x = progress_ces * 640.0
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.add_troop(si, so)
return unless so
Graphics.update
@@counter_troops += 1
@@current_troop = so
@@output += sprintf("\n\n\n\n[Troop #%.3d: %s] (%d member(s))\n\n", si, so.name, so.members.size)
so.members.each {|se| @@output += troop_member(get_enemy(se.enemy_id), se.x, se.y, se.hidden, se.immortal) }
@@current_troop.pages.each_with_index do |sp, sj|
@@output += "\n\t\n\t\n\t[Page ##{sj + 1}]"
@@output += "\n\t\t\n\t\tCode Size: #{sp.list.size}\n\t\tTrigger Span: #{TROOP_SPAN[sp.span]}"
@@output += "\n\t\t\n\t\t\n\t\t[Code]\n\t\t\n\t\t"
sp.list.each {|sc| add_command(sc, "\t\t") }
end
@@progressbar_troops.zoom_x = progress_troops * 640.0
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.terminate
if @@progress_bitmap
@@progress_bitmap.dispose
@@progressbar_maps.dispose
@@progressbar_ces.dispose
@@progressbar_troops.dispose
end
@@text_title.bitmap.dispose
@@text_ver.bitmap.dispose
@@text_press.bitmap.dispose
@@text_done.bitmap.dispose
@@text_exit.bitmap.dispose
@@back_bars.bitmap.dispose
@@background.bitmap.dispose
@@text_title.dispose
@@text_ver.dispose
@@text_press.dispose
@@text_done.dispose
@@text_exit.dispose
@@back_bars.dispose
@@background.dispose
@@viewport.dispose
end
#--------------------------------------------------------------------------
# *
#--------------------------------------------------------------------------
def self.run
$data_actors ||= load_data("Data/Actors.rxdata")
$data_classes ||= load_data("Data/Classes.rxdata")
$data_skills ||= load_data("Data/Skills.rxdata")
$data_items ||= load_data("Data/Items.rxdata")
$data_weapons ||= load_data("Data/Weapons.rxdata")
$data_armors ||= load_data("Data/Armors.rxdata")
$data_enemies ||= load_data("Data/Enemies.rxdata")
$data_troops ||= load_data("Data/Troops.rxdata")
$data_states ||= load_data("Data/States.rxdata")
$data_animations ||= load_data("Data/Animations.rxdata")
$data_tilesets ||= load_data("Data/Tilesets.rxdata")
$data_common_events = load_data("Data/CommonEvents.rxdata")
$data_system ||= load_data("Data/System.rxdata")
$data_mapinfos ||= load_data("Data/MapInfos.rxdata")
@@viewport = Viewport.new(0, 0, 640, 480)
@@viewport.z = 0x7FFFFFFC
@@background = Sprite.new(@@viewport)
@@background.bitmap = Bitmap.new(1, 1)
@@background.bitmap.set_pixel(0, 0, Color.new(0, 0, 0, 128))
@@background.zoom_x = 640.0
@@background.zoom_y = 480.0
@@background.z = 0x7FFFFFFC
@@back_bars = Sprite.new(@@viewport)
@@back_bars.bitmap = Bitmap.new(1, 1)
@@back_bars.bitmap.set_pixel(0, 0, Color.new(40, 200, 64, 64))
@@back_bars.zoom_x = 640.0
@@back_bars.zoom_y = 48.0
@@back_bars.y = 432
@@back_bars.z = 0x7FFFFFFD
@@text_title = Sprite.new(@@viewport)
@@text_title.y = 0
@@text_title.z = 0x7FFFFFFE
@@text_title.bitmap = Bitmap.new(640, 48)
@@text_title.bitmap.font.size = 36
@@text_title.bitmap.font.bold = true
@@text_ver = Sprite.new(@@viewport)
@@text_ver.y = 56
@@text_ver.z = 0x7FFFFFFE
@@text_ver.bitmap = Bitmap.new(640, 24)
@@text_ver.bitmap.font.size = 20
@@text_ver.bitmap.font.bold = true
@@text_press = Sprite.new(@@viewport)
@@text_press.bitmap = Bitmap.new(640, 32)
@@text_press.bitmap.font.size = 24
@@text_press.y = 96
@@text_press.z = 0x7FFFFFFE
@@text_done = Sprite.new(@@viewport)
@@text_done.bitmap = Bitmap.new(640, 32)
@@text_done.bitmap.font.size = 24
@@text_done.y = 120
@@text_done.z = 0x7FFFFFFE
@@text_exit = Sprite.new(@@viewport)
@@text_exit.bitmap = Bitmap.new(640, 24)
@@text_exit.bitmap.font.size = 20
@@text_exit.y = 160
@@text_exit.z = 0x7FFFFFFE
st = "Event Exportexter for RPGXP"
@@text_title.bitmap.draw_text(0, 0, 640, 48, st, 1)
st = "[rv20220216] © 2022 KotatsuAkira"
@@text_ver.bitmap.draw_text(0, 0, 640, 24, st, 1)
st = "Press [L+R] to start or [B] to cancel"
@@text_press.bitmap.draw_text(0, 0, 640, 32, st, 1)
@@progress_bitmap = nil
loop do
Graphics.update
Input.update
break if Input.press?(Input::B)
next unless Input.press?(Input::L) && Input.press?(Input::R)
@@text_press.bitmap.font.color.set(160, 160, 160, 255)
@@text_press.bitmap.clear
st = "Processing data..."
@@text_press.bitmap.draw_text(0, 0, 640, 32, st, 1)
@@output = ""
@@current_map = nil
@@current_ce = nil
@@current_troop = nil
@@progress_bitmap = Bitmap.new(1, 1)
@@progress_bitmap.set_pixel(0, 0, Color.new(40, 200, 64, 255))
@@progressbar_maps = Sprite.new(@@viewport)
@@progressbar_ces = Sprite.new(@@viewport)
@@progressbar_troops = Sprite.new(@@viewport)
@@progressbar_maps.bitmap = @@progress_bitmap
@@progressbar_ces.bitmap = @@progress_bitmap
@@progressbar_troops.bitmap = @@progress_bitmap
@@progressbar_maps.y = 432
@@progressbar_ces.y = 448
@@progressbar_troops.y = 464
@@progressbar_maps.zoom_x = 0.0
@@progressbar_ces.zoom_x = 0.0
@@progressbar_troops.zoom_x = 0.0
@@progressbar_maps.zoom_y = 16.0
@@progressbar_ces.zoom_y = 16.0
@@progressbar_troops.zoom_y = 16.0
@@progressbar_maps.z = 0x7FFFFFFE
@@progressbar_ces.z = 0x7FFFFFFE
@@progressbar_troops.z = 0x7FFFFFFE
@@new_line = "\n\t\t\t"
@@counter_maps = 0
$data_mapinfos.keys.sort.each {|sk| add_map(sk, $data_mapinfos[sk]) }
@@current_map = nil
@@new_line = "\n\t"
@@counter_ces = 0
$data_common_events.each_with_index {|se, si| add_common_event(si, se) }
@@current_ce = nil
@@new_line = "\n\t\t"
@@counter_troops = 0
$data_troops.each_with_index {|se, si| add_troop(si, se) }
@@current_troop = nil
@@text_press.bitmap.font.color.set(255, 255, 255, 255)
@@text_press.bitmap.clear
st = "Processing done (#{@@output.size} bytes)!"
@@text_press.bitmap.draw_text(0, 0, 640, 32, st, 1)
st = "Press [C] to save to \"EventExport.txt\" or [B] to cancel."
@@text_done.bitmap.draw_text(0, 0, 640, 32, st, 1)
st = "The program will exit afterwards."
@@text_exit.bitmap.draw_text(0, 0, 640, 24, st, 1)
loop do
Graphics.update
Input.update
if Input.trigger?(Input::B)
break
elsif Input.trigger?(Input::C)
File.open("EventExport.txt", "w") {|sf| sf.write(@@output) }
break
end
end
terminate
exit
break
end
terminate
end
end
Alles anzeigen
~炬燵あ
Holerö! Es trug sich zu, da veranstaltete das Multimediaxis-Forum im Jahr 2016 für fünf Wochen einen Contest mit dem Thema "Rette die Welt in 20 Minuten", für den Sölf und ich einen kurzen Teaser für ein AceAttorney-ähnliches Spiel produziert haben. Unser Beitrag, ganz knapp noch gelandet auf dem dritten Platz bei der Auswertung, war soweit ich noch weiß der einzige, der im Anschluss nicht veröffentlicht wurde. Und das eigentlich nur, weil wir noch dem Titelbildschirm einen passenden BGM-Track spendieren wollten, dazu kam es aber nie.
Ganz spontan haben wir uns in der Nacht zum 10. März 2023 darüber beraten, ob wir das Ding nicht vielleicht doch mal rausbringen wollen und schwupps ward es geschehen und der Thread drüben im MMX war in aller Frühe schon fertig, das Pendant auf MVde folgte sogleich gegen Mittag. Jetzt übertrage ich den Thread-Mainpost von damals hierhin, damit er nicht verlorengeht, alles ab hier ist unverändert.
Das Spiel
Das Ultimatum der Apokalypse wurde mit dem RPG Maker 2000, damals noch in einer sehr alten Fassung, erstellt und nutzt eine noch recht frühe Version meiner bis heute noch hin und wieder andauernden DestinyScript-Weiterentwicklung. Dazu gesellt sich außerdem eine Modifikation, die die Größe des Spielbildschirms auf die doppelte Höhe ändert, um eine NDS-/3DS-ähnliche Gesamtauflösung zu bieten.
Steuerung
Der Standard-Vollbildmodus wurde vollständig entfernt, die Fenstergröße kann nach wie vor zwischen einfach und doppelt mit F5 gewechselt werden. Die untere Hälfte des Spielbildschirms wird komplett mit der Maus gesteuert, Tastatur- oder Gamepad-Eingaben sind nicht implementiert.
Story
Fenris Vestive, ein anerkannter Detektiv, ist der Aufforderung des Wächtermagiers Kryst Apocallo nachgekommen, den Mörder seiner Eltern und seines Bruders zu finden, wofür er insgesamt 3 Tage Zeit hatte. Sobald die Zeit um Punkt Mittag am heutigen Tage abläuft, wird Kryst, sofern der Mörder nicht gefunden wird, den großen Kristall, der die Schutzbarriere der letzten Bastion der Menschen gegen gefährliche Monster und Seuchen/Krankheiten aufrecht erhält, überladen und ihn somit, das Ende der Welt herbeiführend, zerstören.
Es verbleiben noch ungefähr 20 Minuten, als Fenris, Kryst und General Dilces, Überwacher der Ermittlungen und derzeitiges Oberhaupt des Militärs, sich die Aussage des vermeintlichen Täters Lilk Redmur, einem alten Kollegen von Dilces im Ruhestand, in der Kristallkammer anhören. Nun liegt es an Fenris, den sturen Altgeneral schlussendlich mit Beweisen zu konfrontieren, die seine Schuld belegen.
Aufbau
Durch die Contestvorgaben waren wir auf etwa 20min Gameplay begrenzt. Wir haben uns daher dafür entschieden, ein einzelnes Kreuzverhör zu erstellen, welches effektiv das letzte eines kompletten Falls darstellt. Da somit alles vor diesem Kreuzverhör komplett fehlt, ist der Schwierigkeitsgrad entsprechend hoch angesetzt, da ihr mit Beweisen eines mehrstündigen Falls bombardiert werdet, die ihr nun alle sichten, verstehen und teilweise auch anwenden müsst. Macht euch mit ihnen am besten vertraut, bevor der 20-minütige Timer bei der Eröffnung des Verhörs gestartet wird.
Keine Bange, wenn ihr diese Konfrontation nicht im ersten Versuch meistert, das ist relativ normal. Uns ist klar, dass das alles nicht optimal gelöst ist, diese Aufmachung ergab sich damals so aus dem Contest.
Download
★ Auf Mediafire (Offizielle Downloadquelle, hochgeladen von Sölf)
Falls ihr das Spiel selbst irgendwo hochladen wollt, fragt uns vorher.
Die Inhalte zu modifizieren oder zu erweitern ist nicht gestattet.
Wir wünschen euch viel Spaß! Auch wenn es unwahrscheinlich ist, dass wir nach all der Zeit hierdran noch was machen werden (daher auch die direkte Verfrachtung ins Friedhof-Forum), ist Feedback gerne gesehen!
Holerö und so, ich bin dann auch mal hier rübergewandert. °ω°'
Ich befasse mich jetzt schon über geschlagene zwei Dekaden mit der RPG-Maker-Reihe und für eine ebenfalls sehr lange Zeit mit der Historie ihrer ganzen Produktlinie, die noch um einiges weiterreicht. Manche dürften mich aus der Co-Administration von Makerpendium oder auch wenn ich da eher selten zugegen war aus dem alten MVde-Forum kennen (oder vielleicht sogar von meiner täglichen Liveshow).
Meine Fachbereiche im Spielebasteln sind vor allem sehr technischer Natur, soll heißen, Code in x86-ASM, Ruby und DestinyScript kann man von mir erwarten. Abgesehen von 2000RTP- und EasyRPG-Tiles sowie vorgerenderten Partikeleffekten sieht's im Erschaffen von Grafik dann bei mir eher meh bis mies aus, von großen Geschichten will ich gar nicht erst anfangen, für sowas arbeite ich dann lieber mit Leuten zusammen, die das wirklich drauf haben.
Auf MVde hatte ich diverse Materialien in die Datenbank reingestellt, alles davon und noch ein bisschen mehr könnt ihr aber, wenn die Sachen verschwinden sollten, mittlerweile auch auf itch.io finden.
~炬燵あ