Skip to content

Commit

Permalink
Decompiled Eel and BigEel
Browse files Browse the repository at this point in the history
- Avoid eel and big eel to have a random rotation when initialized.
- Improved EEL behaviour and attack angle, he return to initial rotation after attacking.
  • Loading branch information
TokyoSU committed Dec 14, 2024
1 parent 182f8d4 commit 1c0efd4
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 14 deletions.
Binary file modified Database/Tomb2.exe.idb
Binary file not shown.
3 changes: 2 additions & 1 deletion TR2Main-VS/game/box.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ void InitialiseCreature(short itemNumber)
ITEM_INFO* item = &Items[itemNumber];
item->collidable = TRUE;
item->data = NULL;
item->pos.rotY += (GetRandomControl() - PHD_90) >> 1;
if (item->objectID != ID_EEL && item->objectID != ID_BIG_EEL)
item->pos.rotY += (GetRandomControl() - PHD_90) >> 1;
}

int CreatureActive(short itemNumber)
Expand Down
2 changes: 1 addition & 1 deletion TR2Main-VS/game/collide.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ bool IsCollidingOnFloorLift(int x, int z, int ix, int iz, short angle)
// Same block as elevator position.
if (x == ix && z == iz)
return true;
switch (FROM_ANGLE(ABS(angle)))
switch (ANGLE_TO_DEGREE(ABS(angle)))
{
case 0: // NORTH
// Now check for east (+X)
Expand Down
199 changes: 196 additions & 3 deletions TR2Main-VS/game/eel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,205 @@

#include "precompiled.h"
#include "game/eel.h"
#include "3dsystem/phd_math.h"
#include "game/control.h"
#include "game/box.h"
#include "game/effects.h"
#include "specific/init.h"
#include "global/vars.h"

enum BigEelState {
BIGEEL_EMPTY,
BIGEEL_ATTACK,
BIGEEL_STOP,
BIGEEL_DEATH
};

#define BIGEEL_DAMAGE 500
#define BIGEEL_ANGLE ANGLE(10)
#define BIGEEL_RANGE BLOCK(6)
#define BIGEEL_MOVE (BLOCK(1)/10)
#define BIGEEL_LENGTH (BLOCK(5)/2)
#define BIGEEL_SLIDE (BIGEEL_RANGE - BIGEEL_LENGTH)
#define BIGEEL_DIE_ANIM 2
#define BIGEEL_TOUCH 0x180

#define EEL_DAMAGE 50
#define EEL_ANGLE ANGLE(25)
#define EEL_RANGE BLOCK(2)
#define EEL_MOVE (BLOCK(1)/10)
#define EEL_TURN (ANGLE(2)/3)
#define EEL_LENGTH (BLOCK(1)/2)
#define EEL_SLIDE (EEL_RANGE - EEL_LENGTH)
#define EEL_DIE_ANIM 3

static const BITE_INFO BigEelBite = { 7, 157, 333, 7 };

void BigEelControl(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
int pos = (int)item->data;
item->pos.x -= pos * phd_sin(item->pos.rotY) >> W2V_SHIFT;
item->pos.z -= pos * phd_cos(item->pos.rotY) >> W2V_SHIFT;

if (item->hitPoints <= 0)
{
if (pos < BIGEEL_SLIDE)
pos += BIGEEL_MOVE;
if (item->currentAnimState != BIGEEL_DEATH)
SetAnimation(item, BIGEEL_DIE_ANIM, BIGEEL_DEATH);
}
else
{
int z = LaraItem->pos.z - item->pos.z;
int x = LaraItem->pos.x - item->pos.x;
short angle = phd_atan(z, x) - item->pos.rotY;
int distance = phd_sqrt(SQR(z) + SQR(x));

switch (item->currentAnimState)
{
case BIGEEL_STOP:
if (pos > 0)
pos -= BIGEEL_MOVE;
if (distance <= BIGEEL_RANGE && ABS(angle) < BIGEEL_ANGLE)
item->goalAnimState = BIGEEL_ATTACK;
break;

case BIGEEL_ATTACK:
if (pos < (distance - BIGEEL_LENGTH))
pos += BIGEEL_MOVE;

if (!item->requiredAnimState && (item->touchBits & BIGEEL_TOUCH))
{
LaraItem->hitStatus = TRUE;
LaraItem->hitPoints -= BIGEEL_DAMAGE;
CreatureEffect(item, &BigEelBite, DoBloodSplat);
item->requiredAnimState = BIGEEL_STOP;
}
break;
}
}

item->pos.x += pos * phd_sin(item->pos.rotY) >> W2V_SHIFT;
item->pos.z += pos * phd_cos(item->pos.rotY) >> W2V_SHIFT;
item->data = LPVOID(pos);

AnimateItem(item);
}

struct EEL_INFO
{
short originalRotY;
int pos;
};

static EEL_INFO* GetEelInfo(ITEM_INFO* item)
{
return (EEL_INFO*)item->data;
}

void InitializeEel(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
InitialiseCreature(itemNumber);
item->data = game_malloc(sizeof(EEL_INFO), GBUF_TempAlloc);
EEL_INFO* eel = GetEelInfo(item);
eel->originalRotY = item->pos.rotY;
eel->pos = 0;
}

void EelControl(short itemNumber)
{
ITEM_INFO* item = &Items[itemNumber];
EEL_INFO* eel = (EEL_INFO*)item->data;

item->pos.x -= eel->pos * phd_sin(item->pos.rotY) >> W2V_SHIFT;
item->pos.z -= eel->pos * phd_cos(item->pos.rotY) >> W2V_SHIFT;

if (item->hitPoints <= 0)
{
if (eel->pos < EEL_SLIDE)
eel->pos += EEL_MOVE;
if (item->currentAnimState != BIGEEL_DEATH)
SetAnimation(item, EEL_DIE_ANIM, BIGEEL_DEATH);
}
else
{
short absRotY = ABS(eel->originalRotY);
int z = LaraItem->pos.z - item->pos.z;
int x = LaraItem->pos.x - item->pos.x;
short angleToTarget = phd_atan(z, x); // Angle to target
short deltaAngle = angleToTarget - item->pos.rotY; // Difference to current rotation
short rotationDelta = 0;
int distance = phd_sqrt(SQR(z) + SQR(x));

// Normalize deltaAngle to range -16384 to 16384
if (deltaAngle > 16384)
deltaAngle -= 32768;
else if (deltaAngle < -16384)
deltaAngle += 32768;

switch (item->currentAnimState)
{
case BIGEEL_STOP:
if (eel->pos > 0)
eel->pos -= EEL_MOVE;

// Gradually return to original rotation
rotationDelta = eel->originalRotY - item->pos.rotY;
if (rotationDelta > 16384)
rotationDelta -= 32768;
else if (rotationDelta < -16384)
rotationDelta += 32768;

if (rotationDelta > 0)
item->pos.rotY += EEL_TURN;
else if (rotationDelta < 0)
item->pos.rotY -= EEL_TURN;

// Ensure the rotation doesn't overshoot the original rotation
if (ABS(rotationDelta) < EEL_TURN)
item->pos.rotY = eel->originalRotY;

if (distance <= EEL_RANGE && ABS(deltaAngle) < EEL_ANGLE)
item->goalAnimState = BIGEEL_ATTACK;
break;

case BIGEEL_ATTACK:
if (eel->pos < (distance - EEL_LENGTH))
eel->pos += EEL_MOVE;

// Gradually turn to face Lara
if (deltaAngle > 0)
item->pos.rotY += EEL_TURN;
else if (deltaAngle < 0)
item->pos.rotY -= EEL_TURN;

// Ensure the rotation doesn't overshoot the target angle
if (ABS(deltaAngle) < EEL_TURN)
item->pos.rotY = angleToTarget;

if (!item->requiredAnimState && (item->touchBits & BIGEEL_TOUCH))
{
LaraItem->hitStatus = TRUE;
LaraItem->hitPoints -= EEL_DAMAGE;
CreatureEffect(item, &BigEelBite, DoBloodSplat);
item->requiredAnimState = BIGEEL_STOP;
}
break;
}
}

item->pos.x += eel->pos * phd_sin(item->pos.rotY) >> W2V_SHIFT;
item->pos.z += eel->pos * phd_cos(item->pos.rotY) >> W2V_SHIFT;

AnimateItem(item);
}

/*
* Inject function
*/
void Inject_Eel() {
//INJECT(0x0041C120, BigEelControl);
//INJECT(0x0041C2C0, EelControl);
}
INJECT(0x0041C120, BigEelControl);
INJECT(0x0041C2C0, EelControl);
}
6 changes: 4 additions & 2 deletions TR2Main-VS/game/eel.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
/*
* Function list
*/
#define BigEelControl ((void(__cdecl*)(short)) 0x0041C120)
#define EelControl ((void(__cdecl*)(short)) 0x0041C2C0)

