|
-
ich steh kurz vor der fertigstellung eines nützlichen kleinen beitrags, brauche aber noch bitte kurz eure hilfe:
undzwar würde ich gern wissen, in welchen states der held seine waffe ziehen kann.
ich hab schon:
WAITING, TALK, RUN, WALK und SNEAK.
fehlt da noch etwas?
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
-
Was meinst du mit States? Ich kenne keinen Gothic-spezifischen Begriff sodass die von dir genannten Bezeichner darunter fallen.
-
Ich schätze sie meint Bodystates.
-
Zitat von Der Ahnungslose
Ich schätze sie meint Bodystates.
Dachte ich auch. Aber BS_TALK und BS_WAITING gibt es nicht.
@Assa: Erkläre mal genauer was du erreichen willst.
-
talk gibt es nicht? das überrascht mich jetzt aber
ich will das waffenaustauschen vollenden. funktioniert alles, ich habs geschafft dass wenn der spieler ne bestimmte waffe zieht, dieses waffe ausgetauscht wird gegen eine andere. das eignet sich beispielsweise für ausfahrbare klingen oder so.
bei mir ist es bei den klauenkrallen so, dass das item nicht richtig an der hüfte anliegt, wenn ich es an die hand angepasst habe und umgekehrt. jetzt hab ich mir ein dummy-item gemacht das genau an der hüfte liegt und das der held mit sich herumschleppt. sobald der spieler auf die idee kommt es zu ziehen, wird der dummy sofort gegen das an der hand passende ausgetauscht und alles sitzt perfekt.
bei schwertern gibt es z.b. auch so welche, die zwei ausfahrbare klingen haben.
das dummy-item wäre dann eines mit eingefahrenen klingen und wenn mans zieht wechselt es sofort zu den gezogenen.
laserschwerter werden so auch realisierbar
das abschließende "problem" ist, dass ich wissen muss wann der spieler denn überhaupt die waffe ziehen darf.
Er darf es wenn er durch wasser watet (okay englische bezeichnung wäre wohl wading gewesen sorry <.<), rennt, geht, steht, im gespräch ist und schleicht.
zumindest sind das die states die mir einfallen.
wie frage ich es denn nun ab ob der held in diesen staten ist? ich dachte an
Code:
if (Npc_IsInState (hero, BS_STATENAME))
{
};
versteht ihr was ich meine?
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
-
Wie wärs mit Hooks an allen Waffeziehen-Events? Sind bereits alle durch die Shield.d des LeGo Paketes erreichbar (Siehe LeGo_Init in LeGo.d) und mit Sicherheit sinnvoller bzw. weniger aufwändig als eine Triggerschleife.
MfG Gottfried
-
jetzt hab ich aber schon damit angefangen, das funktioniert alles schon. fehlt nur der feinschliff...
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
-
Zitat von Assasine91
Code:
if (Npc_IsInState (hero, BS_STATENAME))
{
};
versteht ihr was ich meine?
Nein.
- Npc_IsInState ist nicht dazu gemacht BodyStates abzufragen.
- Ich verstehe nicht wie BodyStates irgendetwas mit deinem Problem zu tun haben könnten.
Die Lösung für dein Problem besteht aus zwei Teilen:
- Im richtigen Moment (ziehen der Waffe) reagieren zu können. Das lässt sich über eine Triggerschleife lösen (du prüfst also ständig ob der Moment gekommen ist) oder durch das Hooken geeigneter Funktionen (Gottfrieds Vorschlag).
- Das richtige zu tun (also das Waffenvisual austauschen).
Zitat von Assassine
jetzt hab ich aber schon damit angefangen, das funktioniert alles schon. fehlt nur der feinschliff...
Was funktioniert denn schon? Und dein Code könnte wirklich helfen zu verstehen was deine Strategie eigentlich ist.
-
Zitat von Assasine91
jetzt hab ich aber schon damit angefangen, das funktioniert alles schon. fehlt nur der feinschliff...
Wenn man z.B. ein Mobsi benutzt kann man auch eine Waffe ziehen und das macht u.U. extreme Probleme wie z.b. das ein UseWithItem gedoppelt wird und sonstige unschöne Dinge
Über HookEngine Funcs das Waffen ziehen abzufragen wäre wohl einfacher.
z.B. so in der Art. Der code ist von Gottfried und eine Vorversion vom Schild ziehen in LeGo.
Code:
const int oCNpc__EV_DrawWeapon = 7654416; //0x74CC10
const int oCNpc__EV_DrawWeapon1 = 7656160; //0x74D2E0 // Das sind wirklich unterschiedliche Funktionen!
const int oCNpc__EV_RemoveWeapon = 7658272; //0x74DB20
const int oCNpc__EV_RemoveWeapon1 = 7660720; //0x74E4B0 // Das sind wirklich unterschiedliche Funktionen!
const int oCNpc__DropUnconscious = 7560880; //0x735EB0
HookEngine(oCNpc__EV_DrawWeapon, 6, "EVT_SHIELD_DRAW"); // Nur bei Ziehen mit [1] oder aus dem Lauf. [Space] nicht.
HookEngine(oCNpc__EV_DrawWeapon1, 5, "EVT_SHIELD_DRAW"); // Bei Ziehen mit [1] oder [Space]. Aus dem Lauf nicht.
HookEngine(oCNpc__EV_RemoveWeapon, 7, "EVT_SHIELD_REMOVE"); // Nur bei Wegstecken mit [1] oder aus dem Lauf. [Space] nicht.
HookEngine(oCNpc__EV_RemoveWeapon1, 7, "EVT_SHIELD_REMOVE"); // Bei Wegstecken mit [1] oder [Space]. Aus dem Lauf nicht.
HookEngine(oCNpc__DropUnconscious, 7, "EVT_SHIELD_UNEQUIP"); // Wenn Npc umgenietet wird
(Auszug von möglichem SchildInitCode um es zu verdeutlichen)
Das müsste man eben auf deine Krallenhand anpassen bez. neu entwickeln.
Die gefährlichste aller Weltanschauungen ist die Weltanschauung der Leute, welche die Welt nicht angeschaut haben.
Alexander von Humboldt
-
Zitat von Sektenspinner
Nein.
- Npc_IsInState ist nicht dazu gemacht BodyStates abzufragen.
- Ich verstehe nicht wie BodyStates irgendetwas mit deinem Problem zu tun haben könnten.
Die Lösung für dein Problem besteht aus zwei Teilen:
- Im richtigen Moment (ziehen der Waffe) reagieren zu können. Das lässt sich über eine Triggerschleife lösen (du prüfst also ständig ob der Moment gekommen ist) oder durch das Hooken geeigneter Funktionen (Gottfrieds Vorschlag).
- Das richtige zu tun (also das Waffenvisual austauschen).
Was funktioniert denn schon? Und dein Code könnte wirklich helfen zu verstehen was deine Strategie eigentlich ist.
die probleme sind schon gelöst <.<
ich hab die triggerschleife (frame) gewählt, frage die tastendrücke ab und reagiere entsprechend. das letzte problem ist noch dass der bei meiner derzeitigen abfrage ignoriert ob der spieler denn überhaupt die waffe ziehen DARF. kann ja sein dass man aus verstehen an die taste kommt oder so. dann führt der meinen befehl aber trotzdem aus.
ach bitte, dann release ich das eben unfertig -.-
Also zuerst wird das Tastenabfragen von Gottfried gebraucht:
Code:
// Einen Hex-String in einen Integer umwandeln
// "FF00" wird zu 255
func int Hex2Int(var string Hex) {
var int r; r = 0;
var int s; s = 1;
var int l; l = (STR_Len(Hex)>>1)<<1;
var int i; i = 0;
var int p; p = MEM_StackPos.position;
if(i < l) {
var int c; c = STR_GetCharAt(Hex, i);
if (c > 96) { c -= 32; };
if (c > 47&&c < 58) { c -= 48; }
else if(c > 64&&c < 71) { c -= 55; }
else { c = 0; };
r += (c<<(s<<2))<<((i>>1)<<3);
s = !s;
i += 1;
MEM_StackPos.position = p;
};
return r;
};
// Abfragen wie viele Belegungen es für diesen Key gibt
func int Key_GetNumSet(var string Name) {
return STR_Len(MEM_GetGothOpt("KEYS", concatStrings("key", Name)))>>2;
};
// Den Wert des Keys abfragen. Siehe Ikarus_Const.d
func int Key_GetValue(var string Name, var int Offset) {
Offset = !!Offset;
var string key; key = STR_SubStr(MEM_GetGothOpt("KEYS", concatStrings("key", Name)), Offset<<2, 4);
return Hex2Int(key);
};
// Hiermit kannst du abfragen ob eine Inventar-Taste gedrückt wurde.
// (Am besten jeden Frame abfragen)
// 1 = ja, 0 = nein// gibt also bei bestätigung 1 zurück! ich muss noch Inventory durch Weapon ersetzen!
func int IsWeaponKeyPressed() {
return (MEM_KeyPressed(Key_GetValue("Weapon", 0)) == KEY_PRESSED)
||(MEM_KeyPressed(Key_GetValue("Weapon", 1)) == KEY_PRESSED)
||(MEM_KeyPressed (KEY_1)==KEY_PRESSED);
};
dann die EquipWeapon-Funktion von dir, Sekti
Code:
const int EquipWeapon_TogglesEquip = 1;
func void EquipWeapon (var C_NPC slf, var int ItemInst) {
const int oCNpc__EquipWeapon_ptr = 7577648; //0x73A030
if (!Npc_HasItems (slf, ItemInst)) {
CreateInvItems (slf, ItemInst, 1);
};
if (!Npc_GetInvItem(slf, ItemInst)) {
MEM_AssertFail("Unexpected behaviour in EquipWeapon.");
return;
};
if ((item.mainflag == ITEM_KAT_NF) && (Npc_HasReadiedMeleeWeapon(slf)))
|| ((item.mainflag == ITEM_KAT_FF) && (Npc_HasReadiedRangedWeapon(slf))) {
MEM_Warn ("EquipWeapon: Caller wants to equip a weapon while weapon of the same type is readied. Ignoring request.");
return;
};
if (item.flags & ITEM_ACTIVE)
&& (!EquipWeapon_TogglesEquip) {
/* calling EquipWeapon would unequip the weapon. */
MEM_Info ("EquipWeapon: This weapon is already equipped. Ignoring request.");
return;
};
CALL_PtrParam(MEM_InstToPtr(item));
CALL__thiscall(MEM_InstToPtr(slf), oCNpc__EquipWeapon_ptr);
};
dann einen Frametrigger damits auch schnell genug ist (hab ich mit dir zusammen rumgedoktort, weißte noch?)
Code:
var C_ITEM waffelchen;
func void MeineFrameFunktion ()
{
Wld_SendTrigger ("MEIN_FRAME_TRIGGER");
//jetzt kommen die funcs
MEM_InitAll ();
menu1 = MEM_Game.timeStep;
menu2 = MEM_Game.singleStep; //das ist die wichtige!
waffelchen=Npc_GetEquippedMeleeWeapon (hero);
WeaponKeyPressed=IsWeaponKeyPressed ();
if (menu2==0)
{
if (WeaponKeyPressed==1)
{
if (Hlp_GetInstanceID (waffelchen) == Hlp_GetInstanceID (ItMw_Klauen))
{
AI_StandUpQuick (hero);
AI_RemoveWeapon (hero);
EquipWeapon (hero, ItMw_SenseBeliars);
AI_ReadyMeleeWeapon (hero);
}
else if (Hlp_GetInstanceID (waffelchen) == Hlp_GetInstanceID (ItMw_SenseBeliars))
{
AI_StandUpQuick (hero);
AI_RemoveWeapon (hero);
EquipWeapon (hero, ItMw_Klauen);
Npc_RemoveInvItem (hero, ItMw_SenseBeliars);
};
};
};
var oCTriggerScript Mein_Frame_Trigger;
Mein_Frame_Trigger = MEM_PtrToInst (MEM_SearchVobByName ("MEIN_FRAME_TRIGGER"));
Mein_Frame_Trigger._zCVob_nextOnTimer = MEM_Timer.totalTimeFloat;
};
ist natürlich immernoch nicht ganz fertig, feinheiten müssen noch abgestimmt werden und es gibt garantiert schönheitsfehler (von der einrückung ganz zu schweigen....) aber das ist mein Grundgerüst und es funktioniert.
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
Geändert von Bisasam (15.08.2011 um 12:34 Uhr)
-
@Assassine: Ah, ich erinnere mich dunkel dass du sowas schonmal gepostet hast. Dein Ansatz packt allerdings das Problem an einer schlecht geeigneten Stelle an (weil noch zu viel zwischen Tastendruck und Waffe ziehen passieren kann).
Ich bin nun auf folgende Lösung gekommen:
Code:
//************************************************
// Waffen die anderes visual haben, wenn gezogen.
//************************************************
func void HandleDynamicWeaponVisual(var int itemEquipped, var int itemReadied) {
var oCItem weap;
if (Npc_HasReadiedMeleeWeapon(hero) || Npc_HasReadiedRangedWeapon(hero)) {
weap = Npc_GetReadiedWeapon(hero);
if (Hlp_GetInstanceID(weap) == itemEquipped) {
//remove from slot
const int oCNpc__RemoveFromSlot = 7643760; //0x74A270
CALL_IntParam(true); //kill effect
CALL_IntParam(false); //dont drop
CALL_zStringPtrParam("ZS_RIGHTHAND");
CALL__thiscall(MEM_InstToPtr(hero), oCNpc__RemoveFromSlot);
//exchange items
Npc_RemoveInvItem(hero, itemEquipped);
CreateInvItem(hero, itemReadied);
//put in Slot
const int oCNpc__PutInSlot = 7642288; //0x749CB0
CALL_IntParam(true); //is in inventory
CALL_PtrParam(MEM_InstToPtr(item));
if (weap.flags & ITEM_BOW) {
CALL_zStringPtrParam("ZS_LEFTHAND"); //bogen links!
} else {
CALL_zStringPtrParam("ZS_RIGHTHAND");
};
CALL__thiscall(MEM_InstToPtr(hero), oCNpc__PutInSlot);
};
} else {
var int doIt; doIt = false;
weap = Npc_GetEquippedMeleeWeapon(hero);
if (Hlp_GetInstanceID(weap) == itemReadied) { doIt = true; };
weap = Npc_GetEquippedRangedWeapon(hero);
if (Hlp_GetInstanceID(weap) == itemReadied) { doIt = true; };
if (doIt) {
CreateInvItem(hero, itemEquipped);
EquipWeapon(hero, itemEquipped);
Npc_RemoveInvItem(hero, itemReadied);
};
};
};
Wenn du das jeden Frame aufrufst zum Beispiel so:
Code:
HandleDynamicWeaponVisual(ItMw_1h_Bau_Axe, ItMw_1h_Bau_Mace); //Sichel <-> Schwerer Ast
HandleDynamicWeaponVisual(ItMw_1h_Vlk_Dagger, ItMw_1h_Vlk_Mace); //Dolch <-> Gehstock
dann tut das das, was du möchtest.
Das Paket benötigt außer Ikarus nur die EquipWeapon Funktion (die du schon hast).
Edit: Die Funktion funktioniert nun für 1H, 2H und Bogen. Bei Armbrüsten passiert bei mir Quatsch mit der Munition, aber ich bin mir relativ sicher, dass das lediglich an einem Munitionssystem von mir liegt.
Geändert von Sektenspinner (16.08.2011 um 22:59 Uhr)
-
Version 1.1.3, 16.08.11: - Subtiles Problem in MEM_ArrayInsert gelöst, wenn es auf Engine-Arrays angewendet wird. Dies behebt auch Probleme in MEM_RenameVob, MEM_TriggerVob, MEM_UntriggerVob, MEM_InsertKeyEvent und MEM_SetGothOpt.
- Internes Problem bzgl. Gothic 1 und ExitSession (Ikarus konnte nicht geparst werden).
- MEM_GetKey und MEM_GetSecondaryKey zum Abfragen von Tastenbelegungen.
- MEM_GetFuncID und MEM_Call hinzugefügt (geringe Relevanz, siehe Doku).
- Floatpaket dem Download beigelegt.
Ein paar Worte zum Problem in MEM_ArrayInsert: Es gibt eine abweichende Art der Speicherreservierung in zString (darüber alloziert MEM_Alloc Speicher) und engineseitigen zCArrays.
Vermutlich läuft das eine in etwa auf malloc(x*sizeof(int)) und das andere auf new int[x] heraus. Mischung der beiden Arten führt in seltenen Fällen zu quasi nicht nachvollziehbaren Abstürzen zu späteren Zeitpunkten in der von Gothic verwendeten Smart Heap Library. Bei mir hat sich das ganze durch einen Freeze beim Laden eines Savegames geäußert.
Da die genannten Funktionen MEM_ArrayInsert auf Engine Arrays anwenden waren sie alle von diesem Problem betroffen. Tatsächlich aufgetreten ist ein Problem bei mir allerdings nur bei exzessiver Nutzung von MEM_RenameVob.
-
Zitat von Sektenspinner
Ich bin nun auf folgende Lösung gekommen:
Code:
func void HandleDynamicWeaponVisual(var int itemEquipped, var int itemReadied) {
var oCItem weap;
if (Npc_HasReadiedMeleeWeapon(hero)) {
weap = Npc_GetReadiedWeapon(hero);
if (Hlp_GetInstanceID(weap) == itemEquipped) {
//remove from slot
const int oCNpc__RemoveFromSlot = 7643760; //0x74A270
CALL_IntParam(true); //kill effect
CALL_IntParam(false); //dont drop
CALL_zStringPtrParam("ZS_RIGHTHAND");
CALL__thiscall(MEM_InstToPtr(hero), oCNpc__RemoveFromSlot);
//exchange items
Npc_RemoveInvItem(hero, itemEquipped);
CreateInvItem(hero, itemReadied);
//put in Slot
const int oCNpc__PutInSlot = 7642288; //0x749CB0
CALL_IntParam(true); //is in inventory
CALL_PtrParam(MEM_InstToPtr(item));
CALL_zStringPtrParam("ZS_RIGHTHAND");
CALL__thiscall(MEM_InstToPtr(hero), oCNpc__PutInSlot);
};
} else {
weap = Npc_GetEquippedMeleeWeapon(hero);
if (Hlp_GetInstanceID(weap) == itemReadied) {
CreateInvItem(hero, itemEquipped);
EquipWeapon(hero, itemEquipped);
Npc_RemoveInvItem(hero, itemReadied);
};
};
};
Wenn du das jeden Frame aufrufst zum Beispiel so:
Code:
HandleDynamicWeaponVisual(ItMw_1h_Bau_Axe, ItMw_1h_Bau_Mace); //Sichel <-> Schwerer Ast
HandleDynamicWeaponVisual(ItMw_1h_Vlk_Dagger, ItMw_1h_Vlk_Mace); //Dolch <-> Gehstock
dann tut das das, was du möchtest.
Das Paket benötigt außer Ikarus nur die EquipWeapon Funktion (die du schon hast).
Für 2H, Bogen und Armbrust habe ich diese Funktion nicht getestet (sind evtl. andere Slots, glaube ich aber nicht).
Hat das schon jemand für 2H, Bogen und Armbrust getestet? Würde ich ja selber machen, wenn ich G2 installiert hätte.
-
Zitat von LordEdhor
Hat das schon jemand für 2H, Bogen und Armbrust getestet? Würde ich ja selber machen, wenn ich G2 installiert hätte.
Hab nun oben editiert. Bin mir relativ sicher, dass es nun für 2H, Bogen und Armbrust funktioniert.
-
Beschränkungen von Externen Funktionen aushebeln
Manche externe Funktionen, die nur Npcs annehmen, könnten eigentlich genauso gut beliebige Vobs annehmen. Dazu fällt mir ein:
- WLD_SpawnNpcRange: Spawne Npcs im Radius um Vob
- AI_TurnAway: Drehe dich weg von Vob
- AI_TurnToNpc: Drehe dich zu Vob
- AI_GotoNpc: Gehe zu Vob
- Npc_CanSeeNpc: Kann ich ein Vob sehen?
- Npc_CanSeeNpcFreeLOS: Könnte ich ein Vob sehen, wenn ich in die richtige Richtung schauen würde?
- Npc_GetDistToNpc: Distanz zwischen zwei Vobs.
- Npc_GetHeightToNpc: Höhenunterschied zwischen zwei Vobs.
Problem ist allerdings, dass Gothic nur Npcs zulässt und einfach nichts tut, wenn das übergebene Objekt zwar ein zCVob aber kein oCNpc ist.
Diese Beschränkung lässt sich folgendermaßen ein- und ausschalten:
Code:
//************************************************
// Weniger Strenger External Test
//************************************************
const int _ExternalAcceptVobsCount = 0;
const int _oCNpcTypeInfo = 8983472; //0x8913B0
const int _zCVobTypeInfo = 8970208; //0x88DFE0
func void ExternalAcceptVobs() {
if (!_ExternalAcceptVobsCount) {
const int once = 0;
var int ptr; ptr = 7188726; //0x6DB0F6
if (!once) { MemoryProtectionOverride(ptr, 4); };
MEM_WriteInt(ptr, _zCVobTypeInfo); //0x88DFE0
ptr = 7188773; //0x6DB125
if (!once) { MemoryProtectionOverride(ptr, 4); };
MEM_WriteInt(ptr, _zCVobTypeInfo); //0x88DFE0
once = true;
};
_ExternalAcceptVobsCount += 1;
};
func void ExternalDenyVobs() {
_ExternalAcceptVobsCount -= 1;
if (!_ExternalAcceptVobsCount) {
var int ptr; ptr = 7188726; //0x6DB0F6
MEM_WriteInt(ptr, _oCNpcTypeInfo); //0x88DFE0
ptr = 7188773; //0x6DB125
MEM_WriteInt(ptr, _oCNpcTypeInfo); //0x88DFE0
};
};
Danach ist zum Beispiel folgendes möglich (wenn man mal davon ausgeht, dass es ein Vob Namens "ALTE_EICHE" in der Welt gibt:
Code:
var zCVob vob; vob = MEM_PtrToInst(MEM_SearchVobByName("ALTE_EICHE"));
ExternalAcceptVobs(); //Weniger strikte Bedingung.
AI_TurnToNpc(self, vob); //Schaue Eiche an.
AI_Output(self, hero, "OU1"); //Sieh nur, Held! Die alte Eiche! Ich gehe sofort hin.
AI_GotoNpc(self, vob); //Gehe zur Eiche.
ExternalDenyVobs(); //Wieder zurück auf normal.
Geändert von Sektenspinner (19.09.2011 um 23:34 Uhr)
Grund: Optimierung: MemoryProtectionOverride nur beim ersten mal machen.
-
Ah, das ist sehr hilfreich. Ich fand es schon immer umständlich, dass man nicht den Höhenunterschied zwischen dem Helden und einem VOB (z.b. nem WP) abfragen konnte, aber das scheint ja damit zu funzen.
Wie mal ne super Sache
-
Zitat von Kurzer
Ah, das ist sehr hilfreich. Ich fand es schon immer umständlich, dass man nicht den Höhenunterschied zwischen dem Helden und einem VOB (z.b. nem WP) abfragen konnte, aber das scheint ja damit zu funzen.
Wie mal ne super Sache
Das mit dem Waypoint wäre schon etwas komplizierter, weil man erstmal an den Waypoint kommen muss (der kein Vob ist und daher nicht über MEM_SearchVobByName erreichbar ist). Dann muss man auch darauf achten, dass man nicht den Waypoint selbst, sondern das zugehörige Hilfsvob hernimmt und an Npc_GetHeightToNpc übergibt, aber prinzipiell sollte es gehen, ja. Nur ist eben in diesem Beispiel das bestimmen der Höhendistanz eher der einfache Teil.
-
Zitat von Sektenspinner
Das mit dem Waypoint wäre schon etwas komplizierter, weil man erstmal an den Waypoint kommen muss (der kein Vob ist und daher nicht über MEM_SearchVobByName erreichbar ist). Dann muss man auch darauf achten, dass man nicht den Waypoint selbst, sondern das zugehörige Hilfsvob hernimmt und an Npc_GetHeightToNpc übergibt, aber prinzipiell sollte es gehen, ja. Nur ist eben in diesem Beispiel das bestimmen der Höhendistanz eher der einfache Teil.
Achso^^. Na ja, seis drum. Ich bin auch mit einem normalen VOB zufrieden. Bisher war nur immer das Problem, dass ich dann immer versuchen musste mich irgendwie an NPCs in der Nähe zu orientieren. Das is natürlich auch im besten Fall nur suboptimal, da sie ja dynamisch sind und einfach mal weglaufen könnten (wenn der Spieler sieht weglockt).
Ob ich da ein WP oder ein normales VOB nehm is ja egal, hauptsache was statisches. Aber das mit dem WP wusste ich nicht - man lernt nie aus
-
-
Zitat von Sektenspinner
@Milky Way: Es sollte gehen, indem du zCSkyControler_Outdoor::SetWeatherType(zTWEATHER_SNOW) auf dem aktuellen SkyController (MEM_SkyController) aufrufst.
Dazu brauchst du die Skripte aus diesem Post.
Das heißt es geht so:
Code:
const int zCSkyController_Outdoor__SetWeatherType_adr = 6207536; //0x5EB830
func void SetWeatherType (var int raining) {
MEM_InitGlobalInst(); CALL_Init();
if (raining) { raining = 1; }; //0 = snow, 1 = rain
CALL_PushIntParam (raining);
CALL__thiscall (MEM_InstToPtr (MEM_SkyController), zCSkyController_Outdoor__SetWeatherType_adr);
};
Aber ich habe nicht ausprobiert inwiefern der Wechsel der Musikzone oder der Tageszeit dir eine Umstellung auf Wettertyp 0 (Schnee) wieder verhagelt - Verzeihung: verregnet.
Ich habe mal versucht, das auf die aktuelle Ikarus-Version, in die die Call_-Funktionen (teilweise?) integriert sind, zu übertragen, werde allerdings nur mit einem Absturz belohnt.
Code:
const int zCSkyController_Outdoor__SetWeatherType_adr = 6207536; //0x5EB830
func void SetWeatherType (var int raining) {
MEM_InitGlobalInst(); // CALL_Init();
if (raining) { raining = 1; }; //0 = snow, 1 = rain
MEM_PushIntParam (raining);
CALL__thiscall (MEM_InstToPtr (MEM_SkyController), zCSkyController_Outdoor__SetWeatherType_adr);
};
Das Spiel stürzt beim Laden ab. Die letzten zSpy-Einträge:
Code:
00:12 Info: 3 B: ---------- 73% ---------- .... <zViewProgressbar.cpp,#142>
00:12 Info: 3 U: GAM: Calling Startup-Script ... .... <oGame.cpp,#862>
00:12 Info: 3 U: GAM: Startup-Script finished. .... <oGame.cpp,#866>
00:12 Info: 10 U: (oCWorld::CreateVob) 5228 .... <oWorld.cpp,#315>
00:12 Info: 9 U: NPC: Loading Script-NPC .... <oNpc.cpp,#1624>
00:12 Info: 7 U: NPC: NPC - Instance : MEM_HELPER_INST .... <oNpc.cpp,#1627>
00:12 Info: 9 U: NPC: Finished Script-NPC. .... <oNpc.cpp,#1703>
Was mache ich falsch? Wie geht es richtig?
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
|
|