Tomb Raider Forums  

Go Back   Tomb Raider Forums > Tomb Raider Level Editor and Modding > Tomb Raider Level Editor > Tomb Raider Next Generation

Reply
 
Thread Tools
Old 24-07-19, 21:59   #521
Krystian
Member
 
Joined: May 2010
Posts: 1,187
Default

@AkyV
I understood this description, however I still think that it would be easier to check for the down key (even as scancode if not by game command), rather than trying to force specific animation parameters on animation 88.
The speed value stored by engine for animations is indeed strange and is converted by some complex formula to the SpeedH value we know, so it might not be worth the trouble to go this path...

I suspect that the problem with your current approach is that the walk mode is still engaged briefly (I'm guessing for just a single frame, but even this single frame is troublesome) after the game receives the Down command. As a result the game executes the walk back stateID and Lara initially does the stepping back animation instead of the hop. This is why, for your goal, I do not recommend checking for anim 41 (stepping back), because even if this does result in turning off the walk mode, it is done post-factum, when anim 41 has already been triggered due to the 1 frame delay I mentioned.

Remember that in the end the game works in frame cycles. Once game code has already been executed for one particular frame cycle, it cannot be always retroactively fixed in a later part of that cycle, and when that happens the change can take effect only in next cycle. In this case specifically, the condition for anim 41 asserts that the animation is already executed by game, and thus despite walk mode getting turned off even in the first frame, the animation continues, as it can only stop when reaching a state change. This would explain why the second down key press works fine - the walk mode had already been disabled by this time, thus the hopping back animation is launched instead.

I have strong confidence that detecting the down key press (optionally with additional checks for relevant stateIDs) will allow you to disable the 'walk mode' before game gets chance to launch the "walking back" stateID and animation.

Last edited by Krystian; 24-07-19 at 22:10.
Krystian is offline   Reply With Quote
Old 25-07-19, 19:07   #522
AkyV
Moderator
 
Joined: Dec 2011
Posts: 4,881
Default

Quote:
Originally Posted by Krystian View Post
I have strong confidence that detecting the down key press (optionally with additional checks for relevant stateIDs) will allow you to disable the 'walk mode' before game gets chance to launch the "walking back" stateID and animation.
Thanks for the tip, Krystian, but even if I use it as a very general and harsh condition, just for the tests ("abort stepping back everyway if Down is pressed"), the effect is still the same = first step back, then hop back.

Quote:
Originally Posted by TokyoSU View Post
#define VAR(address, type) (*(type*)(address))
#define Ptr_Lara VAR(0x0080E01C, StrItemTr4*)

use Ptr_Lara->AnimationNow = XX;
The effect is the same, as with the usual "Get". (I typed all of this in Constants_mine.h. However, I did not get clearly, why a formula, i.e "VAR=address.." etc. goes into "define"? It is not a constant. ) So, it was wrong.
However, I need to ask, as an additional question, that does it not ruin the original StrItemTr4 and Get?

Quote:
SetAnimationAndSpeed() (from Plugin_Trng)
I couldn't find it in anywhere in the default sources...

Quote:
ForceAnimationForLara()
That! That was it! It worked!

ForceAnimationForLara(88, 5)

(5 is the stateID for hopping back, including Anim88.)

(But I ask:
why, oh, why does it not work with casual TRNG functions exported or the handy Get function...?)

----------------------

Side note:
When I forced animation and speed=0 with Get, then I noticed it almost worked properly if Lara was close (max. 3-4 sectors) to green wall panels, facing them, aborting stepping back to hopping back. ("Almost" = in the 10-20 % of the cases Down simply turned of the walking mode, but Lara didn't move.)
So perhaps green walls are a good clue to find it out how SpeedH works.
AkyV is online now   Reply With Quote
Old 26-07-19, 07:34   #523
TokyoSU
Member
 
TokyoSU's Avatar
 
Joined: Mar 2019
Posts: 687
Default

Quote:
Originally Posted by AkyV View Post
The effect is the same, as with the usual "Get". (I typed all of this in Constants_mine.h. However, I did not get clearly, why a formula, i.e "VAR=address.." etc. goes into "define"? It is not a constant. ) So, it was wrong.
However, I need to ask, as an additional question, that does it not ruin the original StrItemTr4 and Get?
this variable defined at an address is really working because i use it with my plugins and Arsunt use it in TR2Main, it's not ruining Get because it access directly in the variable (tomb4.exe) and TRNG use this address. it just update variable before trng.



Quote:
Originally Posted by AkyV View Post
I couldn't find it in anywhere in the default sources...
it's in Plugin_trng (final):
Plugin_Trng.cpp and research SetAnimationAndSpeed,
but like you said ForceAnimationForLara is working, this command just add SpeedH.

Quote:
Originally Posted by AkyV View Post
That! That was it! It worked!

ForceAnimationForLara(88, 5)

(5 is the stateID for hopping back, including Anim88.)

(But I ask:
why, oh, why does it not work with casual TRNG functions exported or the handy Get function...?)
i'm glad that it's worked, it's probably because ForceAnimationForLara() is created by Paolone because it's use Get "probably". You can check the code in trng.cpp.

Quote:
Originally Posted by AkyV View Post
----------------------

Side note:
When I forced animation and speed=0 with Get, then I noticed it almost worked properly if Lara was close (max. 3-4 sectors) to green wall panels, facing them, aborting stepping back to hopping back. ("Almost" = in the 10-20 % of the cases Down simply turned of the walking mode, but Lara didn't move.)
So perhaps green walls are a good clue to find it out how SpeedH works.
it's really anoying this bug with speedH that work only if he want
because i cant set a progressive moving to the quad because speedH not want to be updated !

Last edited by TokyoSU; 26-07-19 at 07:35.
TokyoSU is offline   Reply With Quote
Old 27-07-19, 10:57   #524
AkyV
Moderator
 
Joined: Dec 2011
Posts: 4,881
Default

Quote:
Originally Posted by TokyoSU View Post
this variable defined at an address is really working because i use it with my plugins and Arsunt use it in TR2Main, it's not ruining Get because it access directly in the variable (tomb4.exe) and TRNG use this address. it just update variable before trng.
So I can use collaterally each other now Ptr_Lara and GET.Lara for StrItemTr4...
Okay, I get the theory. But, practically: what are the differences?

Quote:
it's in Plugin_trng (final):
Plugin_Trng.cpp and research SetAnimationAndSpeed,
but like you said ForceAnimationForLara is working, this command just add SpeedH.
I always started my plugins with the plugin start map so far.
With your advice, I just realized that there can be functions in the default plugin sources which Paolone does not mention either in the start sources or Plugin SDK 1 or 2 or function collection tutorials.
AkyV is online now   Reply With Quote
Old 27-07-19, 14:33   #525
TokyoSU
Member
 
TokyoSU's Avatar
 
Joined: Mar 2019
Posts: 687
Default

Quote:
Originally Posted by AkyV View Post
So I can use collaterally each other now Ptr_Lara and GET.Lara for StrItemTr4...
Okay, I get the theory. But, practically: what are the differences?
StrItemTr4 is just the structure, Ptr_Lara use StrItemTr4 and get the variable directly in "tomb4.exe" and GET.pLara use TRNG, just that TRNG have defined this variables with "GET." probably initialised in Tomb_NextGeneration.dll.
Ptr_Lara not need Get(enumGET.LARA, 0, 0) than GET.pLara.

Quote:
Originally Posted by AkyV View Post
I always started my plugins with the plugin start map so far.
With your advice, I just realized that there can be functions in the default plugin sources which Paolone does not mention either in the start sources or Plugin SDK 1 or 2 or function collection tutorials.
here you are : Plugin Tutorial Link 246: SetAnimationAndSpeed, another example: Plugin Tutorial Link 231: IsMissingWall
all exist in Plugin_Trng final version. just move it from this project to your project (if you need it)

Last edited by TokyoSU; 27-07-19 at 14:41.
TokyoSU is offline   Reply With Quote
Old 27-07-19, 14:33   #526
Krystian
Member
 
Joined: May 2010
Posts: 1,187
Default

Quote:
Originally Posted by AkyV View Post
So I can use collaterally each other now Ptr_Lara and GET.Lara for StrItemTr4...
Okay, I get the theory. But, practically: what are the differences?
The difference is that this Ptr_Lara is the direct pointer stored by tomb4 game memory, whereas GET.pLara is the value copied from this Ptr_Lara pointer, but it is updated later, by the trng_dll library. In most cases it doesn't make a difference, but occasionally it does. The subprocesses in trng_dll library get called after native tomb4 game code, so updating of this GET.pLara pointer and its associated values (SpeedH, StateIdCurrent, OrientH, etc.) happens at a later stage.
For most plugin work this isn't necessary, but in some specific instances (e.g. plugins that are done in assembly code called directly from Tomb4 game code) this is a much easier and faster way to access the pLara pointer than using the Get() function and GET structure, and in the need of modifying values, allows to change associate values directly, rather than relying on the GET. structure which updates only in trng_dll (so much after the tomb4 call).

EDIT: TokyoSU was faster this time
Krystian is offline   Reply With Quote
Old 27-07-19, 19:28   #527
ChocolateFan
Member
 
Joined: Dec 2017
Posts: 534
Default

AkyV, of course you do not have to use ForceAnimationForLara(). These two implementations are perfectly equivalent:

Code:
void ForceAnimationForLara_GET(int NumAnimation, int NextStateId) {
	Get(enumGET.LARA, 0, 0);
	if (GET.pLara->AnimationNow == NumAnimation) // if current lara animation is already the same to set: quit
		return;
	Get(enumGET.ANIMATION, NumAnimation, 0);
	if (!GET.pAnimation->FrameSize) { // verifiy that wished animation existed really
		SendToLog("ERROR: missing animation number %d for Lara", NumAnimation);
		return;
	}
	GET.pLara->FrameNow = GET.pAnimation->FrameStart;
	GET.pLara->StateIdCurrent = GET.pAnimation->StateId;
	if (NextStateId != -1) {
		GET.pLara->StateIdNext = NextStateId;
	} else {
		GET.pLara->StateIdNext = GET.pAnimation->StateId;
	}
	GET.pLara->AnimationNow = NumAnimation;
}
Code:
/* https://github.com/Arsunt/TR2Main/blob/b762737f1f317c0c2dd9398560d782398189c666/global/vars.h#L38 */
#define VAR_U_(address, type) (*(type*)(address)) // uninitialized variable

#define Ptr_Lara VAR_U_(0x80E01C, StrItemTr4 *)
#define Ptr_VetAnimations VAR_U_(0x533938, StrAnimationTr4 *)

void ForceAnimationForLara_TR2MainMacros(int NumAnimation, int NextStateId) {
	StrAnimationTr4 *Animation;

	if (Ptr_Lara->AnimationNow == NumAnimation) // if current lara animation is already the same to set: quit
		return;
	Animation = &Ptr_VetAnimations[NumAnimation];
	if (!Animation->FrameSize) { // verifiy that wished animation existed really
		SendToLog("ERROR: missing animation number %d for Lara", NumAnimation);
		return;
	}
	Ptr_Lara->FrameNow = Animation->FrameStart;
	Ptr_Lara->StateIdCurrent = Animation->StateId;
	if (NextStateId != -1) {
		Ptr_Lara->StateIdNext = NextStateId;
	} else {
		Ptr_Lara->StateIdNext = Animation->StateId;
	}
	Ptr_Lara->AnimationNow = NumAnimation;
}
Just pick the one that you feel more comfortable with.
ChocolateFan is offline   Reply With Quote
Old 28-07-19, 11:13   #528
AkyV
Moderator
 
Joined: Dec 2011
Posts: 4,881
Default

Quote:
Originally Posted by TokyoSU View Post
StrItemTr4 is just the structure, Ptr_Lara use StrItemTr4 and get the variable directly in "tomb4.exe" and GET.pLara use TRNG, just that TRNG have defined this variables with "GET." probably initialised in Tomb_NextGeneration.dll.
Ptr_Lara not need Get(enumGET.LARA, 0, 0) than GET.pLara.
Quote:
Originally Posted by Krystian View Post
The difference is that this Ptr_Lara...
Thank you, guys, for this info.

Quote:
here you are : Plugin Tutorial Link 246: SetAnimationAndSpeed, another example: Plugin Tutorial Link 231: IsMissingWall
all exist in Plugin_Trng final version. just move it from this project to your project (if you need it)
Thanks. I don't know how I could forget it. I surely encountered it when I examined this tutorial, learning basic, back in 2016-2017.
@Any of us: that would be good an expanded function collection, with the original function collection tutorial, plus added functions from Paolone's other tutorials, from the default tutorial sources (including "old functions" there), from the original code, and perhaps some handy custom new ones. It could be expanded more later by any of us.
Does anybody have the mood and time to work on it?

Quote:
Originally Posted by ChocolateFan View Post
AkyV, of course you do not have to use ForceAnimationForLara(). These two implementations are perfectly equivalent:
Ah, okay, it is nice, I will keep it in my mind.
AkyV is online now   Reply With Quote
Old 05-08-19, 14:44   #529
TokyoSU
Member
 
TokyoSU's Avatar
 
Joined: Mar 2019
Posts: 687
Default

#fixed

Last edited by TokyoSU; 07-08-19 at 09:42.
TokyoSU is offline   Reply With Quote
Old 07-08-19, 05:57   #530
TokyoSU
Member
 
TokyoSU's Avatar
 
Joined: Mar 2019
Posts: 687
Default

i need help for something, i want to reproduce the TR4 flame from the SentryGun.
but in the function (IDApro) the sentry use the mesh 7 for throwing fire.
i need to use a different mesh and position, so for that i need to recreate the function to not change the original address.
the code:
Code:
    StrMovePosition pos_start, pos_end;
    StrSparks* sprk;
    bool end;
    int i, size, CordX, CordY, CordZ;
    signed long long distance = 0x66666667i64;

    i = 3;
    do
    {
        sprk = &spark[GetFreeSparks()];
        sprk->On = 1;
        sprk->sB = -1;
        sprk->sG = 48;
        sprk->sR = (GetRandomControl() & 0x1F) + 48;
        sprk->dR = (GetRandomControl() & 0x3F) - 64;
        sprk->dB = 32;
        sprk->dG = (GetRandomControl() & 0x3F) + (-128);
        sprk->ColFadeSpeed = 12;
        sprk->FadeToBlack = 8;
        sprk->TransType = 2;
        sprk->Life = (GetRandomControl() & 0x1F) + 16;
        sprk->sLife = (GetRandomControl() & 0x1F) + 16;

        pos_start.RelX = flamer_bite.x;
        pos_start.RelY = flamer_bite.y;
        pos_start.RelZ = flamer_bite.z;
        GetJointAbsPosition(item, &pos_start, flamer_bite.mesh_num);
        sprk->x = (GetRandomControl() & 0x1F) + pos_start.RelX - 16;
        sprk->y = (GetRandomControl() & 0x1F) + pos_start.RelY - 16;
        sprk->z = (GetRandomControl() & 0x1F) + pos_start.RelZ - 16;
        pos_end.RelX = flamer_bite.x - 800;
        pos_end.RelY = flamer_bite.y;
        pos_end.RelZ = flamer_bite.z;
        GetJointAbsPosition(item, &pos_end, flamer_bite.mesh_num);

        CordX = ((((distance * (GetRandomControl() & 0x3F) + 192) * (pos_end.RelX - pos_start.RelX)) >> 32) >> 31);
        sprk->Xvel = (CordX >> 31) + CordX;
        CordY = ((((distance * (GetRandomControl() & 0x3F) + 192) * (pos_end.RelY - pos_start.RelY)) >> 32) >> 2);
        sprk->Yvel = (CordY >> 31) + CordY;
        CordZ = ((((distance * (GetRandomControl() & 0x3F) + 192) * (pos_end.RelZ - pos_start.RelZ)) >> 32) >> 2);
        sprk->Yvel = (CordZ >> 31) + CordZ;

        sprk->Friction = 85;
        sprk->Gravity = -16 - (GetRandomControl() & 0x1F);
        sprk->MaxYvel = 0;
        sprk->Flags = 538;
        end = ((ValOscilla0_255 & 1) == 0);

        if (!end)
        {
            size = 255;
            sprk->Flags = 539;
        }

        sprk->Scalar = 3;
        sprk->dSize = (size * ((GetRandomControl() & 7) + 60) >> 8);
        sprk->sSize = (size * ((GetRandomControl() & 7) + 60) >> 8) >> 4;
        sprk->Size = (size * ((GetRandomControl() & 7) + 60) >> 8) >> 4;
        end = (i == 1);
        --i;
    } while (!end);
but for unknown reason it not work at all after placing it in the project (and trigger for an object with the correct meshid.
i dont known why but the sprite is not the flame at all and position is bugged.
here the address:
- turret flame: 0x43EDC0
- getfreesparks: 0x433830
- sparks array: 0x8012E0

sparks structure:
Code:
struct StrSparks
{
    DWORD x;
    int y;
    DWORD z;
    short Xvel;
    short Yvel;
    short Zvel;
    short Gravity;
    short rotAng;
    short Flags;
    unsigned char sSize;
    unsigned char dSize;
    unsigned char Size;
    unsigned char Friction;
    unsigned char Scalar;
    unsigned char Def;
    char RotAdd;
    char MaxYvel;
    unsigned char On;
    unsigned char sR;
    unsigned char sG;
    unsigned char sB;
    unsigned char dR;
    unsigned char dG;
    unsigned char dB;
    unsigned char R;
    unsigned char G;
    unsigned char B;
    unsigned char ColFadeSpeed;
    unsigned char FadeToBlack;
    unsigned char sLife;
    unsigned char Life;
    unsigned char TransType;
    unsigned char extras;
    char Dynamic;
    unsigned char FxObj;
    unsigned char RoomNumber;
    unsigned char NodeNumber;
};
thanks in advance for the help

Last edited by TokyoSU; 15-08-19 at 17:21. Reason: fixed what i wanted
TokyoSU is offline   Reply With Quote
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



All times are GMT. The time now is 21:28.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Tomb Raider Forums is not owned or operated by CDE Entertainment Ltd.
Lara Croft and Tomb Raider are trademarks of CDE Entertainment Ltd.