void BigEelControl(short itemNumber); // 0x0041C120
void InitializeEel(short itemNumber);
void EelControl(short itemNumber); // 0x0041C2C0

#endif // EEL_H_INCLUDED
2 changes: 1 addition & 1 deletion TR2Main-VS/game/setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ void BaddyObjects() {
}
obj = &Objects[ID_EEL];
if (obj->loaded) {
obj->initialise = InitialiseCreature;
obj->initialise = InitializeEel;
obj->collision = CreatureCollision;
obj->control = EelControl;
#if defined(FEATURE_MOD_CONFIG)
Expand Down
8 changes: 4 additions & 4 deletions TR2Main-VS/global/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ typedef struct {
#define PHD_45 (PHD_ONE/8)
#define PHD_270 (PHD_90*3)
#define PHD_DEGREE (PHD_ONE/360)
#define ANGLE(x) ((x) * PHD_DEGREE)
#define FROM_ANGLE(x) ((x) / PHD_DEGREE)
#define ANGLE(x) ((x) * PHD_DEGREE)
#define ANGLE_TO_DEGREE(x) ((x) / PHD_DEGREE)

// String macros
#ifdef FEATURE_HUD_IMPROVED
Expand Down Expand Up @@ -2637,11 +2637,11 @@ typedef enum OrientAxis_e

static inline ORIENT_AXIS GetOrientAxis(short rotY)
{
return static_cast<ORIENT_AXIS>((USHORT)(rotY + PHD_45) / PHD_90);
return static_cast<ORIENT_AXIS>((UINT16)(rotY + PHD_45) / PHD_90);
}
static inline ORIENT_AXIS GetOrientAxisInverted(short rotY)
{
return static_cast<ORIENT_AXIS>((USHORT)((rotY + PHD_180) + PHD_45) / PHD_90);
return static_cast<ORIENT_AXIS>((UINT16)((rotY + PHD_180) + PHD_45) / PHD_90);
}
static inline PHD_VECTOR GetOrientAxisDirection(short rotY, int radius = 1) {
ORIENT_AXIS axis = GetOrientAxis(rotY);
Expand Down
3 changes: 1 addition & 2 deletions TR2Main-VS/specific/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,8 +547,7 @@ static LIGHT_ROOM S_CalculateRoomStaticLights(int x, int y, int z, short roomNum
LIGHT_INFO* light = NULL;
int xdist, ydist, zdist;
int distance;
int intensity;
int falloff;
int intensity, falloff;
int shade;

light_result.ambient = room->ambient;
Expand Down

0 comments on commit 1c0efd4

Please sign in to comment.