diff --git a/TR5Main/Objects/TR5/tr5_brownbeast.cpp b/TR5Main/Objects/TR5/tr5_brownbeast.cpp index cb47c680d..100e144d7 100644 --- a/TR5Main/Objects/TR5/tr5_brownbeast.cpp +++ b/TR5Main/Objects/TR5/tr5_brownbeast.cpp @@ -1,5 +1,12 @@ #include "../newobjects.h" #include "../../Game/items.h" +#include "../../Game/Box.h" +#include "../../Game/effects.h" +#include "../../Game/effect2.h" +#include "../../Game/tomb4fx.h" + +BITE_INFO BrownBeastBite1 = { 0, 0, 0, 16 }; +BITE_INFO BrownBeastBite2 = { 0, 0, 0, 22 }; void InitialiseBrownBeast(short itemNum) { @@ -11,4 +18,179 @@ void InitialiseBrownBeast(short itemNum) item->frameNumber = Anims[item->animNumber].frameBase; item->goalAnimState = 1; item->currentAnimState = 1; +} + +void ControlBrowsBeast(short itemNumber) +{ + if (CreatureActive(itemNumber)) + { + ITEM_INFO* item = &Items[itemNumber]; + CREATURE_INFO* creature = (CREATURE_INFO*)item->data; + + short angle = 0; + + if (item->hitPoints <= 0) + { + item->hitPoints = 0; + if (item->currentAnimState != 7) + { + item->animNumber = Objects[ID_MAZE_MONSTER].animIndex + 10; + item->currentAnimState = 7; + item->frameNumber = Anims[item->animNumber].frameBase; + } + } + else + { + if (item->aiBits) + { + GetAITarget(creature); + } + else if (creature->hurtByLara) + { + creature->enemy = LaraItem; + } + + AI_INFO info; + CreatureAIInfo(item, &info); + + int distance; + + if (creature->enemy == LaraItem) + { + distance = info.distance; + } + else + { + int dx = LaraItem->pos.xPos - item->pos.xPos; + int dz = LaraItem->pos.zPos - item->pos.zPos; + ATAN(dz, dz); + distance = SQUARE(dx) + SQUARE(dz); + } + + GetCreatureMood(item, &info, VIOLENT); + CreatureMood(item, &info, VIOLENT); + + angle = CreatureTurn(item, creature->maximumTurn); + creature->maximumTurn = ANGLE(7); + switch (item->currentAnimState) + { + case 1: + creature->flags = 0; + if (creature->mood == ATTACK_MOOD) + { + if (distance <= SQUARE(1024)) + { + if (GetRandomControl() & 1) + item->goalAnimState = 4; + else + item->goalAnimState = 6; + } + else if (GetRandomControl() & 1) + { + item->goalAnimState = 2; + } + else + { + item->goalAnimState = 3; + } + } + else + { + item->goalAnimState = 1; + } + break; + + case 2: + case 3: + if (distance < SQUARE(1024) || creature->mood != ATTACK_MOOD) + item->goalAnimState = 1; + SoundEffect(SFX_IMP_BARREL_ROLL, &item->pos, 0); + break; + + case 4: + case 6: + creature->maximumTurn = 0; + if (abs(info.angle) >= ANGLE(2)) + { + if (info.angle > 0) + item->pos.yRot += ANGLE(2); + else + item->pos.yRot -= ANGLE(2); + } + else + { + item->pos.yRot += info.angle; + } + + if (creature->flags) + break; + + if (item->touchBits & 0x3C000) + { + if (item->animNumber == Objects[ID_MAZE_MONSTER].animIndex + 8) + { + if (item->frameNumber > Anims[item->animNumber].frameBase + 19 + && item->frameNumber < Anims[item->animNumber].frameBase + 25) + { + CreatureEffect2(item, &BrownBeastBite1, 20, item->pos.yRot, DoBloodSplat); + LaraItem->hitPoints -= 150; + LaraItem->hitStatus = true; + creature->flags |= 1; + break; + } + } + + if (item->animNumber == Objects[ID_MAZE_MONSTER].animIndex + 2) + { + if (item->frameNumber > Anims[item->animNumber].frameBase + 6 + && item->frameNumber < Anims[item->animNumber].frameBase + 16) + { + CreatureEffect2(item, &BrownBeastBite1, 20, item->pos.yRot, DoBloodSplat); + LaraItem->hitPoints -= 150; + LaraItem->hitStatus = true; + creature->flags |= 1; + break; + } + } + } + + if (!(item->touchBits & 0xF00000)) + break; + + if (item->animNumber == Objects[ID_MAZE_MONSTER].animIndex + 8) + { + if (item->frameNumber > Anims[item->animNumber].frameBase + 13 + && item->frameNumber < Anims[item->animNumber].frameBase + 20) + { + CreatureEffect2(item, &BrownBeastBite2, 20, item->pos.yRot, DoBloodSplat); + LaraItem->hitPoints -= 150; + LaraItem->hitStatus = true; + creature->flags |= 2; + break; + } + } + + if (item->animNumber == Objects[ID_MAZE_MONSTER].animIndex + 2) + { + if (item->frameNumber > Anims[item->animNumber].frameBase + 33 + && item->frameNumber < Anims[item->animNumber].frameBase + 43) + { + CreatureEffect2(item, &BrownBeastBite2, 20, item->pos.yRot, DoBloodSplat); + LaraItem->hitPoints -= 150; + LaraItem->hitStatus = true; + creature->flags |= 2; + break; + } + } + + break; + + default: + break; + + } + } + + CreatureAnimation(itemNumber, angle, 0); + } } \ No newline at end of file diff --git a/TR5Main/Objects/TR5/tr5_ghost.cpp b/TR5Main/Objects/TR5/tr5_ghost.cpp index d537ac737..92fe909d8 100644 --- a/TR5Main/Objects/TR5/tr5_ghost.cpp +++ b/TR5Main/Objects/TR5/tr5_ghost.cpp @@ -1,5 +1,10 @@ #include "../newobjects.h" #include "../../Game/items.h" +#include "../../Game/Box.h" +#include "../../Game/effects.h" +#include "../../Game/effect2.h" + +BITE_INFO InvisibleGhostBite = { 0, 0, 0, 17 }; void InitialiseInvisibleGhost(short itemNum) { @@ -12,4 +17,96 @@ void InitialiseInvisibleGhost(short itemNum) item->goalAnimState = 1; item->currentAnimState = 1; item->pos.yPos += CLICK(2); +} + +void ControlInvisibleGhost(short itemNumber) +{ + if (CreatureActive(itemNumber)) + { + short joint0 = 0; + short joint2 = 0; + short joint1 = 0; + short angle = 0; + + ITEM_INFO* item = &Items[itemNumber]; + CREATURE_INFO* creature = (CREATURE_INFO*)item->data; + + if (item->aiBits) + { + GetAITarget(creature); + } + else if (creature->hurtByLara) + { + creature->enemy = LaraItem; + } + + AI_INFO info; + CreatureAIInfo(item, &info); + + angle = CreatureTurn(item, creature->maximumTurn); + if (abs(info.angle) >= ANGLE(3)) + { + if (info.angle > 0) + item->pos.yRot += ANGLE(3); + else + item->pos.yRot -= ANGLE(3); + } + else + { + item->pos.yRot += info.angle; + } + + if (info.ahead) + { + joint0 = info.angle >> 1; + joint2 = info.angle >> 1; + joint1 = info.xAngle; + } + + creature->maximumTurn = 0; + + if (item->currentAnimState == 1) + { + creature->flags = 0; + if (info.distance < SQUARE(614)) + { + if (GetRandomControl() & 1) + item->goalAnimState = 2; + else + item->goalAnimState = 3; + } + } + else if (item->currentAnimState > 1 + && item->currentAnimState <= 3 + && !creature->flags + && item->touchBits & 0x9470 + && item->frameNumber > Anims[item->animNumber].frameBase + 18) + { + LaraItem->hitPoints -= 400; + LaraItem->hitStatus = true; + CreatureEffect2(item, &InvisibleGhostBite, 10, item->pos.yRot, DoBloodSplat); + creature->flags = 1; + } + + CreatureJoint(item, 0, joint0); + CreatureJoint(item, 1, joint1); + CreatureJoint(item, 2, joint2); + + if (info.distance >= SQUARE(1536)) + { + item->afterDeath = 125; + item->itemFlags[0] = 0; + } + else + { + item->afterDeath = SQRT_ASM(info.distance) >> 4; + if (item->itemFlags[0] == 0) + { + item->itemFlags[0] = 1; + SoundEffect(SFX_SKELETON_APPEAR, &item->pos, 0); + } + } + + CreatureAnimation(itemNumber, angle, 0); + } } \ No newline at end of file diff --git a/TR5Main/Objects/TR5/tr5_gladiator.cpp b/TR5Main/Objects/TR5/tr5_gladiator.cpp index 9e0f8b98d..6a9f080b6 100644 --- a/TR5Main/Objects/TR5/tr5_gladiator.cpp +++ b/TR5Main/Objects/TR5/tr5_gladiator.cpp @@ -1,5 +1,13 @@ #include "../newobjects.h" #include "../../Game/items.h" +#include "../../Game/Box.h" +#include "../../Game/sphere.h" +#include "../../Game/debris.h" +#include "../../Game/effect2.h" +#include "../../Game/effects.h" +#include "../../Game/tomb4fx.h" + +BITE_INFO GladiatorBite = { 0, 0, 0, 16 }; void InitialiseGladiator(short itemNum) { @@ -13,4 +21,341 @@ void InitialiseGladiator(short itemNum) item->currentAnimState = 1; if (item->triggerFlags == 1) *item->pad2 = -1; +} + +void ControlGladiator(short itemNumber) +{ + if (CreatureActive(itemNumber)) + { + short tilt = 0; + short angle = 0; + short joint2 = 0; + short joint1 = 0; + short joint0 = 0; + PHD_VECTOR pos; + short roomNumber; + ROOM_INFO* r; + MESH_INFO* mesh; + FLOOR_INFO* floor; + int i; + + ITEM_INFO* item = &Items[itemNumber]; + CREATURE_INFO* creature = (CREATURE_INFO*)item->data; + + if (item->hitPoints <= 0) + { + item->hitPoints = 0; + if (item->currentAnimState != 6) + { + item->animNumber = Objects[ID_GLADIATOR].animIndex + 16; + item->currentAnimState = 6; + item->frameNumber = Anims[item->animNumber].frameBase; + } + } + else + { + if (item->aiBits) + { + GetAITarget(creature); + } + else if (creature->hurtByLara) + { + creature->enemy = LaraItem; + } + + AI_INFO info; + AI_INFO laraInfo; + + CreatureAIInfo(item, &info); + + int unknown = true; + short rot; + int distance; + + if (creature->enemy == LaraItem) + { + laraInfo.distance = info.distance; + rot = info.angle; + } + else + { + int dx = LaraItem->pos.xPos - item->pos.xPos; + int dz = LaraItem->pos.zPos - item->pos.zPos; + + rot = ATAN(dz, dx) - item->pos.yRot; + if (rot <= -ANGLE(90) || rot >= ANGLE(90)) + unknown = false; + + distance = SQUARE(dx) + SQUARE(dz); + } + + GetCreatureMood(item, &info, VIOLENT); + CreatureMood(item, &info, VIOLENT); + + angle = CreatureTurn(item, creature->maximumTurn); + + if (info.ahead) + { + joint0 = info.angle >> 1; + joint2 = info.angle >> 1; + joint1 = info.xAngle; + } + + switch (item->currentAnimState) + { + case 1: + creature->flags = 0; + joint2 = rot; + creature->maximumTurn = (-(creature->mood != 0)) & 0x16C; + + if (item->aiBits & GUARD + || !(GetRandomControl() & 0x1F) + && (info.distance > SQUARE(1024) + || creature->mood != ATTACK_MOOD)) + { + joint2 = AIGuard(creature); + break; + } + + if (item->aiBits & PATROL1) + { + item->goalAnimState = 2; + } + else + { + if (creature->mood == ESCAPE_MOOD) + { + if (Lara.target != item + && info.ahead + && !item->hitStatus) + { + item->goalAnimState = 1; + break; + } + } + else + { + if (!creature->mood + || item->aiBits & FOLLOW + && (creature->reachedGoal + || distance > SQUARE(2048))) + { + if (item->requiredAnimState) + { + item->goalAnimState = item->requiredAnimState; + } + else if (!(GetRandomControl() & 0x3F)) + { + item->goalAnimState = 2; + } + break; + } + + if (Lara.target == item + && unknown + && distance < SQUARE(1536) + && GetRandomControl() & 1 + && (Lara.gunType == WEAPON_SHOTGUN + || !(GetRandomControl() & 0xF)) + && item->meshBits == -1) + { + item->goalAnimState = 4; + break; + } + + if (info.bite && info.distance < SQUARE(819)) + { + if (GetRandomControl() & 1) + item->goalAnimState = 8; + else + item->goalAnimState = 9; + break; + } + } + item->goalAnimState = 2; + } + break; + + case 2: + creature->flags = 0; + joint2 = rot; + creature->maximumTurn = creature->mood != BORED_MOOD ? ANGLE(7) : ANGLE(2); + + if (item->aiBits & PATROL1) + { + item->goalAnimState = 2; + joint2 = 0; + } + else if (creature->mood == ESCAPE_MOOD) + { + item->goalAnimState = 3; + } + else if (creature->mood) + { + if (info.distance < SQUARE(1024)) + { + item->goalAnimState = 1; + break; + } + + if (info.bite && info.distance < SQUARE(2048)) + { + item->goalAnimState = 11; + } + else if (!info.ahead || info.distance > SQUARE(1536)) + { + item->goalAnimState = 3; + } + } + else if (!(GetRandomControl() & 0x3F)) + { + item->goalAnimState = 1; + break; + } + + break; + + case 3: + creature->LOT.isJumping = false; + if (info.ahead) + joint2 = info.angle; + creature->maximumTurn = ANGLE(11); + tilt = angle / 2; + + if (item->aiBits & GUARD) + { + creature->maximumTurn = 0; + item->goalAnimState = 1; + break; + } + + if (creature->mood == ESCAPE_MOOD) + { + if (Lara.target != item && info.ahead) + { + item->goalAnimState = 1; + break; + } + break; + } + + if (item->aiBits & FOLLOW + && (creature->reachedGoal + || distance > SQUARE(2048))) + { + item->goalAnimState = 1; + break; + } + + if (!creature->mood) + { + item->goalAnimState = 2; + break; + } + + if (info.distance < SQUARE(1536)) + { + if (info.bite) + item->goalAnimState = 10; + else + item->goalAnimState = 2; + } + break; + + case 4: + if (item->hitStatus) + { + if (!unknown) + { + item->goalAnimState = 1; + break; + } + } + else if (Lara.target != item + || !(GetRandomControl() & 0x7F)) + { + item->goalAnimState = 1; + break; + } + break; + + case 5: + if (Lara.target != item) + item->goalAnimState = 1; + break; + + case 8: + case 9: + case 10: + case 11: + creature->maximumTurn = 0; + if (abs(info.angle) >= ANGLE(7)) + { + if (info.angle >= 0) + item->pos.yRot += ANGLE(7); + else + item->pos.yRot -= ANGLE(7); + } + else + { + item->pos.yRot += info.angle; + } + + if (item->frameNumber > Anims[item->animNumber].frameBase + 10) + { + r = &Rooms[item->roomNumber]; + pos.x = 0; + pos.y = 0; + pos.z = 0; + GetJointAbsPosition(item, &pos, 16); + + floor = &XZ_GET_SECTOR(r, pos.x - r->x, pos.z - r->z); + if (floor->stopper) + { + for (i = 0; i < r->numMeshes; i++) + { + mesh = &r->mesh[i]; + + if (!((pos.z ^ mesh->z) & 0xFFFFFC00)) + { + if (!((pos.x ^ mesh->x) & 0xFFFFFC00)) + { + if (mesh->staticNumber >= 50 && mesh->staticNumber <= 59) + { + ShatterObject(0, mesh, -64, LaraItem->roomNumber, 0); + //SoundEffect(ShatterSounds[gfCurrentLevel - 5][*(v28 + 18)], v28, 0); + mesh->Flags &= 0xFEu; + GetFloorHeight(floor, pos.x, pos.y, pos.z); + TestTriggers(TriggerIndex, 1, 0); + } + } + } + } + } + + if (!creature->flags) + { + if (item->touchBits & 0x6000) + { + LaraItem->hitPoints -= 120; + LaraItem->hitStatus = true; + CreatureEffect2(item, &GladiatorBite, 10, item->pos.yRot, DoBloodSplat); + SoundEffect(SFX_LARA_THUD, &item->pos, 0); + creature->flags = 1; + } + } + } + break; + + default: + break; + } + } + + CreatureTilt(item, tilt); + CreatureJoint(item, 0, joint0); + CreatureJoint(item, 1, joint1); + CreatureJoint(item, 2, joint2); + CreatureAnimation(itemNumber, angle, 0); + } } \ No newline at end of file diff --git a/TR5Main/Objects/oldobjects.h b/TR5Main/Objects/oldobjects.h index 9c0f87892..735a177ed 100644 --- a/TR5Main/Objects/oldobjects.h +++ b/TR5Main/Objects/oldobjects.h @@ -15,15 +15,15 @@ #define ControlHydra ((void (__cdecl*)(short)) 0x0043BF70) //#define ControlImp ((void (__cdecl*)(short)) 0x0043BEA0) #define ControlLightingGuide ((void (__cdecl*)(short)) 0x0048E580) -#define ControlBrowsBeast ((void (__cdecl*)(short)) 0x0048E960) +//#define ControlBrowsBeast ((void (__cdecl*)(short)) 0x0048E960) #define InitialiseLagoonWitch ((void (__cdecl*)(short)) 0x0047D2D0) // not used anymore ! #define ControlLagoonWitch ((void (__cdecl*)(short)) 0x0047D360) // not used anymore ! -#define ControlInvisibleGhost ((void (__cdecl*)(short)) 0x00477AB0) +//#define ControlInvisibleGhost ((void (__cdecl*)(short)) 0x00477AB0) #define InitialiseLittleBats ((void (__cdecl*)(short)) 0x00407EC0) #define ControlLittleBats ((void (__cdecl*)(short)) 0x00407F50) #define InitialiseSpiders ((void (__cdecl*)(short)) 0x0043F2B0) #define ControlSpiders ((void (__cdecl*)(short)) 0x0047A200) -#define ControlGladiator ((void (__cdecl*)(short)) 0x00436700) +//#define ControlGladiator ((void (__cdecl*)(short)) 0x00436700) #define ControlRomanStatue ((void (__cdecl*)(short)) 0x0046BC10) #define ControlAutoGuns ((void (__cdecl*)(short)) 0x004078A0) #define ControlGunShip ((void (__cdecl*)(short)) 0x00487FF0) @@ -60,3 +60,6 @@ void ControlReaper(short itemNumber); void ControlGuardM16(short itemNumber); void ImpThrowStones(ITEM_INFO* item); void ControlImp(short itemNumber); +void ControlGladiator(short itemNumber); +void ControlBrowsBeast(short itemNumber); +void ControlInvisibleGhost(short itemNumber);