-
Ich weiß nicht, ob es großartig nützlich ist, aber ich habe eine Möglichkeit gefunden, die Animation, die ausgeführt wird, wenn man Schaden nimmt, zu unterdrücken:
Code:
// Init
const int t = 1;
if (t) {
HookEngineF(6774593, 9, DisableDmgAnimation);
t = 0;
};
func void DisableDmgAnimation() {
if (condition) {
EAX = 0; // Jetzt wird die Animation unterdrückt
};
};
Außer einer Nachricht im zSpy (Irgendwas mit Modell nicht gefunden oder so ) hab ich keine unerwünschten Nebeneffekte gefunden, aber die Benutzung erfolgt auf eigene Gefahr.
Last edited by Lehona; 13.02.2016 at 20:20.
-
dir fehlt da ein oeffnender code-tag.
Mehr habe ich gerade nicht beizutragen.
-
-
 Originally Posted by Lehona
Ich weiß nicht, ob es großartig nützlich ist, aber ich habe eine Möglichkeit gefunden, die Animation, die ausgeführt wird, wenn man Schaden nimmt, zu unterdrücken:
Code:
// Init
const int t = 1;
if (t) {
HookEngineF(6774593, 9, DisableDmgAnimation);
t = 0;
};
func void DisableDmgAnimation() {
if (condition) {
EAX = 0; // Jetzt wird die Animation unterdrückt
};
};
Außer einer Nachricht im zSpy (Irgendwas mit Modell nicht gefunden oder so  ) hab ich keine unerwünschten Nebeneffekte gefunden, aber die Benutzung erfolgt auf eigene Gefahr.
Das ist ja geil.
Wird die ani nur für dieses eine mal, wo die condition passt unterdrückt? Oder ab der ersten erfüllen dann für alle Npcs?
-
Immer wenn die Bedingung erfüllt ist, wird die Animation unterdrückt. In ECX sollte der NPC stehen, also wäre das z.B. möglich:
Code:
var c_npc slf; slf = _^(ECX);
if (Npc_IsPlayer(slf)) { EAX = 0; };
Last edited by Lehona; 14.02.2016 at 06:53.
-
Bug Report
I discovered a bug that Frame Functions are not removed via FF_Remove(FuncName) while the function is applied in the function. 
Example:
Code:
func blahblah
{
if something
{
FF_Remove(blahblah);
};
};
-
Well it actually works for me 
Can you show us the code and how you trigger it?
-
Well I am not using anything like this right now. I had a function of showing X/Y/Z positions via using a compass, but then I removed it and left it print all the time.
My code was like this, item (compass) applied a function FF_Apply(ShowCoordinates); and the function ShowCoordinates looked like this:
Code:
func void ShowCoordinates ()
{
if (FF_Active(ShowCoordinates))
{
B_PrintScreen (ConcatStrings("X: ", Float32ToString(her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_X])), 2, 18, "Font_Default.tga", 75);
B_PrintScreen (ConcatStrings("Y: ", Float32ToString(her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Y])), 2, 18+2, "Font_Default.tga", 75);
B_PrintScreen (ConcatStrings("Z: ", Float32ToString(her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Z])), 2, 18+4, "Font_Default.tga", 75);
}
else
{
FF_Remove(ShowCoordinates);
};
};
-
How is that supposed to work?
Once you have your function going,
FF_Active(ShowCoordinates)
will return true, so the else part to take it out again is never reached.
-
Oh, yea... my bad, didn't think about it this way...
Thank you.
-
 Originally Posted by Abuyin Sharidi
