#include "newobjects.h" #include "..\Global\global.h" #include "..\Game\Box.h" #include "..\Game\items.h" #include "..\Game\lot.h" #include "..\Game\control.h" #include "..\Game\effects.h" #include "..\Game\draw.h" #include "..\Game\sphere.h" #include "..\Game\effect2.h" #include "..\Game\people.h" #include "..\Game\lara.h" void __cdecl InitialiseDemigod(__int16 itemNum) { ITEM_INFO* item = &Items[itemNum]; ClearItem(itemNum); item->animNumber = Objects[item->objectNumber].animIndex; item->goalAnimState = 0; item->frameNumber = Anims[item->animNumber].frameBase; item->currentAnimState = 0; /*if (LevelItems > 0) { ITEM_INFO* currentItem = &Items[0]; __int32 k = 0; while (item == currentItem || currentItem->objectNumber != ID_DEMIGOD3 || currentItem->itemFlags[0]) { k++; currentItem++; if (k >= LevelItems) return; } item->itemFlags[0] = k; }*/ } void __cdecl DemigodControl(__int16 itemNum) { ITEM_INFO* item = &Items[itemNum]; __int32 someItemNum = item->itemFlags[0]; if (someItemNum && Items[someItemNum].status == ITEM_ACTIVE && Items[someItemNum].active) { item->hitPoints = Objects[item->objectNumber].hitPoints; return; } if (!CreatureActive(itemNum)) return; CREATURE_INFO* creature = (CREATURE_INFO*)item->data; __int16 tilt = 0; __int16 angle = 0; __int16 joint0 = 0; __int16 joint1 = 0; __int16 joint2 = 0; __int16 joint3 = 0; /*if (CurrentLevel == 24) { ROOM_INFO* room = &Rooms[item->roomNumber]; __int16* zone = GroundZones[FlipStatus * 2 + creature->LOT.zone]; LaraItem->boxNumber = room->floor[((LaraItem->pos.zPos - room->z) >> WALL_SHIFT) + ((LaraItem->pos.xPos - room->x) >> WALL_SHIFT) * room->xSize].box; if (zone[item->boxNumber] == zone[LaraItem->boxNumber]) { item->aiBits = 0; creature->enemy = LaraItem; } else { item->aiBits = FOLLOW; item->itemFlags[3] = Lara.location; creature->enemy = NULL; } }*/ if (item->hitPoints <= 0) { item->hitPoints = 0; if (item->currentAnimState != 8 && item->currentAnimState != 15) { if (item->currentAnimState == 1 || item->currentAnimState == 2) { item->animNumber = Objects[item->objectNumber].animIndex + 27; item->currentAnimState = 15; item->frameNumber = Anims[item->animNumber].frameBase; } else { item->animNumber = Objects[item->objectNumber].animIndex + 12; item->currentAnimState = 8; item->frameNumber = Anims[item->animNumber].frameBase; } } } else { if (item->aiBits) GetAITarget(creature); AI_INFO info; AI_INFO laraInfo; __int32 dx = 0; __int32 dy = 0; __int32 dz = 0; CreatureAIInfo(item, &info); if (creature->enemy == LaraItem) { laraInfo.ahead = info.ahead; laraInfo.angle = info.angle; laraInfo.xAngle = 0; } else { dx = LaraItem->pos.xPos - item->pos.xPos; dz = LaraItem->pos.zPos - item->pos.zPos; laraInfo.angle = ATAN(dz, dx) - item->pos.yRot; laraInfo.xAngle = 0; laraInfo.ahead = true; if (laraInfo.angle <= -ANGLE(90) || laraInfo.angle >= ANGLE(90)) laraInfo.ahead = false; dx = abs(dx); dy = item->pos.yPos - LaraItem->pos.yPos; dz = abs(dz); if (dx <= dz) laraInfo.xAngle = ATAN(dz + (dx >> 1), dy); else laraInfo.xAngle = ATAN(dx + (dz >> 1), dy); } GetCreatureMood(item, &info, VIOLENT); CreatureMood(item, &info, VIOLENT); angle = CreatureTurn(item, creature->maximumTurn); if (laraInfo.ahead) { joint0 = laraInfo.angle >> 1; joint1 = -laraInfo.xAngle; joint2 = laraInfo.angle >> 1; joint3 = laraInfo.angle >> 1; } else if (info.ahead) { joint0 = info.angle >> 1; joint1 = -info.xAngle; joint2 = info.angle >> 1; joint3 = info.angle >> 1; } switch (item->currentAnimState) { case 0: creature->maximumTurn = 0; if (info.ahead) joint1 = -info.xAngle; if (item->objectNumber == ID_DEMIGOD1) { if (info.distance >= SQUARE(3072)) { item->goalAnimState = 1; break; } if (info.bite || LaraItem->currentAnimState >= 56 && LaraItem->currentAnimState <= 61 && !Lara.location) { item->goalAnimState = 13; break; } } else { if (Targetable(item, &info)) { creature->flags = 1; if (item->objectNumber == ID_DEMIGOD2) item->goalAnimState = 3; else item->goalAnimState = 11; break; } if (item->objectNumber == ID_DEMIGOD3) { if (info.distance <= SQUARE(2048) || info.distance >= SQUARE(5120)) { item->goalAnimState = 1; break; } if (!(GetRandomControl() & 3)) { item->goalAnimState = 9; break; } } } if (info.distance <= SQUARE(3072) || item->objectNumber != ID_DEMIGOD2) { item->goalAnimState = 1; break; } item->goalAnimState = 5; break; case 1: creature->maximumTurn = 1274; if (info.distance < SQUARE(2048)) { item->goalAnimState = 0; break; } if (item->objectNumber == ID_DEMIGOD1) { if (info.distance < SQUARE(3072)) { item->goalAnimState = 0; break; } } else { if (Targetable(item, &info)) { item->goalAnimState = 0; break; } } if (info.distance > SQUARE(3072)) { if (item->objectNumber == ID_DEMIGOD2) { item->goalAnimState = 5; } else { item->goalAnimState = 2; } } break; case 2: creature->maximumTurn = 1274; if (info.distance < SQUARE(2048)) { item->goalAnimState = 0; break; } if (item->objectNumber == ID_DEMIGOD1) { if (info.distance < SQUARE(3072)) { item->goalAnimState = 0; break; } } else { if (Targetable(item, &info) || item->objectNumber == ID_DEMIGOD3 && info.distance > SQUARE(2048)) { item->goalAnimState = 0; break; } if (info.distance < SQUARE(3072)) { item->goalAnimState = 1; } } break; case 3: if (info.ahead) { joint1 = -info.xAngle; } creature->maximumTurn = 0; if (item->animNumber == Objects[item->objectNumber].animIndex + 6) { 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 (Targetable(item, &info) || creature->flags) { item->goalAnimState = 4; creature->flags = 0; } else { item->goalAnimState = 0; creature->flags = 0; } break; case 4: case 12: DemigodEnergyAttack(itemNum); break; case 6: creature->maximumTurn = ANGLE(7); if (Targetable(item, &info)) { item->goalAnimState = 7; } break; case 9: creature->maximumTurn = ANGLE(7); if (!Targetable(item, &info) && info.distance < SQUARE(5120)) { item->goalAnimState = 10; } break; case 10: creature->maximumTurn = ANGLE(7); DemigodEnergyAttack(itemNum); if (!Targetable(item, &info) || info.distance < SQUARE(5120) || !GetRandomControl()) { item->goalAnimState = 0; break; } break; case 11: joint2 = joint0; joint0 = 0; if (info.ahead) { joint1 = -info.xAngle; } creature->maximumTurn = 0; if (item->animNumber == Objects[(signed __int16)item->objectNumber].animIndex + 6) { 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 (Targetable(item, &info) || creature->flags) { item->goalAnimState = 12; creature->flags = 0; } else { item->goalAnimState = 0; creature->flags = 0; } break; case 13: // Aiming creature->maximumTurn = 0; joint2 = joint0; joint0 = 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 (info.distance >= SQUARE(3072) || !info.bite && (LaraItem->currentAnimState < 56 || LaraItem->currentAnimState > 61 || Lara.location)) { item->goalAnimState = 0; } else { item->goalAnimState = 14; } break; case 14: // Hammer attack if (item->frameNumber - Anims[item->animNumber].frameBase == 26) { PHD_VECTOR pos; pos.x = 80; pos.y = -8; pos.z = -40; GetJointAbsPosition(item, &pos, 17); __int16 roomNumber = item->roomNumber; FLOOR_INFO* floor = GetFloor(pos.x, pos.y, pos.z, &roomNumber); __int32 height = GetFloorHeight(floor, pos.x, pos.y, pos.z); if (height == -32512) { pos.y = pos.y - 128; } else { pos.y = height - 128; } TriggerShockwave((PHD_3DPOS *)&pos, 0x00580018, 256, 545292416, 0x20000, 0); DemigodHammerAttack(pos.x, pos.y + 128, pos.z, 8); Camera.bounce = -128; if (LaraItem->currentAnimState >= 56 && LaraItem->currentAnimState <= 61 && !Lara.location) { Lara.torsoXrot = 0; // dword_80DF6C Lara.torsoYrot = 0; // dword_80DF6C Lara.headXrot = 0; Lara.headYrot = 0; LaraItem->goalAnimState = 3; LaraItem->currentAnimState = 3; LaraItem->animNumber = 34; LaraItem->frameNumber = Anims[item->animNumber].frameBase; LaraItem->hitStatus = true; LaraItem->speed = 2; LaraItem->fallspeed = 1; Lara.gunStatus = LG_NO_ARMS; } } default: break; } } CreatureTilt(item, 0); CreatureJoint(item, 0, joint0); CreatureJoint(item, 1, joint1); CreatureJoint(item, 2, joint2); CreatureJoint(item, 3, joint3); CreatureAnimation(itemNum, angle, 0); } void __cdecl DemigodThrowEnergyAttack(PHD_3DPOS* pos, __int16 roomNumber, __int32 something) { return; __int16 fxNum = CreateNewEffect(roomNumber); if (fxNum != -1) { FX_INFO* fx = &Effects[fxNum]; fx->pos.xPos = pos->xPos; fx->pos.yPos = pos->yPos - (GetRandomControl() & 0x3F) - 32; fx->pos.zPos = pos->zPos; fx->pos.xRot = pos->xRot; if (something < 4) { fx->pos.yRot = pos->yRot; } else { fx->pos.yRot = pos->yRot + (GetRandomControl() & 0x7FF) - 1024; } fx->pos.zRot = 0; fx->roomNumber = roomNumber; fx->counter = 2 * GetRandomControl() + -ANGLE(180); fx->flag1 = something; fx->speed = (GetRandomControl() & 0x1F) + 96; fx->objectNumber = ID_BUBBLES; if (something >= 4) something--; fx->frameNumber = Objects[ID_BUBBLES].meshIndex + 2 * something; } } void __cdecl DemigodEnergyAttack(__int16 itemNum) { ITEM_INFO* item = &Items[itemNum]; __int16 animIndex = item->animNumber - Objects[item->objectNumber].animIndex; if (animIndex != 8 && animIndex != 16 && animIndex != 19) return; if (animIndex == 8) { if (item->frameNumber == Anims[item->animNumber].frameBase) { PHD_VECTOR pos1; PHD_VECTOR pos2; pos1.x = -544; pos1.y = 96; pos1.z = 0; GetJointAbsPosition(item, &pos1, 16); pos2.x = -900; pos2.y = 96; pos2.z = 0; GetJointAbsPosition(item, &pos2, 16); __int16 angles[2]; phd_GetVectorAngles(pos2.x - pos1.x, pos2.y - pos1.y, pos2.z - pos1.z, angles); PHD_3DPOS pos; pos.xPos = pos1.x; pos.yPos = pos1.y; pos.zPos = pos1.z; pos.xRot = angles[0]; pos.yRot = angles[1]; pos.zRot = 0; if (item->objectNumber == ID_DEMIGOD3) { DemigodThrowEnergyAttack(&pos, item->roomNumber, 3); } else { DemigodThrowEnergyAttack(&pos, item->roomNumber, 5); } } } else { __int32 frameNumber = item->frameNumber - Anims[item->animNumber].frameBase; if (frameNumber >= 8 && frameNumber <= 64) { PHD_VECTOR pos1; PHD_VECTOR pos2; pos1.x = 0; pos1.y = 0; pos1.z = 192; pos2.x = 0; pos2.y = 0; pos2.z = 384; if (GlobalCounter & 1) { GetJointAbsPosition(item, &pos1, 18); GetJointAbsPosition(item, &pos2, 18); } else { GetJointAbsPosition(item, &pos1, 17); GetJointAbsPosition(item, &pos2, 17); } __int16 angles[2]; phd_GetVectorAngles(pos2.x - pos1.x, pos2.y - pos1.y, pos2.z - pos1.z, angles); PHD_3DPOS pos; pos.xPos = pos1.x; pos.yPos = pos1.y; pos.zPos = pos1.z; pos.xRot = angles[0]; pos.yRot = angles[1]; pos.zRot = 0; DemigodThrowEnergyAttack(&pos, item->roomNumber, 4); } } } void __cdecl DemigodHammerAttack(__int32 x, __int32 y, __int32 z, __int32 something) { __int32 angle = 2 * GetRandomControl(); __int32 deltaAngle = 0x10000 / something; if (something > 0) { for (__int32 i = 0; i < something; i++) { SMOKE_SPARKS* spark = &SmokeSparks[GetFreeSmokeSpark()]; spark->On = true; spark->sShade = 0; spark->ColFadeSpeed = 4; spark->dShade = (GetRandomControl() & 0x1F) + 96; spark->FadeToBlack = 24 - (GetRandomControl() & 7); spark->TransType = 2; spark->Life = spark->sLife = (GetRandomControl() & 7) + 48; spark->x = (GetRandomControl() & 0x1F) + x - 16; spark->y = (GetRandomControl() & 0x1F) + y - 16; spark->z = (GetRandomControl() & 0x1F) + z - 16; spark->Xvel = (byte)(GetRandomControl() + 256) * SIN(angle) >> W2V_SHIFT; spark->Yvel = -32 - (GetRandomControl() & 0x3F); spark->Zvel = (byte)(GetRandomControl() + 256) * COS(angle) >> W2V_SHIFT; spark->Friction = 9; if (GetRandomControl() & 1) { spark->Flags = 16; spark->RotAng = GetRandomControl() & 0xFFF; if (GetRandomControl() & 1) { spark->RotAdd = -64 - (GetRandomControl() & 0x3F); } else { spark->RotAdd = (GetRandomControl() & 0x3F) + 64; } } else if (Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND) { spark->Flags = 256; } else { spark->Flags = 0; } spark->Gravity = -4 - (GetRandomControl() & 3); spark->MaxYvel = -4 - (GetRandomControl() & 3); spark->dSize = ((GetRandomControl() & 0x3F) + 64); spark->sSize = spark->dSize >> 3; spark->Size = spark->dSize >> 3; angle += deltaAngle; } } }