|
-
There's a script in the LeGo-Thread that changes the value of an item during trading.
https://forum.worldofplayers.de/foru...1#post21130811
Maybe that's what you're lloking for
-
Funktionen kürzer als fünf Bytes
Ich beschäftige mich gerade ein bisschen mit dem Bytecode von Daedalus-Funktionen und frage mich, ob es ausser einer leeren Funktion (zPAR_TOK_RET = ein Byte) noch andere Möglichkeiten gibt, dass eine (sinnvolle) Daedalus-Funktion jemals weniger als fünf Bytes lang ist.
Weiss jemand da ein Beispiel oder kann mir bestätigen, dass das nicht geht?
-
Ich wüsste auch nichts. Aber die kürzeste Funktion, abgesehen von einer leeren Funktion, sollte 6 Byte sein: Irgendeine 5 Byte Funktion und dann kommt immer noch ein zPAR_TOK_RET.
-
Danke. Ich denke da hast du recht. Bedenken hatte ich bei Funktionen wie
Code:
func float castfromintf(var int f) {
f;
};
Da hatte ich befürchtet, das Funktionsargument bliebe einfach auf dem Stack, aber das ist nicht der Fall:
Code:
zPAR_TOK_PUSHVAR, castfromintf.f (5 bytes)
zPAR_OP_IS (1 byte)
zPAR_TOK_PUSHVAR, castfromintf.f (5 bytes)
zPAR_TOK_RET (1 byte)
-
Zitat von mud-freak
Da hatte ich befürchtet, das Funktionsargument bliebe einfach auf dem Stack, aber das ist nicht der Fall:
Code:
zPAR_TOK_PUSHVAR, castfromintf.f (5 bytes)
zPAR_OP_IS (1 byte)
zPAR_TOK_PUSHVAR, castfromintf.f (5 bytes)
zPAR_TOK_RET (1 byte)
Die ersten beiden Op-Codes sind Teil des Funktions-Prologs. Die Parameter, mit welchen die Funktion aufgerufen wird, legt der Aufrufer auf den Stack. Da die Parameter auch nur (statische) Symbole sind, ist es die Aufgabe des Compilers, die Werte vom Stack den Parameter-Symbolen zuzuweisen. Mir ist kein Daedalus-Compiler bekannt, der diese Funktion optimieren würde (den Parameter auf dem Stack liegen lassen und sofort zurückkehren).
"Unter diesen schwierigen Umständen bin ich mir sicher, daß diese guten Menschen meinen augenblicklichen Bedarf an deren Gold verstehen werden." -- Connor
Geändert von NicoDE (22.02.2018 um 07:05 Uhr)
-
Hier mal ein kleines Stück Code, vielleicht findet es ja jemand mal nützlich. Ich musste sicherstellen, dass ein Gitter offen ist, weil der Spieler sonst eventuell feststeckt. Das Problem ist, dass der Spieler das Gitter im Spiel zuvor selbst geschlossen haben könnte. Wld_SendTrigger würde ein offenes Gitter schließen und ein geschlossenes Gitter öffnen.
Die Lösung war letzten Endes sehr einfach, aber vielleicht hilft es ja jemandem, der mal ein ähnliches Problem hat.
Code:
// GEFAENGNISGITTER_RECHTS_03 needs to be open so the hero can get out
var zCMover moverGitter;
moverGitter = MEM_PtrToInst(MEM_SearchVobByName("GEFAENGNISGITTER_RECHTS_03"));
if moverGitter.actKeyframe == 0
{
Wld_SendTrigger("GEFAENGNISGITTER_RECHTS_03");
};
GEFAENGNISGITTER_RECHTS_03 ist der Name des Movers, und bei uns ist keyframe == 0 der geschlossene Zustand, so dass ich in diesem Fall per Trigger das Gitter öffnen kann.
Sollte man mal mit einem komplizierteren Mover arbeiten, habe ich auch noch die Funktionen
Code:
void __thiscall zCMover::MoveToKeyframe(int) 0x006125D0 0 9 protected: void __thiscall zCMover::MoveToKeyframe(int)
void __thiscall zCMover::SetToKeyframe(float float) 0x00612090 0 6 public: void __thiscall zCMover::SetToKeyframe(float float)
gefunden. Ich vermute, dass man mit der ersten Funktion den Mover auf die gewünschte Position (in meinem Fall 1) setzen kann, aber in meinem Fall hat obige Lösung bereits geklappt, weshalb ich das nicht weiter ausprobiert habe.
-
Ich wünschte, ich könnte Sektis "Speichern verbieten"-System verwenden... Aber da mir die G1-Engineadressen nicht zur Verfügung stehen, versuche ich mich derzeit an einem Workaround.
Maßgebend ist die Funktion "Update_Menu_Item", die ich vor geraumer Zeit mit korrekter Engineadresse (aber leider nur für den Text) erhalten habe.
Das Ziel ist es, den Menüpunkt auszugrauen (Schriftart ändern?), den Menüpunkt nicht mehr anwählbar zu haben (flags IT_SELECTABLE) und vielleicht noch den Schriftzug "Speichern nicht möglich" reinzukriegen. Letzteres ist wohl das einfachste davon... Hab ich mit Update_Menu_Item schon hingekriegt. Der Rest ist nicht ganz so einfach.
Code:
func void SpeichernVerbieten(var string name, var string val)
{
MEM_InitAll ();
var int itPtr;
itPtr = MEM_GetMenuItemByString(name);
CONST INT IT_SELECTABLE = 4; //wird unten gebraucht, aus der Definitionsdatei des Menüs
if (!itPtr) {
//MEM_Error(ConcatStrings("Update_Menu_Item: Invalid Menu Item: ", name));
return;
};
var zCMenuItem Speichern;
Speichern=MEM_PtrToInst (MEM_GetMenuItemByString(name));
const int SetText =5061760;
if ForbidSaving==1 //Variable wird in einem Dialog gesetzt
{
Speichern.zCView_flags = Speichern.zCView_flags & ~IT_SELECTABLE;//nicht mehr selectable
CALL_IntParam(true);
CALL_IntParam(0);
CALL_zStringPtrParam(val);
CALL__thiscall(itPtr, SetText);
}else
{
Speichern.zCView_flags = Speichern.zCView_flags | IT_SELECTABLE;//erlaubt
CALL_IntParam(true);
CALL_IntParam(0);
CALL_zStringPtrParam("Spiel speichern");
CALL__thiscall(itPtr, SetText);
};
};
Das Ergebnis: Es steht der Text "Speichern nicht möglich" (übergebe ich in einer Frameschleife), aber der Menüpunkt ist immer noch voll funktionsfähig.
Es würde mir auch schon reichen, wenn ich den Menüpunkt kurzzeitig gegen einen Dummy austauschen könnte, der nicht selektierbar ist und ausgegraut. Nur wie mache ich DAS?
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
-
Wenn ich das richtig sehe, brauchst du nur die Engineadresse für die QuickSaves?
Kann ich dir nachher mal raussuchen. Wenn ich sie finde, editier' ich die hier rein.
Wobei... Gibt es bei G1 überhaupt Quicksaves? Ich meine nämlich nicht. Wäre es dann nicht damit getan, die Quicksave-Parts einfach rauszunehmen?
-
In G1 GIBT es Quicksaves, habe ich durch diverse Tester meiner Mod rausgefunden. Die haben das gerne benutzt. Allerdings kann man diese nicht mehr laden, wenn man Gothic beendet hat. Die sind also nur für diese Session verfügbar.
Was ist mit 256? Ändert sich das etwa nicht?
Ich paste mal vorsichtshalber den ganzen alten Code von Sektenspinner:
Code:
//######################################################
//
// Speicherkontrolle
//
//######################################################
/* Von Dir auszufüllende Funktion!
* Entscheide ob man gerade Speichern darf oder nicht.
* Gibt den entsprechenden Wert zurück. */
func int AllowSaving() {
/* Voreingestellt: Speichern immer erlaubt */
return true;
};
/* Wird aufgerufen, wenn Speichern verboten war,
* jetzt aber gerade wieder erlaubt wurde. */
func void OnAllowSaving() {
Print ("Speichern ab jetzt erlaubt!");
};
/* Wird aufgerufen, wenn Speichern erlaubt war,
* jetzt aber gerade wieder verboten wurde. */
func void OnDisallowSaving() {
Print ("Speichern ab jetzt verboten!");
};
//######################################################
//
// INTERNAS - Ändern auf eigene Gefahr
//
//######################################################
/* Benötigte Konstante */
const INT IT_ONLY_OUT_GAME = 256;
/* War speichern beim letzten Check erlaubt? Für Benachrichtigungsfunktionen. */
var int SavingDisabled_LastCheck;
/* Hier steht ob Quicksaves an sind: */
const int s_bUseQuickSave_address = 9118160; //0x8B21D0
/* Funktion für den Nutzer, die AllowSaving auswertet und umsetzt */
instance saveMenuItem (zCMenuItem);
func void EnforceSavingPolicy() {
//--------------------------------------
// Menüitem holen:
//--------------------------------------
var int saveMenuItemPtr;
saveMenuItemPtr = MEM_GetMenuItemByString ("MENUITEM_MAIN_SAVEGAME_SAVE");
if (!saveMenuItemPtr) {
//wtf?
var string err; err = "EnforceSavingPolicy: MENUITEM_MAIN_SAVEGAME_SAVE not found!?";
Print (err); PrintDebug (err);
return;
};
MEM_AssignInst (saveMenuItem, saveMenuItemPtr);
//--------------------------------------
// Der eigentliche Code:
//--------------------------------------
if (!AllowSaving()) {
saveMenuItem.m_parItemFlags = saveMenuItem.m_parItemFlags | IT_ONLY_OUT_GAME;
/* Scripter benachrichten, falls wirkliche Änderung */
if (!SavingDisabled_LastCheck) {
SavingDisabled_LastCheck = TRUE;
OnDisallowSaving();
//Quicksave aus.
MEM_WriteInt (s_bUseQuickSave_address, 0);
};
} else {
/* Speichern ist erlaubt */
saveMenuItem.m_parItemFlags = saveMenuItem.m_parItemFlags &~ IT_ONLY_OUT_GAME;
/* Scripter benachrichten, falls wirkliche Änderung */
if (SavingDisabled_LastCheck) {
SavingDisabled_LastCheck = 0;
OnAllowSaving();
//Quicksave an:
MEM_WriteInt (s_bUseQuickSave_address, 1);
};
};
};
edit: Der Code funktioniert einwandfrei, wenn ich die Quicksaves rausnehme. In G1 sind die auf den Tasten F9 (speichern) und F10 (laden). Ich hatte beim ersten Anwenden sekundenmäßige Ruckler, darum habe ich zugunsten der Performance vor das Setzen des flags eine Abfrage gemacht, ob das Flag schon darin enthalten ist (if !(saveMenuItem.m_parItemFlags & IT_ONLY_OUT_GAME)) . Nicht, dass irgendwas doppelt und dreifach gesetzt wird. Die Ruckler sind dadurch verschwunden.
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
Geändert von Bisasam (16.04.2018 um 15:04 Uhr)
-
Hmm, ich hab grade nochmal gesucht. Leider finde ich keine Quicksave-Funktion in der GothicMod.exe...
Wo wir allerdings gerade beim Thema sind... Während eines Dialogs wird ja die Kamera gelockt. Ist es vielleicht möglich, die mithilfe von Ikarus freizugeben, sodass man sie (theoretisch) drehen könnte?
-
Echt nicht? Ist das mit dem Systempack gekommen?
Versuch du mal in deiner Version mit F9 zu speichern und F10 zu laden. Geht aber nur außerhalb des devmodes.
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
-
Tatsache...
Gut, bei mir crasht Gothic einfach nur, aber... Hey, wieder was neues gelernt
-
Zitat von Dada
Wo wir allerdings gerade beim Thema sind... Während eines Dialogs wird ja die Kamera gelockt. Ist es vielleicht möglich, die mithilfe von Ikarus freizugeben, sodass man sie (theoretisch) drehen könnte?
In LeGo Trialoge.d gibt es Funktionen um die Dialogkamera abzuschalten und Kamerafahrten auszuführen während Dialog.
-
Stimmt, danke dir. Hab ich gar nicht mehr dran gedacht
-
Kannst du vielleicht in der Gothic.exe nachgucken statt in der GothicMod.exe? Tut mir Leid, dass ich dich so rumscheuche. Danke, dass du dir das überhaupt angesehen hast
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
-
Zitat von Bisasam
Kannst du vielleicht in der Gothic.exe nachgucken statt in der GothicMod.exe? Tut mir Leid, dass ich dich so rumscheuche. Danke, dass du dir das überhaupt angesehen hast
Die hätte, glaube ich, keine Debuginformationen, da würde man also quasi im Dunkeln stochern. Und ich denke auch nicht, dass sich das Quicksave-Feature nur in der Gothic.exe versteckt.
-
Mal abgesehen davon... Wird nicht durch den GothicStarter generell die GothicMod.exe gestartet?
-
Zitat von Bisasam
Kannst du vielleicht in der Gothic.exe nachgucken statt in der GothicMod.exe? Tut mir Leid, dass ich dich so rumscheuche. Danke, dass du dir das überhaupt angesehen hast
Die Installer einiger Mods haben um die Spielversion zu erkennen wohl einfach auf die Größe der Gothic.exe in Bytes geschaut. Damit diese Mods sich weiterhin installieren lassen, ist seit dem Playerkit und Version 1.08k die Gothic.exe einfach so gut wie leer und startet direkt die GothicMod.exe, hat aber die selbe größe wie früher.
Soweit ich weiß hat NicoDE da etwas mit zu tun gehabt. Für mehr Informationen also besser dort fragen.
Fakt ist jedenfalls, das die Gothic.exe nix taugt, das Spiel läuft in der GothicMod.exe ab.
-
Zitat von Degenerated
Soweit ich weiß hat NicoDE da etwas mit zu tun gehabt.
Jupp, das war meine Idee (die Gothic.exe wurde künstlich vergrößert, um die existierenden Setups weiterhin zu unterstützen).
Die Gothic.exe aus dem 'aktuellen' Player-Kit für Gothic 1 macht nichts anderes als "GothicStarter.exe -game:GothicGame" auszuführen und sich zu beenden.
Allerdings gibt es Fälle, wo es zwei vollständige Gothic.exe und GothicMod.exe (wird vom GothicStarter gestartet) in der Installation vorhanden sind. Wenn ich mich recht erinnere, dann ist das bei der GOG-Version so. Eigentlich sollte nur noch der GothicStarter (und dadurch indirekt die GothicMod.exe) verwendet werden...
"Unter diesen schwierigen Umständen bin ich mir sicher, daß diese guten Menschen meinen augenblicklichen Bedarf an deren Gold verstehen werden." -- Connor
-
Och menno auf die Frage nach der exe hab ich ne Antwort aber nicht auf die Frage nach Quicksaves. <.<
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
|
|