mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-06 19:01:06 +03:00
Move CurrentPendulum, ApplyVelocityToRope() and SetPendulumVelocity() to rope.cpp; Fix InitialiseRope(), PrepareRope() and NormaliseRopeVector(); Add rope functions
This commit is contained in:
parent
6976d7f6a6
commit
ba95c939a0
7 changed files with 520 additions and 73 deletions
|
@ -41,7 +41,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int KeyTriggerActive;
|
||||
PENDULUM CurrentPendulum;
|
||||
int number_los_rooms;
|
||||
short los_rooms[20];
|
||||
int ClosestItem;
|
||||
|
|
|
@ -35,7 +35,6 @@ static short RightClimbTab[4] = // offset 0xA0640
|
|||
};
|
||||
|
||||
extern Inventory* g_Inventory;
|
||||
extern PENDULUM CurrentPendulum;
|
||||
|
||||
short angle = 0;
|
||||
short elevation = 57346;
|
||||
|
@ -3498,33 +3497,6 @@ void lara_as_rope(ITEM_INFO* item, COLL_INFO* coll)//17958(<), 17A8C(<) (F)
|
|||
LookUpDown();
|
||||
}
|
||||
|
||||
void ApplyVelocityToRope(int node, short angle, short n)//178E4, 17A18 (F)
|
||||
{
|
||||
SetPendulumVelocity(
|
||||
(unsigned short) n * SIN(angle) >> 2,
|
||||
0,
|
||||
(unsigned short) n * COS(angle) >> 2);
|
||||
}
|
||||
|
||||
void SetPendulumVelocity(int x, int y, int z)
|
||||
{
|
||||
int node;
|
||||
|
||||
node = 2 * (CurrentPendulum.node >> 1);
|
||||
if (node < 24)
|
||||
{
|
||||
int val = 4096 / (24 - node) * 256;
|
||||
|
||||
x = (x * val) >> 16;
|
||||
y = (y * val) >> 16;
|
||||
z = (z * val) >> 16;
|
||||
}
|
||||
|
||||
CurrentPendulum.Velocity.x += x;
|
||||
CurrentPendulum.Velocity.y += y;
|
||||
CurrentPendulum.Velocity.z += z;
|
||||
}
|
||||
|
||||
void UpdateRopeSwing(ITEM_INFO* item)//17508, 1763C
|
||||
{
|
||||
if (Lara.ropeMaxXForward > 9000)
|
||||
|
|
|
@ -201,7 +201,6 @@ void LookUpDown();
|
|||
void ResetLook();
|
||||
void SetCornerAnim(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip);
|
||||
int CanLaraHangSideways(ITEM_INFO* item, COLL_INFO* coll, short angle);
|
||||
void ApplyVelocityToRope(int node, short angle, short n);
|
||||
void UpdateRopeSwing(ITEM_INFO* item);
|
||||
void JumpOffRope(ITEM_INFO* item);
|
||||
void FallFromRope(ITEM_INFO* item);
|
||||
|
@ -236,7 +235,6 @@ short LaraFloorFront(ITEM_INFO* item, short ang, int dist);
|
|||
void GetLaraCollisionInfo(ITEM_INFO* item, COLL_INFO* coll);
|
||||
int TestLaraVault(ITEM_INFO* item, COLL_INFO* coll);
|
||||
int TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll);
|
||||
void SetPendulumVelocity(int x, int y, int z);
|
||||
void LaraClimbRope(ITEM_INFO* item, COLL_INFO* coll);
|
||||
|
||||
//int GetLaraJointPos(PHD_VECTOR* pos, int joint);
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "effect2.h"
|
||||
#include "healt.h"
|
||||
#include "misc.h"
|
||||
#include "rope.h"
|
||||
#include "draw.h"
|
||||
|
||||
extern LaraExtraInfo g_LaraExtra;
|
||||
extern GameFlow* g_GameFlow;
|
||||
|
@ -883,10 +885,8 @@ void AnimateLara(ITEM_INFO* item)
|
|||
item->speed = velocity >> 16;
|
||||
}
|
||||
|
||||
#define SomeRopeCollisionFunc ((void (__cdecl*)(ITEM_INFO*)) 0x0046D510)
|
||||
|
||||
if (Lara.ropePtr != -1)
|
||||
SomeRopeCollisionFunc(item);
|
||||
DelAlignLaraToRope(item);
|
||||
|
||||
if (!Lara.isMoving) // TokyoSU: i dont know why but it's wreid, in TR3 only the 2 first line there is used and worked fine !
|
||||
{
|
||||
|
@ -896,4 +896,88 @@ void AnimateLara(ITEM_INFO* item)
|
|||
item->pos.xPos += lateral * SIN(Lara.moveAngle + ANGLE(90)) >> W2V_SHIFT;
|
||||
item->pos.zPos += lateral * COS(Lara.moveAngle + ANGLE(90)) >> W2V_SHIFT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DelAlignLaraToRope(ITEM_INFO* item)
|
||||
{
|
||||
ROPE_STRUCT* rope;
|
||||
short ropeY;
|
||||
PHD_VECTOR vec, vec2, vec3, vec4, vec5, pos, pos2, diff, diff2;
|
||||
int matrix[12];
|
||||
short angle[3];
|
||||
ANIM_FRAME* frame;
|
||||
|
||||
vec.x = 4096;
|
||||
vec.y = 0;
|
||||
vec.z = 0;
|
||||
frame = (ANIM_FRAME*) GetBestFrame(item);
|
||||
ropeY = Lara.ropeY - ANGLE(90);
|
||||
rope = &Ropes[Lara.ropePtr];
|
||||
_0x0046D130(rope, (Lara.ropeSegment - 1 << 7) + frame->OffsetY, &pos.x, &pos.y, &pos.z);
|
||||
_0x0046D130(rope, (Lara.ropeSegment - 1 << 7) + frame->OffsetY - 192, &pos2.x, &pos2.y, &pos2.z);
|
||||
diff.x = pos.x - pos2.x << 16;
|
||||
diff.y = pos.y - pos2.y << 16;
|
||||
diff.z = pos.z - pos2.z << 16;
|
||||
NormaliseRopeVector(&diff);
|
||||
diff.x >>= 2;
|
||||
diff.y >>= 2;
|
||||
diff.z >>= 2;
|
||||
ScaleVector(&diff, DotProduct(&vec, &diff), &vec2);
|
||||
vec2.x = vec.x - vec2.x;
|
||||
vec2.y = vec.y - vec2.y;
|
||||
vec2.z = vec.z - vec2.z;
|
||||
vec3.x = vec2.x;
|
||||
vec3.y = vec2.y;
|
||||
vec3.z = vec2.z;
|
||||
vec4.x = vec2.x;
|
||||
vec4.y = vec2.y;
|
||||
vec4.z = vec2.z;
|
||||
diff2.x = diff.x;
|
||||
diff2.y = diff.y;
|
||||
diff2.z = diff.z;
|
||||
ScaleVector(&vec3, COS(ropeY), &vec3);
|
||||
ScaleVector(&diff2, DotProduct(&diff2, &vec2), &diff2);
|
||||
ScaleVector(&diff2, 4096 - COS(ropeY), &diff2);
|
||||
CrossProduct(&diff, &vec2, &vec4);
|
||||
ScaleVector(&vec4, SIN(ropeY), &vec4);
|
||||
diff2.x += vec3.x;
|
||||
diff2.y += vec3.y;
|
||||
diff2.z += vec3.z;
|
||||
vec2.x = diff2.x + vec4.x << 16;
|
||||
vec2.y = diff2.y + vec4.y << 16;
|
||||
vec2.z = diff2.z + vec4.z << 16;
|
||||
NormaliseRopeVector(&vec2);
|
||||
vec2.x >>= 2;
|
||||
vec2.y >>= 2;
|
||||
vec2.z >>= 2;
|
||||
CrossProduct(&diff, &vec2, &vec5);
|
||||
vec5.x <<= 16;
|
||||
vec5.y <<= 16;
|
||||
vec5.z <<= 16;
|
||||
NormaliseRopeVector(&vec5);
|
||||
vec5.x >>= 2;
|
||||
vec5.y >>= 2;
|
||||
vec5.z >>= 2;
|
||||
matrix[M00] = vec5.x;
|
||||
matrix[M01] = diff.x;
|
||||
matrix[M02] = vec2.x;
|
||||
matrix[M10] = vec5.y;
|
||||
matrix[M11] = diff.y;
|
||||
matrix[M12] = vec2.y;
|
||||
matrix[M20] = vec5.z;
|
||||
matrix[M21] = diff.z;
|
||||
matrix[M22] = vec2.z;
|
||||
_0x0046D420(matrix, angle);
|
||||
item->pos.xPos = rope->position.x + (rope->meshSegment[Lara.ropeSegment].x >> 16);
|
||||
item->pos.yPos = rope->position.y + (rope->meshSegment[Lara.ropeSegment].y >> 16) + Lara.ropeOffset;
|
||||
item->pos.zPos = rope->position.z + (rope->meshSegment[Lara.ropeSegment].z >> 16);
|
||||
phd_PushUnitMatrix();
|
||||
phd_RotYXZ(angle[1], angle[0], angle[2]);
|
||||
item->pos.xPos += -112 * MatrixPtr[M02] >> W2V_SHIFT;
|
||||
item->pos.yPos += -112 * MatrixPtr[M12] >> W2V_SHIFT;
|
||||
item->pos.zPos += -112 * MatrixPtr[M22] >> W2V_SHIFT;
|
||||
phd_PopMatrix();
|
||||
item->pos.xRot = angle[0];
|
||||
item->pos.yRot = angle[1];
|
||||
item->pos.zRot = angle[2];
|
||||
}
|
||||
|
|
|
@ -1,22 +1,33 @@
|
|||
#include "rope.h"
|
||||
#include "..\Global\global.h"
|
||||
#include "draw.h"
|
||||
#include "laramisc.h"
|
||||
|
||||
PENDULUM CurrentPendulum;
|
||||
PENDULUM AlternatePendulum;
|
||||
|
||||
void InitialiseRope(short itemNumber)
|
||||
{
|
||||
ITEM_INFO* item = &Items[itemNumber];
|
||||
__int16 roomNumber = item->roomNumber;
|
||||
PHD_VECTOR itemPos;
|
||||
|
||||
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
|
||||
int ceiling = GetCeiling(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
||||
ITEM_INFO* item = &Items[itemNumber];
|
||||
short roomNumber = item->roomNumber;
|
||||
|
||||
itemPos.x = item->pos.xPos;
|
||||
itemPos.y = item->pos.yPos;
|
||||
itemPos.z = item->pos.zPos;
|
||||
|
||||
FLOOR_INFO* floor = GetFloor(itemPos.x, itemPos.y, itemPos.z, &roomNumber);
|
||||
itemPos.y = GetCeiling(floor, itemPos.x, itemPos.y, itemPos.z);
|
||||
|
||||
PHD_VECTOR pos;
|
||||
pos.x = 0;
|
||||
pos.y = 0;
|
||||
pos.z = 16384;
|
||||
pos.y = 16384;
|
||||
pos.z = 0;
|
||||
|
||||
ROPE_STRUCT* rope = &Ropes[NumRopes];
|
||||
|
||||
PrepareRope(rope, (PHD_VECTOR*)&item->pos, &pos, 128, item);
|
||||
PrepareRope(rope, &itemPos, &pos, 128, item);
|
||||
|
||||
item->triggerFlags = NumRopes;
|
||||
NumRopes++;
|
||||
|
@ -38,57 +49,412 @@ void PrepareRope(ROPE_STRUCT* rope, PHD_VECTOR* pos1, PHD_VECTOR* pos2, int leng
|
|||
else
|
||||
rope->coiled = 0;
|
||||
|
||||
int il = 0x300000;
|
||||
int l = 0;
|
||||
int sum = 0;
|
||||
PHD_VECTOR* pos = &rope->segment[0];
|
||||
PHD_VECTOR* velocity = &rope->velocity[0];
|
||||
do
|
||||
{
|
||||
pos->x = pos2->x * sum >> 16;
|
||||
pos->y = pos2->y * sum >> 16;
|
||||
pos->z = pos2->z * sum >> 16;
|
||||
int il = 3145728;
|
||||
|
||||
velocity->x = 0;
|
||||
velocity->y = 0;
|
||||
velocity->z = 0;
|
||||
for (int i = 0; i < 24; ++i)
|
||||
{
|
||||
rope->segment[i].x = (int64_t) sum * pos2->x >> 16;
|
||||
rope->segment[i].y = (int64_t) sum * pos2->y >> 16;
|
||||
rope->segment[i].z = (int64_t) sum * pos2->z >> 16;
|
||||
|
||||
rope->velocity[i].x = 0;
|
||||
rope->velocity[i].y = 0;
|
||||
rope->velocity[i].z = 0;
|
||||
|
||||
if (item->triggerFlags == -1)
|
||||
{
|
||||
pos->x = l;
|
||||
pos->y >>= 4;
|
||||
rope->segment[i].x = l;
|
||||
rope->segment[i].y >>= 4;
|
||||
|
||||
velocity->x = 16384;
|
||||
velocity->y = il;
|
||||
velocity->z = 16384;
|
||||
rope->velocity[i].x = 16384;
|
||||
rope->velocity[i].y = il;
|
||||
rope->velocity[i].z = 16384;
|
||||
}
|
||||
|
||||
pos++;
|
||||
velocity++;
|
||||
l += 1024;
|
||||
sum += rope->segmentLength;
|
||||
il -= 0x20000;
|
||||
} while (il > 0);
|
||||
il -= 131072;
|
||||
}
|
||||
|
||||
rope->active = 0;
|
||||
}
|
||||
|
||||
void NormaliseRopeVector(PHD_VECTOR* vec)
|
||||
PHD_VECTOR* NormaliseRopeVector(PHD_VECTOR* vec)
|
||||
{
|
||||
int x = vec->x >> 16;
|
||||
int y = vec->y >> 16;
|
||||
int z = vec->z >> 16;
|
||||
|
||||
if (!x && !y && !z)
|
||||
return;
|
||||
return vec;
|
||||
|
||||
int length = SQUARE(x) + SQUARE(y) + SQUARE(z);
|
||||
if (length < 0)
|
||||
length = -length;
|
||||
|
||||
length = 0x1000000 / (SQRT_ASM(length) << 16 >> 8) << 8 >> 8;
|
||||
length = 65536 / SQRT_ASM(length);
|
||||
|
||||
vec->x = vec->x * length >> 16;
|
||||
vec->y = vec->y * length >> 16;
|
||||
vec->z = vec->z * length >> 16;
|
||||
}
|
||||
vec->x = (int64_t) length * vec->x >> 16;
|
||||
vec->y = (int64_t) length * vec->y >> 16;
|
||||
vec->z = (int64_t) length * vec->z >> 16;
|
||||
return vec;
|
||||
}
|
||||
|
||||
void _0x0046D130(ROPE_STRUCT* rope, int segmentFrame, int* x, int* y, int* z) /* 0x0046D130 */
|
||||
{
|
||||
int segment;
|
||||
short frame;
|
||||
|
||||
segment = segmentFrame >> 7;
|
||||
frame = segmentFrame & 0x7F;
|
||||
*x = (rope->normalisedSegment[segment].x * frame >> 16) + (rope->meshSegment[segment].x >> 16) + rope->position.x;
|
||||
*y = (rope->normalisedSegment[segment].y * frame >> 16) + (rope->meshSegment[segment].y >> 16) + rope->position.y;
|
||||
*z = (rope->normalisedSegment[segment].z * frame >> 16) + (rope->meshSegment[segment].z >> 16) + rope->position.z;
|
||||
}
|
||||
|
||||
int DotProduct(PHD_VECTOR* u, PHD_VECTOR* v) /* 0x0046D360 */
|
||||
{
|
||||
return u->x * v->x + u->y * v->y + u->z * v->z >> W2V_SHIFT;
|
||||
}
|
||||
|
||||
void ScaleVector(PHD_VECTOR* u, int c, PHD_VECTOR* destination) /* 0x0046D310 */
|
||||
{
|
||||
destination->x = c * u->x >> W2V_SHIFT;
|
||||
destination->y = c * u->y >> W2V_SHIFT;
|
||||
destination->z = c * u->z >> W2V_SHIFT;
|
||||
}
|
||||
|
||||
void CrossProduct(PHD_VECTOR* u, PHD_VECTOR* v, PHD_VECTOR* destination) /* 0x0046D3A0 */
|
||||
{
|
||||
destination->x = u->y * v->z - u->z * v->y >> W2V_SHIFT;
|
||||
destination->y = u->z * v->x - u->x * v->z >> W2V_SHIFT;
|
||||
destination->z = u->x * v->y - u->y * v->x >> W2V_SHIFT;
|
||||
}
|
||||
|
||||
void _0x0046D420(int* matrix, short* angle) /* 0x0046D420 */
|
||||
{
|
||||
angle[0] = ATAN(SQRT_ASM(SQUARE(matrix[M22]) + SQUARE(matrix[M02])), matrix[M12]);
|
||||
if (matrix[M12] >= 0 && angle[0] > 0 || matrix[M12] < 0 && angle[0] < 0)
|
||||
angle[0] = -angle[0];
|
||||
angle[1] = ATAN(matrix[M22], matrix[M02]);
|
||||
angle[2] = ATAN(matrix[M00] * COS(angle[1]) - matrix[M20] * SIN(angle[1]), matrix[M21] * SIN(angle[1]) - matrix[M01] * COS(angle[1]));
|
||||
}
|
||||
|
||||
void RopeControl(short itemNumber)
|
||||
{
|
||||
ITEM_INFO* item;
|
||||
ROPE_STRUCT* rope;
|
||||
|
||||
item = &Items[itemNumber];
|
||||
rope = &Ropes[item->triggerFlags];
|
||||
if (TriggerActive(item))
|
||||
{
|
||||
rope->active = 1;
|
||||
RopeDynamics(rope);
|
||||
}
|
||||
else
|
||||
{
|
||||
rope->active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void RopeCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
|
||||
{
|
||||
ITEM_INFO* item;
|
||||
ROPE_STRUCT* rope;
|
||||
ANIM_FRAME* frame;
|
||||
int segment;
|
||||
|
||||
item = &Items[itemNumber];
|
||||
rope = &Ropes[item->triggerFlags];
|
||||
if (TrInput & IN_ACTION && Lara.gunStatus == LG_NO_ARMS && (l->currentAnimState == STATE_LARA_REACH || l->currentAnimState == STATE_LARA_JUMP_UP) && l->gravityStatus && l->fallspeed > 0 && rope->active)
|
||||
{
|
||||
frame = (ANIM_FRAME*) GetBoundsAccurate(l);
|
||||
segment = _0x0046D200(rope, l->pos.xPos, l->pos.yPos + frame->MinY + 512, l->pos.zPos + (frame->MaxZ * COS(l->pos.yRot) >> W2V_SHIFT), l->currentAnimState == STATE_LARA_REACH ? 128 : 320);
|
||||
if (segment >= 0)
|
||||
{
|
||||
if (l->currentAnimState == STATE_LARA_REACH)
|
||||
{
|
||||
l->animNumber = ANIMATION_LARA_ROPE_JUMP_TO_GRAB;
|
||||
l->currentAnimState = STATE_LARA_ROPE_SWING;
|
||||
Lara.ropeFrame = Anims[ANIMATION_LARA_ROPE_SWING_FORWARD_SEMIHARD].frameBase + 32 << 8;
|
||||
Lara.ropeDFrame = Anims[ANIMATION_LARA_ROPE_SWING_FORWARD_SEMIHARD].frameBase + 60 << 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
l->animNumber = ANIMATION_LARA_MONKEY_TO_ROPE_BEGIN;
|
||||
l->currentAnimState = STATE_LARA_ROPE_IDLE;
|
||||
}
|
||||
l->frameNumber = Anims[l->animNumber].frameBase;
|
||||
l->gravityStatus = false;
|
||||
l->fallspeed = 0;
|
||||
Lara.gunStatus = LG_HANDS_BUSY;
|
||||
Lara.ropePtr = item->triggerFlags;
|
||||
Lara.ropeSegment = segment;
|
||||
Lara.ropeY = l->pos.yRot;
|
||||
DelAlignLaraToRope(l);
|
||||
CurrentPendulum.Velocity.x = 0;
|
||||
CurrentPendulum.Velocity.y = 0;
|
||||
CurrentPendulum.Velocity.z = 0;
|
||||
ApplyVelocityToRope(segment, l->pos.yRot, 16 * LaraItem->speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RopeDynamics(ROPE_STRUCT* rope)
|
||||
{
|
||||
int flag, i;
|
||||
PENDULUM* pendulumPointer;
|
||||
PHD_VECTOR vec, vec2;
|
||||
|
||||
flag = 0;
|
||||
if (rope->coiled)
|
||||
{
|
||||
--rope->coiled;
|
||||
if (!rope->coiled)
|
||||
{
|
||||
for (i = 0; i < 24; ++i)
|
||||
rope->velocity[i].y = 0;
|
||||
}
|
||||
}
|
||||
if (rope == &Ropes[Lara.ropePtr])
|
||||
{
|
||||
pendulumPointer = &CurrentPendulum;
|
||||
if (CurrentPendulum.node != Lara.ropeSegment + 1)
|
||||
{
|
||||
_0x0046E1C0(rope, Lara.ropeSegment + 1);
|
||||
flag = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pendulumPointer = &AlternatePendulum;
|
||||
if (Lara.ropePtr == -1 && CurrentPendulum.Rope)
|
||||
{
|
||||
for (i = 0; i < CurrentPendulum.node; ++i)
|
||||
{
|
||||
CurrentPendulum.Rope->velocity[i].x = CurrentPendulum.Rope->velocity[CurrentPendulum.node].x;
|
||||
CurrentPendulum.Rope->velocity[i].y = CurrentPendulum.Rope->velocity[CurrentPendulum.node].y;
|
||||
CurrentPendulum.Rope->velocity[i].z = CurrentPendulum.Rope->velocity[CurrentPendulum.node].z;
|
||||
}
|
||||
CurrentPendulum.Position.x = 0;
|
||||
CurrentPendulum.Position.y = 0;
|
||||
CurrentPendulum.Position.z = 0;
|
||||
CurrentPendulum.Velocity.x = 0;
|
||||
CurrentPendulum.Velocity.y = 0;
|
||||
CurrentPendulum.Velocity.z = 0;
|
||||
CurrentPendulum.node = -1;
|
||||
CurrentPendulum.Rope = NULL;
|
||||
}
|
||||
}
|
||||
if (Lara.ropePtr != -1)
|
||||
{
|
||||
vec.x = pendulumPointer->Position.x - rope->segment[0].x;
|
||||
vec.y = pendulumPointer->Position.y - rope->segment[0].y;
|
||||
vec.z = pendulumPointer->Position.z - rope->segment[0].z;
|
||||
NormaliseRopeVector(&vec);
|
||||
for (i = pendulumPointer->node; i >= 0; --i)
|
||||
{
|
||||
rope->segment[i].x = rope->meshSegment[i - 1].x + ((int64_t) rope->segmentLength * vec.x >> 16);
|
||||
rope->segment[i].y = rope->meshSegment[i - 1].y + ((int64_t) rope->segmentLength * vec.y >> 16);
|
||||
rope->segment[i].z = rope->meshSegment[i - 1].z + ((int64_t) rope->segmentLength * vec.z >> 16);
|
||||
rope->velocity[i].x = 0;
|
||||
rope->velocity[i].y = 0;
|
||||
rope->velocity[i].z = 0;
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
vec2.x = pendulumPointer->Position.x - rope->segment[pendulumPointer->node].x;
|
||||
vec2.y = pendulumPointer->Position.y - rope->segment[pendulumPointer->node].y;
|
||||
vec2.z = pendulumPointer->Position.z - rope->segment[pendulumPointer->node].z;
|
||||
rope->segment[pendulumPointer->node].x = pendulumPointer->Position.x;
|
||||
rope->segment[pendulumPointer->node].y = pendulumPointer->Position.y;
|
||||
rope->segment[pendulumPointer->node].z = pendulumPointer->Position.z;
|
||||
for (i = pendulumPointer->node; i < 24; ++i)
|
||||
{
|
||||
rope->segment[i].x -= vec2.x;
|
||||
rope->segment[i].y -= vec2.y;
|
||||
rope->segment[i].z -= vec2.z;
|
||||
rope->velocity[i].x = 0;
|
||||
rope->velocity[i].y = 0;
|
||||
rope->velocity[i].z = 0;
|
||||
}
|
||||
}
|
||||
_0x0046E080(rope, pendulumPointer, &rope->velocity[0], &pendulumPointer->Velocity, rope->segmentLength * pendulumPointer->node);
|
||||
pendulumPointer->Velocity.y += 393216;
|
||||
pendulumPointer->Position.x += pendulumPointer->Velocity.x;
|
||||
pendulumPointer->Position.y += pendulumPointer->Velocity.y;
|
||||
pendulumPointer->Position.z += pendulumPointer->Velocity.z;
|
||||
pendulumPointer->Velocity.x -= pendulumPointer->Velocity.x >> 8;
|
||||
pendulumPointer->Velocity.z -= pendulumPointer->Velocity.z >> 8;
|
||||
}
|
||||
for (i = pendulumPointer->node; i < 23; ++i)
|
||||
_0x0046DF00(&rope->segment[i], &rope->segment[i + 1], &rope->velocity[i], &rope->velocity[i + 1], rope->segmentLength);
|
||||
for (i = 0; i < 24; ++i)
|
||||
{
|
||||
rope->segment[i].x += rope->velocity[i].x;
|
||||
rope->segment[i].y += rope->velocity[i].y;
|
||||
rope->segment[i].z += rope->velocity[i].z;
|
||||
}
|
||||
for (i = pendulumPointer->node; i < 24; ++i)
|
||||
{
|
||||
rope->velocity[i].y += 196608;
|
||||
if (pendulumPointer->Rope)
|
||||
{
|
||||
rope->velocity[i].x -= rope->velocity[i].x >> 4;
|
||||
rope->velocity[i].z -= rope->velocity[i].z >> 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
rope->velocity[i].x -= rope->velocity[i].x >> 7;
|
||||
rope->velocity[i].z -= rope->velocity[i].z >> 7;
|
||||
}
|
||||
}
|
||||
rope->segment[0].x = 0;
|
||||
rope->segment[0].y = 0;
|
||||
rope->segment[0].z = 0;
|
||||
rope->velocity[0].x = 0;
|
||||
rope->velocity[0].y = 0;
|
||||
rope->velocity[0].z = 0;
|
||||
for (i = 0; i < 23; ++i)
|
||||
{
|
||||
rope->normalisedSegment[i].x = rope->segment[i + 1].x - rope->segment[i].x;
|
||||
rope->normalisedSegment[i].y = rope->segment[i + 1].y - rope->segment[i].y;
|
||||
rope->normalisedSegment[i].z = rope->segment[i + 1].z - rope->segment[i].z;
|
||||
NormaliseRopeVector(&rope->normalisedSegment[i]);
|
||||
}
|
||||
if (rope != &Ropes[Lara.ropePtr])
|
||||
{
|
||||
rope->meshSegment[0].x = rope->segment[0].x;
|
||||
rope->meshSegment[0].y = rope->segment[0].y;
|
||||
rope->meshSegment[0].z = rope->segment[0].z;
|
||||
rope->meshSegment[1].x = rope->segment[0].x + ((int64_t) rope->segmentLength * rope->normalisedSegment[0].x >> 16);
|
||||
rope->meshSegment[1].y = rope->segment[0].y + ((int64_t) rope->segmentLength * rope->normalisedSegment[0].y >> 16);
|
||||
rope->meshSegment[1].z = rope->segment[0].z + ((int64_t) rope->segmentLength * rope->normalisedSegment[0].z >> 16);
|
||||
for (i = 2; i < 24; ++i)
|
||||
{
|
||||
rope->meshSegment[i].x = rope->meshSegment[i - 1].x + ((int64_t) rope->segmentLength * rope->normalisedSegment[i - 1].x >> 16);
|
||||
rope->meshSegment[i].y = rope->meshSegment[i - 1].y + ((int64_t) rope->segmentLength * rope->normalisedSegment[i - 1].y >> 16);
|
||||
rope->meshSegment[i].z = rope->meshSegment[i - 1].z + ((int64_t) rope->segmentLength * rope->normalisedSegment[i - 1].z >> 16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rope->meshSegment[pendulumPointer->node].x = rope->segment[pendulumPointer->node].x;
|
||||
rope->meshSegment[pendulumPointer->node].y = rope->segment[pendulumPointer->node].y;
|
||||
rope->meshSegment[pendulumPointer->node].z = rope->segment[pendulumPointer->node].z;
|
||||
rope->meshSegment[pendulumPointer->node + 1].x = rope->segment[pendulumPointer->node].x + ((int64_t) rope->segmentLength * rope->normalisedSegment[pendulumPointer->node].x >> 16);
|
||||
rope->meshSegment[pendulumPointer->node + 1].y = rope->segment[pendulumPointer->node].y + ((int64_t) rope->segmentLength * rope->normalisedSegment[pendulumPointer->node].y >> 16);
|
||||
rope->meshSegment[pendulumPointer->node + 1].z = rope->segment[pendulumPointer->node].z + ((int64_t) rope->segmentLength * rope->normalisedSegment[pendulumPointer->node].z >> 16);
|
||||
for (i = pendulumPointer->node + 1; i < 23; ++i)
|
||||
{
|
||||
rope->meshSegment[i + 1].x = rope->meshSegment[i].x + ((int64_t) rope->segmentLength * rope->normalisedSegment[i].x >> 16);
|
||||
rope->meshSegment[i + 1].y = rope->meshSegment[i].y + ((int64_t) rope->segmentLength * rope->normalisedSegment[i].y >> 16);
|
||||
rope->meshSegment[i + 1].z = rope->meshSegment[i].z + ((int64_t) rope->segmentLength * rope->normalisedSegment[i].z >> 16);
|
||||
}
|
||||
for (i = 0; i < pendulumPointer->node; ++i)
|
||||
{
|
||||
rope->meshSegment[i].x = rope->segment[i].x;
|
||||
rope->meshSegment[i].y = rope->segment[i].y;
|
||||
rope->meshSegment[i].z = rope->segment[i].z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int _0x0046D200(ROPE_STRUCT* rope, int x, int y, int z, int radius) /* 0x0046D200 */
|
||||
{
|
||||
int dx, dy, dz;
|
||||
|
||||
for (int i = 0; i < 22; ++i)
|
||||
{
|
||||
if (y > rope->position.y + (rope->meshSegment[i].y >> 16) && y < rope->position.y + (rope->meshSegment[i + 1].y >> 16))
|
||||
{
|
||||
dx = x - (rope->meshSegment[i + 1].x + rope->meshSegment[i].x >> 17) - rope->position.x;
|
||||
dy = y - (rope->meshSegment[i + 1].y + rope->meshSegment[i].y >> 17) - rope->position.y;
|
||||
dz = z - (rope->meshSegment[i + 1].z + rope->meshSegment[i].z >> 17) - rope->position.z;
|
||||
if (SQUARE(dx) + SQUARE(dy) + SQUARE(dz) < SQUARE(radius + 64))
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ApplyVelocityToRope(int node, short angle, short n)
|
||||
{
|
||||
SetPendulumVelocity(
|
||||
(unsigned short) n * SIN(angle) >> 2,
|
||||
0,
|
||||
(unsigned short) n * COS(angle) >> 2);
|
||||
}
|
||||
|
||||
void SetPendulumVelocity(int x, int y, int z)
|
||||
{
|
||||
int node;
|
||||
|
||||
node = 2 * (CurrentPendulum.node >> 1);
|
||||
if (node < 24)
|
||||
{
|
||||
int val = 4096 / (24 - node) * 256;
|
||||
|
||||
x = (int64_t) val * x >> 16;
|
||||
y = (int64_t) val * y >> 16;
|
||||
z = (int64_t) val * z >> 16;
|
||||
}
|
||||
|
||||
CurrentPendulum.Velocity.x += x;
|
||||
CurrentPendulum.Velocity.y += y;
|
||||
CurrentPendulum.Velocity.z += z;
|
||||
}
|
||||
|
||||
void _0x0046E1C0(ROPE_STRUCT* rope, int node) /* 0x0046E1C0 */
|
||||
{
|
||||
CurrentPendulum.Position.x = rope->segment[node].x;
|
||||
CurrentPendulum.Position.y = rope->segment[node].y;
|
||||
CurrentPendulum.Position.z = rope->segment[node].z;
|
||||
if (CurrentPendulum.node == -1)
|
||||
{
|
||||
CurrentPendulum.Velocity.x += rope->velocity[node].x;
|
||||
CurrentPendulum.Velocity.y += rope->velocity[node].y;
|
||||
CurrentPendulum.Velocity.z += rope->velocity[node].z;
|
||||
}
|
||||
CurrentPendulum.node = node;
|
||||
CurrentPendulum.Rope = rope;
|
||||
}
|
||||
|
||||
void _0x0046E080(ROPE_STRUCT* rope, PENDULUM* pendulumPointer, PHD_VECTOR* ropeVelocity, PHD_VECTOR* pendulumVelocity, int value) /* 0x0046E080 */
|
||||
{
|
||||
PHD_VECTOR vec;
|
||||
int result;
|
||||
|
||||
vec.x = pendulumPointer->Position.x + pendulumVelocity->x - rope->segment[0].x;
|
||||
vec.y = pendulumPointer->Position.y + pendulumVelocity->y - rope->segment[0].y;
|
||||
vec.z = pendulumPointer->Position.z + pendulumVelocity->z - rope->segment[0].z;
|
||||
result = 65536 * SQRT_ASM(abs(SQUARE(vec.x >> 16) + SQUARE(vec.y >> 16) + SQUARE(vec.z >> 16))) - value;
|
||||
NormaliseRopeVector(&vec);
|
||||
pendulumVelocity->x -= (int64_t) result * vec.x >> 16;
|
||||
pendulumVelocity->y -= (int64_t) result * vec.y >> 16;
|
||||
pendulumVelocity->z -= (int64_t) result * vec.z >> 16;
|
||||
}
|
||||
|
||||
void _0x0046DF00(PHD_VECTOR* segment, PHD_VECTOR* nextSegment, PHD_VECTOR* velocity, PHD_VECTOR* nextVelocity, int length) /* 0x0046DF00 */
|
||||
{
|
||||
PHD_VECTOR vec;
|
||||
int result;
|
||||
|
||||
vec.x = nextSegment->x + nextVelocity->x - segment->x - velocity->x;
|
||||
vec.y = nextSegment->y + nextVelocity->y - segment->y - velocity->y;
|
||||
vec.z = nextSegment->z + nextVelocity->z - segment->z - velocity->z;
|
||||
result = 65536 * SQRT_ASM(abs(SQUARE(vec.x >> 16) + SQUARE(vec.y >> 16) + SQUARE(vec.z >> 16))) - length >> 1;
|
||||
NormaliseRopeVector(&vec);
|
||||
vec.x = (int64_t) result * vec.x >> 16;
|
||||
vec.y = (int64_t) result * vec.y >> 16;
|
||||
vec.z = (int64_t) result * vec.z >> 16;
|
||||
velocity->x += vec.x;
|
||||
velocity->y += vec.y;
|
||||
velocity->z += vec.z;
|
||||
nextVelocity->x -= vec.x;
|
||||
nextVelocity->y -= vec.y;
|
||||
nextVelocity->z -= vec.z;
|
||||
}
|
||||
|
|
|
@ -23,11 +23,24 @@ struct PENDULUM
|
|||
ROPE_STRUCT* Rope; // size=1172, offset=28
|
||||
};
|
||||
|
||||
//#define InitialiseRope ((void (__cdecl*)(short)) 0x0046F060)
|
||||
#define RopeControl ((void (__cdecl*)(short)) 0x0046DD40)
|
||||
#define RopeCollision ((void (__cdecl*)(short,ITEM_INFO*,COLL_INFO*)) 0x0046DAE0)
|
||||
extern PENDULUM CurrentPendulum;
|
||||
|
||||
#define CalculateRopePoints ((void (__cdecl*)(ROPE_STRUCT*)) 0x0046EC70)
|
||||
|
||||
void InitialiseRope(short itemNumber);
|
||||
void PrepareRope(ROPE_STRUCT* rope, PHD_VECTOR* pos1, PHD_VECTOR* pos2, int length, ITEM_INFO* item);
|
||||
void NormaliseRopeVector(PHD_VECTOR* vec);
|
||||
PHD_VECTOR* NormaliseRopeVector(PHD_VECTOR* vec);
|
||||
void _0x0046D130(ROPE_STRUCT* rope, int segmentFrame, int* x, int* y, int* z);
|
||||
int DotProduct(PHD_VECTOR* u, PHD_VECTOR* v);
|
||||
void ScaleVector(PHD_VECTOR* src, int c, PHD_VECTOR* dest);
|
||||
void CrossProduct(PHD_VECTOR* u, PHD_VECTOR* v, PHD_VECTOR* dest);
|
||||
void _0x0046D420(int* array, short* angle);
|
||||
void RopeControl(short itemNumber);
|
||||
void RopeCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll);
|
||||
void RopeDynamics(ROPE_STRUCT* rope);
|
||||
int _0x0046D200(ROPE_STRUCT* rope, int x, int y, int z, int value);
|
||||
void ApplyVelocityToRope(int node, short angle, short n);
|
||||
void SetPendulumVelocity(int x, int y, int z);
|
||||
void _0x0046E1C0(ROPE_STRUCT* rope, int node);
|
||||
void _0x0046E080(ROPE_STRUCT* rope, PENDULUM* pendulumPointer, PHD_VECTOR* ropeVelocity, PHD_VECTOR* pendulumVelocity, int value);
|
||||
void _0x0046DF00(PHD_VECTOR* segment, PHD_VECTOR* nextSegment, PHD_VECTOR* velocity, PHD_VECTOR* nextVelocity, int length);
|
||||
|
|
|
@ -1405,6 +1405,21 @@ struct SP_DYNAMIC
|
|||
unsigned char Pad[2]; // size=2, offset=6
|
||||
};
|
||||
|
||||
struct ANIM_FRAME // Variable size
|
||||
{
|
||||
short MinX; // size=0, offset=0
|
||||
short MaxX; // size=0, offset=2
|
||||
short MinY; // size=0, offset=4
|
||||
short MaxY; // size=0, offset=6
|
||||
short MinZ; // size=0, offset=8
|
||||
short MaxZ; // size=0, offset=10
|
||||
short OffsetX; // size=0, offset=12
|
||||
short OffsetY; // size=0, offset=14
|
||||
short OffsetZ; // size=0, offset=16
|
||||
short NumValues; // size=0, offset=18
|
||||
unsigned short AngleSets[1]; // Variable size
|
||||
};
|
||||
|
||||
typedef void (cdecl *EFFECT_ROUTINE)(ITEM_INFO*);
|
||||
typedef void (cdecl *LARA_COLLISION_ROUTINE)(ITEM_INFO*, COLL_INFO*);
|
||||
typedef void (cdecl *LARA_CONTROL_ROUTINE)(ITEM_INFO*, COLL_INFO*);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue