From 4991da66f651b62624dba3e8f8db70dfa134441c Mon Sep 17 00:00:00 2001 From: MontyTRC89 Date: Fri, 20 Aug 2021 06:00:34 +0200 Subject: [PATCH] Refactored energy bubbles function names; Removed LanguageScript.cpp from the project; Working on ID_CROCODILE_GOD; --- TR5Main/Game/Box.h | 10 +- TR5Main/Objects/Effects/tr4_bubbles.cpp | 729 ++++++++++--------- TR5Main/Objects/Effects/tr4_bubbles.h | 5 +- TR5Main/Objects/TR4/Entity/tr4_crocodile.cpp | 2 +- TR5Main/Objects/TR4/Entity/tr4_mutant.cpp | 635 ++++++++-------- TR5Main/Objects/TR4/Entity/tr4_mutant.h | 34 +- TR5Main/Objects/TR4/tr4_objects.cpp | 4 +- TR5Main/Objects/TR5/tr5_objects.cpp | 2 +- TR5Main/Objects/objectslist.h | 2 +- TR5Main/TR5Main.vcxproj | 1 - 10 files changed, 720 insertions(+), 704 deletions(-) diff --git a/TR5Main/Game/Box.h b/TR5Main/Game/Box.h index b1b7134f5..17b1c7eec 100644 --- a/TR5Main/Game/Box.h +++ b/TR5Main/Game/Box.h @@ -38,14 +38,14 @@ enum ZoneType ZONE_HUMAN_LONGJUMP_AND_MONKEY, }; -struct OBJECT_Bones +struct OBJECT_BONES { short bone0; short bone1; short bone2; short bone3; - OBJECT_Bones() + OBJECT_BONES() { this->bone0 = 0; this->bone1 = 0; @@ -53,7 +53,7 @@ struct OBJECT_Bones this->bone3 = 0; } - OBJECT_Bones(short all) + OBJECT_BONES(short all) { this->bone0 = all; this->bone1 = all; @@ -61,7 +61,7 @@ struct OBJECT_Bones this->bone3 = all; } - OBJECT_Bones(short angleY, short angleX) + OBJECT_BONES(short angleY, short angleX) { this->bone0 = angleY; this->bone1 = angleX; @@ -69,7 +69,7 @@ struct OBJECT_Bones this->bone3 = angleX; } - OBJECT_Bones(short angleY, short angleX, bool total) + OBJECT_BONES(short angleY, short angleX, bool total) { this->bone0 = angleY; this->bone1 = angleX; diff --git a/TR5Main/Objects/Effects/tr4_bubbles.cpp b/TR5Main/Objects/Effects/tr4_bubbles.cpp index 17813106e..d3bad2128 100644 --- a/TR5Main/Objects/Effects/tr4_bubbles.cpp +++ b/TR5Main/Objects/Effects/tr4_bubbles.cpp @@ -11,426 +11,429 @@ #include "lara.h" #include "tr4_mutant.h" -void BubblesEffect1(short fxNum, short xVel, short yVel, short zVel) +namespace ten::entities::all { - FX_INFO* fx = &EffectList[fxNum]; - - int dx = LaraItem->pos.xPos - fx->pos.xPos; - int dz = LaraItem->pos.zPos - fx->pos.zPos; - - if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384) + void TriggerSethMissileFlame(short fxNum, short xVel, short yVel, short zVel) { - SPARKS* spark = &Sparks[GetFreeSpark()]; + FX_INFO* fx = &EffectList[fxNum]; - spark->on = 1; - spark->sR = 0; - spark->dR = 0; - spark->sG = (GetRandomControl() & 0x7F) + 32; - spark->sB = spark->dG + 64; - spark->dB = (GetRandomControl() & 0x7F) + 32; - spark->dG = spark->dB + 64; - spark->fadeToBlack = 8; - spark->colFadeSpeed = (GetRandomControl() & 3) + 4; - spark->transType = COLADD; - spark->life = spark->sLife = (GetRandomControl() & 3) + 16; - spark->y = 0; - spark->x = (GetRandomControl() & 0xF) - 8; - spark->xVel = xVel; - spark->yVel = yVel; - spark->z = (GetRandomControl() & 0xF) - 8; - spark->zVel = zVel; - spark->friction = 68; - spark->flags = 602; - spark->rotAng = GetRandomControl() & 0xFFF; - if (GetRandomControl() & 1) + int dx = LaraItem->pos.xPos - fx->pos.xPos; + int dz = LaraItem->pos.zPos - fx->pos.zPos; + + if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384) { - spark->rotAdd = -32 - (GetRandomControl() & 0x1F); - } - else - { - spark->rotAdd = (GetRandomControl() & 0x1F) + 32; - } - spark->gravity = 0; - spark->maxYvel = 0; - spark->fxObj = fxNum; - if (fx->flag1 == 1) - { - spark->scalar = 3; - } - else - { - spark->scalar = 2; - } - spark->sSize = spark->size = (GetRandomControl() & 7) + 64; - spark->dSize = spark->size / 32; - } -} + SPARKS* spark = &Sparks[GetFreeSpark()]; -void BubblesEffect2(short fxNum, short xVel, short yVel, short zVel) -{ - FX_INFO* fx = &EffectList[fxNum]; - - int dx = LaraItem->pos.xPos - fx->pos.xPos; - int dz = LaraItem->pos.zPos - fx->pos.zPos; - - if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384) - { - SPARKS* spark = &Sparks[GetFreeSpark()]; - - spark->on = 1; - spark->sR = 0; - spark->sG = (GetRandomControl() & 0x7F) + 32; - spark->sB = spark->dG + 64; - spark->dB = 0; - spark->dG = spark->dR = (GetRandomControl() & 0x7F) + 32; - spark->fadeToBlack = 8; - spark->colFadeSpeed = (GetRandomControl() & 3) + 4; - spark->transType = COLADD; - spark->life = spark->sLife = (GetRandomControl() & 3) + 16; - spark->y = 0; - spark->x = (GetRandomControl() & 0xF) - 8; - spark->xVel = xVel; - spark->zVel = zVel; - spark->z = (GetRandomControl() & 0xF) - 8; - spark->yVel = yVel; - spark->friction = 68; - spark->flags = 602; - spark->rotAng = GetRandomControl() & 0xFFF; - if (GetRandomControl() & 1) - { - spark->rotAdd = -32 - (GetRandomControl() & 0x1F); - } - else - { - spark->rotAdd = (GetRandomControl() & 0x1F) + 32; - } - spark->gravity = 0; - spark->maxYvel = 0; - spark->fxObj = fxNum; - spark->scalar = 2; - spark->sSize = spark->size = (GetRandomControl() & 7) + 64; - spark->dSize = spark->size / 32; - } -} - -void BubblesEffect4(short fxNum, short xVel, short yVel, short zVel) -{ - FX_INFO* fx = &EffectList[fxNum]; - - int dx = LaraItem->pos.xPos - fx->pos.xPos; - int dz = LaraItem->pos.zPos - fx->pos.zPos; - - if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384) - { - SPARKS* spark = &Sparks[GetFreeSpark()]; - - spark->on = 1; - if (fx->flag1 == 3 || fx->flag1 == 4) - { + spark->on = 1; spark->sR = 0; spark->dR = 0; - spark->sB = (GetRandomControl() & 0x7F) + 32; - spark->sG = spark->sB + 64; - spark->dG = (GetRandomControl() & 0x7F) + 32; - spark->dB = spark->dG + 64; - } - else - { - spark->sR = (GetRandomControl() & 0x7F) + 32; - spark->sG = spark->sR - (GetRandomControl() & 0x1F); - spark->sB = 0; - spark->dR = (GetRandomControl() & 0x7F) + 32; - spark->dB = 0; - spark->dG = spark->dR - (GetRandomControl() & 0x1F); - } - spark->fadeToBlack = 8; - spark->colFadeSpeed = (GetRandomControl() & 3) + 4; - spark->transType = COLADD; - spark->life = spark->sLife = (GetRandomControl() & 3) + 16; - spark->y = 0; - spark->x = (GetRandomControl() & 0xF) - 8; - spark->yVel = yVel; - spark->zVel = zVel; - spark->z = (GetRandomControl() & 0xF) - 8; - spark->xVel = xVel; - spark->friction = 68; - spark->flags = 602; - spark->rotAng = GetRandomControl() & 0xFFF; - if (GetRandomControl() & 1) - { - spark->rotAdd = -32 - (GetRandomControl() & 0x1F); - } - else - { - spark->rotAdd = (GetRandomControl() & 0x1F) + 32; - } - spark->gravity = 0; - spark->maxYvel = 0; - spark->fxObj = fxNum; - spark->scalar = 2; - spark->sSize = spark->size = (GetRandomControl() & 7) + 64; - spark->dSize = spark->size / 32; - } -} - -void BubblesShatterFunction(FX_INFO* fx, int param1, int param2) -{ - ShatterItem.yRot = fx->pos.yRot; - ShatterItem.meshp = &g_Level.Meshes[fx->frameNumber]; - ShatterItem.sphere.x = fx->pos.xPos; - ShatterItem.sphere.y = fx->pos.yPos; - ShatterItem.sphere.z = fx->pos.zPos; - ShatterItem.bit = 0; - ShatterItem.flags = fx->flag2 & 0x400; - ShatterObject(&ShatterItem, 0, param2, fx->roomNumber, param1); -} - -void BubblesControl(short fxNum) -{ - FX_INFO* fx = &EffectList[fxNum]; - - short angles[2]; - phd_GetVectorAngles( - LaraItem->pos.xPos - fx->pos.xPos, - LaraItem->pos.yPos - fx->pos.yPos - STEP_SIZE, - LaraItem->pos.zPos - fx->pos.zPos, - angles); - - int maxRotation = 0; - int maxSpeed = 0; - - if (fx->flag1 == 1) - { - maxRotation = 512; - maxSpeed = 256; - } - else - { - if (fx->flag1 == 6) - { - if (fx->counter) + spark->sG = (GetRandomControl() & 0x7F) + 32; + spark->sB = spark->dG + 64; + spark->dB = (GetRandomControl() & 0x7F) + 32; + spark->dG = spark->dB + 64; + spark->fadeToBlack = 8; + spark->colFadeSpeed = (GetRandomControl() & 3) + 4; + spark->transType = TransTypeEnum::COLADD; + spark->life = spark->sLife = (GetRandomControl() & 3) + 16; + spark->y = 0; + spark->x = (GetRandomControl() & 0xF) - 8; + spark->xVel = xVel; + spark->yVel = yVel; + spark->z = (GetRandomControl() & 0xF) - 8; + spark->zVel = zVel; + spark->friction = 68; + spark->flags = 602; + spark->rotAng = GetRandomControl() & 0xFFF; + if (GetRandomControl() & 1) { - fx->counter--; + spark->rotAdd = -32 - (GetRandomControl() & 0x1F); } - maxRotation = 256; + else + { + spark->rotAdd = (GetRandomControl() & 0x1F) + 32; + } + spark->gravity = 0; + spark->maxYvel = 0; + spark->fxObj = fxNum; + if (fx->flag1 == 1) + { + spark->scalar = 3; + } + else + { + spark->scalar = 2; + } + spark->sSize = spark->size = (GetRandomControl() & 7) + 64; + spark->dSize = spark->size / 32; } - else - { - maxRotation = 768; - } - maxSpeed = 192; } - if (fx->speed < maxSpeed) + void TriggerHarpyFlameFlame(short fxNum, short xVel, short yVel, short zVel) { - if (fx->flag1 == 6) + FX_INFO* fx = &EffectList[fxNum]; + + int dx = LaraItem->pos.xPos - fx->pos.xPos; + int dz = LaraItem->pos.zPos - fx->pos.zPos; + + if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384) { - fx->speed++; + SPARKS* spark = &Sparks[GetFreeSpark()]; + + spark->on = 1; + spark->sR = 0; + spark->sG = (GetRandomControl() & 0x7F) + 32; + spark->sB = spark->dG + 64; + spark->dB = 0; + spark->dG = spark->dR = (GetRandomControl() & 0x7F) + 32; + spark->fadeToBlack = 8; + spark->colFadeSpeed = (GetRandomControl() & 3) + 4; + spark->transType = COLADD; + spark->life = spark->sLife = (GetRandomControl() & 3) + 16; + spark->y = 0; + spark->x = (GetRandomControl() & 0xF) - 8; + spark->xVel = xVel; + spark->zVel = zVel; + spark->z = (GetRandomControl() & 0xF) - 8; + spark->yVel = yVel; + spark->friction = 68; + spark->flags = 602; + spark->rotAng = GetRandomControl() & 0xFFF; + if (GetRandomControl() & 1) + { + spark->rotAdd = -32 - (GetRandomControl() & 0x1F); + } + else + { + spark->rotAdd = (GetRandomControl() & 0x1F) + 32; + } + spark->gravity = 0; + spark->maxYvel = 0; + spark->fxObj = fxNum; + spark->scalar = 2; + spark->sSize = spark->size = (GetRandomControl() & 7) + 64; + spark->dSize = spark->size / 32; } - else - { - fx->speed += 3; - } - - int dy = angles[0] - fx->pos.yRot; - if (abs(dy) <= ANGLE(180.0f)) - { - dy = -dy; - } - - int dx = angles[1] - fx->pos.xRot; - if (abs(dx) <= ANGLE(180.0f)) - dx = -dx; - - dy /= 8; - dx /= 8; - - if (dy < -maxRotation) - dy = -maxRotation; - else if (dy > maxRotation) - dy = maxRotation; - - if (dx < -maxRotation) - dx = -maxRotation; - else if (dx > maxRotation) - dx = maxRotation; - - if (fx->flag1 != 4 && (fx->flag1 != 6 || !fx->counter)) - { - fx->pos.yRot += dy; - } - fx->pos.xRot += dx; } - fx->pos.zRot += 16 * fx->speed; - if (fx->flag1 == 6) - fx->pos.zRot += 16 * fx->speed; - - int oldX = fx->pos.xPos; - int oldY = fx->pos.yPos; - int oldZ = fx->pos.zPos; - - int speed = (fx->speed * phd_cos(fx->pos.xRot)); - fx->pos.zPos += (speed * phd_cos(fx->pos.yRot)); - fx->pos.xPos += (speed * phd_sin(fx->pos.yRot)); - fx->pos.yPos += -((fx->speed * phd_sin(fx->pos.xRot))) + fx->fallspeed; - - short roomNumber = fx->roomNumber; - FLOOR_INFO* floor = GetFloor(fx->pos.xPos, fx->pos.yPos, fx->pos.zPos, &roomNumber); - int floorHeight = GetFloorHeight(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos); - int ceilingHeight = GetCeiling(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos); - - if (fx->pos.yPos >= floorHeight || fx->pos.yPos <= ceilingHeight) + void TriggerDemigodMissileFlame(short fxNum, short xVel, short yVel, short zVel) { - fx->pos.xPos = oldX; - fx->pos.yPos = oldY; - fx->pos.zPos = oldZ; + FX_INFO* fx = &EffectList[fxNum]; + + int dx = LaraItem->pos.xPos - fx->pos.xPos; + int dz = LaraItem->pos.zPos - fx->pos.zPos; + + if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384) + { + SPARKS* spark = &Sparks[GetFreeSpark()]; + + spark->on = 1; + if (fx->flag1 == 3 || fx->flag1 == 4) + { + spark->sR = 0; + spark->dR = 0; + spark->sB = (GetRandomControl() & 0x7F) + 32; + spark->sG = spark->sB + 64; + spark->dG = (GetRandomControl() & 0x7F) + 32; + spark->dB = spark->dG + 64; + } + else + { + spark->sR = (GetRandomControl() & 0x7F) + 32; + spark->sG = spark->sR - (GetRandomControl() & 0x1F); + spark->sB = 0; + spark->dR = (GetRandomControl() & 0x7F) + 32; + spark->dB = 0; + spark->dG = spark->dR - (GetRandomControl() & 0x1F); + } + spark->fadeToBlack = 8; + spark->colFadeSpeed = (GetRandomControl() & 3) + 4; + spark->transType = COLADD; + spark->life = spark->sLife = (GetRandomControl() & 3) + 16; + spark->y = 0; + spark->x = (GetRandomControl() & 0xF) - 8; + spark->yVel = yVel; + spark->zVel = zVel; + spark->z = (GetRandomControl() & 0xF) - 8; + spark->xVel = xVel; + spark->friction = 68; + spark->flags = 602; + spark->rotAng = GetRandomControl() & 0xFFF; + if (GetRandomControl() & 1) + { + spark->rotAdd = -32 - (GetRandomControl() & 0x1F); + } + else + { + spark->rotAdd = (GetRandomControl() & 0x1F) + 32; + } + spark->gravity = 0; + spark->maxYvel = 0; + spark->fxObj = fxNum; + spark->scalar = 2; + spark->sSize = spark->size = (GetRandomControl() & 7) + 64; + spark->dSize = spark->size / 32; + } + } + + void BubblesShatterFunction(FX_INFO* fx, int param1, int param2) + { + ShatterItem.yRot = fx->pos.yRot; + ShatterItem.meshp = &g_Level.Meshes[fx->frameNumber]; + ShatterItem.sphere.x = fx->pos.xPos; + ShatterItem.sphere.y = fx->pos.yPos; + ShatterItem.sphere.z = fx->pos.zPos; + ShatterItem.bit = 0; + ShatterItem.flags = fx->flag2 & 0x400; + ShatterObject(&ShatterItem, 0, param2, fx->roomNumber, param1); + } + + void ControlEnemyMissile(short fxNum) + { + FX_INFO* fx = &EffectList[fxNum]; + + short angles[2]; + phd_GetVectorAngles( + LaraItem->pos.xPos - fx->pos.xPos, + LaraItem->pos.yPos - fx->pos.yPos - STEP_SIZE, + LaraItem->pos.zPos - fx->pos.zPos, + angles); + + int maxRotation = 0; + int maxSpeed = 0; - if (fx->flag1 != 6) - BubblesShatterFunction(fx, 0, -32); - if (fx->flag1 == 1) { - TriggerShockwave(&fx->pos, 32, 160, 64, 64, 128, 00, 24, (((~g_Level.Rooms[fx->roomNumber].flags) / 16) & 2) * 65536, 0); - TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 2, fx->roomNumber); + maxRotation = 512; + maxSpeed = 256; } else { - int shockwaveValue = 0; - byte r, g, b, life; - - if (fx->flag1) + if (fx->flag1 == 6) { - if (fx->flag1 == 3 || fx->flag1 == 4) + if (fx->counter) { - shockwaveValue = 268451968; - r = 128; - g = 64; - b = 0; - life = 16; + fx->counter--; } - else if (fx->flag1 == 5) + maxRotation = 256; + } + else + { + maxRotation = 768; + } + maxSpeed = 192; + } + + if (fx->speed < maxSpeed) + { + if (fx->flag1 == 6) + { + fx->speed++; + } + else + { + fx->speed += 3; + } + + int dy = angles[0] - fx->pos.yRot; + if (abs(dy) <= ANGLE(180.0f)) + { + dy = -dy; + } + + int dx = angles[1] - fx->pos.xRot; + if (abs(dx) <= ANGLE(180.0f)) + dx = -dx; + + dy /= 8; + dx /= 8; + + if (dy < -maxRotation) + dy = -maxRotation; + else if (dy > maxRotation) + dy = maxRotation; + + if (dx < -maxRotation) + dx = -maxRotation; + else if (dx > maxRotation) + dx = maxRotation; + + if (fx->flag1 != 4 && (fx->flag1 != 6 || !fx->counter)) + { + fx->pos.yRot += dy; + } + fx->pos.xRot += dx; + } + + fx->pos.zRot += 16 * fx->speed; + if (fx->flag1 == 6) + fx->pos.zRot += 16 * fx->speed; + + int oldX = fx->pos.xPos; + int oldY = fx->pos.yPos; + int oldZ = fx->pos.zPos; + + int speed = (fx->speed * phd_cos(fx->pos.xRot)); + fx->pos.zPos += (speed * phd_cos(fx->pos.yRot)); + fx->pos.xPos += (speed * phd_sin(fx->pos.yRot)); + fx->pos.yPos += -((fx->speed * phd_sin(fx->pos.xRot))) + fx->fallspeed; + + short roomNumber = fx->roomNumber; + FLOOR_INFO* floor = GetFloor(fx->pos.xPos, fx->pos.yPos, fx->pos.zPos, &roomNumber); + int floorHeight = GetFloorHeight(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos); + int ceilingHeight = GetCeiling(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos); + + if (fx->pos.yPos >= floorHeight || fx->pos.yPos <= ceilingHeight) + { + fx->pos.xPos = oldX; + fx->pos.yPos = oldY; + fx->pos.zPos = oldZ; + + if (fx->flag1 != 6) + BubblesShatterFunction(fx, 0, -32); + + if (fx->flag1 == 1) + { + TriggerShockwave(&fx->pos, 32, 160, 64, 64, 128, 00, 24, (((~g_Level.Rooms[fx->roomNumber].flags) / 16) & 2) * 65536, 0); + TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 2, fx->roomNumber); + } + else + { + int shockwaveValue = 0; + byte r, g, b, life; + + if (fx->flag1) { - shockwaveValue = 276848640; - r = 0; - g = 96; - b = 128; - life = 16; - } - else - { - if (fx->flag1 != 2) + if (fx->flag1 == 3 || fx->flag1 == 4) { - if (fx->flag1 == 6) - { - TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 0, fx->roomNumber); - TriggerShockwave(&fx->pos, 48, 240, 64, 0, 96, 128, 24, 0, 2); - fx->pos.yPos -= 128; - TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 2); - fx->pos.yPos += 256; - TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 2); - } + shockwaveValue = 268451968; + r = 128; + g = 64; + b = 0; + life = 16; } - else + else if (fx->flag1 == 5) { - shockwaveValue = 276856832; + shockwaveValue = 276848640; r = 0; - g = 128; + g = 96; b = 128; life = 16; } + else + { + if (fx->flag1 != 2) + { + if (fx->flag1 == 6) + { + TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 0, fx->roomNumber); + TriggerShockwave(&fx->pos, 48, 240, 64, 0, 96, 128, 24, 0, 2); + fx->pos.yPos -= 128; + TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 2); + fx->pos.yPos += 256; + TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 2); + } + } + else + { + shockwaveValue = 276856832; + r = 0; + g = 128; + b = 128; + life = 16; + } + } + } + else + { + shockwaveValue = 268468288; + r = 64; + g = 128; + b = 0; + life = 16; + } + + TriggerShockwave(&fx->pos, 32, 160, 64, r, g, b, life, 0, 0); + } + + KillEffect(fxNum); + return; + } + + if (ItemNearLara(&fx->pos, 200)) + { + LaraItem->hitStatus = true; + if (fx->flag1 != 6) + { + BubblesShatterFunction(fx, 0, -32); + } + + KillEffect(fxNum); + + if (fx->flag1 == 1) + { + TriggerShockwave(&fx->pos, 48, 240, 64, 64, 128, 0, 24, 0, 0); + TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 2, fx->roomNumber); + LaraBurn(); + } + else if (fx->flag1) + { + switch (fx->flag1) + { + case 3: + case 4: + TriggerShockwave(&fx->pos, 32, 160, 64, 128, 64, 0, 16, 0, 1); + break; + case 5: + TriggerShockwave(&fx->pos, 32, 160, 64, 0, 96, 128, 16, 0, 2); + break; + case 2: + TriggerShockwave(&fx->pos, 32, 160, 64, 0, 128, 128, 16, 0, 2); + break; + case 6: + TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 0, fx->roomNumber); + TriggerShockwave(&fx->pos, 48, 240, 64, 0, 96, 128, 24, 0, 0); + fx->pos.yPos -= 128; + TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 0); + fx->pos.yPos += 256; + TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 0); + LaraBurn(); + break; } } else { - shockwaveValue = 268468288; - r = 64; - g = 128; - b = 0; - life = 16; - } - - TriggerShockwave(&fx->pos, 32, 160, 64, r, g, b, life, 0, 0); - } - - KillEffect(fxNum); - return; - } - - if (ItemNearLara(&fx->pos, 200)) - { - LaraItem->hitStatus = true; - if (fx->flag1 != 6) - { - BubblesShatterFunction(fx, 0, -32); - } - - KillEffect(fxNum); - - if (fx->flag1 == 1) - { - TriggerShockwave(&fx->pos, 48, 240, 64, 64, 128, 0, 24, 0, 0); - TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 2, fx->roomNumber); - LaraBurn(); - } - else if (fx->flag1) - { - switch (fx->flag1) - { - case 3: - case 4: - TriggerShockwave(&fx->pos, 32, 160, 64, 128, 64, 0, 16, 0, 1); - break; - case 5: - TriggerShockwave(&fx->pos, 32, 160, 64, 0, 96, 128, 16, 0, 2); - break; - case 2: - TriggerShockwave(&fx->pos, 32, 160, 64, 0, 128, 128, 16, 0, 2); - break; - case 6: - TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 0, fx->roomNumber); - TriggerShockwave(&fx->pos, 48, 240, 64, 0, 96, 128, 24, 0, 0); - fx->pos.yPos -= 128; - TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 0); - fx->pos.yPos += 256; - TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 0); - LaraBurn(); - break; + TriggerShockwave(&fx->pos, 24, 88, 48, 64, 128, 0, 16, (((~g_Level.Rooms[fx->roomNumber].flags) / 16) & 2) * 65536, 0); } } else { - TriggerShockwave( &fx->pos, 24, 88, 48, 64, 128, 0, 16, (((~g_Level.Rooms[fx->roomNumber].flags) / 16) & 2) * 65536, 0); - } - } - else - { - if (roomNumber != fx->roomNumber) - EffectNewRoom(fxNum, roomNumber); + if (roomNumber != fx->roomNumber) + EffectNewRoom(fxNum, roomNumber); - int dx = oldX - fx->pos.xPos; - int dy = oldY - fx->pos.yPos; - int dz = oldZ - fx->pos.zPos; + int dx = oldX - fx->pos.xPos; + int dy = oldY - fx->pos.yPos; + int dz = oldZ - fx->pos.zPos; - if (Wibble & 4) - { - switch (fx->flag1) + if (Wibble & 4) { + switch (fx->flag1) + { default: case 1: - BubblesEffect1(fxNum, 32 * dx, 32 * dy, 32 * dz); + TriggerSethMissileFlame(fxNum, 32 * dx, 32 * dy, 32 * dz); break; case 2: - BubblesEffect2(fxNum, 16 * dx, 16 * dy, 16 * dz); + TriggerHarpyFlameFlame(fxNum, 16 * dx, 16 * dy, 16 * dz); break; case 3: case 4: case 5: - BubblesEffect4(fxNum, 16 * dx, 16 * dy, 16 * dz); + TriggerDemigodMissileFlame(fxNum, 16 * dx, 16 * dy, 16 * dz); break; case 6: - TriggerMutantRocketEffects(fxNum, 16 * dx, 16 * dy, 16 * dz); + ten::entities::tr4::TriggerCrocgodMissileFlame(fxNum, 16 * dx, 16 * dy, 16 * dz); break; + } } } } diff --git a/TR5Main/Objects/Effects/tr4_bubbles.h b/TR5Main/Objects/Effects/tr4_bubbles.h index 33fcd8772..c0bbefb80 100644 --- a/TR5Main/Objects/Effects/tr4_bubbles.h +++ b/TR5Main/Objects/Effects/tr4_bubbles.h @@ -1,3 +1,6 @@ #pragma once -void BubblesControl(short fxNum); \ No newline at end of file +namespace ten::entities::all +{ + void ControlEnemyMissile(short fxNum); +} \ No newline at end of file diff --git a/TR5Main/Objects/TR4/Entity/tr4_crocodile.cpp b/TR5Main/Objects/TR4/Entity/tr4_crocodile.cpp index 9a0e0ec2e..77df24059 100644 --- a/TR5Main/Objects/TR4/Entity/tr4_crocodile.cpp +++ b/TR5Main/Objects/TR4/Entity/tr4_crocodile.cpp @@ -104,7 +104,7 @@ void CrocodileControl(short itemNumber) OBJECT_INFO* obj; CREATURE_INFO* crocodile; AI_INFO info; - OBJECT_Bones boneRot; + OBJECT_BONES boneRot; short angle; short boneAngle; diff --git a/TR5Main/Objects/TR4/Entity/tr4_mutant.cpp b/TR5Main/Objects/TR4/Entity/tr4_mutant.cpp index 8b8c83d49..5f9a32e7a 100644 --- a/TR5Main/Objects/TR4/Entity/tr4_mutant.cpp +++ b/TR5Main/Objects/TR4/Entity/tr4_mutant.cpp @@ -10,341 +10,324 @@ #include "objectslist.h" #include "trmath.h" -enum MUTANT_STATE +namespace ten::entities::tr4 { - MUTANT_EMPTY, - MUTANT_APPEAR, - MUTANT_IDLE, - MUTANT_SHOOT, - MUTANT_LOCUST1, - MUTANT_LOCUST2, -}; - -enum class MissileRotationType -{ - M_FRONT, - M_LEFT, - M_RIGHT -}; - -constexpr auto MUTANT_ANIM_APPEAR = 0; -constexpr auto MUTANT_SHOOT_RANGE = SQUARE(SECTOR(10)); -constexpr auto MUTANT_LOCUST1_RANGE = SQUARE(SECTOR(15)); -constexpr auto MUTANT_LOCUST2_RANGE = SQUARE(SECTOR(30)); - -static void TriggerMutantRocket(PHD_3DPOS* src, short roomNumber, short counter) -{ - FX_INFO* fx; - short fxNumber = NO_ITEM; - - fxNumber = CreateNewEffect(roomNumber); - if (fxNumber != NO_ITEM) + void TriggerCrocgodMissile(PHD_3DPOS* src, short roomNumber, short counter) { + FX_INFO* fx; + short fxNumber = NO_ITEM; + + fxNumber = CreateNewEffect(roomNumber); + if (fxNumber != NO_ITEM) + { + fx = &EffectList[fxNumber]; + fx->pos.xPos = src->xPos; + fx->pos.yPos = src->yPos - (GetRandomControl() & 0x3F) - 32; + fx->pos.zPos = src->zPos; + fx->pos.xRot = src->xRot; + fx->pos.yRot = src->yRot; + fx->pos.zRot = 0; + fx->roomNumber = roomNumber; + fx->counter = 16 * counter + 15; + fx->objectNumber = ID_ENERGY_BUBBLES; + fx->frameNumber = Objects[fx->objectNumber].meshIndex + 5 * 2; + fx->speed = (GetRandomControl() & 0x1F) + 96; + fx->flag1 = 6; + } + } + + void TriggerCrocgodMissileFlame(short fxNumber, short xVel, short yVel, short zVel) + { + FX_INFO* fx; + SPARKS* sptr; + BYTE color, life, size; + + //x = LaraItem->pos.xPos - Effects[m_fxNumber].pos.xPos; + //z = LaraItem->pos.zPos - Effects[m_fxNumber].pos.zPos; + //if (x >= -0x4000u && x <= 0x4000 && z >= -0x4000u && z <= 0x4000) + fx = &EffectList[fxNumber]; - fx->pos.xPos = src->xPos; - fx->pos.yPos = src->yPos - (GetRandomControl() & 0x3F) - 32; - fx->pos.zPos = src->zPos; - fx->pos.xRot = src->xRot; - fx->pos.yRot = src->yRot; - fx->pos.zRot = 0; - fx->roomNumber = roomNumber; - fx->counter = 16 * counter + 15; - fx->objectNumber = ID_ENERGY_BUBBLES; - fx->frameNumber = Objects[fx->objectNumber].meshIndex + 5 * 2; - fx->speed = (GetRandomControl() & 0x1F) + 96; - fx->flag1 = 6; - } -} - -void TriggerMutantRocketEffects(short fxNumber, short xVel, short yVel, short zVel) -{ - FX_INFO* fx; - SPARKS* sptr; - BYTE color, life, size; - - //x = LaraItem->pos.xPos - Effects[m_fxNumber].pos.xPos; - //z = LaraItem->pos.zPos - Effects[m_fxNumber].pos.zPos; - //if (x >= -0x4000u && x <= 0x4000 && z >= -0x4000u && z <= 0x4000) - - fx = &EffectList[fxNumber]; - sptr = &Sparks[GetFreeSpark()]; - sptr->on = true; - color = (GetRandomControl() & 0x3F) - 128; - sptr->sB = 0; - sptr->sR = color; - sptr->sG = color / 2; - color = (GetRandomControl() & 0x3F) - 128; - sptr->dB = 0; - sptr->dR = color; - sptr->dG = color / 2; - sptr->fadeToBlack = 8; - sptr->colFadeSpeed = (GetRandomControl() & 3) + 8; - sptr->transType = COLADD; - sptr->dynamic = -1; - life = (GetRandomControl() & 7) + 32; - sptr->life = life; - sptr->sLife = life; - sptr->x = (GetRandomControl() & 0xF) - 8; - sptr->y = 0; - sptr->z = (GetRandomControl() & 0xF) - 8; - sptr->x += fx->pos.xPos; - sptr->y += fx->pos.yPos; - sptr->z += fx->pos.zPos; - sptr->xVel = xVel; - sptr->yVel = yVel; - sptr->zVel = zVel; - sptr->friction = 34; - sptr->flags = SP_EXPDEF | SP_ROTATE | SP_DEF | SP_SCALE; - sptr->rotAng = GetRandomControl() & 0xFFF; - if (GetRandomControl() & 1) - sptr->rotAdd = (GetRandomControl() & 0x1F) - 32; - else - sptr->rotAdd = (GetRandomControl() & 0x1F) + 32; - sptr->gravity = 0; - sptr->maxYvel = 0; - sptr->fxObj = byte(fxNumber); - sptr->scalar = 2; - size = (GetRandomControl() & 0xF) + 128; - sptr->size = size; - sptr->sSize = size; - sptr->dSize = size / 4; -} - -static void ShootFireball(PHD_3DPOS* src, MissileRotationType rotation, short roomNumber, int timer) -{ - switch (rotation) - { - case MissileRotationType::M_LEFT: - src->yRot -= GetRandomControl() % 0x2000; - break; - case MissileRotationType::M_RIGHT: - src->yRot += GetRandomControl() % 0x2000; - break; + sptr = &Sparks[GetFreeSpark()]; + sptr->on = true; + color = (GetRandomControl() & 0x3F) - 128; + sptr->sB = 0; + sptr->sR = color; + sptr->sG = color / 2; + color = (GetRandomControl() & 0x3F) - 128; + sptr->dB = 0; + sptr->dR = color; + sptr->dG = color / 2; + sptr->fadeToBlack = 8; + sptr->colFadeSpeed = (GetRandomControl() & 3) + 8; + sptr->transType = TransTypeEnum::COLADD; + sptr->dynamic = -1; + life = (GetRandomControl() & 7) + 32; + sptr->life = life; + sptr->sLife = life; + sptr->x = (GetRandomControl() & 0xF) - 8; + sptr->y = 0; + sptr->z = (GetRandomControl() & 0xF) - 8; + sptr->x += fx->pos.xPos; + sptr->y += fx->pos.yPos; + sptr->z += fx->pos.zPos; + sptr->xVel = xVel; + sptr->yVel = yVel; + sptr->zVel = zVel; + sptr->friction = 34; + sptr->flags = SP_EXPDEF | SP_ROTATE | SP_DEF | SP_SCALE; + sptr->rotAng = GetRandomControl() & 0xFFF; + if (GetRandomControl() & 1) + sptr->rotAdd = (GetRandomControl() & 0x1F) - 32; + else + sptr->rotAdd = (GetRandomControl() & 0x1F) + 32; + sptr->gravity = 0; + sptr->maxYvel = 0; + sptr->fxObj = byte(fxNumber); + sptr->scalar = 2; + size = (GetRandomControl() & 0xF) + 128; + sptr->size = size; + sptr->sSize = size; + sptr->dSize = size / 4; } - TriggerMutantRocket(src, roomNumber, timer); -} - -static bool ShootFrame(ITEM_INFO* item) -{ - short frameNumber = (item->frameNumber - g_Level.Anims[item->objectNumber].frameBase); - if (frameNumber == 45 - //|| frameNumber == 50 - //|| frameNumber == 55 - || frameNumber == 60 - //|| frameNumber == 65 - //|| frameNumber == 70 - || frameNumber == 75) - return true; - else - return false; -} - -static void RotateHeadToTarget(ITEM_INFO* item, CREATURE_INFO* creature, int joint, short& headAngle) -{ - if (creature->enemy == nullptr) + static void ShootFireball(PHD_3DPOS* src, MissileRotationType rotation, short roomNumber, int timer) { - headAngle = item->pos.yRot; - return; - } - ITEM_INFO* enemy = creature->enemy; - PHD_VECTOR pos; - int x, z; - pos.x = 0; - pos.y = 0; - pos.z = 0; - GetJointAbsPosition(item, &pos, joint); - x = enemy->pos.xPos - pos.x; - z = enemy->pos.zPos - pos.z; - headAngle = (short)(phd_atan(z, x) - item->pos.yRot) / 2; -} - -static void GetTargetPosition(ITEM_INFO* item, PHD_3DPOS* target) -{ - PHD_VECTOR start, end; - short angles[2]; - start.x = 0; - start.y = -96; - start.z = 144; - GetJointAbsPosition(item, &start, 9); - end.x = 0; - end.y = -128; - end.z = 288; - GetJointAbsPosition(item, &end, 9); - phd_GetVectorAngles(end.x - start.x, end.y - start.y, end.z - start.z, angles); - target->xPos = end.x; - target->yPos = end.y; - target->zPos = end.z; - target->yRot = angles[0]; - target->xRot = angles[1]; - target->zRot = 0; -} - -enum CARDINAL_POINT -{ - C_NORTH = 0, - C_NORTH_EAST = 45, - C_EAST = 90, - C_EAST_SOUTH = 135, - C_SOUTH = 180, - C_SOUTH_WEST = 225, - C_WEST = 270, - C_WEST_NORTH = 315 -}; - -static void MoveItemFront(ITEM_INFO* item, int distance) -{ - short degree = short(TO_DEGREES(item->pos.yRot)); - switch (degree) - { - case C_NORTH: - item->pos.zPos += distance; - break; - case C_EAST: - item->pos.xPos += distance; - break; - case C_SOUTH: - item->pos.zPos -= distance; - break; - case C_WEST: - item->pos.xPos -= distance; - break; - } -} - -static void MoveItemBack(ITEM_INFO* item, int distance) -{ - short degree = short(TO_DEGREES(item->pos.yRot)); - switch (degree) - { - case C_NORTH: - item->pos.zPos -= distance; - break; - case C_EAST: - item->pos.xPos -= distance; - break; - case C_SOUTH: - item->pos.zPos += distance; - break; - case C_WEST: - item->pos.xPos += distance; - break; - } -} - -static void MutantAIFix(ITEM_INFO* item, AI_INFO* info) -{ - MoveItemFront(item, SECTOR(2)); - item->pos.yPos -= CLICK(3); - CreatureAIInfo(item, info); - item->pos.yPos += CLICK(3); - MoveItemBack(item, SECTOR(2)); -} - -void InitialiseMutant(short itemNumber) -{ - ITEM_INFO* item; - InitialiseCreature(itemNumber); - - item = &g_Level.Items[itemNumber]; - item->animNumber = Objects[item->objectNumber].animIndex + MUTANT_ANIM_APPEAR; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - item->currentAnimState = MUTANT_APPEAR; - item->goalAnimState = MUTANT_APPEAR; -} - -void MutantControl(short itemNumber) -{ - if (!CreatureActive(itemNumber)) - return; - - ITEM_INFO* item; - CREATURE_INFO* mutant; - AI_INFO info; - OBJECT_Bones mutant_joint; - short frameNumber; - short headY; - short angle; - - item = &g_Level.Items[itemNumber]; - mutant = GetCreatureInfo(item); - angle = 0; - headY = 0; - - if (item->aiBits & ALL_AIOBJ) - GetAITarget(mutant); - else if (mutant->hurtByLara) - mutant->enemy = LaraItem; - else - TargetNearestEntity(item, mutant); - - MutantAIFix(item, &info); - RotateHeadToTarget(item, mutant, 9, headY); - GetCreatureMood(item, &info, VIOLENT); - CreatureMood(item, &info, VIOLENT); - mutant->maximumTurn = 0; - angle = CreatureTurn(item, 0); - - switch (item->currentAnimState) - { - case MUTANT_IDLE: - if (info.ahead) + switch (rotation) { - int random = GetRandomControl() & 31; - if ((random > 0 && random < 10) && info.distance <= MUTANT_SHOOT_RANGE) - item->goalAnimState = MUTANT_SHOOT; - else if ((random > 10 && random < 20) && info.distance <= MUTANT_LOCUST1_RANGE) - item->goalAnimState = MUTANT_LOCUST1; - else if ((random > 20 && random < 30) && info.distance <= MUTANT_LOCUST2_RANGE) - item->goalAnimState = MUTANT_LOCUST2; + case MissileRotationType::M_LEFT: + src->yRot -= GetRandomControl() % 0x2000; + break; + case MissileRotationType::M_RIGHT: + src->yRot += GetRandomControl() % 0x2000; + break; } - break; - case MUTANT_SHOOT: - frameNumber = (item->frameNumber - g_Level.Anims[item->objectNumber].frameBase); - if (frameNumber >= 94 && frameNumber <= 96) - { - PHD_3DPOS src; - GetTargetPosition(item, &src); - if (frameNumber == 94) - { - ShootFireball(&src, MissileRotationType::M_FRONT, item->roomNumber, 0); - } - else if (frameNumber == 95) - { - ShootFireball(&src, MissileRotationType::M_LEFT, item->roomNumber, 1); - //ShootFireball(&src, MissileRotationType::M_LEFT, item->roomNumber, 1); - } - else if (frameNumber == 96) - { - ShootFireball(&src, MissileRotationType::M_RIGHT, item->roomNumber, 1); - //ShootFireball(&src, MissileRotationType::M_RIGHT, item->roomNumber, 1); - } - } - break; - case MUTANT_LOCUST1: - frameNumber = (item->frameNumber - g_Level.Anims[item->objectNumber].frameBase); - if (frameNumber >= 60 && frameNumber <= 120) - ten::entities::tr4::SpawnLocust(item); - break; - case MUTANT_LOCUST2: - if (ShootFrame(item)) - { - PHD_3DPOS src; - GetTargetPosition(item, &src); - ShootFireball(&src, MissileRotationType::M_FRONT, item->roomNumber, 1); - } - break; + + TriggerCrocgodMissile(src, roomNumber, timer); } - if (item->currentAnimState != MUTANT_LOCUST1) - mutant_joint = OBJECT_Bones(headY, info.xAngle, true); - else - mutant_joint = OBJECT_Bones(0); + static bool ShootFrame(ITEM_INFO* item) + { + short frameNumber = (item->frameNumber - g_Level.Anims[item->objectNumber].frameBase); + if (frameNumber == 45 + //|| frameNumber == 50 + //|| frameNumber == 55 + || frameNumber == 60 + //|| frameNumber == 65 + //|| frameNumber == 70 + || frameNumber == 75) + return true; + else + return false; + } - CreatureJoint(item, 0, mutant_joint.bone0); - CreatureJoint(item, 1, mutant_joint.bone1); - CreatureJoint(item, 2, mutant_joint.bone2); - CreatureJoint(item, 3, mutant_joint.bone3); - CreatureAnimation(itemNumber, angle, 0); -} + static void RotateHeadToTarget(ITEM_INFO* item, CREATURE_INFO* creature, int joint, short& headAngle) + { + if (creature->enemy == nullptr) + { + headAngle = item->pos.yRot; + return; + } + ITEM_INFO* enemy = creature->enemy; + PHD_VECTOR pos; + int x, z; + pos.x = 0; + pos.y = 0; + pos.z = 0; + GetJointAbsPosition(item, &pos, joint); + x = enemy->pos.xPos - pos.x; + z = enemy->pos.zPos - pos.z; + headAngle = (short)(phd_atan(z, x) - item->pos.yRot) / 2; + } + static void GetTargetPosition(ITEM_INFO* item, PHD_3DPOS* target) + { + PHD_VECTOR start, end; + short angles[2]; + start.x = 0; + start.y = -96; + start.z = 144; + GetJointAbsPosition(item, &start, 9); + end.x = 0; + end.y = -128; + end.z = 288; + GetJointAbsPosition(item, &end, 9); + phd_GetVectorAngles(end.x - start.x, end.y - start.y, end.z - start.z, angles); + target->xPos = end.x; + target->yPos = end.y; + target->zPos = end.z; + target->yRot = angles[0]; + target->xRot = angles[1]; + target->zRot = 0; + } + + enum CARDINAL_POINT + { + C_NORTH = 0, + C_NORTH_EAST = 45, + C_EAST = 90, + C_EAST_SOUTH = 135, + C_SOUTH = 180, + C_SOUTH_WEST = 225, + C_WEST = 270, + C_WEST_NORTH = 315 + }; + + static void MoveItemFront(ITEM_INFO* item, int distance) + { + short degree = short(TO_DEGREES(item->pos.yRot)); + switch (degree) + { + case C_NORTH: + item->pos.zPos += distance; + break; + case C_EAST: + item->pos.xPos += distance; + break; + case C_SOUTH: + item->pos.zPos -= distance; + break; + case C_WEST: + item->pos.xPos -= distance; + break; + } + } + + static void MoveItemBack(ITEM_INFO* item, int distance) + { + short degree = short(TO_DEGREES(item->pos.yRot)); + switch (degree) + { + case C_NORTH: + item->pos.zPos -= distance; + break; + case C_EAST: + item->pos.xPos -= distance; + break; + case C_SOUTH: + item->pos.zPos += distance; + break; + case C_WEST: + item->pos.xPos += distance; + break; + } + } + + static void MutantAIFix(ITEM_INFO* item, AI_INFO* info) + { + MoveItemFront(item, SECTOR(2)); + item->pos.yPos -= CLICK(3); + CreatureAIInfo(item, info); + item->pos.yPos += CLICK(3); + MoveItemBack(item, SECTOR(2)); + } + + void InitialiseCrocgod(short itemNumber) + { + ITEM_INFO* item; + InitialiseCreature(itemNumber); + + item = &g_Level.Items[itemNumber]; + item->animNumber = Objects[item->objectNumber].animIndex + MUTANT_ANIM_APPEAR; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + item->currentAnimState = STATE_MUTANT_APPEAR; + item->goalAnimState = STATE_MUTANT_APPEAR; + } + + void CrocgodControl(short itemNumber) + { + if (!CreatureActive(itemNumber)) + return; + + ITEM_INFO* item; + CREATURE_INFO* mutant; + AI_INFO info; + OBJECT_BONES mutant_joint; + short frameNumber; + short headY; + short angle; + + item = &g_Level.Items[itemNumber]; + mutant = GetCreatureInfo(item); + angle = 0; + headY = 0; + + if (item->aiBits & ALL_AIOBJ) + GetAITarget(mutant); + else if (mutant->hurtByLara) + mutant->enemy = LaraItem; + else + TargetNearestEntity(item, mutant); + + MutantAIFix(item, &info); + RotateHeadToTarget(item, mutant, 9, headY); + GetCreatureMood(item, &info, VIOLENT); + CreatureMood(item, &info, VIOLENT); + mutant->maximumTurn = 0; + angle = CreatureTurn(item, 0); + + switch (item->currentAnimState) + { + case STATE_MUTANT_IDLE: + if (info.ahead) + { + int random = GetRandomControl() & 31; + if ((random > 0 && random < 10) && info.distance <= MUTANT_SHOOT_RANGE) + item->goalAnimState = STATE_MUTANT_SHOOT; + else if ((random > 10 && random < 20) && info.distance <= MUTANT_LOCUST1_RANGE) + item->goalAnimState = STATE_MUTANT_LOCUST1; + else if ((random > 20 && random < 30) && info.distance <= MUTANT_LOCUST2_RANGE) + item->goalAnimState = STATE_MUTANT_LOCUST2; + } + break; + + case STATE_MUTANT_SHOOT: + frameNumber = (item->frameNumber - g_Level.Anims[item->objectNumber].frameBase); + if (frameNumber >= 94 && frameNumber <= 96) + { + PHD_3DPOS src; + GetTargetPosition(item, &src); + if (frameNumber == 94) + { + ShootFireball(&src, MissileRotationType::M_FRONT, item->roomNumber, 0); + } + else if (frameNumber == 95) + { + ShootFireball(&src, MissileRotationType::M_LEFT, item->roomNumber, 1); + //ShootFireball(&src, MissileRotationType::M_LEFT, item->roomNumber, 1); + } + else if (frameNumber == 96) + { + ShootFireball(&src, MissileRotationType::M_RIGHT, item->roomNumber, 1); + //ShootFireball(&src, MissileRotationType::M_RIGHT, item->roomNumber, 1); + } + } + break; + + case STATE_MUTANT_LOCUST1: + frameNumber = (item->frameNumber - g_Level.Anims[item->objectNumber].frameBase); + if (frameNumber >= 60 && frameNumber <= 120) + ten::entities::tr4::SpawnLocust(item); + break; + + case STATE_MUTANT_LOCUST2: + if (ShootFrame(item)) + { + PHD_3DPOS src; + GetTargetPosition(item, &src); + ShootFireball(&src, MissileRotationType::M_FRONT, item->roomNumber, 1); + } + break; + } + + if (item->currentAnimState != STATE_MUTANT_LOCUST1) + mutant_joint = OBJECT_BONES(headY, info.xAngle, true); + else + mutant_joint = OBJECT_BONES(0); + + CreatureJoint(item, 0, mutant_joint.bone0); + CreatureJoint(item, 1, mutant_joint.bone1); + CreatureJoint(item, 2, mutant_joint.bone2); + CreatureJoint(item, 3, mutant_joint.bone3); + CreatureAnimation(itemNumber, angle, 0); + } +} \ No newline at end of file diff --git a/TR5Main/Objects/TR4/Entity/tr4_mutant.h b/TR5Main/Objects/TR4/Entity/tr4_mutant.h index b32827a5c..33a4140f1 100644 --- a/TR5Main/Objects/TR4/Entity/tr4_mutant.h +++ b/TR5Main/Objects/TR4/Entity/tr4_mutant.h @@ -1,5 +1,33 @@ #pragma once -void InitialiseMutant(short itemNumber); -void MutantControl(short itemNumber); -void TriggerMutantRocketEffects(short fxNumber, short xVel, short yVel, short zVel); \ No newline at end of file +#include "framework.h" +#include "trmath.h" + +namespace ten::entities::tr4 +{ + enum MUTANT_STATE + { + STATE_MUTANT_EMPTY, + STATE_MUTANT_APPEAR, + STATE_MUTANT_IDLE, + STATE_MUTANT_SHOOT, + STATE_MUTANT_LOCUST1, + STATE_MUTANT_LOCUST2, + }; + + enum class MissileRotationType + { + M_FRONT, + M_LEFT, + M_RIGHT + }; + + constexpr auto MUTANT_ANIM_APPEAR = 0; + constexpr auto MUTANT_SHOOT_RANGE = SQUARE(SECTOR(10)); + constexpr auto MUTANT_LOCUST1_RANGE = SQUARE(SECTOR(15)); + constexpr auto MUTANT_LOCUST2_RANGE = SQUARE(SECTOR(30)); + + void InitialiseCrocgod(short itemNumber); + void CrocgodControl(short itemNumber); + void TriggerCrocgodMissileFlame(short fxNumber, short xVel, short yVel, short zVel); +} \ No newline at end of file diff --git a/TR5Main/Objects/TR4/tr4_objects.cpp b/TR5Main/Objects/TR4/tr4_objects.cpp index ccd586050..46e0ce7b5 100644 --- a/TR5Main/Objects/TR4/tr4_objects.cpp +++ b/TR5Main/Objects/TR4/tr4_objects.cpp @@ -664,8 +664,8 @@ static void StartBaddy(OBJECT_INFO* obj) obj = &Objects[ID_CROCODILE_GOD]; if (obj->loaded) { - obj->initialise = InitialiseMutant; - obj->control = MutantControl; + obj->initialise = ten::entities::tr4::InitialiseCrocgod; + obj->control = ten::entities::tr4::CrocgodControl; obj->collision = CreatureCollision; obj->shadowSize = UNIT_SHADOW / 2; obj->hitPoints = NOT_TARGETABLE; diff --git a/TR5Main/Objects/TR5/tr5_objects.cpp b/TR5Main/Objects/TR5/tr5_objects.cpp index 4861ca73e..ef6cf0862 100644 --- a/TR5Main/Objects/TR5/tr5_objects.cpp +++ b/TR5Main/Objects/TR5/tr5_objects.cpp @@ -1241,7 +1241,7 @@ static void StartShatter(OBJECT_INFO *obj) static void StartProjectiles(OBJECT_INFO *obj) { - InitProjectile(obj, BubblesControl, ID_ENERGY_BUBBLES, true); + InitProjectile(obj, ten::entities::all::ControlEnemyMissile, ID_ENERGY_BUBBLES, true); InitProjectile(obj, MissileControl, ID_BUBBLES, true); InitProjectile(obj, MissileControl, ID_IMP_ROCK, true); InitProjectile(obj, TorpedoControl, ID_TORPEDO); diff --git a/TR5Main/Objects/objectslist.h b/TR5Main/Objects/objectslist.h index c4995b9f8..ca4046fa1 100644 --- a/TR5Main/Objects/objectslist.h +++ b/TR5Main/Objects/objectslist.h @@ -110,7 +110,7 @@ enum GAME_OBJECT_ID : short ID_DOBERMAN, ID_HAMMERHEAD, // TR4 - OK ID_CROCODILE_GOD, // TR4 Citadel Gate Mutant - ID_LOCUSTS_EMITTER, + ID_LOCUSTS_EMITTER, // TR4 - OK /* Humans */ ID_SCUBA_HARPOON = 150, diff --git a/TR5Main/TR5Main.vcxproj b/TR5Main/TR5Main.vcxproj index 963ed4372..e256f21e6 100644 --- a/TR5Main/TR5Main.vcxproj +++ b/TR5Main/TR5Main.vcxproj @@ -711,7 +711,6 @@ xcopy /Y "$(ProjectDir)Shaders\HUD\*.hlsl" "$(TargetDir)\Shaders\HUD\" -