bin gestern Abend auf ein neues kleines Problem gestoßen und zwar müsste ich die Entfernung zwischen NPCs (in meinem Fall der Held) und Freepoints (im Test der Freepoint, an dem ein bestimmter Waran in der Startup gespawnt wird) messen. Es gibt leider nur einen Befehl, um die Entfernung zwischen NPCs und Waypoints herauszubekommen, dieser funktioniert leider nicht für Freepoints, das hab ich schon in größter Hoffnung versucht...
Mein Ansatz, dies zu umgehen, war nun in etwa so:
In der Startup:
Code:
Wld_InsertNpc(waran_Test,"FP_ROAM_XARDAS_SECRET_08");
var string WP_Test;
WP_Test = Npc_GetNearestWP(waran_Test);
Das funktioniert leider nicht, und das wäre wohl auch nicht sehr schön. Denn dafür müsste ich in der Gothic.src die Datei mit dem letzteren Code nach der Startup parsen lassen, was ich nicht schön finde. Außerdem würde dadurch nicht die reale Entfernung zwischen NPC und Freepoint gemessen, sondern nur die zwischen NPC und dem Waypoint, der dem Freepoint am nächsten ist.
Gibts da irgendwie einen leichteren, schöneren Weg für mein Problem?
bin gestern Abend auf ein neues kleines Problem gestoßen und zwar müsste ich die Entfernung zwischen NPCs (in meinem Fall der Held) und Freepoints (im Test der Freepoint, an dem ein bestimmter Waran in der Startup gespawnt wird) messen. Es gibt leider nur einen Befehl, um die Entfernung zwischen NPCs und Waypoints herauszubekommen, dieser funktioniert leider nicht für Freepoints, das hab ich schon in größter Hoffnung versucht...
Mein Ansatz, dies zu umgehen, war nun in etwa so:
In der Startup:
Code:
Wld_InsertNpc(waran_Test,"FP_ROAM_XARDAS_SECRET_08");
var string WP_Test;
WP_Test = Npc_GetNearestWP(waran_Test);
Das funktioniert leider nicht, und das wäre wohl auch nicht sehr schön. Denn dafür müsste ich in der Gothic.src die Datei mit dem letzteren Code nach der Startup parsen lassen, was ich nicht schön finde. Außerdem würde dadurch nicht die reale Entfernung zwischen NPC und Freepoint gemessen, sondern nur die zwischen NPC und dem Waypoint, der dem Freepoint am nächsten ist.
Gibts da irgendwie einen leichteren, schöneren Weg für mein Problem?
Vielen Dank im Voraus,
Gladi
Was ist denn das eigentliche Problem? Du willst ja mit der Entfernung von hero zu FP irgendetwas anstellen. Vielleicht lässt sich das ja noch auf einem anderen Weg lösen, als die Distanz von hero zu FP rauszufinden? Am besten beschreibst du mal, was dein Ziel ist.
Ansonsten sollte es möglich sein (nicht getestet!), sich den FP als Vob zu suchen und dann über Npc_GetDistToNPC() die Distanz abzufragen:
Code:
var int vobPtr;
vobPtr = MEM_SearchVobByName("FP_ROAM_XARDAS_SECRET_08");
if(vobPtr) {
var zCVob vob;
vob = _^(vobPtr);
if(Npc_GetDistToNPC (hero, vob) <= 1000) {
print("Jap. Hat geklappt.");
};
};
Zuerst das Wieso: Ich möchte das Respawnsystem verbessern, die Respawnfunktion soll nicht mehr nur beim Schlafen aufgerufen werden, sondern auch einmal täglich durch die B_RefreshArmor, welche jeden Tag um 0 Uhr einmal aufgerufen wird. Damit aber keine Monster direkt neben dem Helden respawnt werden, möchte ich dies durch die Distanz zu den jeweiligen Waypoints / Freepoints abfangen. Daher meine Frage.
Habe es jetzt, wie von dir vorgeschlagen, im Testskript ausprobiert:
Das funktioniert leider nicht korrekt, der Waran wird auch respawnt, wenn ich direkt neben ihm stehe.
Wenn ich könnte, würde ich dir ja eine Funktion schreiben welche direkt das hier aufrufen würde.
Leider komme ich nicht auf den Rückgabewert klar... bekomme jedesmal werte um den dreh 1189086201 zurück (test mit hero und vob NONE_100_Xardas) mit meinen bescheidenen Ikarus und Engine kenntnissen.
Irgendwas wird wohl an meinen Call_xxx aufrufen nicht stimmen
Vielleicht meldet sich ja wer, der da klüger ist als ich
Puuh, ich hab leider keine Ahnung, was du da gemacht hast, aber vielen Dank für deine Hilfe! Auch, dass du mir gern eine Funktion dafür geschrieben hättest, weiß ich wirklich sehr zu schätzen.
Es ist immer wieder toll, zu sehen, wie einem - selbst nach fast 20 Jahren - immer noch so schnell und hilfsbereit geholfen wird!
Ich hoffe natürlich trotzdem noch, dass es dafür irgendeine Lösung gibt.
Wenn ich könnte, würde ich dir ja eine Funktion schreiben welche direkt das hier aufrufen würde.
Leider komme ich nicht auf den Rückgabewert klar... bekomme jedesmal werte um den dreh 1189086201 zurück (test mit hero und vob NONE_100_Xardas) mit meinen bescheidenen Ikarus und Engine kenntnissen.
Irgendwas wird wohl an meinen Call_xxx aufrufen nicht stimmen
Vielleicht meldet sich ja wer, der da klüger ist als ich
Könnte es daran liegen, dass der Call einen Float zurückgibt? Bedenkst du die Umrechnung?
Daran wird es liegen. Floats müssen bei Engine-Calls gesondert behandelt werden (CALL_RetValIsFloat oder so) und außerdem bekommst du dann so einen Integer-Float (Paradox, I know), d.h. du darfst nur mit den Funktionen aus dem Float-Paket rechnen. Am einfachsten kannst du roundf(float) aufrufen, um einen (gerundeten) Integer zu bekommen. Den kannst du dann auch einfach printen.
Im Zweifelsfall kannst du ja einfach mal deinen Code zeigen.
Daran wird es liegen. Floats müssen bei Engine-Calls gesondert behandelt werden (CALL_RetValIsFloat oder so) und außerdem bekommst du dann so einen Integer-Float (Paradox, I know), d.h. du darfst nur mit den Funktionen aus dem Float-Paket rechnen. Am einfachsten kannst du roundf(float) aufrufen, um einen (gerundeten) Integer zu bekommen. Den kannst du dann auch einfach printen.
Im Zweifelsfall kannst du ja einfach mal deinen Code zeigen.
An meinem Float lags nicht, sondern daran das ich die Vob-Ptr nicht korrekt übergeben habe, habe direkt _@(c_npcInst) verwendet, nachdem ich wie in FreeAim\rangedAiming.d erst eine var int npcPtr = _@(c_npcInst); und dann diese als Call_Thiscall(_@(npcPtr),...) übergeben habe hats geklappt.
Code:
/*
* Gibt die Approximation der Entfernung des npc zu dem toVob zurück.
*
* Beispielaufruf:
* var zCVob xard; xard = Hlp_GetNpc(NONE_100_Xardas);
* var int dist; dist = Npc_GetDistToVob(hero, xard);
*/
func int Npc_GetDistToVob(var C_NPC npc, var zCVob toVob) {
const int zCVob__GetDistanceToVob = 6404368; // 0061B910
const int zCVob__GetDistanceToVobApprox = 6404464; // 0x00061B970
var int npcPtr; npcPtr = _@(npc);
var int toPtr; toPtr = _@(toVob);
const int call = 0;
if (CALL_Begin(call)) {
CALL_RetValIsFloat();
CALL_PtrParam(_@(toPtr));
CALL_PutRetValTo(_@(flt));
CALL__thiscall(_@(npcPtr), zCVob__GetDistanceToVobApprox);
call = CALL_End();
};
var int flt; flt = roundf(+flt);
return +flt;
};
Das kann ich jetzt so beispielsweise in meine Externals.d übernehmen und dann die Funktion Npc_GetDistToVob so nutzen?
Vielen, vielen Dank für deine Mühen!
Soweit ich das weiß ist die Externals.d eigentlich nicht in der Gothic.src drin, weil dort ja nur "dokumentation" ist.
die "Npc_GetDistToVob.d" (einfach in eigene Datei abspeichern) müsste irgendwo nach Ikarus/LeGo in der Gothic.src stehen. Danach könntest du die Funktion so benutzen, wie es in dem Kommentar über der Funktion steht (im Quellcode) also mit Npc_GetDistanceToVob(hero, vob) - vob ist dabei eine zCVob Instanz.
Falls du noch kein Ikarus verwenden solltest (irgendwo ein Mem_InitAll() beim Story.d -> Init_Global() z.B. ) müsstest du das noch entsprechend initialisieren
Soweit ich das weiß ist die Externals.d eigentlich nicht in der Gothic.src drin, weil dort ja nur "dokumentation" ist.
die "Npc_GetDistToVob.d" (einfach in eigene Datei abspeichern) müsste irgendwo nach Ikarus/LeGo in der Gothic.src stehen. Danach könntest du die Funktion so benutzen, wie es in dem Kommentar über der Funktion steht (im Quellcode) also mit Npc_GetDistanceToVob(hero, vob) - vob ist dabei eine zCVob Instanz.
Falls du noch kein Ikarus verwenden solltest (irgendwo ein Mem_InitAll() beim Story.d -> Init_Global() z.B. ) müsstest du das noch entsprechend initialisieren
Oh, stimmt, hab ich übersehen. Alles klar, dann weiß ich, was jetzt zu tun und zu testen ist!
/*
* Beispielaufruf:
* var zCVob xard; xard = Hlp_GetNpc(NONE_100_Xardas);
* var int dist; dist = Npc_GetDistToVob(hero, xard);
*/
Ganz kurze Frage noch hierzu, wahrscheinlich bin ich gerade einfach blind:
Wie bekäme ich in deinem Beispiel in die zCVob -Variable "xard" einen Freepoint gespeichert?
Du nimmst dort ja die NPC-Instanz "NONE_100_Xardas" durch Hlp_GetNPC.
Ganz kurze Frage noch hierzu, wahrscheinlich bin ich gerade einfach blind:
Wie bekäme ich in deinem Beispiel in die zCVob -Variable "xard" einen Freepoint gespeichert?
Du nimmst dort ja die NPC-Instanz "NONE_100_Xardas" durch Hlp_GetNPC.
Das Hlp_GetNpc musst du durch folgenden Code ersetzen:
Sorry für Doppelpost, aber ich habe ein Problem. Keine Ahnung, wieso das nun plötzlich auftaucht.
Und zwar stürzt das Spiel jetzt mit einer Access Violation ab, wenn die Funktion "Npc_GetDistToVob" ausgeführt wird.
Ich weiß nicht, wo das plötzlich herkommt, denn es hatte ja kurzzeitig funktioniert und Änderungen habe ich danach daran nicht mehr vorgenommen..
/*
* Gibt die Approximation der Entfernung des npc zu dem toVob zurück.
*
* Beispielaufruf:
* var zCVob xard; xard = Hlp_GetNpc(NONE_100_Xardas);
* var int dist; dist = Npc_GetDistToVob(hero, xard);
*/
func int Npc_GetDistToVob(var C_NPC npc, var zCVob toVob) {
// für den Fall das man mehr Genauigkeit möchte, kann man diese Adressen unten im CALL_Thiscall austauschen. Sollte nicht nötig sein!
const int zCVob__GetDistanceToVob = 6404368; // 0x0061B910
const int zCVob__GetDistanceToVobApprox = 6404464; // 0x0061B970
var int npcPtr; npcPtr = _@(npc);
var int toPtr; toPtr = _@(toVob);
const int call = 0;
if (CALL_Begin(call)) {
CALL_RetValIsFloat();
CALL_PtrParam(_@(toPtr));
CALL_PutRetValTo(_@(flt));
CALL__thiscall(_@(npcPtr), zCVob__GetDistanceToVobApprox);
call = CALL_End();
};
var int flt; flt = roundf(+flt);
return +flt;
};
Wenn ich alle Schnipsel mit der Funktion "Npc_GetDistToVob" rausnehme, bekomme ich keinen Absturz mehr beim Monsterrespawn. Ich bin deshalb so verwirrt, weil es ja schon einmal geklappt hat und ich damit ausgiebig getestet hatte.
Kann mir jemand evtl. sagen, was da das Problem ist?
Wenn ich alle Schnipsel mit der Funktion "Npc_GetDistToVob" rausnehme, bekomme ich keinen Absturz mehr beim Monsterrespawn. Ich bin deshalb so verwirrt, weil es ja schon einmal geklappt hat und ich damit ausgiebig getestet hatte.
Kann mir jemand evtl. sagen, was da das Problem ist?
Vielen Dank schon mal!
Bist du sicher das der Vob/Freepoint auch so existiert? Nicht das du dich da vertippt hast, oder den irgendwann mal umbenannt hast.
Was gibt dir "MEM_SearchVobByName("FP_ROAM_BF_NEST_26")" zurück?
Nach möglichkeit solltest du das ergebnis erstmal prüfen. Ebenfalls kann manchmal "hero" kein gültiger NPC sein (Ladebildschirm z.B.)
Code:
func void xxxxx() {
if (Hlp_IsValidNpc(hero) {
var int vobPtr; vobPtr = MEM_SearchVobByName("FP_ROAM_BF_NEST_26");
if (vobPtr) {
// Gefunden ...
};
};
};
Die Freepoints müssten passen, mit dem alten Respawnsystem hat alles funktioniert. Geändert hat sich zum neuen Respawnsystem lediglich die Prüfung der Distanz zum Hero. Die Änderungen dafür hab ich per RegEx automatisch machen lassen, deshalb hat sich an den Freepoint-Bezeichnungen nichts geändert.
Zitat von Kirides
Was gibt dir "MEM_SearchVobByName("FP_ROAM_BF_NEST_26")" zurück?
Nach möglichkeit solltest du das ergebnis erstmal prüfen. Ebenfalls kann manchmal "hero" kein gültiger NPC sein (Ladebildschirm z.B.)
Wie kann ich das prüfen?
Vielen Dank für deine (wie immer) so schnelle Antwort!
Edit: Oh, hab deinen Code jetzt erst gesehen, sorry. Ich probiers mal.
func void b_monster_respawnen() {
if (Hlp_IsValidNpc(hero)) {
var int vobPtr; vobPtr = MEM_SearchVobByName("FP_ROAM_BF_NEST_26");
if (vobPtr) {
PrintScreen("Gefunden",-1,0,FONT_Screen,3);
} else {
PrintScreen("Nicht gefunden",-1,0,FONT_Screen,3);
};
};
};
Gibt mir "Nicht gefunden" aus, also gibts anscheinend ein Problem mit MEM_SearchVobByName? Der FP existiert definitiv, hab im Spacer nachgeschaut. Komisch..