mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-10 20:46:47 +03:00
Fixed enemy monkey; Added new zone for ID_VON_CROY; Small AI fixes; Added 3 blocks jump;
This commit is contained in:
parent
b987e9bda8
commit
82af97c8cc
9 changed files with 236 additions and 478 deletions
|
@ -25,6 +25,7 @@ typedef enum ZoneType
|
|||
ZONE_BASIC,
|
||||
ZONE_FLYER,
|
||||
ZONE_HUMAN_CLASSIC,
|
||||
ZONE_VON_CROY,
|
||||
ZONE_WATER,
|
||||
ZONE_MAX,
|
||||
/// custom zone (using zone above for LOT.zone):
|
||||
|
@ -34,6 +35,7 @@ typedef enum ZoneType
|
|||
ZONE_BLOCKABLE, // for trex, shiva, etc..
|
||||
ZONE_SOPHIALEE, // dont want sophia to go down again !
|
||||
ZONE_APE, // only 2 click climb
|
||||
ZONE_HUMAN_LONGJUMP_AND_MONKEY,
|
||||
};
|
||||
|
||||
typedef struct OBJECT_Bones
|
||||
|
|
|
@ -1009,7 +1009,7 @@ int SearchLOT(LOT_INFO* LOT, int depth)
|
|||
continue;
|
||||
|
||||
delta = g_Level.Boxes[boxNumber].height - box->height;
|
||||
if (delta > LOT->step || delta < LOT->drop)
|
||||
if ((delta > LOT->step || delta < LOT->drop) && !((flags & BOX_MONKEY) && LOT->canMonkey))
|
||||
continue;
|
||||
|
||||
expand = &LOT->node[boxNumber];
|
||||
|
@ -1587,6 +1587,8 @@ void CreatureMood(ITEM_INFO* item, AI_INFO* info, int violent)
|
|||
do
|
||||
{
|
||||
//overlapIndex++;
|
||||
//if (g_Level.Overlaps[overlapIndex++].flags & (BOX_JUMP|BOX_MONKEY))
|
||||
//{
|
||||
nextBox = g_Level.Overlaps[overlapIndex].box;
|
||||
flags = g_Level.Overlaps[overlapIndex++].flags;
|
||||
} while (nextBox != NO_BOX && ((flags & BOX_END_BIT) == FALSE) && (nextBox != startBox));
|
||||
|
|
|
@ -239,6 +239,15 @@ void InitialiseSlot(short itemNum, short slot)
|
|||
creature->LOT.zone = ZONE_HUMAN_CLASSIC;
|
||||
break;
|
||||
|
||||
case ZONE_HUMAN_LONGJUMP_AND_MONKEY:
|
||||
// Can climb, jump, monkey, long jump
|
||||
creature->LOT.step = SECTOR(1);
|
||||
creature->LOT.drop = -SECTOR(1);
|
||||
creature->LOT.canJump = true;
|
||||
creature->LOT.canMonkey = true;
|
||||
creature->LOT.zone = ZONE_VON_CROY;
|
||||
break;
|
||||
|
||||
case ZONE_SPIDER:
|
||||
creature->LOT.step = SECTOR(1) - CLICK(2);
|
||||
creature->LOT.drop = -(SECTOR(1) - CLICK(2));
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
#include "lara.h"
|
||||
#include "sound.h"
|
||||
|
||||
#define STATE_GUIDE_STOP 1
|
||||
#define STATE_GUIDE_WALK 2
|
||||
#define STATE_GUIDE_RUN 3
|
||||
#define STATE_GUIDE_IGNITE_TORCH 11
|
||||
|
||||
BITE_INFO guideBiteInfo1 = { 0, 20, 200, 18 };
|
||||
BITE_INFO guideBiteInfo2 = { 30, 80, 50, 15 };
|
||||
|
||||
|
@ -23,8 +28,8 @@ void InitialiseGuide(short itemNumber)
|
|||
|
||||
item->animNumber = Objects[item->objectNumber].animIndex + 4;
|
||||
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
||||
item->goalAnimState = 1;
|
||||
item->currentAnimState = 1;
|
||||
item->goalAnimState = STATE_GUIDE_STOP;
|
||||
item->currentAnimState = STATE_GUIDE_STOP;
|
||||
item->swapMeshFlags = 0x40000;
|
||||
}
|
||||
|
||||
|
@ -124,6 +129,7 @@ void GuideControl(short itemNumber)
|
|||
|
||||
ITEM_INFO* currentItem = &g_Level.Items[baddie->itemNum];
|
||||
if (currentItem->objectNumber != ID_GUIDE &&
|
||||
currentItem->objectNumber != ID_VON_CROY &&
|
||||
abs(currentItem->pos.yPos - item->pos.yPos) <= 512)
|
||||
{
|
||||
dx = currentItem->pos.xPos - item->pos.xPos;
|
||||
|
@ -173,7 +179,7 @@ void GuideControl(short itemNumber)
|
|||
|
||||
switch (item->currentAnimState)
|
||||
{
|
||||
case 1:
|
||||
case STATE_GUIDE_STOP:
|
||||
creature->LOT.isJumping = false;
|
||||
creature->flags = 0;
|
||||
creature->maximumTurn = 0;
|
||||
|
@ -195,7 +201,7 @@ void GuideControl(short itemNumber)
|
|||
/*if (Objects[ID_WRAITH1].loaded & 0x10000)
|
||||
{
|
||||
if (item->itemFlags[3] == 5)
|
||||
item->goalAnimState = 2;
|
||||
item->goalAnimState = STATE_GUIDE_WALK;
|
||||
|
||||
if (item->itemFlags[3] == 5 || item->itemFlags[3] == 6)
|
||||
{
|
||||
|
@ -232,7 +238,7 @@ void GuideControl(short itemNumber)
|
|||
}
|
||||
else if (/*true ||*/ enemy != LaraItem || info.distance > SQUARE(2048))
|
||||
{
|
||||
item->goalAnimState = 2;
|
||||
item->goalAnimState = STATE_GUIDE_WALK;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -309,12 +315,12 @@ void GuideControl(short itemNumber)
|
|||
}
|
||||
else
|
||||
{
|
||||
item->goalAnimState = 1;
|
||||
item->goalAnimState = STATE_GUIDE_STOP;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case STATE_GUIDE_WALK:
|
||||
creature->LOT.isJumping = false;
|
||||
|
||||
creature->maximumTurn = ANGLE(7);
|
||||
|
@ -333,8 +339,8 @@ void GuideControl(short itemNumber)
|
|||
|
||||
if (item->itemFlags[1] == 1)
|
||||
{
|
||||
item->goalAnimState = 1;
|
||||
item->requiredAnimState = 11; // Ignite torch
|
||||
item->goalAnimState = STATE_GUIDE_STOP;
|
||||
item->requiredAnimState = STATE_GUIDE_IGNITE_TORCH; // Ignite torch
|
||||
}
|
||||
else if (creature->reachedGoal)
|
||||
{
|
||||
|
@ -347,7 +353,7 @@ void GuideControl(short itemNumber)
|
|||
|
||||
break;
|
||||
}
|
||||
item->goalAnimState = 1;
|
||||
item->goalAnimState = STATE_GUIDE_STOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -361,33 +367,33 @@ void GuideControl(short itemNumber)
|
|||
{
|
||||
if (info.distance > 0x1000000)
|
||||
{
|
||||
item->goalAnimState = 3;
|
||||
item->goalAnimState = STATE_GUIDE_RUN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item->goalAnimState = 1;
|
||||
item->goalAnimState = STATE_GUIDE_STOP;
|
||||
}
|
||||
}
|
||||
else if (Lara.location > item->itemFlags[3] && laraInfo.distance > 0x400000)
|
||||
{
|
||||
item->goalAnimState = 3;
|
||||
item->goalAnimState = STATE_GUIDE_RUN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item->goalAnimState = 1;
|
||||
item->goalAnimState = STATE_GUIDE_STOP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item->goalAnimState = 1;
|
||||
item->goalAnimState = STATE_GUIDE_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case STATE_GUIDE_RUN:
|
||||
if (info.ahead)
|
||||
{
|
||||
joint2 = info.angle;
|
||||
|
@ -398,7 +404,7 @@ void GuideControl(short itemNumber)
|
|||
|
||||
if (info.distance < SQUARE(2048) || Lara.location < item->itemFlags[3])
|
||||
{
|
||||
item->goalAnimState = 1;
|
||||
item->goalAnimState = STATE_GUIDE_STOP;
|
||||
break;
|
||||
}
|
||||
if (creature->reachedGoal)
|
||||
|
@ -412,17 +418,17 @@ void GuideControl(short itemNumber)
|
|||
|
||||
break;
|
||||
}
|
||||
item->goalAnimState = 1;
|
||||
item->goalAnimState = STATE_GUIDE_STOP;
|
||||
}
|
||||
else if (foundEnemy && (info.distance < 0x200000 || !(item->swapMeshFlags & 0x40000) && info.distance < SQUARE(3072)))
|
||||
{
|
||||
item->goalAnimState = 1;
|
||||
item->goalAnimState = STATE_GUIDE_STOP;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 11:
|
||||
case STATE_GUIDE_IGNITE_TORCH:
|
||||
// Ignite torch
|
||||
pos1.x = guideBiteInfo2.x;
|
||||
pos1.y = guideBiteInfo2.y;
|
||||
|
@ -715,7 +721,7 @@ void GuideControl(short itemNumber)
|
|||
{
|
||||
if (item->frameNumber == g_Level.Anims[item->animNumber].frameBase + 20)
|
||||
{
|
||||
item->goalAnimState = 1;
|
||||
item->goalAnimState = STATE_GUIDE_STOP;
|
||||
|
||||
floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &item->roomNumber);
|
||||
GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
||||
|
@ -732,7 +738,7 @@ void GuideControl(short itemNumber)
|
|||
|
||||
if (item->frameNumber == g_Level.Anims[item->animNumber].frameBase + 70 && item->roomNumber == 70)
|
||||
{
|
||||
item->requiredAnimState = 3;
|
||||
item->requiredAnimState = STATE_GUIDE_RUN;
|
||||
item->swapMeshFlags |= 0x200000;
|
||||
SoundEffect(SFX_TR4_GUIDE_SCARE, &item->pos, 0);
|
||||
}
|
||||
|
@ -794,7 +800,7 @@ void GuideControl(short itemNumber)
|
|||
}
|
||||
else if (item->triggerFlags <= 999)
|
||||
{
|
||||
item->goalAnimState = 1;
|
||||
item->goalAnimState = STATE_GUIDE_STOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#define ANIMATION_VON_CROY_STEP_DOWN_HIGH 36
|
||||
#define ANIMATION_VON_CROY_CLIMB_UP_AFTER_JUMP 52
|
||||
|
||||
#define SWAP_MESH_BITS_VON_CROY 0x40080
|
||||
#define SWAPMESHFLAGS_VON_CROY 0x40080
|
||||
|
||||
#define VON_CROY_FLAG_JUMP 6
|
||||
|
||||
|
@ -55,7 +55,7 @@ void InitialiseVonCroy(short itemNumber)
|
|||
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
||||
item->goalAnimState = STATE_VON_CROY_TOGGLE_KNIFE;
|
||||
item->currentAnimState = STATE_VON_CROY_TOGGLE_KNIFE;
|
||||
item->swapMeshFlags = SWAP_MESH_BITS_VON_CROY;
|
||||
item->swapMeshFlags = SWAPMESHFLAGS_VON_CROY;
|
||||
|
||||
memset(VonCroyPassedWaypoints, 0, 128);
|
||||
}
|
||||
|
@ -106,6 +106,13 @@ void VonCroyControl(short itemNumber)
|
|||
floor = GetFloor(x, item->pos.yPos, z, &roomNumber);
|
||||
int height3 = GetFloorHeight(floor, x, item->pos.yPos, z);
|
||||
|
||||
x += dx ;
|
||||
z += dz ;
|
||||
|
||||
roomNumber = item->roomNumber;
|
||||
floor = GetFloor(x, item->pos.yPos, z, &roomNumber);
|
||||
int height4 = GetFloorHeight(floor, x, item->pos.yPos, z);
|
||||
|
||||
bool canJump1block;
|
||||
if (item->boxNumber == LaraItem->boxNumber
|
||||
|| item->pos.yPos >= height1 - 384
|
||||
|
@ -125,6 +132,17 @@ void VonCroyControl(short itemNumber)
|
|||
else
|
||||
canJump2blocks = true;
|
||||
|
||||
bool canJump3blocks;
|
||||
if (item->boxNumber == LaraItem->boxNumber
|
||||
|| item->pos.yPos >= height1 - 384
|
||||
|| item->pos.yPos >= height2 - 384
|
||||
|| item->pos.yPos >= height3 - 384
|
||||
|| item->pos.yPos >= height4 + 256
|
||||
|| item->pos.yPos <= height4 - 256)
|
||||
canJump3blocks = false;
|
||||
else
|
||||
canJump3blocks = true;
|
||||
|
||||
// Von Croy must follow Lara and navigate with ID_AI_FOLLOW objects
|
||||
item->aiBits = FOLLOW;
|
||||
GetAITarget(creature);
|
||||
|
@ -272,413 +290,125 @@ void VonCroyControl(short itemNumber)
|
|||
|
||||
short rot = 0;
|
||||
int dy, height, ceiling, flags;
|
||||
|
||||
printf("State: %d\n", item->currentAnimState);
|
||||
|
||||
switch (item->currentAnimState)
|
||||
{
|
||||
case STATE_VON_CROY_STOP:
|
||||
creature->LOT.isMonkeying = false;
|
||||
creature->LOT.isJumping = false;
|
||||
joint2 = laraInfo.angle;
|
||||
creature->flags = 0;
|
||||
creature->maximumTurn = 0;
|
||||
|
||||
joint3 = 0;
|
||||
joint2 = info.angle >> 1;
|
||||
if (info.ahead)
|
||||
joint3 = info.angle / 2;
|
||||
if (info.ahead && item->aiBits & FOLLOW)
|
||||
{
|
||||
joint1 = info.xAngle >> 1;
|
||||
joint0 = info.angle >> 1;
|
||||
joint1 = info.angle / 2;
|
||||
joint2 = info.xAngle;
|
||||
}
|
||||
|
||||
if (item->requiredAnimState)
|
||||
if (item->aiBits & GUARD)
|
||||
{
|
||||
item->goalAnimState = item->requiredAnimState;
|
||||
joint3 = AIGuard(creature);
|
||||
item->goalAnimState = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/*if (item->itemFlags[2] == 2)
|
||||
{
|
||||
rot = enemy->pos.yRot - item->pos.yRot;
|
||||
if (rot < -1024)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_LOOK_BACK_RIGHT;
|
||||
break;
|
||||
}
|
||||
else if (rot > 1024)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_LOOK_BACK_LEFT;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->itemFlags[2] = 0;
|
||||
if (!item->flags)
|
||||
{
|
||||
creature->reachedGoal = false;
|
||||
creature->enemy = NULL;
|
||||
item->aiBits = FOLLOW;
|
||||
item->location++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// Wait for Lara
|
||||
if (Lara.location < item->location && creature->reachedGoal)
|
||||
if (item->aiBits & MODIFY)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
if (item->floor > item->pos.yPos + (STEP_SIZE * 3))
|
||||
item->aiBits &= ~MODIFY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (foundTarget != 0)
|
||||
if (canJump3blocks || item->itemFlags[2] == VON_CROY_FLAG_JUMP)
|
||||
{
|
||||
if (info.distance < SQUARE(3072) && (item->swapMeshFlags & SWAP_MESH_BITS_VON_CROY))
|
||||
if (item->itemFlags[2] != VON_CROY_FLAG_JUMP && !canJump2blocks)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_TOGGLE_KNIFE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (info.distance >= SQUARE(1024))
|
||||
{
|
||||
if (enemy != LaraItem && info.distance > SQUARE(640))
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_WALK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!info.bite)
|
||||
{
|
||||
if (enemy->hitPoints > 0 && info.ahead)
|
||||
{
|
||||
if (abs(enemy->pos.yPos - item->pos.yPos + 512) < 512)
|
||||
item->goalAnimState = STATE_VON_CROY_KNIFE_ATTACK_HIGH;
|
||||
else
|
||||
item->goalAnimState = STATE_VON_CROY_KNIFE_ATTACK_LOW;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!creature->reachedGoal)
|
||||
{
|
||||
if (laraInfo.bite)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (canJump1block || canJump2blocks)
|
||||
{
|
||||
creature->maximumTurn = 0;
|
||||
item->animNumber = obj->animIndex + 22;
|
||||
item->currentAnimState = STATE_VON_CROY_JUMP;
|
||||
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
||||
if (canJump2blocks)
|
||||
item->goalAnimState = STATE_VON_CROY_JUMP_2BLOCKS;
|
||||
creature->LOT.isJumping = true;
|
||||
break;
|
||||
}
|
||||
else if (creature->monkeyAhead)
|
||||
{
|
||||
floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
|
||||
height = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
||||
if (GetCeiling(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos) == height - 1536)
|
||||
{
|
||||
/*if (!(item->swapMeshFlags & SWAP_MESH_BITS_VON_CROY))
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_TOGGLE_KNIFE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{*/
|
||||
item->goalAnimState = STATE_VON_CROY_START_MONKEY;
|
||||
break;
|
||||
//}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (foundTarget != 0)
|
||||
{
|
||||
if (info.distance < SQUARE(3072)
|
||||
&& (item->swapMeshFlags & SWAP_MESH_BITS_VON_CROY))
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_TOGGLE_KNIFE;
|
||||
break;
|
||||
}
|
||||
if (info.distance < SQUARE(1024))
|
||||
{
|
||||
if (!info.bite)
|
||||
{
|
||||
if (enemy->hitPoints > 0 && info.ahead)
|
||||
{
|
||||
if (abs(enemy->pos.yPos - item->pos.yPos + 512) < 512)
|
||||
item->goalAnimState = STATE_VON_CROY_KNIFE_ATTACK_HIGH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_KNIFE_ATTACK_LOW;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((info.distance < SQUARE(640)
|
||||
|| laraInfo.distance > SQUARE(5120))
|
||||
&& Lara.location < item->location)
|
||||
break;
|
||||
}
|
||||
|
||||
item->goalAnimState = STATE_VON_CROY_WALK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Lara.location <= item->location)
|
||||
{
|
||||
if (enemy && enemy->flags)
|
||||
{
|
||||
/*if (Lara.locationPad == item->location)
|
||||
goto LAB_00419db3;*/
|
||||
if (!enemy->flags && laraInfo.distance > 3072)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*if (item->itemFlags[2] == 0)
|
||||
{
|
||||
if (laraInfo.angle < 1024)
|
||||
{
|
||||
if (laraInfo.angle < -1024)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_LOOK_BACK_LEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->itemFlags[2] = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_LOOK_BACK_RIGHT;
|
||||
}
|
||||
break;
|
||||
}*/
|
||||
|
||||
/*if (item->itemFlags[2] == 1)
|
||||
{
|
||||
if (!(GetRandomControl() & 0xF))
|
||||
{
|
||||
if (laraInfo.distance < SQUARE(3072))
|
||||
item->goalAnimState = STATE_VON_CROY_CALL_LARA2;
|
||||
else
|
||||
item->goalAnimState = STATE_VON_CROY_CALL_LARA1;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->itemFlags[2] = 0;
|
||||
}
|
||||
break;
|
||||
}*/
|
||||
|
||||
creature->reachedGoal = false;
|
||||
creature->enemy = NULL;
|
||||
item->aiBits = FOLLOW;
|
||||
item->location++;
|
||||
break;
|
||||
}
|
||||
|
||||
/*if (enemy->flags > 32)
|
||||
{
|
||||
if (enemy->flags == 34)
|
||||
{
|
||||
if (Lara.location <= item->location)
|
||||
{
|
||||
item->goalAnimState = 32;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
creature->reachedGoal = false;
|
||||
creature->enemy = NULL;
|
||||
item->aiBits = FOLLOW;
|
||||
item->location += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (enemy->flags == 36)
|
||||
{
|
||||
if (Lara.location <= item->location)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (enemy->flags == 40)
|
||||
{
|
||||
if (item->itemFlags[2] != VON_CROY_FLAG_JUMP)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_JUMP_BACK;
|
||||
item->pos.xPos = enemy->pos.xPos;
|
||||
item->pos.yPos = enemy->pos.yPos;
|
||||
item->pos.zPos = enemy->pos.zPos;
|
||||
item->pos.xRot = enemy->pos.xRot;
|
||||
item->pos.yRot = enemy->pos.yRot;
|
||||
item->pos.zRot = enemy->pos.zRot;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_RUN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (enemy->flags == 48)
|
||||
{
|
||||
GetFloorAndTestTriggers(
|
||||
creature->aiTarget.pos.xPos,
|
||||
creature->aiTarget.pos.yPos,
|
||||
creature->aiTarget.pos.zPos,
|
||||
creature->aiTarget.roomNumber,
|
||||
1, 0);
|
||||
creature->reachedGoal = false;
|
||||
creature->enemy = NULL;
|
||||
item->aiBits = FOLLOW;
|
||||
item->location++;
|
||||
break;
|
||||
}
|
||||
else if (enemy->flags == -1)
|
||||
{
|
||||
creature->reachedGoal = false;
|
||||
creature->enemy = NULL;
|
||||
item->aiBits = FOLLOW;
|
||||
item->location++;
|
||||
break;
|
||||
item->goalAnimState = STATE_VON_CROY_JUMP_BACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
item->goalAnimState = STATE_VON_CROY_RUN;
|
||||
}
|
||||
}
|
||||
|
||||
if (enemy->flags == 2)
|
||||
{
|
||||
item->currentAnimState = STATE_VON_CROY_GRAB_LADDER;
|
||||
item->animNumber = Objects[item->objectNumber].animIndex + 37;
|
||||
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
||||
item->pos.xPos = enemy->pos.xPos;
|
||||
item->pos.yPos = enemy->pos.yPos;
|
||||
item->pos.zPos = enemy->pos.zPos;
|
||||
item->pos.xRot = enemy->pos.xRot;
|
||||
item->pos.yRot = enemy->pos.yRot;
|
||||
item->pos.zRot = enemy->pos.zRot;
|
||||
}
|
||||
else if (enemy->flags == 4)
|
||||
{
|
||||
item->currentAnimState = STATE_VON_CROY_STEP_DOWN_HIGH;
|
||||
item->animNumber = Objects[item->objectNumber].animIndex + 36;
|
||||
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
||||
|
||||
item->pos.xPos = enemy->pos.xPos;
|
||||
item->pos.yPos = enemy->pos.yPos;
|
||||
item->pos.zPos = enemy->pos.zPos;
|
||||
item->pos.xRot = enemy->pos.xRot;
|
||||
item->pos.yRot = enemy->pos.yRot;
|
||||
item->pos.zRot = enemy->pos.zRot;
|
||||
|
||||
creature->LOT.isJumping = true;
|
||||
}
|
||||
else if (enemy->flags == 8)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_ENABLE_TRAP;
|
||||
break;
|
||||
}
|
||||
else if (enemy->flags == 10)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_LOOK_BEFORE_JUMP;
|
||||
break;
|
||||
}
|
||||
else if (enemy->flags == 12)
|
||||
else if (canJump1block || canJump2blocks)
|
||||
{
|
||||
creature->maximumTurn = 0;
|
||||
|
||||
item->animNumber = Objects[item->objectNumber].animIndex + 22;
|
||||
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
||||
item->currentAnimState = STATE_VON_CROY_JUMP;
|
||||
if (canJump2blocks == 0)
|
||||
{
|
||||
creature->LOT.isJumping = true;
|
||||
|
||||
if (!canJump2blocks && !canJump3blocks)
|
||||
item->goalAnimState = STATE_VON_CROY_JUMP;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_JUMP_2BLOCKS;
|
||||
}
|
||||
|
||||
item->pos.xPos = enemy->pos.xPos;
|
||||
item->pos.yPos = enemy->pos.yPos;
|
||||
item->pos.zPos = enemy->pos.zPos;
|
||||
item->pos.xRot = enemy->pos.xRot;
|
||||
item->pos.yRot = enemy->pos.yRot;
|
||||
item->pos.zRot = enemy->pos.zRot;
|
||||
|
||||
creature->LOT.isJumping = true;
|
||||
}
|
||||
else if (enemy->flags == 1 || enemy->flags == 3
|
||||
|| enemy->flags == 5 || enemy->flags == 6
|
||||
|| enemy->flags == 7 || enemy->flags == 9
|
||||
|| enemy->flags == 11)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (creature->monkeyAhead)
|
||||
{
|
||||
floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
|
||||
height = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
||||
if (GetCeiling(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos) == height - 1536)
|
||||
{
|
||||
if (item->swapMeshFlags == SWAPMESHFLAGS_VON_CROY)
|
||||
item->goalAnimState = STATE_VON_CROY_TOGGLE_KNIFE;
|
||||
else
|
||||
item->goalAnimState = STATE_VON_CROY_START_MONKEY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetFloorAndTestTriggers(
|
||||
creature->aiTarget.pos.xPos,
|
||||
creature->aiTarget.pos.yPos,
|
||||
creature->aiTarget.pos.zPos,
|
||||
creature->aiTarget.roomNumber,
|
||||
1, 0);
|
||||
}*/
|
||||
if (creature->enemy && creature->enemy->hitPoints > 0 && info.distance < SQUARE(1024) && creature->enemy != LaraItem
|
||||
&& creature->enemy->objectNumber != ID_AI_FOLLOW)
|
||||
{
|
||||
if (info.bite)
|
||||
{
|
||||
if (enemy->hitPoints > 0 && info.ahead)
|
||||
{
|
||||
if (abs(enemy->pos.yPos - item->pos.yPos + 512) < 512)
|
||||
item->goalAnimState = STATE_VON_CROY_KNIFE_ATTACK_HIGH;
|
||||
else
|
||||
item->goalAnimState = STATE_VON_CROY_KNIFE_ATTACK_LOW;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
creature->reachedGoal = false;
|
||||
creature->enemy = NULL;
|
||||
item->aiBits = FOLLOW;
|
||||
item->location++;
|
||||
item->goalAnimState = STATE_VON_CROY_WALK;
|
||||
break;
|
||||
|
||||
case STATE_VON_CROY_WALK:
|
||||
creature->LOT.isJumping = false;
|
||||
creature->LOT.isMonkeying = false;
|
||||
creature->maximumTurn = ANGLE(6);
|
||||
creature->LOT.isJumping = false;
|
||||
creature->maximumTurn = ANGLE(7);
|
||||
creature->flags = 0;
|
||||
|
||||
if (laraInfo.ahead)
|
||||
{
|
||||
joint3 = laraInfo.angle;
|
||||
}
|
||||
else if (info.ahead)
|
||||
{
|
||||
joint3 = info.angle;
|
||||
}
|
||||
|
||||
if (!laraInfo.ahead)
|
||||
{
|
||||
if (info.ahead)
|
||||
{
|
||||
joint2 = info.angle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
joint2 = laraInfo.angle;
|
||||
}
|
||||
|
||||
if (item->requiredAnimState != 0)
|
||||
{
|
||||
item->goalAnimState = item->requiredAnimState;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((Lara.location < item->location
|
||||
&& laraInfo.distance >SQUARE(5120))
|
||||
|| laraInfo.bite)
|
||||
if (canJump1block || canJump2blocks || canJump3blocks)
|
||||
{
|
||||
creature->maximumTurn = 0;
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (creature->monkeyAhead)
|
||||
if (creature->reachedGoal && creature->monkeyAhead)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
break;
|
||||
|
@ -686,65 +416,77 @@ void VonCroyControl(short itemNumber)
|
|||
|
||||
if (creature->reachedGoal)
|
||||
{
|
||||
if (enemy->flags != 32)
|
||||
if (!creature->enemy->flags)
|
||||
{
|
||||
creature->reachedGoal = false;
|
||||
creature->enemy = NULL;
|
||||
item->aiBits = FOLLOW;
|
||||
item->itemFlags[3]++;
|
||||
|
||||
break;
|
||||
}
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Lara.location >= item->itemFlags[3])
|
||||
{
|
||||
if (!foundTarget || info.distance >= 0x200000 && (item->swapMeshFlags & 0x40000 || info.distance >= 9437184))
|
||||
{
|
||||
if (creature->enemy == LaraItem)
|
||||
{
|
||||
if (info.distance >= 0x400000)
|
||||
{
|
||||
if (info.distance > 0x1000000)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_RUN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
}
|
||||
}
|
||||
else if (Lara.location > item->itemFlags[3] && laraInfo.distance > 0x400000)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_RUN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
if (info.bite)
|
||||
{
|
||||
if (info.distance < SQUARE(1024))
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetFloorAndTestTriggers(
|
||||
creature->aiTarget.pos.xPos,
|
||||
creature->aiTarget.pos.yPos,
|
||||
creature->aiTarget.pos.zPos,
|
||||
creature->aiTarget.roomNumber,
|
||||
1, 0);
|
||||
creature->reachedGoal = false;
|
||||
creature->enemy = NULL;
|
||||
item->aiBits = FOLLOW;
|
||||
item->location++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundTarget != NULL
|
||||
&& (info.distance < SQUARE(1448)
|
||||
|| ((item->swapMeshFlags & SWAP_MESH_BITS_VON_CROY) == 0
|
||||
&& (info.distance < SQUARE(3072)))))
|
||||
if (creature->mood == ATTACK_MOOD &&
|
||||
!(creature->jumpAhead) &&
|
||||
info.distance > SQUARE(1024))
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
break;
|
||||
item->goalAnimState = STATE_VON_CROY_RUN;
|
||||
}
|
||||
|
||||
if (info.distance < SQUARE(640)
|
||||
&& enemy->flags != 32)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (info.distance < SQUARE(3072)
|
||||
|| Lara.location < item->location)
|
||||
break;
|
||||
|
||||
item->goalAnimState = STATE_VON_CROY_RUN;
|
||||
|
||||
break;
|
||||
|
||||
case STATE_VON_CROY_RUN:
|
||||
if (info.ahead)
|
||||
if (info.ahead)
|
||||
{
|
||||
joint2 = info.angle;
|
||||
joint3 = info.angle;
|
||||
}
|
||||
|
||||
if (item->frameNumber == g_Level.Anims[item->animNumber].frameBase)
|
||||
{
|
||||
creature->LOT.isJumping = false;
|
||||
creature->maximumTurn = ANGLE(8);
|
||||
}
|
||||
|
||||
tilt = angle >> 1;
|
||||
|
||||
if (item->itemFlags[2] == VON_CROY_FLAG_JUMP)
|
||||
{
|
||||
creature->maximumTurn = 0;
|
||||
|
@ -752,56 +494,49 @@ void VonCroyControl(short itemNumber)
|
|||
break;
|
||||
}
|
||||
|
||||
if (item->location <= Lara.location
|
||||
&& !canJump1block == 0
|
||||
&& !laraInfo.bite)
|
||||
creature->maximumTurn = ANGLE(11);
|
||||
tilt = abs(angle) / 2;
|
||||
|
||||
if (info.distance < SQUARE(2048) || Lara.location < item->location)
|
||||
{
|
||||
if (creature->monkeyAhead)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
break;
|
||||
}
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!creature->reachedGoal)
|
||||
if (creature->reachedGoal)
|
||||
{
|
||||
if (!enemy->flags)
|
||||
{
|
||||
if (info.distance < SQUARE(640)
|
||||
&& enemy->flags != 32
|
||||
&& enemy->flags != 40)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (enemy->flags == 32)
|
||||
{
|
||||
GetFloorAndTestTriggers(
|
||||
creature->aiTarget.pos.xPos,
|
||||
creature->aiTarget.pos.yPos,
|
||||
creature->aiTarget.pos.zPos,
|
||||
creature->aiTarget.roomNumber,
|
||||
1, 0);
|
||||
creature->reachedGoal = false;
|
||||
creature->enemy = NULL;
|
||||
item->aiBits = FOLLOW;
|
||||
item->location++;
|
||||
item->location;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (info.distance < 512)
|
||||
{
|
||||
if (enemy->flags == 40)
|
||||
{
|
||||
creature->maximumTurn = 0;
|
||||
item->pos.yRot = enemy->pos.yRot;
|
||||
item->goalAnimState = STATE_VON_CROY_JUMP_2BLOCKS;
|
||||
item->itemFlags[2] = VON_CROY_FLAG_JUMP;
|
||||
}
|
||||
break;
|
||||
}
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
break;
|
||||
}
|
||||
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
|
||||
if (canJump1block
|
||||
|| canJump2blocks
|
||||
|| canJump3blocks
|
||||
|| creature->monkeyAhead
|
||||
|| item->aiBits & FOLLOW
|
||||
|| info.distance < SQUARE(1024)
|
||||
|| creature->jumpAhead)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_STOP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (info.distance < SQUARE(1024))
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_WALK;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case STATE_VON_CROY_START_MONKEY:
|
||||
|
@ -839,13 +574,13 @@ void VonCroyControl(short itemNumber)
|
|||
case STATE_VON_CROY_TOGGLE_KNIFE:
|
||||
if (item->frameNumber == g_Level.Anims[item->animNumber].frameBase)
|
||||
{
|
||||
if (!(item->swapMeshFlags & SWAP_MESH_BITS_VON_CROY))
|
||||
if (!(item->swapMeshFlags & SWAPMESHFLAGS_VON_CROY))
|
||||
{
|
||||
item->swapMeshFlags |= SWAP_MESH_BITS_VON_CROY;
|
||||
item->swapMeshFlags |= SWAPMESHFLAGS_VON_CROY;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->swapMeshFlags &= ~SWAP_MESH_BITS_VON_CROY;
|
||||
item->swapMeshFlags &= ~SWAPMESHFLAGS_VON_CROY;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -883,10 +618,12 @@ void VonCroyControl(short itemNumber)
|
|||
|| item->frameNumber > g_Level.Anims[item->animNumber].frameBase + 5)
|
||||
{
|
||||
creature->LOT.isJumping = true;
|
||||
//if (canJump3blocks)
|
||||
// item->itemFlags[2] = VON_CROY_FLAG_JUMP;
|
||||
}
|
||||
else if (canJump1block)
|
||||
else if (canJump1block)
|
||||
{
|
||||
item->goalAnimState = STATE_VON_CROY_JUMP;
|
||||
item->goalAnimState = STATE_VON_CROY_JUMP;
|
||||
}
|
||||
|
||||
if (item->itemFlags[2] == VON_CROY_FLAG_JUMP)
|
||||
|
@ -1098,7 +835,7 @@ void VonCroyControl(short itemNumber)
|
|||
break;
|
||||
|
||||
case STATE_VON_CROY_JUMP_BACK:
|
||||
item->itemFlags[2] = 6;
|
||||
item->itemFlags[2] = VON_CROY_FLAG_JUMP;
|
||||
break;
|
||||
|
||||
case 36:
|
||||
|
|
|
@ -733,7 +733,7 @@ static void StartBaddy(OBJECT_INFO* obj)
|
|||
obj->savePosition = true;
|
||||
obj->saveHitpoints = true;
|
||||
obj->saveMesh = true;
|
||||
obj->zoneType = ZONE_HUMAN_JUMP_AND_MONKEY;
|
||||
obj->zoneType = ZONE_HUMAN_LONGJUMP_AND_MONKEY;
|
||||
|
||||
g_Level.Bones[obj->boneIndex + 4 * 6] |= ROT_X;
|
||||
g_Level.Bones[obj->boneIndex + 4 * 6] |= ROT_Y;
|
||||
|
|
|
@ -2079,7 +2079,7 @@ namespace T5M::Renderer
|
|||
printDebugMessage("Statics: %d", m_staticsToDraw.size());
|
||||
printDebugMessage("Lights: %d", m_lightsToDraw.size());
|
||||
printDebugMessage("Lara.roomNumber: %d", LaraItem->roomNumber);
|
||||
printDebugMessage("LaraItem.boxNumber: %d", LaraItem->boxNumber);
|
||||
printDebugMessage("LaraItem.boxNumber: %d, canJump: %d, canLongJump: %d, canMonkey: %d", LaraItem->boxNumber);
|
||||
printDebugMessage("Lara.pos: %d %d %d", LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos);
|
||||
printDebugMessage("Lara.rot: %d %d %d", LaraItem->pos.xRot, LaraItem->pos.yRot, LaraItem->pos.zRot);
|
||||
printDebugMessage("Lara.animNumber: %d", LaraItem->animNumber);
|
||||
|
|
|
@ -962,15 +962,15 @@ void LoadBoxes()
|
|||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
// Ground zones
|
||||
for (int j = 0; j < 4; j++)
|
||||
for (int j = 0; j < MAX_ZONES - 1; j++)
|
||||
{
|
||||
g_Level.Zones[j][i].resize(numBoxes * sizeof(int));
|
||||
ReadBytes(g_Level.Zones[j][i].data(), numBoxes * sizeof(int));
|
||||
}
|
||||
|
||||
// Fly zone
|
||||
g_Level.Zones[4][i].resize(numBoxes * sizeof(int));
|
||||
ReadBytes(g_Level.Zones[4][i].data(), numBoxes * sizeof(int));
|
||||
g_Level.Zones[MAX_ZONES - 1][i].resize(numBoxes * sizeof(int));
|
||||
ReadBytes(g_Level.Zones[MAX_ZONES - 1][i].data(), numBoxes * sizeof(int));
|
||||
}
|
||||
|
||||
// By default all blockable boxes are blocked
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#define AddPtr(p, t, n) p = (t*)((char*)(p) + (ptrdiff_t)(n));
|
||||
#define MESHES(slot, mesh) (Objects[slot].meshIndex + mesh)
|
||||
|
||||
#define MAX_ZONES 6
|
||||
|
||||
struct ChunkId;
|
||||
struct LEB128;
|
||||
struct SAMPLE_INFO;
|
||||
|
@ -132,7 +134,7 @@ struct LEVEL
|
|||
std::vector<SPRITE> Sprites;
|
||||
std::vector<BOX_INFO> Boxes;
|
||||
std::vector<OVERLAP> Overlaps;
|
||||
std::vector<int> Zones[5][2];
|
||||
std::vector<int> Zones[MAX_ZONES][2];
|
||||
std::vector<short> SoundMap;
|
||||
std::vector<SAMPLE_INFO> SoundDetails;
|
||||
int NumItems;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue