Fixed enemy monkey; Added new zone for ID_VON_CROY; Small AI fixes; Added 3 blocks jump;

This commit is contained in:
Montagna Marco 2020-09-01 07:06:31 +02:00
parent b987e9bda8
commit 82af97c8cc
9 changed files with 236 additions and 478 deletions

View file

@ -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

View file

@ -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));

View file

@ -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));

View file

@ -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
{

View file

@ -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:

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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;