Edit:
RMVX - verdammter Mist, wieso vergesse ich das, zu erwähnen O____o
Okay, Leute... ich hoffe, dass ihr mir helfen könnt.
Vor längerer Zeit hat mir hellminor schon ein kleines Script für meine Novel gebastelt, mit dem ich Switches aus den Spielständen auslesen kann um z.B. abzufragen, ob man in einem Speicher schon etwas erreicht hat.
Jetzt brauche ich für eine Option das ganze andersrum...
Gibt es einen Befehl, mit dem ich einen Switch AN oder AUS machen kann in einem ANDEREN Spielstand?
(Ich nehm auch Variablen oder sonstiges)
Sprich:
Ich schalte Option A in meinem Menü an und in den Savegames geht dadurch Switch 200 (das wäre der) AN. Schalte ich es wieder aus, dann geht es auch überall AUS.
Falls nicht: Gibt es eine andere Option?
Z.B. die Möglichkeit das in eine Textdatei zu speichern und auszulesen?
Wenn das einfacher ist ^^
Ich habe bereits die Möglichkeit von ein paar Threads unter mir probiert, aber leider
scheint diese Art die Variable zu vergessen, sobald das Spiel einmal abgeschaltet war >_<
Das ist nur eine Änderung des Windows, nicht der Speicherstände.
Hier ist eine kleine schnelle Testversion. Wahrscheinlich könnte man dies auch effektiver lösen, allerdings wollte ich es möglichst simpel und leicht verständlich, beziehungsweise einsteigerfreundlich erweiterbar, halten.
Was dieser Code macht?
Er öffnet die Dateien "Save1.rxdata" bis "Save4.rxdata", liest sie ein, ändert den Switch mit der ID 'switch_id' auf den Wert 'new_state' und speichert die Datei wieder ab. In der gleichen Weise wie der Maker die Spielstände öffnen, beziehungsweise speichern, würde.
Ich habe es zwar nicht auf die Schnelle getestet, allerdings sollte es wahrscheinlich funktionieren. Ich kenne mich mit den standard Funktionen des Makers nicht sonderlich aus da ich nie damit arbeite.
Ich kenn mich mit sowas kaum aus (aber erstmal danke für die Mühe ) und wollte jetzt einfach noch einmal nachfragen, weil ich die Funktionsweise nicht ganz verstanden habe.
Ich kopier das ganz normal da rein, wo die Scripte reinkommen (über Main) und im Eventcode mache ich dann Callscript mit:
switches[switch_id] = new_state
Z.B. switches[001] = on
Und dann macht er mir in alle vier Savegames die auf ON?
Hab ich das so richtig verstanden? Ich kann ein gaaaanz klein wenig RGSS verstehen (hab auch hier und da sogar mal was an einem Script ausgebessert), aber eigentlich bin
ich in dem Bereich noch Anfänger.
Edit:
Okay, da hab ich noch iwo nen Denkfehler drin, denk ich.
Du kannst das Script überall overhalb von Main hineinkopieren.
Um es aufzurufen müsstest du im call script folgendes eingeben:
set_switch_for_all_save_files(0,true)
damit würde der Switch mit der ID '0' auf 'ON' geschaltet werden.
Da der Funktionsname für ein Callscript wahrscheinlich zu lang ist, etwas was ich ursprünglich nicht bedacht habe, würde ich dir jedoch raten den Funktionsnamen abzukürzen.
Ich habe es gerade für den RPG-Maker XP getestet, es schein für mich zu funktionieren.
Allerdings habe ich an einer Stelle einen kleinen Fehler gefunden und noch hinzugefügt, dass das Script auch den Switch im derzeit geladenen Projekt ändern falls eines geladen ist.
Hier also nocheinmal eine klein wenig überarbeitete Version.
def set_switch_globally(switch_id, new_state)
if $game_switches != nil
$game_switches[switch_id] = new_state
end
max_save_file_number = 4
for i in 1..max_save_file_number
file_name = "Save" + i.to_s + ".rxdata"
if not FileTest.exist?(file_name)
next
end
file = File.open(file_name, "rb")
characters = Marshal.load(file)
frame_count = Marshal.load(file)
system = Marshal.load(file)
switches = Marshal.load(file)
variables = Marshal.load(file)
self_switches = Marshal.load(file)
screen = Marshal.load(file)
actors = Marshal.load(file)
party = Marshal.load(file)
troop = Marshal.load(file)
map = Marshal.load(file)
player = Marshal.load(file)
file.close
switches[switch_id] = new_state
file = File.open(file_name, "wb")
Marshal.dump(characters, file)
Marshal.dump(frame_count, file)
Marshal.dump(system, file)
Marshal.dump(switches, file)
Marshal.dump(variables, file)
Marshal.dump(self_switches, file)
Marshal.dump(screen, file)
Marshal.dump(actors, file)
Marshal.dump(party, file)
Marshal.dump(troop, file)
Marshal.dump(map, file)
Marshal.dump(player, file)
file.close
end
return true
end
Die vorherige war nicht dafür gedacht gewesen innerhalb eines Spielstandes aufgerufen zu werden sondern nur aus einer Art Menü heraus.
Ich glaube Rosa Canina verwendet der RPGMaker VX (sowas sollte allerdings am Anfang eines Threads gesagt werden).
In dem Fall muss das Script etwas modifiziert werden:
module GlobalSwitches
@switch_state = {} # caches switch values
def self.set(index, value)
return if @switch_state[index] == value
@switch_state[index] = value
(0..3).each do |i|
filename = "Save#{file_index + 1}.rvdata"
next unless FileTest.exist?(filename)
data = []
File.open(filename, "rb") do |io|
until io.eof?
data << Marshal.load(io)
end
end
sw = data.find {|s| s.kind_of?(Game_Switches)}
if sw[index] != value then
sw[index] = value
File.open(filename, "wb") do |io|
data.each do |d|
Marshal.dump(d, io)
end
end
end
end
end
end
Ich habe nicht recht darüber nachgedacht, ich dachte es würde nichts desto trotz funktionieren.
Das Problem liegt einfach daran, dass die Save-Files des RMVX anders benannt sind als diejenigen des RPG-Makers XP.
Anstatt .rxdata ist das Appendix beim VX .rvdata.
Das Script von -KD- jedoch wird den Switch-Zustand nicht ändern sofern er bereits richtig gesetzt ist. Das könnte gefährlich sein in dem Fall, dass er bereits an anderer Stelle lokal verändert wurde.
In dem Script (welches wirklich sehr viel besser als meines aussieht) sollte diese Zeile heraus genommen werden:
return if @switch_state[index] == value
Damit das Endergebnis so aussieht:
module GlobalSwitches
@switch_state = {} # caches switch values
def self.set(index, value)
@switch_state[index] = value
(0..3).each do |i|
filename = "Save#{file_index + 1}.rvdata"
next unless FileTest.exist?(filename)
data = []
File.open(filename, "rb") do |io|
until io.eof?
data << Marshal.load(io)
end
end
sw = data.find {|s| s.kind_of?(Game_Switches)}
if sw[index] != value then
sw[index] = value
File.open(filename, "wb") do |io|
data.each do |d|
Marshal.dump(d, io)
end
end
end
end
end
end
Das Problem nämlich welches ich sonst sehe wäre folgendes:
Gemäß dem Fall jeder Switch wird als "false" initialisiert würde der Switch in jedem neu erstellten Speicherstand immer false sein und könnte, wenn er bereits auf false gesetzt ist nichtmehr für alle anderen Speicherstände auf false gesetzt werden, auch wenn dieser Switch bei anderen Speicherständen auf true stehen würde.
Außer natürlich ich habe irgendetwas übersehen.
@-KD-
Ja, sorry. Tut mir echt leid. Ich war mir sicher es geschrieben zu haben und hab es dann doch iwie übersehen. Doof, da mir das schon einmal
bei einer Frage hier passiert ist (und ich frage scripttechnisch nun wirklich nur alle Jubeljahre mal was :'D)
Hab beide Varianten jetzt ausprobiert und bekomme eine Fehlermeldung für diese Zeile: filename = "Save#{file_index + 1}.rvdata" (Zeile 7 bzw 6, je nach Version des Scriptes)
KA, was an ihr falsch sein soll O_o
Fehlermeldung besagt:
Script "Global Variable" line 6 (oder 7): NameError occured.
undefined local variable or method "file_index" for
GlobalSwitches:Module
Zitat
Ich habe nicht recht darüber nachgedacht, ich dachte es würde nichts desto trotz funktionieren.
...
Eine Umbenennung der Dateiendung im Script hat leider auch Fehlermeldungen ausgegeben. ._.
@Cornix: Hm, ja, es kann zu Fehlern kommen wenn man diesen globalen Switch über ein normales control switches verändert, ohne diese Methode aufzurufen, und danach das Spiel abspeichert. Man könnte in Game_Switches einen Code einfügen, der den Cache leert, sobald ein Switch gesetzt wird.
Das würde dann so aussehen:
class Game_Switches
alias set_global_switch []=
def []=(switch_id, value)
GlobalSwitches.remove_from_cache(switch_id, value)
set_global_switch(switch_id, value)
end
end
module GlobalSwitches
@switch_state = {} # caches switch values
def self.remove_from_cache index, value
@switch_state.delete(index) if @switch_state[index] != value
end
def self.set(index, value)
return if @switch_state[index] == value
$game_switches.set_global_switch(index, value)
@switch_state[index] = value
(0..3).each do |i|
filename = "Save#{i + 1}.rvdata"
next unless FileTest.exist?(filename)
data = []
File.open(filename, "rb") do |io|
until io.eof?
data << Marshal.load(io)
end
end
sw = data.find {|s| s.kind_of?(Game_Switches)}
if sw[index] != value then
sw[index] = value
File.open(filename, "wb") do |io|
data.each do |d|
Marshal.dump(d, io)
end
end
end
end
end
end
Vielen Dank, -KD- (und auch an dich cornix).
Bei meinem Test gerade lief es vorzüglich.
Ich schreib euch in die Credits von SSM:SF Akte1 rein. ^^
(Release ist vermutlich nächste Woche, dies war, neben dem Betatest das einzige, was noch fehlte)