Well I am not using anything like this right now. I had a function of showing X/Y/Z positions via using a compass, but then I removed it and left it print all the time.
My code was like this, item (compass) applied a function FF_Apply(ShowCoordinates); and the function ShowCoordinates looked like this:
Code:
func void ShowCoordinates ()
{
if (FF_Active(ShowCoordinates))
{
B_PrintScreen (ConcatStrings("X: ", Float32ToString(her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_X])), 2, 18, "Font_Default.tga", 75);
B_PrintScreen (ConcatStrings("Y: ", Float32ToString(her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Y])), 2, 18+2, "Font_Default.tga", 75);
B_PrintScreen (ConcatStrings("Z: ", Float32ToString(her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Z])), 2, 18+4, "Font_Default.tga", 75);
}
else
{
FF_Remove(ShowCoordinates);
};
};
Mmm, how do you expect the function to be removed? If you call ShowCoordinates via FF, then FF_Active(ShowCoordinates), will be always true unless you remove it. But since it will be always true FF_Remove will never be called.
EDIT: sorry didn't see milky way message
Last edited by Frank-95; 14.02.2016 at 21:58.
-
Hi all. Since I noted some troubles from G2 to G1 as regards moving and rotating objects (here), I searched for functions related to these topics in the forum, and I adapted them for both G1, both G2.
NOTE: functions are all made by gottried and/or lehona! I just found relative G1 addresses. Moreover I couldn't test them. In fact I do not own gothic 1, but I only was sent the executable by Bisasam. I don't think there are any problem though.
From Gottried scripts (link), I corrected the first functions numbers, and add G1 address for sincos approx:
Code:
func void TRF_MoveToY(var zCVob obj, var int y) {
obj.trafoObjToWorld[ 7] = y;
};
func void TRF_MoveToZ(var zCVob obj, var int z) {
obj.trafoObjToWorld[ 11] = z;
};
const int TRFINT_Adr_Sin_G1 = 6092576; //0x5CF720
const int TRFINT_Adr_Sin_G2 = 8599080; //0x833628
func int TRFINT_SIN(var int x) {
x = mulf(x, 1148848204); //* 1000.13
x = addf(x, 1162107260); //+ 1000*PI
x = roundf(x);
var int ptr; ptr = MEM_StackPos.position;
if(x<0) {
x+=6284;
MEM_StackPos.position = ptr;
};
x = x%6284;
return MEM_ReadInt(MEMINT_SwitchG1G2(TRFINT_Adr_Sin_G1,TRFINT_Adr_Sin_G2)+(4*x));
};
From misc.d file in LeGo package:
Code:
const int HALFPI = 1070141312; // PI/2 rad
func int atan2f(var int x, var int y) {
const int _atan2f_G1 = 7757480; //0x765EA8
const int _atan2f_G2 = 8123804; //0x7BF59C
const int call = 0;
var int ret;
if (Call_Begin(call)) {
CALL_FloatParam(_@(x));
CALL_FloatParam(_@(y));
CALL_RetValisFloat();
CALL_PutRetValTo(_@(ret));
CALL__cdecl(MEMINT_SwitchG1G2(_atan2f_G1,_atan2f_G2));
call = CALL_End();
};
return +ret;
};
func int distance2Df(var int x1, var int x2, var int y1, var int y2) {
var int dx; dx = subf(x1, x2);
var int dy; dy = subf(y1, y2);
return +(sqrtf(addf(mulf(dx, dx), mulf(dy, dy))));
};
func int distance2D(var int x1, var int x2, var int y1, var int y2) {
return roundf(distance2Df(mkf(x1), mkf(x2), mkf(y1), mkf(y2)));
};
func int sin(var int angle) {
const int _sinf_G1 = 7757586; //0x765F12
const int _sinf_G2 = 8123910; //0x7BF606
const int call = 0;
var int ret;
if (Call_Begin(call)) {
CALL_FloatParam(_@(angle));
CALL_RetValisFloat();
CALL_PutRetValTo(_@(ret));
CALL__cdecl(MEMINT_SwitchG1G2(_sinf_G1,_sinf_G2));
call = CALL_End();
};
return +ret;
};
func int acos(var int cosine) {
const int _acosf_G1 = 7757470; //0x765E9E
const int _acosf_G2 = 8123794; //0x7BF592
const int call = 0;
var int ret;
if (Call_Begin(call)) {
CALL_FloatParam(_@(cosine));
CALL_RetValisFloat();
CALL_PutRetValTo(_@(ret));
CALL__cdecl(MEMINT_SwitchG1G2(_acosf_G1,_acosf_G2));
call = CALL_End();
};
return +ret;
};
func int asin(var int sine) {
return +subf(halfpi, acos(sine));
};
func int cos(var int angle) {
return +sin(subf(halfpi, angle));
};

-
I tried to use the code this way:
Code:
func int GetNpcDirectionQuarter(var C_NPC slf) //return the caster direction quarter
{
var zCVob zslf; zslf = Hlp_GetNpc(slf);
if(gf(zslf.trafoObjToWorld[0], mkf(0)) && gf(zslf.trafoObjToWorld[8], mkf(0)))
{
return 1;
}
else if(lf(zslf.trafoObjToWorld[0], mkf(0)) && gf(zslf.trafoObjToWorld[8], mkf(0)))
{
return 2;
}
else if(lf(zslf.trafoObjToWorld[0], mkf(0)) && lf(zslf.trafoObjToWorld[8], mkf(0)))
{
return 3;
}
else if(gf(zslf.trafoObjToWorld[0], mkf(0)) && lf(zslf.trafoObjToWorld[8], mkf(0)))
{
return 4;
};
};
//////////////////////////////////////////////////////
func void TRF_MoveToY(var zCVob obj, var int y) {
obj.trafoObjToWorld[ 7] = y;
};
func void TRF_MoveToZ(var zCVob obj, var int z) {
obj.trafoObjToWorld[ 11] = z;
};
const int TRFINT_Adr_Sin_G1 = 6092576; //0x5CF720
const int TRFINT_Adr_Sin_G2 = 8599080; //0x833628
func int TRFINT_SIN(var int x) {
x = mulf(x, 1148848204); //* 1000.13
x = addf(x, 1162107260); //+ 1000*PI
x = roundf(x);
var int ptr; ptr = MEM_StackPos.position;
if(x<0) {
x+=6284;
MEM_StackPos.position = ptr;
};
x = x%6284;
return MEM_ReadInt(MEMINT_SwitchG1G2(TRFINT_Adr_Sin_G1,TRFINT_Adr_Sin_G2)+(4*x));
};
const int HALFPI = 1070141312; // PI/2 rad
func int atan2f(var int x, var int y) {
const int _atan2f_G1 = 7757480; //0x765EA8
const int _atan2f_G2 = 8123804; //0x7BF59C
const int call = 0;
var int ret;
if (Call_Begin(call)) {
CALL_FloatParam(_@(x));
CALL_FloatParam(_@(y));
CALL_RetValisFloat();
CALL_PutRetValTo(_@(ret));
CALL__cdecl(MEMINT_SwitchG1G2(_atan2f_G1,_atan2f_G2));
call = CALL_End();
};
return +ret;
};
func int distance2Df(var int x1, var int x2, var int y1, var int y2) {
var int dx; dx = subf(x1, x2);
var int dy; dy = subf(y1, y2);
return +(sqrtf(addf(mulf(dx, dx), mulf(dy, dy))));
};
func int distance2D(var int x1, var int x2, var int y1, var int y2) {
return roundf(distance2Df(mkf(x1), mkf(x2), mkf(y1), mkf(y2)));
};
func int sin(var int angle) {
const int _sinf_G1 = 7757586; //0x765F12
const int _sinf_G2 = 8123910; //0x7BF606
const int call = 0;
var int ret;
if (Call_Begin(call)) {
CALL_FloatParam(_@(angle));
CALL_RetValisFloat();
CALL_PutRetValTo(_@(ret));
CALL__cdecl(MEMINT_SwitchG1G2(_sinf_G1,_sinf_G2));
call = CALL_End();
};
return +ret;
};
func int acos(var int cosine) {
const int _acosf_G1 = 7757470; //0x765E9E
const int _acosf_G2 = 8123794; //0x7BF592
const int call = 0;
var int ret;
if (Call_Begin(call)) {
CALL_FloatParam(_@(cosine));
CALL_RetValisFloat();
CALL_PutRetValTo(_@(ret));
CALL__cdecl(MEMINT_SwitchG1G2(_acosf_G1,_acosf_G2));
call = CALL_End();
};
return +ret;
};
func int asin(var int sine) {
return +subf(halfpi, acos(sine));
};
func int cos(var int angle) {
return +sin(subf(halfpi, angle));
};
//////////////////////////////////////
func void InBlickrichtungMitDir(var oCNpc Held, var oCNpc GivenNpc,var int angleRot)//angleRot z.B. 90
{
MEM_InitAll();
var zCVob slf; slf = Hlp_GetNpc(Held);
var int dx; var int dy; var int dz;
dy = addf(slf.trafoObjToWorld[zCVob_trafoObjToWorld_Y],mkf(20));
dx = addf(slf.trafoObjToWorld[3], mulf(mkf(50), slf.trafoObjToWorld[2]));
dz = addf(slf.trafoObjToWorld[11], mulf(mkf(50), slf.trafoObjToWorld[10]));
//**************************** Rotation***********************************
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
var int rotx; var int roty; var int angle;
if(GetNpcDirectionQuarter(hero) == 1)
{
angle = addf(asin(slf.trafoObjToWorld[8]), mkf(angleRot));
}
else if(GetNpcDirectionQuarter(hero) == 2)
{
angle = addf(acos(slf.trafoObjToWorld[0]), mkf(angleRot));
}
else if(GetNpcDirectionQuarter(hero) == 3)
{
var int delta; delta = subf(pi, acos(slf.trafoObjToWorld[0]));
angle = addf(pi, delta);
angle = addf(angle, mkf(angleRot));
}
else if(GetNpcDirectionQuarter(hero) == 4)
{
angle = addf(asin(slf.trafoObjToWorld[8]), mkf(angleRot));
};
rotx = cos(angle);
roty = sin(angle);
GivenNpc._zCVob_trafoObjToWorld[0] = rotx;
GivenNpc._zCVob_trafoObjToWorld[8] = roty;
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
GivenNpc._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_X] = dx;
GivenNpc._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Y] = dy; //höhe
GivenNpc._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Z] = dz;
};
//**********************************************
//
//**********************************************
func void Npc_MoveToHero(var oCNpc GivenNpc)
{
var oCNpc her; her = Hlp_GetNpc(hero);
InBlickrichtungMitDir (her,GivenNpc,90);
VobPositionUpdated (_@(GivenNpc));
};
(Every frame)
The result:
[Video]
That doesn't seem to be correct
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
-
I tried to use other indexes in g2 and they seem to have some effects on scale. So just try other index pairs. Instead of 0 and 8, 1 and 9 or 2 and 10. Maybe they are just different from G2 ones. Make some tries I don't have a crystall ball
Last edited by Frank-95; 15.02.2016 at 18:02.
-
Depending on what exactly you need I made a working version:
Code:
const int zCVob__Move_G2 = 6402784; //0x61B2E0
const int zCVob__Move_G1 = 6217184; //0x5EDDE0
func void Vob_Move(var int ptr, var int x, var int y, var int z) {
CALL_FloatParam(x);
CALL_FloatParam(y);
CALL_FloatParam(z);
CALL__thiscall(ptr, MEMINT_SwitchG1G2(zCVob__Move_G1, zCVob__Move_G2));
};
func void zCVob_RotateWorld(var int vobPtr, var int vecPtr, var int scale) {
const int zCVob__RotateWorld_G2 = 6403360; //61B520h
const int zCVob__RotateWorld_G1 = 6217744; //5EE010h
CALL_FloatParam(scale);
CALL_PtrParam(vecPtr);
CALL__thiscall(vobPtr, MEMINT_SwitchG1G2(zCVob__RotateWorld_G1, zCVob__RotateWorld_G2));
};
func void zCVob_Turn(var int vobPtr, var int degreesf) {
var int vec[3];
vec[0] = 0;
vec[1] = FLOATEINS;
vec[2] = 0;
zCVob_RotateWorld(vobPtr, _@(vec), degreesf);
};
func void moveFocusInFrontOfHero(var int vobPtr) {
var zCVob her; her = Hlp_GetNpc(hero);
var zCVob vob; vob = _^(vobPtr);
// trafo kopieren
MEM_CopyBytes(_@(her)+60, vobPtr+60, 64);
// Vob vor den Helden setzen
var int delta; delta = mkf(50);
Vob_Move(vobPtr, mulf(her.trafoObjToWorld[10], delta), mulf(her.trafoObjToWorld[6], delta), mulf(her.trafoObjToWorld[2], delta));
// Vob drehen
zCVob_Turn(vobPtr, mkf(180));
};
Called every Frame it sort of attaches a vob to the front of the hero (facing him). I hate trigonometry so it's doing something rather crude - taking the hero's rotation and turning the vob by 180°. It works, but if you're making turns it rotates the other way (obviously).
The addresses are only tested for G2, but I very much doubt there's any difference.
 Originally Posted by Frank-95
