|
-
Einstiegspunkte für Dietrich abgebrochen, Gegenstand verkaufen und Waffe ausrüsten
Hi zusammen!
Ich suche nach den Einstiegspunkten (Falls es die bereits gibt direkt in den Scripten, ansonsten auch gerne per Hook) folgender Events in Gothic 2:
- Dietrich abgebrochen (gab es da nicht was in Gothic 1, wo der Held "Hmm... abgebrochen." gesagt hat? Müsste es ja eigentlich dann geben, nur find ich es nicht)
- Gegenstand kaufen und Held hat nicht genug Gold dafür (Die Funktion PLAYER_TRADE_NOT_ENOUGH_GOLD() in B_RefuseAction.d gibt es ja schon, scheint allerdings nicht ausgeführt zu werden?)
- Waffe ausrüsten (evt. ein Hook für on_equip?)
Ziel von diesen Einstiegspunkten ist für mich einige neue SVMs hinzuzufügen, um das Spiel etwas lebendiger zu gestalten und mit weniger Hinweis-Prints auszukommen. Nur, damit ihr auch wisst, worauf ich hinaus will.
Wenn jemand da Anhaltspunkte hätte, wäre ich sehr dankbar =) Die Funktionalität von Hooks habe ich auch verstanden, allerdings fällt es mir immer noch schwer, das so zusammenzusetzen, bis es dann funktioniert
Geändert von Draxes (24.03.2020 um 19:44 Uhr)
-
Dietrich: wenn du in G2 nach "abgebrochen" suchst in den Skripten, findest du z.B. PRINT_PICKLOCK_BROKEN. Wenn du dann danach suchst, findest du die Funktion Content\Story\G_Functions\G_Picklock.d, die vielversprechend aussieht. (Ich habe nicht getestet, ob sie auch tatsächlich ausgeführt wird.)
Waffe: theoretisch kannst du jeder Waffe händisch eine on_equip Funktion schreiben.
Für Hooks: geht es um G1 oder G2?
-
Zitat von Milky-Way
Dietrich: wenn du in G2 nach "abgebrochen" suchst in den Skripten, findest du z.B. PRINT_PICKLOCK_BROKEN. Wenn du dann danach suchst, findest du die Funktion Content\Story\G_Functions\G_Picklock.d, die vielversprechend aussieht. (Ich habe nicht getestet, ob sie auch tatsächlich ausgeführt wird.)
Ahh, du hast vollkommen recht. Ich habe nur nach der SVM PickBroken geschaut, die gar nicht verwendet wird. Stattdessen wird dort direkt ein Sound aufgerufen... Danke dir! Ich teste das nachher mal.
Zitat von Milky-Way
Waffe: theoretisch kannst du jeder Waffe händisch eine on_equip Funktion schreiben.
Theoretisch ja, praktisch sehr viel Aufwand. Deshalb dachte ich, ist es vielleicht einfacher, wenn man sich da mithilfe eines Hooks einklinkt (oder so).
Zitat von Milky-Way
Für Hooks: geht es um G1 oder G2?
Gothic 2
-
Hier kannst du ja mal schauen, ob es Funktionen gibt, die passen könnten:
https://forum.worldofplayers.de/foru...7#post17631567
Z.B.:
Code:
void __thiscall oCNpc::EquipWeapon(oCItem *) 0x0073A030 0 5 public: void __thiscall oCNpc::EquipWeapon(oCItem *)
Für die Funktion kannst du so einen Hook einbauen:
Code:
const int oCNpc__EquipWeapon = 7577648; // 0x0073A030
func void Hook_EquipWeapon()
{
var C_NPC slf; slf = _^(ECX); // Npc, für den die Funktion aufgerufen wurde
var C_ITEM itm; itm = _^(MEM_ReadInt(ESP+4)); // ESP+4 sollte das erste Argument der Engine-Funktion sein (oCItem), das zweite ist ESP+8,... wenn es noch mehr gibt
// abfragen, ob slf der Spieler ist
// abfragen, ob itm das gewünschte Item ist
// SVM abspielen
};
func void Hook_Init()
{
HookEngineF(oCNpc__EquipWeapon, 5, Hook_EquipWeapon);
};
Die Funktion Hook_Init sollte dann einmal pro Gothic-Session aufgerufen werden. Zum Beispiel so
Code:
const int newsession = TRUE;
...
func void init_global()
{
...
MEM_InitAll();
LeGo_Init(...);
if newsession
{
Hook_Init();
newsession = FALSE;
};
...
};
Dann sollte die Funktion oCNpc::EquipWeapon gehooked sein und deine Funktion Hook_EquipWeapon aufgerufen werden.
Für die Konstante
Code:
const int oCNpc__EquipWeapon = 7577648; // 0x0073A030
musst du einfach die Hex-Adresse 0x0073A030 nach dezimal umrechnen, z.B. mit dem Windows Taschenrechner oder über google eine beliebige Seite finden, die das kann.
Die Zahl 5 kannst du hier direkt aus der Zeile ganz oben übernehmen.
Hook_EquipWeapon ist deine eigene Funktion, die aufgerufen werden soll.
Im Zweifel am Besten unterschiedliche Situation ausprobieren (Held legt Item an, Npc legt Item an, Held versucht ein Item anzulegen, dass er nicht anlegen kann / das in der on_equip wieder abgelegt wird,...) und zur Sicherheit vermutlich auch lieber überprüfen, ob slf und itm auch ein valider Npc (Hlp_IsValidNpc) und ein valides Item (Hlp_IsValidItem) sind.
Geändert von Milky-Way (24.03.2020 um 17:40 Uhr)
-
Zitat von Milky-Way
Danke dir! Das hat mir jetzt sehr weitergeholfen. Zwar hat es mit dem EquipWeapon-Hook nicht geklappt, aber mit der Liste und deiner Erklärung konnte ich solange herumprobieren, bis ich auf eine Lösung gekommen bin.
Hier mal meine Lösung, für alle die mal ein ähnliches Problem haben. Geht sicher noch etwas eleganter, aber das ist zumindest schon mal ein lauffähiger Stand. Erwähnenswert ist, dass die Funktion nicht nur für Waffen, sondern für alle Items aufgerufen wird. Aber da normalerweise nur Waffen Attribut-Conditions haben, soll mir das erstmal egal sein.
Code:
const int oCNpc__CanUse = 7543216;
func void checkItemConditions(var c_item item) {
if (item.cond_atr == ATR_STRENGTH) {
if (item.cond_value > hero.attribute[ATR_STRENGTH]) {
// play SVM
return;
};
} else if (item.cond_atr == ATR_DEXTERITY) {
if (item.cond_value > hero.attribute[ATR_DEXTERITY]) {
// play SVM
return;
};
} else if (item.cond_atr == ATR_MANA_MAX) {
if (item.cond_value > hero.attribute[ATR_MANA_MAX]) {
// play SVM
return;
};
};
if (item.cond_atr[2] == ATR_STRENGTH) {
if (item.cond_value[2] > hero.attribute[ATR_STRENGTH]) {
// play SVM
return;
};
} else if (item.cond_atr[2] == ATR_DEXTERITY) {
if (item.cond_value[2] > hero.attribute[ATR_DEXTERITY]) {
// play SVM
return;
};
} else if (item.cond_atr[2] == ATR_MANA_MAX) {
if (item.cond_value[2] > hero.attribute[ATR_MANA_MAX]) {
// play SVM
return;
};
};
};
func void Hook_CanUse()
{
var C_NPC slf; slf = _^(ECX);
var C_ITEM item; item = _^(MEM_ReadInt(ESP+4));
if (!Hlp_IsValidNpc(slf)) {
return;
};
if (!Hlp_IsValidItem(item)) {
return;
};
if (Hlp_GetInstanceID(slf) != Hlp_GetInstanceID(hero)) {
return;
};
checkItemConditions(item);
};
func void Init_CanUseHook()
{
HookEngineF(oCNpc__CanUse, 6, Hook_CanUse);
};
-
Wenn jemand bzgl. "Gegenstand kaufen" eine Idee hat, immer her damit =) Habe gerade schon ein wenig herumprobiert mit oCViewDialogTrade__OnTransferRight. Allerdings habe ich es nicht hinbekommen, das aktuell anvisierte Item zu finden. Beim hero geht das ja mit
Code:
_^(List_GetS(her.inventory2_oCItemContainer_contents, her.inventory2_oCItemContainer_selectedItem + 2));
recht einfach. Bei einem anderen Npc scheint das Problem zu sein, dass nicht alle Items im Handelsmenü sind.
-
Zitat von Falugify
Das müsste die Print Ausgabe sein. Also die Funktion scheint schon aktiv zu sein
Du hast vollkommen recht, der print klappt... Ich weiß auch nicht, wie ich auf die Idee kam, dass die Funktion nicht klappt. Allerdings klappt B_Say_Overlay hier nicht. Aber das Problem kriege ich dann in den Griff. Danke dir =)
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
|
|