-
Problem bei Schadensberechnung ändern in G1
hab vor einiger Zeit mal angefangen die Schadensberechnung in G1 zu modifizieren, musste leider ne kurze Auszeit nehmen und wollte nun weitermachen. Ich habe bereits mehrfach die Schadensberechnung in G2 geändert (bonusschaden, prozentuelle Rüstung) und all das, hat wunderbar geklappt. Aber in G1 klappt es nicht wirklich,
hier der code aus der startup.d, habe schon nen wesentlich längeren code, fernkampf (bogen) und so klappt nur oth.protection[PROT_EDGE]; bringt mich zur Weißglut
Code:
var int newdmg;
func int B_calculatenewarmour (var int incdmg, var int incarmour, var int meleeprot) ///neues rüstungsystem
{
var int initialdmg; initialdmg=incdmg;
var int availablearmour; availablearmour=incarmour;
var int max_absorption_step; var int armourneeded;
var int finaldmg; finaldmg=initialdmg;
///step 1, first 20% damage, 1 armour needed, 20% total armour needed
max_absorption_step=initialdmg*2/10; armourneeded=max_absorption_step*1;
if (armourneeded>availablearmour) {max_absorption_step=availablearmour*1; armourneeded=availablearmour; };
availablearmour-=armourneeded; finaldmg-=max_absorption_step;
///step 2, 20-40% damage, 1.5 armour needed, 30+20%=50 total armour needed
max_absorption_step=initialdmg*2/10; armourneeded=max_absorption_step*3/2;
if (armourneeded>availablearmour) {max_absorption_step=availablearmour*2/3; armourneeded=availablearmour; };
availablearmour-=armourneeded; finaldmg-=max_absorption_step;
///step 3, 40-60% damage, 2.0 armour needed , 40+30+20% = 90 total armour needed
max_absorption_step=initialdmg*2/10; armourneeded=max_absorption_step*2;
if (armourneeded>availablearmour) {max_absorption_step=availablearmour/2; armourneeded=availablearmour; };
availablearmour-=armourneeded; finaldmg-=max_absorption_step;
///step 4, 60-80% damage, 3.0 armour needed , 60+40+30+20% = 150 total armour needed
max_absorption_step=initialdmg*2/10; armourneeded=max_absorption_step*3;
if (armourneeded>availablearmour) {max_absorption_step=availablearmour/3; armourneeded=availablearmour; };
availablearmour-=armourneeded; finaldmg-=max_absorption_step;
///step 5, 80-90% damage, 5.0 armour needed , 50+60+40+30+20% = 200 total armour needed
max_absorption_step=initialdmg*1/10; armourneeded=max_absorption_step*5;
if (armourneeded>availablearmour) {max_absorption_step=availablearmour/5; armourneeded=availablearmour; };
availablearmour-=armourneeded; finaldmg-=max_absorption_step;
if (finaldmg<initialdmg*1/10) { finaldmg=initialdmg*1/10; };
if (finaldmg<1) { finaldmg=1; };
newdmg=finaldmg;
return newdmg;
};
func int DMG_OnDmg (var int victimPtr, var int attackerPtr, var int dmg)
{
Var c_npc slf; slf = _^(attackerptr);
Var c_npc oth; oth = _^(victimPtr);
var int mydamage; var int meleedamage; var int myarmour; var int attributsboni; var int critrandom; var int critchance; var int critboni;var int bonusmeleeprot;
if (C_NpcIsMonster(slf)) ////monster richten edge an
{
meleedamage=slf.attribute[ATR_STRENGTH];
meleedamage=100;
if (oth.id == 0) ///hero hat neues Rüstungssystwm
{
myarmour =oth.protection[PROT_EDGE];
B_calculatenewarmour(meleedamage,myarmour,bonusmeleeprot); meleedamage=newdmg;
}
else
{
myarmour =oth.protection[PROT_EDGE];
meleedamage=(meleedamage-myarmour); if (meleedamage<1) {meleedamage=1;};
};
dmg=meleedamage;
};
return dmg;
};
Problem ist nur, dass ich instant umfalle wenn ich getroffen werden, myarmour =oth.protection[PROT_EDGE]; scheint irgendwie nicht zu klappen, habe daraufhinmal B_RaiseAttribute (ATR_STRENGTH, myarmour); eingegeben um zu sehen wie groß der Wert ist, wie erwartet ein sehr großer NEGATIVER WERT. habe daraufhin auch mal die anderen Rüstungswerte des Helden agefragt, alle anderen waren >=0.
Nur protection[PROT_EDGE] scheint Probleme zu machen, mein neues Fernkampfsystem (bonusschaden durch Geschick) klappte, dort konnte ich protection[PROT_POINT] gut abfragem. Habe daraufhin es mal so geändert, dass bei Monster nicht oth.protection[PROT_EDGE] sondern oth.protection[PROT_BLUNT] abgefragt wird. draufhin klappte alles wunderbar. Mein neues % Rüstungssystem klappt, bei sehr hohen Rüstungswerten (200) nahm ich immer noch 10% sprich 10 Schaden. Habe daraufhin mal per cheats nur protection[PROT_EDGE] auf 200 gesetzt und was passierte? ich nahm nur noch 1 Schaden wobei [PROT_EDGE] überhaupt nicht abgefragt worden ist in meinem veränderten sprict.
Beim Nahkampf gab es ähnliche Probleme, konnte den Schaden durch [PROT_BLUNT] ändern, da alle Waffen nur durch [PROT_BLUNT] beeinflusst werden, hab per cheat prot edge auf nen hohen Wert gesetzt, wurde getroffen und Absturz obwohl [PROT_EDGE] gar nicht im code vorkam.
Hat schonmal jemand versucht die G1 Schadensberechnung zu modifizieren?
-
Hast du an irgendeiner Stelle eine konkrete Engineadresse stehen? Bei ungültigen Adressen (z.B. weil sie aus G2 genommen wurden) stürzt G1 ab. Kann auch sein, dass Edge ne andere Adresse hat o.ä.
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
-
das hier habe ich verwendet.
Code:
func void _DMG_OnDmg ()
{
EAX = DMG_OnDmg (ECX, MEM_ReadInt (MEM_ReadInt (ESP+548)+4), EAX);
};
func void InitDamage () {
const int dmg = 0;
if (dmg) { return; };
HookEngineF(7567329, 6, _DMG_OnDmg);
dmg = 1;
};
-
Solange du nicht extra das G1 Pendant zu 7567329 rausgesucht hast, wird es da jede Menge Probleme geben. Das blöde ist, dass ich dir das nicht raussuchen kann. Hatte überhaupt nicht die Zeit mich mit sowas zu beschäftigen.
Vielleicht kann Lehona ja helfen oder Mud-Freak?
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
-
Ich drücke euch die Daumen mit dieser Engine Adresse Sache.
Würde auch sehr gerne die Schadensberechnung von Gothic 1 bearbeiten können.
-
7567329 (0x007377E1) ist die Adresse für G1
-
Nur für zukünftige Forensucher: Die Schadensskripte (inklusive der Speicheradressen) für Gothic 1 und Gothic 2 sind beide in diesem Thread zu finden (das Skript für Gothic 1 auf der dritten Seite).
Ich denke du solltest noch mehr mit Debug-Ausgaben (MEM_Info) arbeiten, um herauszufinden wo genau das Problem liegt. Du solltest dir zu Anfang und am Ende der DMG_OnDmg alle verschiedenen Rüstungswerte (BLUNT, EDGE, ...) und den Schadenswert nach der Verrechnung ausgeben lassen und mit den Charakterwerten vergleichen. Ebenso solltest du die Werte zwischen die ganzen Verrechnungen in B_calculatenewarmour überprüfen.
-
Dankeschön!
-
Wann und wo initialisierst du Ikarus und LeGo? Bei mir kam es zum Beispiel vor, dass die Initialisierung bei Weltenwechsel nichtig wurde. Wenn ich in der neuen Welt die alten Skripte benutzen wollte, gab es ohne neue Init einen saftigen Absturz.
Im Zweifel vielleicht vor dem Funktionsaufruf nochmal initialisieren?
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
-
Zitat von Bisasam
Wann und wo initialisierst du Ikarus und LeGo? Bei mir kam es zum Beispiel vor, dass die Initialisierung bei Weltenwechsel nichtig wurde. Wenn ich in der neuen Welt die alten Skripte benutzen wollte, gab es ohne neue Init einen saftigen Absturz.
Im Zweifel vielleicht vor dem Funktionsaufruf nochmal initialisieren?
Ich kann nicht versprechen, dass das gut geht. LeGo wurde mit dem Hintergedanken entwickelt, dass es exakt(!) in der INIT_Global() aufgerufen wird. Es gab damit bereits Probleme bei der G1-Portierung (wenn ich mich nicht irre), da dort die INIT-Funktionen doppelt aufgerufen wurden. Es ist einfacher, den Initialisierungsaufruf an einer einzigen Stelle zu halten*, dann muss man sich bei anderen Problemen keine Gedanken machen, ob es nicht vielleicht daran liegt.
*Und LeGo nicht in Item/Npc/Dialog-Instanzen zu verwenden.
-
G1 hat das Problem, dass es dort keine Init_Global gibt. Oder bin ich nur dumm und finde sie nicht? Ich hab sämtliche Startups abgesucht und keine gefunden. Man MUSS die Initialisierung also in die World-Init schreiben.
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
-
Ja, die INIT_Global gibt es in G1 nicht, aber das macht meine Aussage ja nicht falsch Im LeGo-Einleitungspost ist ein Post von mud-freak verlinkt, der beschreibt, wie man LeGo am sinnvollsten initialisiert in G1.
-
Wie ist das denn gemeint?
Zitat von Lehona
*Und LeGo nicht in Item/Npc/Dialog-Instanzen zu verwenden.
Gilt das nur für G1, oder generell? Wenn generell, inwiefern?
-
Dialoginstanzen (nicht die Funktionen, die zum Dialog gehören!), Npc-Instanzen und vermutlich auch Item-Instanzen werden ausgeführt, bevor die INIT_Global() aufgerufen wird, wenn man ein Savegame lädt. Zu dem Zeitpunkt ist LeGo also nicht initialisiert und dann gibt es potentiell Murks
-
Stimmt, macht irgendwie Sinn
Also wenn ich eine LeGo-Funktion in einer Funktion ausführe, die als onUse in einem Item angegeben wird, sollte es keine Probleme geben?
-
Nein, das betrifft nur Code, der in der Instanzfunktion auch ausgeführt wird.
-
Zitat von Bisasam
Solange du nicht extra das G1 Pendant zu 7567329 rausgesucht hast, wird es da jede Menge Probleme geben.
Zitat von Dada
7567329 (0x007377E1) ist die Adresse für G1
Zitat von mud-freak
Nur für zukünftige Forensucher: Die Schadensskripte (inklusive der Speicheradressen) für Gothic 1 und Gothic 2 sind beide in diesem Thread zu finden (das Skript für Gothic 1 auf der dritten Seite).
Habe ich doch gemacht, die Adresse für G2 ist 6736583, 5, (verlinkiter Thread Seite 1)
und für G1 ist 7567329, 6,
wenn ich den G2 code für G1 benutzte stürzt das Spiel eh ab sobald Diego vor mir steht.
Zitat von mud-freak
Ich denke du solltest noch mehr mit Debug-Ausgaben (MEM_Info) arbeiten, um herauszufinden wo genau das Problem liegt. Du solltest dir zu Anfang und am Ende der DMG_OnDmg alle verschiedenen Rüstungswerte (BLUNT, EDGE, ...) und den Schadenswert nach der Verrechnung ausgeben lassen und mit den Charakterwerten vergleichen. Ebenso solltest du die Werte zwischen die ganzen Verrechnungen in B_calculatenewarmour überprüfen.
Sowas habe ich noch nie gemacht aber dann weiß ich wenigstens was ich heute zu tun habe, wird aber wohl nen bisschen dauern bis ich das begriffen habe wie das funktioniert. Bisher habe ich das auf eher unprofessionelle Art und Weise geprüft mit B_RaiseAttribute(ATR_STRENGTH, value); bei nur einem wert oder bei mehreren werten CreateInvItems(hero, item1-10), value1-10); , .... bei mehreren Werten. Ich kanns ja nachher nochmal überprüfen aber ich bin mir ziemlich sicher das alle Werte ok waren bis auf protection[PROT_EDGE];
-
Am einfachsten (für einen Anfänger) geht das vermutlich mit der Funktion MEM_InfoBox("Nachricht") (Nachricht solltest du natürlich mit deinem eigenen Text ersetzen). Wenn diese Zeile ausgeführt wird, wird Gothic komplett pausiert, d.h. auch das Script wird nicht weiter ausgeführt, und es erscheint eine Windows-Messagebox mit deinem Text drin. Sobald du auf "OK" klickst, wird Gothic fortgesetzt. Du könntest dann zum Beispiel so verfahren:
Code:
func int DMG_OnDmg (var int victimPtr, var int attackerPtr, var int dmg)
{
Var c_npc slf; slf = _^(attackerptr);
Var c_npc oth; oth = _^(victimPtr);
var int mydamage; var int meleedamage; var int myarmour; var int attributsboni; var int critrandom; var int critchance; var int critboni;var int bonusmeleeprot;
var int msg; msg = ConcatStrings("PROT_EDGE: ", IntToString(oth.protection[PROT_EDGE));
MEM_InfoBox(msg);
if (C_NpcIsMonster(slf)) ////monster richten edge an
{
meleedamage=slf.attribute[ATR_STRENGTH];
meleedamage=100;
...
Jedes Mal, wenn jetzt die DMG_OnDmg() ausgeführt wird, bleibt Gothic kurz stehen und dir wird der entsprechende Wert angezeigt.
Edit: Das wird dich vermutlich aus dem Vollbildschirm werfen, aber ich teste beim Entwickeln sowieso immer im Fenstermodus...
-
PROBLEM GELÖST
Bekam ne Fehlermeldung Func does not return an int (line 66)
erste Vermutung, hab ne alte Lego Version, gleich mal geschaut und Tata Fehlerquelle gefunden.
Neues Lego drauf und bisher klappte alles 100% einwandfrei.
Das war dumm von mir, hätte da mal viel früher nachschauen müssen,
erst danach ist mir eingefallen, dass Texte string und nicht int sind (+ ein fehlendes ] am Ende) sprich
var string msg; msg = ConcatStrings("PROT_EDGE: ", IntToString(oth.protection[PROT_EDGE]));
MEM_InfoBox(msg);
Das klappt auch wunderbar, nur wird Gothic minimiert, ich klicke auf OK, nur dann wird Gothic wieder zum Vollbild vergrößert, in dieser Zeit geht das Spie lschon weiter und ich werde erneut getroffen ohne per cheats Rüstungswerte zu verändern, wie kann ich das einstellen, dass Gothic dann im Kleinbild Format bleibt.
-
Am besten einfach direkt im Fenstermodus starten, dazu gibt es eine Option im GothicStarter. Ansonsten kannst du auch im Spiel mittels F3 (im Marvin-Modus) zwischen Vollbild und Fenstermodus wechseln.
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
|