I tried to use other indexes in g2 and they seem to have some effects on scale. So just try other index pairs. Instead of 0 and 8, 1 and 9 or 2 and 10. Maybe they are just different from G2 ones. Make some tries I don't have a crystall ball 
No, the indices should be the same.
-
Lehona did it the right way.
Just for addition, I wanna try to explain a little bit, why it didn't worked:
The engine has to know for each object its location and its orientation. Location is simply a vector with the global axis components x,y,z. Because we are in 3d, the orientation has to be defined by three vectors, defining the up-direction, the right direction and the look direction.
The up-direction, right-direction and look direction are therefore the local coordination system of the specific object.
For illustration here is the content of trafoObjToWorld:
 Originally Posted by NicoDE
Code:
+ | 0 | 1 | 2 | 3 |
-------+---------------+------------+-------------+---------------+
0 * 4 | RightVector X | UpVector X | OutVector X | Translation X |
-------+---------------+------------+-------------+---------------+
1 * 4 | RightVector Y | UpVector Y | OutVector Y | Translation Y |
-------+---------------+------------+-------------+---------------+
2 * 4 | RightVector Z | UpVector Z | OutVector Z | Translation Z |
-------+---------------+------------+-------------+---------------+
3 * 4 | | | | |
-------+---------------+------------+-------------+---------------+
An example would be:
Code:
+ | 0 | 1 | 2 | 3 |
-------+---------------+------------+-------------+---------------+
0 * 4 | 1 | 0 | 0 | 0 |
-------+---------------+------------+-------------+---------------+
1 * 4 | 0 | 1 | 0 | 0 |
-------+---------------+------------+-------------+---------------+
2 * 4 | 0 | 0 | 1 | 0 |
-------+---------------+------------+-------------+---------------+
3 * 4 | | | | |
-------+---------------+------------+-------------+---------------+
So: RightVector (local x axis) is identically to the (world) x axis.
UpVector (local y axis) is identically to (world) y axis. Analogous is OutVector (local z axis) the world z axis.
Also to notice: The object is at the origin (0,0,0).
Now, just say we want to rotate the object about 90° on the local y axis. This is the same, as we would rotate the coordinate system at the y axis. So, if we rotate the x-axis about 90°, it is now equal to the world's z axis and analogous the local z-axis is equal to the world's -x axis. The local y axis is not changing.The final matrix would now look so:
Code:
+ | 0 | 1 | 2 | 3 |
-------+---------------+------------+-------------+---------------+
0 * 4 | 0 | 0 | -1 | 0 |
-------+---------------+------------+-------------+---------------+
1 * 4 | 0 | 1 | 0 | 0 |
-------+---------------+------------+-------------+---------------+
2 * 4 | 1 | 0 | 0 | 0 |
-------+---------------+------------+-------------+---------------+
3 * 4 | | | | |
-------+---------------+------------+-------------+---------------+
At this point, it should be clear, that only changing the offsets 0 and 8 does not give you the exact result. This is also the reason, why your npc is scaled, because your vectors aren't orthogonal anymore.
This was just a simple example where we could just guess the right values, but if you want to calculate it for all angles and all possible rotation axis (because the UpVector can be different, too!) it is much more complicated. The idea would be to do matrix multiplication with a rotation matrix and then normalize UpVector, RightVector and OutVector because they have to be unit vectors( otherwise you would accidently scale your object!).
All in all, for your purposes, its the best just to use the functions, Pyranha Bytes created already. But if you are interested in this sort of math, when i would suggest you to look into a 3D Computer Graphics book your search online about Matrix Mulitplication and transformation matrices (especially rotation matrix).
-
Lehonas Code works perfectly for me. I just have another request.
The height of the Vob should be higher than the one of the hero.
I tried to simply modify trafoobj 7 by that height, but the game crashes.
Also, I don't understand why you use 2, 6 and 10 instead of 3, 7 and 11.
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
-
At first, he sets the npc's orientation and location equal to that of the hero simply by asigning the npc the exact matrix. Hero and npc have so the same location and orientation.
Code:
// trafo kopieren
MEM_CopyBytes(_@(her)+60, vobPtr+60, 64);
In order to position the npc in front of the hero, you have to move the npc on the out-vector (the look direction). That's the reason for the indices 2,6 and 10:
Code:
// Vob vor den Helden setzen
var int delta; delta = mkf(50);
Vob_Move(vobPtr, mulf(her.trafoObjToWorld[10], delta), mulf(her.trafoObjToWorld[6], delta), mulf(her.trafoObjToWorld[2], delta));
For your second problem i'm clueless, too. It's definitely no math problem.
Maybe you get it work if you use the function Vob_Move instead of directly changing the matrix.
-
I removed the collision of my vob and there is no crash anymore. It was a matter of worldcollision.
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
-
Thanks for the very good explaination Neconspictor!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
|